Search in sources :

Example 1 with TransferCallback

use of org.alfresco.service.cmr.transfer.TransferCallback in project alfresco-repository by Alfresco.

the class TransferAsyncAction method executeImpl.

@SuppressWarnings("unchecked")
@Override
protected void executeImpl(Action action, NodeRef actionedUponNodeRef) {
    logger.debug("In TransferAsyncAction");
    String targetName = (String) action.getParameterValue("targetName");
    TransferDefinition definition = (TransferDefinition) action.getParameterValue("definition");
    Collection<TransferCallback> callback = (Collection<TransferCallback>) action.getParameterValue("callbacks");
    transferService.transfer(targetName, definition, callback);
}
Also used : TransferDefinition(org.alfresco.service.cmr.transfer.TransferDefinition) Collection(java.util.Collection) TransferCallback(org.alfresco.service.cmr.transfer.TransferCallback)

Example 2 with TransferCallback

use of org.alfresco.service.cmr.transfer.TransferCallback in project alfresco-repository by Alfresco.

the class TransferServiceImplTest method testAsyncCancel.

// test async callback
/**
 * Test the transfer cancel method when it is running async.
 *
 * This is a unit test so it does some shenanigans to send to the same instance of alfresco.
 */
@Test
public void testAsyncCancel() throws Exception {
    final int MAX_SLEEPS = 5;
    final String CONTENT_TITLE = "ContentTitle";
    final String CONTENT_NAME_A = "Demo Node A";
    final String CONTENT_NAME_B = "Demo Node B";
    final Locale CONTENT_LOCALE = Locale.GERMAN;
    final String CONTENT_STRING = "Hello";
    final String targetName = "testAsyncCallback";
    final NodeRef guestHome = repositoryHelper.getGuestHome();
    class TestContext {

        TransferTarget transferMe;

        NodeRef nodeRefA = null;

        NodeRef nodeRefB = null;
    }
    ;
    /**
     * Unit test kludge to transfer from guest home to company home
     */
    final UnitTestTransferManifestNodeFactory testNodeFactory = unitTestKludgeToTransferGuestHomeToCompanyHome();
    RetryingTransactionCallback<TestContext> setupCB = new RetryingTransactionCallback<TestContext>() {

        @Override
        public TestContext execute() throws Throwable {
            TestContext ctx = new TestContext();
            ctx.nodeRefA = nodeService.getChildByName(guestHome, ContentModel.ASSOC_CONTAINS, CONTENT_NAME_A);
            if (ctx.nodeRefA == null) {
                /**
                 * Create a test node that we will read and write
                 */
                ChildAssociationRef child = nodeService.createNode(guestHome, ContentModel.ASSOC_CONTAINS, QName.createQName(GUID.generate()), ContentModel.TYPE_CONTENT);
                ctx.nodeRefA = child.getChildRef();
                nodeService.setProperty(ctx.nodeRefA, ContentModel.PROP_TITLE, CONTENT_TITLE);
                nodeService.setProperty(ctx.nodeRefA, ContentModel.PROP_NAME, CONTENT_NAME_A);
                ContentWriter writer = contentService.getWriter(ctx.nodeRefA, ContentModel.PROP_CONTENT, true);
                writer.setLocale(CONTENT_LOCALE);
                writer.putContent(CONTENT_STRING);
            }
            ctx.nodeRefB = nodeService.getChildByName(guestHome, ContentModel.ASSOC_CONTAINS, CONTENT_NAME_B);
            if (ctx.nodeRefB == null) {
                ChildAssociationRef child = nodeService.createNode(guestHome, ContentModel.ASSOC_CONTAINS, QName.createQName(GUID.generate()), ContentModel.TYPE_CONTENT);
                ctx.nodeRefB = child.getChildRef();
                nodeService.setProperty(ctx.nodeRefB, ContentModel.PROP_TITLE, CONTENT_TITLE);
                nodeService.setProperty(ctx.nodeRefB, ContentModel.PROP_NAME, CONTENT_NAME_B);
                ContentWriter writer = contentService.getWriter(ctx.nodeRefB, ContentModel.PROP_CONTENT, true);
                writer.setLocale(CONTENT_LOCALE);
                writer.putContent(CONTENT_STRING);
            }
            /**
             * Now go ahead and create our first transfer target
             */
            if (!transferService.targetExists(targetName)) {
                createTransferTarget(targetName);
            } else {
                transferService.getTransferTarget(targetName);
            }
            return ctx;
        }
    };
    final TestContext testContext = transactionService.getRetryingTransactionHelper().doInTransaction(setupCB, false, true);
    /**
     * The transfer report is a plain report of the transfer - no async shenanigans to worry about
     */
    final List<TransferEvent> transferReport = new ArrayList<TransferEvent>(50);
    RetryingTransactionCallback<Void> transferAsyncCB = new RetryingTransactionCallback<Void>() {

        @Override
        public Void execute() throws Throwable {
            /**
             * The poison callback will cancel the transfer after
             * the begin
             */
            TransferCallback poison = new TransferCallback() {

                String transferId = null;

                public void processEvent(TransferEvent event) {
                    logger.debug(event.toString());
                    if (event instanceof TransferEventBegin) {
                        TransferEventBegin beginEvent = (TransferEventBegin) event;
                        transferId = beginEvent.getTransferId();
                        transferService.cancelAsync(transferId);
                    }
                }
            };
            TestTransferCallback callback = new TestTransferCallback();
            Set<TransferCallback> callbacks = new HashSet<TransferCallback>();
            callbacks.add(callback);
            callbacks.add(poison);
            TransferDefinition definition = new TransferDefinition();
            Set<NodeRef> nodes = new HashSet<NodeRef>();
            nodes.add(testContext.nodeRefA);
            nodes.add(testContext.nodeRefB);
            definition.setNodes(nodes);
            transferService.transferAsync(targetName, definition, callbacks);
            logger.debug("transfer async has returned");
            /**
             * Need to poll the transfer events here until callback receives the last event
             */
            Queue<TransferEvent> events = callback.getEvents();
            int sleepCount = MAX_SLEEPS;
            boolean ended = false;
            TransferEvent event = events.poll();
            while (!ended) {
                logger.debug("polling loop:" + sleepCount);
                while (event != null) {
                    /**
                     * Got an event - reset the sleep counter
                     */
                    sleepCount = MAX_SLEEPS;
                    logger.debug("Got an event" + event.toString());
                    /**
                     * Squirrel away the event for analysis later
                     */
                    transferReport.add(event);
                    /**
                     * If we read the last record which will either be SUCCESS or ERROR then we we have finished
                     */
                    if (event.isLast()) {
                        logger.debug("got last event");
                        ended = true;
                    }
                    /**
                     * Try to get the next event
                     */
                    event = events.poll();
                }
                if (event == null && !ended) {
                    if (sleepCount <= 0) {
                        fail("timed out without receiving last event");
                        ended = true;
                    } else {
                        /**
                         *  No content - go to sleep to wait for some more
                         */
                        if (sleepCount-- > 0) {
                            // Sleep for 5 second
                            Thread.sleep(5000);
                        }
                    }
                    /**
                     * Try to get the next event
                     */
                    event = events.poll();
                }
            }
            return null;
        }
    };
    transactionService.getRetryingTransactionHelper().doInTransaction(transferAsyncCB);
    /**
     * Now validate the transferReport
     */
    assertTrue("transfer report is too small", transferReport.size() > 3);
    assertTrue("transfer report does not start with START", transferReport.get(0).getTransferState().equals(TransferEvent.TransferState.START));
    assertTrue("transfer report does not end with CANCELLED", transferReport.get(transferReport.size() - 1).getTransferState().equals(TransferEvent.TransferState.CANCELLED));
// last event is the transfer report event.
}
Also used : Locale(java.util.Locale) ArrayList(java.util.ArrayList) TransferTarget(org.alfresco.service.cmr.transfer.TransferTarget) TransferDefinition(org.alfresco.service.cmr.transfer.TransferDefinition) NodeRef(org.alfresco.service.cmr.repository.NodeRef) HashSet(java.util.HashSet) TransferEvent(org.alfresco.service.cmr.transfer.TransferEvent) TransferEventBegin(org.alfresco.service.cmr.transfer.TransferEventBegin) ChildAssociationRef(org.alfresco.service.cmr.repository.ChildAssociationRef) TransferCallback(org.alfresco.service.cmr.transfer.TransferCallback) ContentWriter(org.alfresco.service.cmr.repository.ContentWriter) RetryingTransactionCallback(org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback) BaseAlfrescoSpringTest(org.alfresco.util.BaseAlfrescoSpringTest) Test(org.junit.Test)

