Search in sources :

Example 1 with TransferEventCancelled

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

the class ReplicationActionExecutor method executeImpl.

@Override
protected void executeImpl(Action action, NodeRef actionedUponNodeRef) {
    if (action instanceof ReplicationDefinition) {
    // Already of the correct type
    } else if (action.getActionDefinitionName().equals(ReplicationDefinitionImpl.EXECUTOR_NAME)) {
        // Specialise the action if needed, eg when loaded directly from
        // the NodeRef without going via the replication service
        action = new ReplicationDefinitionImpl(action);
    }
    // Off we go
    final ReplicationDefinition replicationDef = (ReplicationDefinition) action;
    if (replicationDef.getTargetName() == null || replicationDef.getTargetName().equals("")) {
        throw new ReplicationServiceException(I18NUtil.getMessage(MSG_ERR_TARGET_NOT_GIVEN));
    }
    if (replicationDef.getPayload().size() == 0) {
        throw new ReplicationServiceException(I18NUtil.getMessage(MSG_ERR_NO_PAYLOADS_SPECIFIED));
    }
    if (!replicationDef.isEnabled()) {
        throw new DisabledReplicationJobException(I18NUtil.getMessage(MSG_ERR_REPLICATION_DEF_DISABLED));
    }
    if (!replicationParams.isEnabled()) {
        throw new ReplicationServiceException(I18NUtil.getMessage(MSG_ERR_UNABLE_TO_REPLICATE));
    }
    // Lock the service - only one instance of the replication
    // should occur at a time
    ReplicationDefinitionLockExtender lock = new ReplicationDefinitionLockExtender(replicationDef);
    // Turn our payload list of root nodes into something that
    // the transfer service can work with
    Set<NodeRef> toTransfer;
    try {
        toTransfer = expandPayload(replicationDef);
    } catch (Exception e) {
        lock.close();
        throw new ReplicationServiceException(I18NUtil.getMessage(MSG_ERR_PROCESSING_PAYLOAD, e.getMessage()), e);
    }
    // Ask the transfer service to do the replication
    // work for us
    TransferEndEvent endEvent = null;
    try {
        // Build the definition
        TransferDefinition transferDefinition = buildTransferDefinition(replicationDef, toTransfer);
        // Off we go
        endEvent = transferService.transfer(replicationDef.getTargetName(), transferDefinition, lock);
        if (endEvent instanceof TransferEventCancelled) {
            if (logger.isDebugEnabled())
                logger.debug("Cancelling replication job");
            // that this is correctly recorded
            throw new ActionCancelledException(replicationDef);
        }
        // Record details of the transfer reports (in success case)
        replicationDef.setLocalTransferReport(endEvent.getSourceReport());
        replicationDef.setRemoteTransferReport(endEvent.getDestinationReport());
        replicationDefinitionPersister.saveReplicationDefinition(replicationDef);
    } catch (Exception e) {
        if (e instanceof ActionCancelledException) {
            writeDefinitionReports(replicationDef, endEvent.getSourceReport(), endEvent.getDestinationReport());
            throw (ActionCancelledException) e;
        }
        if (e instanceof TransferFailureException) {
            TransferEventError failureEndEvent = ((TransferFailureException) e).getErrorEvent();
            writeDefinitionReports(replicationDef, failureEndEvent.getSourceReport(), failureEndEvent.getDestinationReport());
            Throwable cause = (e.getCause() == null) ? e : e.getCause();
            throw new ReplicationServiceException(I18NUtil.getMessage(MSG_ERR_EXECUTING_TRANSFER, cause.getMessage()), cause);
        }
        writeDefinitionReports(replicationDef, null, null);
        throw new ReplicationServiceException(I18NUtil.getMessage(MSG_ERR_EXECUTING_TRANSFER, e.getMessage()), e);
    } finally {
        lock.close();
    }
}
Also used : ReplicationServiceException(org.alfresco.service.cmr.replication.ReplicationServiceException) TransferEndEvent(org.alfresco.service.cmr.transfer.TransferEndEvent) TransferEventCancelled(org.alfresco.service.cmr.transfer.TransferEventCancelled) DisabledReplicationJobException(org.alfresco.service.cmr.replication.DisabledReplicationJobException) ActionCancelledException(org.alfresco.repo.action.ActionCancelledException) TransferFailureException(org.alfresco.service.cmr.transfer.TransferFailureException) LockAcquisitionException(org.alfresco.repo.lock.LockAcquisitionException) ReplicationServiceException(org.alfresco.service.cmr.replication.ReplicationServiceException) DisabledReplicationJobException(org.alfresco.service.cmr.replication.DisabledReplicationJobException) TransferDefinition(org.alfresco.service.cmr.transfer.TransferDefinition) NodeRef(org.alfresco.service.cmr.repository.NodeRef) ReplicationDefinition(org.alfresco.service.cmr.replication.ReplicationDefinition) ActionCancelledException(org.alfresco.repo.action.ActionCancelledException) TransferEventError(org.alfresco.service.cmr.transfer.TransferEventError) TransferFailureException(org.alfresco.service.cmr.transfer.TransferFailureException)

Example 2 with TransferEventCancelled

use of org.alfresco.service.cmr.transfer.TransferEventCancelled 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)

Aggregations

NodeRef (org.alfresco.service.cmr.repository.NodeRef)2 TransferEndEvent (org.alfresco.service.cmr.transfer.TransferEndEvent)2 TransferEventCancelled (org.alfresco.service.cmr.transfer.TransferEventCancelled)2 TransferEventError (org.alfresco.service.cmr.transfer.TransferEventError)2 TransferFailureException (org.alfresco.service.cmr.transfer.TransferFailureException)2 File (java.io.File)1 FileOutputStream (java.io.FileOutputStream)1 IOException (java.io.IOException)1 SimpleDateFormat (java.text.SimpleDateFormat)1 Date (java.util.Date)1 LinkedList (java.util.LinkedList)1 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)1 AlfrescoRuntimeException (org.alfresco.error.AlfrescoRuntimeException)1 ActionCancelledException (org.alfresco.repo.action.ActionCancelledException)1 LockAcquisitionException (org.alfresco.repo.lock.LockAcquisitionException)1 DisabledReplicationJobException (org.alfresco.service.cmr.replication.DisabledReplicationJobException)1 ReplicationDefinition (org.alfresco.service.cmr.replication.ReplicationDefinition)1 ReplicationServiceException (org.alfresco.service.cmr.replication.ReplicationServiceException)1 TransferCallback (org.alfresco.service.cmr.transfer.TransferCallback)1 TransferCancelledException (org.alfresco.service.cmr.transfer.TransferCancelledException)1