Example 3 with TransferCallback

use of org.alfresco.service.cmr.transfer.TransferCallback in project alfresco-repository by Alfresco.

the class TransferServiceImpl2 method transferImpl.

private TransferEndEvent transferImpl(String targetName, final TransferDefinition definition, final TransferEventProcessor eventProcessor) throws TransferFailureException {
    if (logger.isDebugEnabled()) {
        logger.debug("transfer started to :" + targetName);
    }
    // transfer end event
    TransferEndEvent endEvent = null;
    Exception failureException = null;
    TransferTarget target = null;
    Transfer transfer = null;
    final List<TransferEvent> transferReportEvents = new LinkedList<TransferEvent>();
    NodeRef sourceReport = null;
    NodeRef destinationReport = null;
    File manifest = null;
    File requisite = null;
    int pollRetries = 0;
    int pollPosition = -1;
    boolean cancelled = false;
    Descriptor currentDescriptor = descriptorService.getCurrentRepositoryDescriptor();
    Descriptor serverDescriptor = descriptorService.getServerDescriptor();
    final String localRepositoryId = currentDescriptor.getId();
    TransferVersion fromVersion = new TransferVersionImpl(serverDescriptor);
    // Wire in the transferReport - so any callbacks are stored in transferReport
    TransferCallback reportCallback = new TransferCallback() {

        public void processEvent(TransferEvent event) {
            transferReportEvents.add(event);
        }
    };
    eventProcessor.addObserver(reportCallback);
    TransferContext transferContext = new TransferContext();
    // start transfer
    ClientTransferState clientState = ClientTransferState.Begin;
    while (clientState != ClientTransferState.Exit) {
        try {
            switch(clientState) {
                case Begin:
                    {
                        eventProcessor.start();
                        manifest = createManifest(definition, localRepositoryId, fromVersion, transferContext);
                        logger.debug("transfer begin");
                        target = getTransferTarget(targetName);
                        checkTargetEnabled(target);
                        transfer = transmitter.begin(target, localRepositoryId, fromVersion);
                        String transferId = transfer.getTransferId();
                        TransferStatus status = new TransferStatus();
                        transferMonitoring.put(transferId, status);
                        logger.debug("transfer begun transferId:" + transferId);
                        eventProcessor.begin(transferId);
                        checkCancel(transferId);
                        // next state
                        clientState = ClientTransferState.Prepare;
                        break;
                    }
                case Prepare:
                    {
                        // check alfresco versions are compatible
                        TransferVersion toVersion = transfer.getToVersion();
                        if (!this.transferVersionChecker.checkTransferVersions(fromVersion, toVersion)) {
                            throw new TransferException(MSG_INCOMPATIBLE_VERSIONS, new Object[] { transfer.getTransferId(), fromVersion, toVersion });
                        }
                        // send Manifest, get the requsite back.
                        eventProcessor.sendSnapshot(1, 1);
                        requisite = createRequisiteFile();
                        FileOutputStream reqOutput = new FileOutputStream(requisite);
                        transmitter.sendManifest(transfer, manifest, reqOutput);
                        logger.debug("manifest sent");
                        checkCancel(transfer.getTransferId());
                        if (logger.isDebugEnabled()) {
                            logger.debug("requisite file written to local filesystem");
                            try {
                                outputFile(requisite);
                            } catch (IOException error) {
                                // This is debug code - so an exception thrown while debugging
                                logger.debug("error while outputting snapshotFile");
                                error.printStackTrace();
                            }
                        }
                        sendContent(transfer, definition, eventProcessor, manifest, requisite);
                        logger.debug("content sending finished");
                        checkCancel(transfer.getTransferId());
                        // prepare
                        eventProcessor.prepare();
                        transmitter.prepare(transfer);
                        checkCancel(transfer.getTransferId());
                        // next state
                        clientState = ClientTransferState.Commit;
                        break;
                    }
                case Commit:
                    {
                        logger.debug("about to start committing transferId:" + transfer.getTransferId());
                        eventProcessor.commit();
                        transmitter.commit(transfer);
                        logger.debug("committing transferId:" + transfer.getTransferId());
                        checkCancel(transfer.getTransferId());
                        // next state
                        clientState = ClientTransferState.Poll;
                        break;
                    }
                case Poll:
                    {
                        TransferProgress progress = null;
                        try {
                            progress = transmitter.getStatus(transfer);
                            // reset retries for next poll
                            pollRetries = 0;
                        } catch (TransferException e) {
                            pollRetries++;
                            if (pollRetries == 3) {
                                throw new TransferException(MSG_FAILED_TO_GET_TRANSFER_STATUS, new Object[] { target.getName() });
                            }
                        }
                        // check status
                        if (progress.getStatus() == TransferProgress.Status.ERROR) {
                            Throwable targetError = progress.getError();
                            // NOTE: it's possible the error is not returned from pre v3.4 target repositories
                            if (targetError == null) {
                                targetError = new TransferException(MSG_UNKNOWN_TARGET_ERROR);
                            }
                            if (Exception.class.isAssignableFrom(targetError.getClass())) {
                                failureException = (Exception) targetError;
                            } else {
                                failureException = new TransferException(MSG_TARGET_ERROR, new Object[] { targetError.getMessage() }, targetError);
                            }
                            clientState = ClientTransferState.Finished;
                            break;
                        } else if (progress.getStatus() == TransferProgress.Status.CANCELLED) {
                            cancelled = true;
                            clientState = ClientTransferState.Finished;
                            break;
                        }
                        // notify transfer progress
                        if (progress.getCurrentPosition() != pollPosition) {
                            pollPosition = progress.getCurrentPosition();
                            logger.debug("committing :" + pollPosition);
                            eventProcessor.committing(progress.getEndPosition(), pollPosition);
                        }
                        if (progress.getStatus() == TransferProgress.Status.COMPLETE) {
                            clientState = ClientTransferState.Finished;
                            break;
                        }
                        checkCancel(transfer.getTransferId());
                        // sleep before next poll
                        try {
                            Thread.sleep(commitPollDelay);
                        } catch (InterruptedException e) {
                        // carry on
                        }
                        break;
                    }
                case Cancel:
                    {
                        logger.debug("Abort - waiting for target confirmation of cancel");
                        transmitter.abort(transfer);
                        // next state... poll for confirmation of cancel from target
                        clientState = ClientTransferState.Poll;
                        break;
                    }
                case Finished:
                    {
                        try {
                            TransferEndEventImpl endEventImpl = null;
                            String reportName = null;
                            try {
                                if (failureException != null) {
                                    logger.debug("TransferException - unable to transfer", failureException);
                                    TransferEventError errorEvent = new TransferEventError();
                                    errorEvent.setTransferState(TransferEvent.TransferState.ERROR);
                                    errorEvent.setException(failureException);
                                    errorEvent.setMessage(failureException.getMessage());
                                    endEventImpl = errorEvent;
                                    reportName = "error";
                                } else if (cancelled) {
                                    endEventImpl = new TransferEventCancelled();
                                    endEventImpl.setTransferState(TransferEvent.TransferState.CANCELLED);
                                    endEventImpl.setMessage("cancelled");
                                    reportName = "cancelled";
                                } else {
                                    logger.debug("committed transferId:" + transfer.getTransferId());
                                    endEventImpl = new TransferEventSuccess();
                                    endEventImpl.setTransferState(TransferEvent.TransferState.SUCCESS);
                                    endEventImpl.setMessage("success");
                                    reportName = "success";
                                }
                                // manually add the terminal event to the transfer report event list
                                transferReportEvents.add(endEventImpl);
                            } catch (Exception e) {
                                // report this failure as last resort
                                failureException = e;
                                reportName = "error";
                                logger.warn("Exception - unable to notify end transfer state", e);
                            }
                            reportName += "_" + new SimpleDateFormat("yyyyMMddhhmmssSSS").format(new Date());
                            try {
                                if (transfer != null) {
                                    logger.debug("now pull back the destination transfer report");
                                    destinationReport = persistDestinationTransferReport(reportName, transfer, target);
                                    if (destinationReport != null) {
                                        eventProcessor.writeReport(destinationReport, TransferEventReport.ReportType.DESTINATION, endEventImpl.getTransferState());
                                    }
                                }
                                logger.debug("now persist the client side transfer report");
                                sourceReport = persistTransferReport(reportName, transfer, target, definition, transferReportEvents, manifest, failureException);
                                if (sourceReport != null) {
                                    eventProcessor.writeReport(sourceReport, TransferEventReport.ReportType.SOURCE, endEventImpl.getTransferState());
                                }
                            } catch (Exception e) {
                                logger.warn("Exception - unable to write transfer reports", e);
                            }
                            try {
                                endEventImpl.setLast(true);
                                endEventImpl.setSourceReport(sourceReport);
                                endEventImpl.setDestinationReport(destinationReport);
                                endEvent = endEventImpl;
                                eventProcessor.end(endEvent);
                            } catch (Exception e) {
                                // report this failure as last resort
                                failureException = e;
                                logger.warn("Exception - unable to notify end transfer state", e);
                            }
                        } finally {
                            clientState = ClientTransferState.Exit;
                        }
                    }
            }
        } catch (TransferCancelledException e) {
            logger.debug("Interrupted by transfer cancel request from client");
            clientState = ClientTransferState.Cancel;
        } catch (Exception e) {
            logger.debug("Exception - unable to transfer", e);
            /**
             * Save the first exception that we encounter.
             */
            if (failureException == null) {
                failureException = e;
            }
            if (transfer != null && (clientState == ClientTransferState.Begin || clientState == ClientTransferState.Prepare || clientState == ClientTransferState.Commit)) {
                // we must first inform the target repository that a client failure has occurred to allow it to
                // clean up appropriately, too
                clientState = ClientTransferState.Cancel;
            } else {
                clientState = ClientTransferState.Finished;
            }
        }
    }
    try {
        if (endEvent == null) {
            TransferEventError error = new TransferEventError();
            error.setTransferState(TransferEvent.TransferState.ERROR);
            TransferFailureException endException = new TransferFailureException(error);
            error.setMessage(endException.getMessage());
            error.setException(endException);
            error.setSourceReport(sourceReport);
            error.setDestinationReport(destinationReport);
            error.setLast(true);
            endEvent = error;
        }
        if (endEvent instanceof TransferEventError) {
            TransferEventError endError = (TransferEventError) endEvent;
            throw new TransferFailureException(endError);
        }
        return endEvent;
    } finally {
        // clean up
        if (transfer != null) {
            transferMonitoring.remove(transfer.getTransferId());
        }
        if (manifest != null) {
            manifest.delete();
            logger.debug("manifest file deleted");
        }
        if (requisite != null) {
            requisite.delete();
            logger.debug("requisite file deleted");
        }
    }
}
Also used : TransferCancelledException(org.alfresco.service.cmr.transfer.TransferCancelledException) TransferTarget(org.alfresco.service.cmr.transfer.TransferTarget) NodeRef(org.alfresco.service.cmr.repository.NodeRef) TransferEventSuccess(org.alfresco.service.cmr.transfer.TransferEventSuccess) TransferEventError(org.alfresco.service.cmr.transfer.TransferEventError) TransferFailureException(org.alfresco.service.cmr.transfer.TransferFailureException) TransferEndEvent(org.alfresco.service.cmr.transfer.TransferEndEvent) TransferEvent(org.alfresco.service.cmr.transfer.TransferEvent) TransferEventCancelled(org.alfresco.service.cmr.transfer.TransferEventCancelled) IOException(java.io.IOException) TransferCancelledException(org.alfresco.service.cmr.transfer.TransferCancelledException) TransferFailureException(org.alfresco.service.cmr.transfer.TransferFailureException) TransferException(org.alfresco.service.cmr.transfer.TransferException) SAXException(org.xml.sax.SAXException) IOException(java.io.IOException) AlfrescoRuntimeException(org.alfresco.error.AlfrescoRuntimeException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) LinkedList(java.util.LinkedList) TransferCallback(org.alfresco.service.cmr.transfer.TransferCallback) Date(java.util.Date) TransferProgress(org.alfresco.service.cmr.transfer.TransferProgress) TransferException(org.alfresco.service.cmr.transfer.TransferException) FileOutputStream(java.io.FileOutputStream) Descriptor(org.alfresco.service.descriptor.Descriptor) File(java.io.File) TransferVersion(org.alfresco.service.cmr.transfer.TransferVersion) SimpleDateFormat(java.text.SimpleDateFormat)

Example 4 with TransferCallback

use of org.alfresco.service.cmr.transfer.TransferCallback in project alfresco-repository by Alfresco.

the class TransferTreeWithCancelActionExecuter method executeImpl.

/* (non-Javadoc)
     * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
     */
@Override
protected void executeImpl(Action action, NodeRef actionedUponNodeRef) {
    TransferTarget target = serviceRegistry.getTransactionService().getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<TransferTarget>() {

        public TransferTarget execute() throws Throwable {
            return TransferTestUtil.getTestTarget(transferService);
        }
    }, false, true);
    NodeCrawler crawler = new StandardNodeCrawlerImpl(serviceRegistry);
    crawler.setNodeFinders(new ChildAssociatedNodeFinder(ContentModel.ASSOC_CONTAINS));
    Set<NodeRef> nodes = crawler.crawl(actionedUponNodeRef);
    TransferDefinition td = new TransferDefinition();
    td.setNodes(nodes);
    transferService.transferAsync(target.getName(), td, new TransferCallback() {

        private String transferId;

        public void processEvent(TransferEvent event) {
            if (event instanceof TransferEventBegin) {
                transferId = ((TransferEventBegin) event).getTransferId();
            } else if (event instanceof TransferEventCommittingStatus) {
                transferService.cancelAsync(transferId);
            }
        }
    });
}
Also used : NodeCrawler(org.alfresco.service.cmr.transfer.NodeCrawler) RetryingTransactionHelper(org.alfresco.repo.transaction.RetryingTransactionHelper) TransferEvent(org.alfresco.service.cmr.transfer.TransferEvent) TransferEventBegin(org.alfresco.service.cmr.transfer.TransferEventBegin) TransferTarget(org.alfresco.service.cmr.transfer.TransferTarget) TransferCallback(org.alfresco.service.cmr.transfer.TransferCallback) TransferDefinition(org.alfresco.service.cmr.transfer.TransferDefinition) NodeRef(org.alfresco.service.cmr.repository.NodeRef) TransferEventCommittingStatus(org.alfresco.service.cmr.transfer.TransferEventCommittingStatus)

Example 5 with TransferCallback

use of org.alfresco.service.cmr.transfer.TransferCallback in project alfresco-repository by Alfresco.

the class TransferServiceToBeRefactoredTest method testTransferReport.

/**
 * Test the transfer report.
 *
 * This is a unit test so it does some shenanigans to send to the same instance of alfresco.
 */
@Test
public void testTransferReport() throws Exception {
    final NodeRef guestHome = repositoryHelper.getGuestHome();
    /**
     *  For unit test
     *  - replace the HTTP transport with the in-process transport
     *  - replace the node factory with one that will map node refs, paths etc.
     */
    TransferTransmitter transmitter = new UnitTestInProcessTransmitterImpl(this.receiver, this.contentService, transactionService);
    transferServiceImpl.setTransmitter(transmitter);
    UnitTestTransferManifestNodeFactory testNodeFactory = new UnitTestTransferManifestNodeFactory(this.transferManifestNodeFactory);
    transferServiceImpl.setTransferManifestNodeFactory(testNodeFactory);
    List<Pair<Path, Path>> pathMap = testNodeFactory.getPathMap();
    // Map company_home/guest_home to company_home so tranferred nodes and moved "up" one level.
    pathMap.add(new Pair<Path, Path>(PathHelper.stringToPath(GUEST_HOME_XPATH_QUERY), PathHelper.stringToPath(COMPANY_HOME_XPATH_QUERY)));
    DescriptorService mockedDescriptorService = getMockDescriptorService(REPO_ID_A);
    transferServiceImpl.setDescriptorService(mockedDescriptorService);
    /**
     * Now go ahead and create our first transfer target
     * This needs to be committed before we can call transfer asycnc.
     */
    final String CONTENT_TITLE = "ContentTitle";
    final String CONTENT_NAME_A = "Report Node A";
    final String CONTENT_NAME_B = "Report Node B";
    final Locale CONTENT_LOCALE = Locale.GERMAN;
    final String CONTENT_STRING = "Hello";
    class TestData {

        NodeRef nodeRefA;

        NodeRef nodeRefB;

        NodeRef testFolder;

        NodeRef transferReport;

        NodeRef transferDestReport;
    }
    final TestData testData = new TestData();
    final String targetName = "testTransferReport";
    transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>() {

        @Override
        public Void execute() throws Throwable {
            {
                String name = GUID.generate();
                ChildAssociationRef child = nodeService.createNode(guestHome, ContentModel.ASSOC_CONTAINS, QName.createQName(name), ContentModel.TYPE_FOLDER);
                testData.testFolder = child.getChildRef();
                nodeService.setProperty(testData.testFolder, ContentModel.PROP_TITLE, CONTENT_TITLE);
                nodeService.setProperty(testData.testFolder, ContentModel.PROP_NAME, name);
            }
            {
                /**
                 * Create a test node that we will read and write
                 */
                ChildAssociationRef child = nodeService.createNode(testData.testFolder, ContentModel.ASSOC_CONTAINS, QName.createQName(GUID.generate()), ContentModel.TYPE_CONTENT);
                testData.nodeRefA = child.getChildRef();
                nodeService.setProperty(testData.nodeRefA, ContentModel.PROP_TITLE, CONTENT_TITLE);
                nodeService.setProperty(testData.nodeRefA, ContentModel.PROP_NAME, CONTENT_NAME_A);
                ContentWriter writer = contentService.getWriter(testData.nodeRefA, ContentModel.PROP_CONTENT, true);
                writer.setLocale(CONTENT_LOCALE);
                writer.putContent(CONTENT_STRING);
            }
            {
                ChildAssociationRef child = nodeService.createNode(testData.testFolder, ContentModel.ASSOC_CONTAINS, QName.createQName(GUID.generate()), ContentModel.TYPE_CONTENT);
                testData.nodeRefB = child.getChildRef();
                nodeService.setProperty(testData.nodeRefB, ContentModel.PROP_TITLE, CONTENT_TITLE);
                nodeService.setProperty(testData.nodeRefB, ContentModel.PROP_NAME, CONTENT_NAME_B);
                ContentWriter writer = contentService.getWriter(testData.nodeRefB, ContentModel.PROP_CONTENT, true);
                writer.setLocale(CONTENT_LOCALE);
                writer.putContent(CONTENT_STRING);
            }
            /**
             * Now go ahead and create our first transfer target
             */
            if (!transferService.targetExists(targetName)) {
                createTransferTarget(targetName);
            }
            return null;
        }
    });
    /**
     * Step 1.
     * Call the transfer method. to get a failed transfer - orphan nodes exist
     */
    TestTransaction.start();
    try {
        TestTransferCallback callback = new TestTransferCallback();
        Set<TransferCallback> callbacks = new HashSet<TransferCallback>();
        callbacks.add(callback);
        TransferDefinition definition = new TransferDefinition();
        Set<NodeRef> nodes = new HashSet<NodeRef>();
        nodes.add(testData.nodeRefA);
        nodes.add(testData.nodeRefB);
        // missing the folder node (testFolder)
        definition.setNodes(nodes);
        try {
            transferService.transfer(targetName, definition, callbacks);
            fail("transfer should have failed with an orphan not found exception");
        } catch (TransferException te) {
            logger.debug("deliberatly caught and ignored exception");
        }
        // Can't dirty read transfer report here
        boolean foundSourceReport = false;
        boolean foundDestReport = false;
        for (TransferEvent event : callback.getEvents()) {
            if (event instanceof TransferEventReport) {
                TransferEventReport reportEvent = (TransferEventReport) event;
                switch(reportEvent.getReportType()) {
                    case DESTINATION:
                        foundDestReport = true;
                        testData.transferDestReport = reportEvent.getNodeRef();
                        assertNotNull("dest transfer nodeId null", testData.transferDestReport);
                        break;
                    case SOURCE:
                        foundSourceReport = true;
                        testData.transferReport = reportEvent.getNodeRef();
                        break;
                }
            }
        }
        assertTrue("source report not found", foundSourceReport);
        assertTrue("dest report not found", foundDestReport);
    } finally {
        TestTransaction.end();
    }
    /**
     * Now validate the client side error transfer report against the xsd file
     */
    transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>() {

        @Override
        public Void execute() throws Throwable {
            ContentReader reader = contentService.getReader(testData.transferReport, ContentModel.PROP_CONTENT);
            assertNotNull("transfer reader is null", reader);
            assertEquals("client report mimetype not set", reader.getMimetype(), MimetypeMap.MIMETYPE_XML);
            String name = (String) nodeService.getProperty(testData.transferReport, ContentModel.PROP_NAME);
            assertTrue("client report does not end with .xml", name.endsWith(".xml"));
            logger.debug("This report should have failed");
            if (logger.isDebugEnabled()) {
                dumpToSystemOut(testData.transferReport);
            }
            // Now validate the client side transfer report against the XSD
            Source transferReportSource = new StreamSource(reader.getContentInputStream());
            SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            final String TRANSFER_REPORT_SCHEMA_LOCATION = "classpath:org/alfresco/repo/transfer/report/TransferReport2.xsd";
            Schema schema = sf.newSchema(ResourceUtils.getURL(TRANSFER_REPORT_SCHEMA_LOCATION));
            Validator validator = schema.newValidator();
            try {
                validator.validate(transferReportSource);
            } catch (Exception e) {
                fail(e.getMessage());
            }
            return null;
        }
    });
    /**
     * Step 2
     * Call the transfer method to get a good success transfer report
     */
    transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>() {

        @Override
        public Void execute() throws Throwable {
            {
                TestTransferCallback callback = new TestTransferCallback();
                Set<TransferCallback> callbacks = new HashSet<TransferCallback>();
                callbacks.add(callback);
                TransferDefinition definition = new TransferDefinition();
                Set<NodeRef> nodes = new HashSet<NodeRef>();
                nodes.add(testData.nodeRefA);
                nodes.add(testData.nodeRefB);
                nodes.add(testData.testFolder);
                definition.setNodes(nodes);
                testData.transferReport = transferService.transfer(targetName, definition, callbacks);
                assertNotNull("transfer report is null", testData.transferReport);
                // Can't dirty read transfer report here
                boolean foundSourceReport = false;
                boolean foundDestReport = false;
                for (TransferEvent event : callback.getEvents()) {
                    if (event instanceof TransferEventReport) {
                        TransferEventReport reportEvent = (TransferEventReport) event;
                        switch(reportEvent.getReportType()) {
                            case DESTINATION:
                                foundDestReport = true;
                                testData.transferDestReport = reportEvent.getNodeRef();
                                assertNotNull("dest transfer nodeId null", testData.transferDestReport);
                                assertFalse("dest transfer nodeId not correct", testData.transferReport.equals(testData.transferDestReport));
                                break;
                            case SOURCE:
                                foundSourceReport = true;
                                assertEquals("source transfer nodeId not correct", testData.transferReport, reportEvent.getNodeRef());
                                break;
                        }
                    }
                }
                assertTrue("source report not found", foundSourceReport);
                assertTrue("dest report not found", foundDestReport);
            }
            return null;
        }
    });
    /**
     * Now validate the client side transfer report against the xsd file
     */
    transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>() {

        @Override
        public Void execute() throws Throwable {
            ContentReader reader = contentService.getReader(testData.transferReport, ContentModel.PROP_CONTENT);
            assertNotNull("transfer reader is null", reader);
            logger.debug("This report should succeed");
            if (logger.isDebugEnabled()) {
                dumpToSystemOut(testData.transferReport);
            }
            // Now validate the client side transfer report against the XSD
            Source transferReportSource = new StreamSource(reader.getContentInputStream());
            SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            final String TRANSFER_REPORT_SCHEMA_LOCATION = "classpath:org/alfresco/repo/transfer/report/TransferReport2.xsd";
            Schema schema = sf.newSchema(ResourceUtils.getURL(TRANSFER_REPORT_SCHEMA_LOCATION));
            Validator validator = schema.newValidator();
            try {
                validator.validate(transferReportSource);
            } catch (Exception e) {
                fail(e.getMessage());
            }
            return null;
        }
    });
    /**
     * Now validate the destination side transfer report against its xsd file
     */
    transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>() {

        @Override
        public Void execute() throws Throwable {
            ContentReader reader = contentService.getReader(testData.transferDestReport, ContentModel.PROP_CONTENT);
            assertNotNull("transfer reader is null", reader);
            assertEquals("dest report mimetype not set", reader.getMimetype(), MimetypeMap.MIMETYPE_XML);
            String name = (String) nodeService.getProperty(testData.transferReport, ContentModel.PROP_NAME);
            assertTrue("dest report does not end with .xml", name.endsWith(".xml"));
            if (logger.isDebugEnabled()) {
                dumpToSystemOut(testData.transferDestReport);
            }
            // Now validate the destination side transfer report against the XSD
            Source transferReportSource = new StreamSource(reader.getContentInputStream());
            SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            final String TRANSFER_REPORT_SCHEMA_LOCATION = "classpath:org/alfresco/repo/transfer/reportd/TransferDestinationReport.xsd";
            Schema schema = sf.newSchema(ResourceUtils.getURL(TRANSFER_REPORT_SCHEMA_LOCATION));
            Validator validator = schema.newValidator();
            try {
                validator.validate(transferReportSource);
            } catch (Exception e) {
                fail("Destination Transfer Report " + e.getMessage());
            }
            return null;
        }
    });
    /**
     * Now validate all transfer reports.
     */
    transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>() {

        @Override
        public Void execute() throws Throwable {
            String query = "TYPE:\"trx:transferReportDest\"";
            ResultSet results = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_LUCENE, query);
            SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            final String TRANSFER_REPORT_SCHEMA_LOCATION = "classpath:org/alfresco/repo/transfer/reportd/TransferDestinationReport.xsd";
            Schema schema = sf.newSchema(ResourceUtils.getURL(TRANSFER_REPORT_SCHEMA_LOCATION));
            Validator validator = schema.newValidator();
            for (ResultSetRow result : results) {
                NodeRef reportNode = result.getNodeRef();
                logger.debug("validating  reportNode " + reportNode);
                // Now validate the destination side transfer report against the XSD
                ContentReader reader = contentService.getReader(reportNode, ContentModel.PROP_CONTENT);
                assertNotNull("transfer reader is null", reader);
                if (reader.getMimetype().equals(MimetypeMap.MIMETYPE_XML)) {
                    Source transferReportSource = new StreamSource(reader.getContentInputStream());
                    try {
                        validator.validate(transferReportSource);
                    } catch (Exception e) {
                        fail("Destination Transfer Report reportNode:" + reportNode + " message :" + e.getMessage());
                    }
                }
            }
            return null;
        }
    });
    transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>() {

        @Override
        public Void execute() throws Throwable {
            logger.debug("now delete the target:" + targetName);
            transferService.deleteTransferTarget(targetName);
            return null;
        }
    });
}
Also used : Locale(java.util.Locale) Schema(javax.xml.validation.Schema) TransferEventReport(org.alfresco.service.cmr.transfer.TransferEventReport) StreamSource(javax.xml.transform.stream.StreamSource) Source(javax.xml.transform.Source) TransferDefinition(org.alfresco.service.cmr.transfer.TransferDefinition) NodeRef(org.alfresco.service.cmr.repository.NodeRef) ResultSet(org.alfresco.service.cmr.search.ResultSet) DescriptorService(org.alfresco.service.descriptor.DescriptorService) Pair(org.alfresco.util.Pair) HashSet(java.util.HashSet) Path(org.alfresco.service.cmr.repository.Path) SchemaFactory(javax.xml.validation.SchemaFactory) ContentReader(org.alfresco.service.cmr.repository.ContentReader) StreamSource(javax.xml.transform.stream.StreamSource) TransferEvent(org.alfresco.service.cmr.transfer.TransferEvent) ResultSetRow(org.alfresco.service.cmr.search.ResultSetRow) ChildAssociationRef(org.alfresco.service.cmr.repository.ChildAssociationRef) TransferCallback(org.alfresco.service.cmr.transfer.TransferCallback) TransferException(org.alfresco.service.cmr.transfer.TransferException) IOException(java.io.IOException) ContentWriter(org.alfresco.service.cmr.repository.ContentWriter) TransferException(org.alfresco.service.cmr.transfer.TransferException) Validator(javax.xml.validation.Validator) BaseAlfrescoSpringTest(org.alfresco.util.BaseAlfrescoSpringTest) Test(org.junit.Test)

Aggregations

TransferCallback (org.alfresco.service.cmr.transfer.TransferCallback)6 NodeRef (org.alfresco.service.cmr.repository.NodeRef)5 TransferDefinition (org.alfresco.service.cmr.transfer.TransferDefinition)5 TransferEvent (org.alfresco.service.cmr.transfer.TransferEvent)5 TransferTarget (org.alfresco.service.cmr.transfer.TransferTarget)4 HashSet (java.util.HashSet)3 Locale (java.util.Locale)3 ChildAssociationRef (org.alfresco.service.cmr.repository.ChildAssociationRef)3 ContentWriter (org.alfresco.service.cmr.repository.ContentWriter)3 BaseAlfrescoSpringTest (org.alfresco.util.BaseAlfrescoSpringTest)3 Test (org.junit.Test)3 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 RetryingTransactionHelper (org.alfresco.repo.transaction.RetryingTransactionHelper)2 RetryingTransactionCallback (org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback)2 TransferEventBegin (org.alfresco.service.cmr.transfer.TransferEventBegin)2 TransferException (org.alfresco.service.cmr.transfer.TransferException)2 File (java.io.File)1 FileOutputStream (java.io.FileOutputStream)1 SimpleDateFormat (java.text.SimpleDateFormat)1