mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Fixes to replication job status handling:
- success, error and cancelled states now correctly reported - source and target reports now correctly provided for each of above Changes: - deprecated TransferService interface, replaced by TransferService2 - introduces new sync transfer methods - new TransferServiceImpl2 class, old TransferServiceImpl delegates to new class - sync transfer now returns TransferEndEvent - sync transfer now raises TransferFailureException - success, error and cancelled events are now end events (raised after report events) - transfer client handling refactored to support cancel and errors appropriately - converted to event loop with polling of server status for all states - cancel request may now end with success or error (depending on when cancel requested) - extract transfer errors from server - only raise exception for errors (cancelled now returns) - source and destination reports written for all states - Added TransferEndEvent interface for end events - reports attached to end event - replication service fixed to record source and dest reports in error case - action service fixed to record cancelled state git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@22390 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -10,6 +10,9 @@ transfer_service.comms.unsuccessful_response=Received unsuccessful response code
|
||||
transfer_service.comms.http_request_failed=Failed to execute HTTP request {0} to target: {1} status: {2}
|
||||
transfer_service.no_nodes=No nodes to transfer
|
||||
transfer_service.cancelled=Transfer cancelled
|
||||
transfer_service.failed_to_get_transfer_status=Failed to retrieve transfer status from target {0}
|
||||
transfer_service.target_error=Transfer target failed with {0}
|
||||
transfer_service.unknown_target_error=Unknown error
|
||||
|
||||
transfer_service.receiver.failed_to_create_staging_folder=Unable to create staging directory for transfer {0}
|
||||
transfer_service.receiver.lock_folder_not_found=Unable to locate specified lock folder: {0}
|
||||
|
@@ -41,10 +41,7 @@
|
||||
|
||||
<!-- Replication Service base bean -->
|
||||
<bean id="replicationService" class="org.alfresco.repo.replication.ReplicationServiceImpl" >
|
||||
<property name="nodeService" ref="NodeService" />
|
||||
<property name="actionService" ref="ActionService"/>
|
||||
<property name="dictionaryService" ref="dictionaryService" />
|
||||
<property name="transferService" ref="TransferService" />
|
||||
<property name="scheduledPersistedActionService" ref="scheduledPersistedActionService" />
|
||||
<property name="replicationDefinitionPersister" ref="replicationDefinitionPersister" />
|
||||
</bean>
|
||||
@@ -68,14 +65,14 @@
|
||||
<value>{http://www.alfresco.org/model/content/1.0}folder</value>
|
||||
</list>
|
||||
</property>
|
||||
<property name="jobLockService" ref="JobLockService" />
|
||||
<property name="transferService" ref="TransferService" />
|
||||
<property name="replicationService" ref="ReplicationService" />
|
||||
<property name="nodeCrawlerFactory" ref="NodeCrawlerFactory" />
|
||||
<property name="actionTrackingService" ref="actionTrackingService" />
|
||||
<property name="jobLockService" ref="JobLockService" />
|
||||
<property name="transferService" ref="TransferService2" />
|
||||
<property name="nodeCrawlerFactory" ref="NodeCrawlerFactory" />
|
||||
<property name="actionTrackingService" ref="actionTrackingService" />
|
||||
<property name="transactionService" ref="transactionService" />
|
||||
<property name="replicationDefinitionPersister" ref="replicationDefinitionPersister" />
|
||||
</bean>
|
||||
|
||||
|
||||
<!-- JavaScript API support -->
|
||||
<bean id="replicationServiceScript" parent="baseJavaScriptExtension"
|
||||
class="org.alfresco.repo.replication.script.ScriptReplicationService">
|
||||
|
@@ -1,8 +1,14 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
|
||||
<beans>
|
||||
<!-- Transfer Service Configuration -->
|
||||
<bean id="transferService" class="org.alfresco.repo.transfer.TransferServiceImpl"
|
||||
<!-- Transfer Service Configuration -->
|
||||
<bean id="transferService" class="org.alfresco.repo.transfer.TransferServiceImpl">
|
||||
<property name="transferServiceImpl2">
|
||||
<ref bean="transferService2" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="transferService2" class="org.alfresco.repo.transfer.TransferServiceImpl2"
|
||||
init-method="init">
|
||||
<property name="actionService">
|
||||
<ref bean="ActionService" />
|
||||
@@ -146,24 +152,41 @@
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Transfer service bean -->
|
||||
<bean id="TransferService" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||
<property name="proxyInterfaces">
|
||||
<value>org.alfresco.service.cmr.transfer.TransferService</value>
|
||||
</property>
|
||||
<property name="target">
|
||||
<ref bean="transferService" />
|
||||
</property>
|
||||
<property name="interceptorNames">
|
||||
<list>
|
||||
<idref local="TransferService_transaction" />
|
||||
<idref bean="AuditMethodInterceptor" />
|
||||
<idref bean="exceptionTranslator" />
|
||||
<idref local="TransferService_security" />
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Transfer service bean -->
|
||||
<bean id="TransferService" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||
<property name="proxyInterfaces">
|
||||
<value>org.alfresco.service.cmr.transfer.TransferService</value>
|
||||
</property>
|
||||
<property name="target">
|
||||
<ref bean="transferService" />
|
||||
</property>
|
||||
<property name="interceptorNames">
|
||||
<list>
|
||||
<idref local="TransferService_transaction" />
|
||||
<idref bean="AuditMethodInterceptor" />
|
||||
<idref bean="exceptionTranslator" />
|
||||
<idref local="TransferService_security" />
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
<bean id="TransferService2" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||
<property name="proxyInterfaces">
|
||||
<value>org.alfresco.service.cmr.transfer.TransferService2</value>
|
||||
</property>
|
||||
<property name="target">
|
||||
<ref bean="transferService2" />
|
||||
</property>
|
||||
<property name="interceptorNames">
|
||||
<list>
|
||||
<idref local="TransferService_transaction" />
|
||||
<idref bean="AuditMethodInterceptor" />
|
||||
<idref bean="exceptionTranslator" />
|
||||
<idref local="TransferService_security" />
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="TransferReceiver_security"
|
||||
class="org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor" />
|
||||
@@ -180,6 +203,7 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
|
||||
<!-- Transfer service bean -->
|
||||
<bean id="TransferReceiver" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||
<property name="proxyInterfaces">
|
||||
@@ -198,7 +222,6 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
|
||||
<bean id="transfer-async" class="org.alfresco.repo.transfer.TransferAsyncAction"
|
||||
parent="action-executer">
|
||||
|
||||
|
@@ -244,7 +244,7 @@ public class ActionTrackingServiceImpl implements ActionTrackingService
|
||||
* Schedule the recording of the action failure to occur in another
|
||||
* transaction
|
||||
*/
|
||||
public void recordActionFailure(Action action, Throwable exception)
|
||||
public void recordActionFailure(Action action, final Throwable exception)
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
@@ -313,10 +313,18 @@ public class ActionTrackingServiceImpl implements ActionTrackingService
|
||||
.createAction(actionNode);
|
||||
|
||||
// Update it
|
||||
if (exception instanceof ActionCancelledException)
|
||||
{
|
||||
action.setExecutionStatus(ActionStatus.Cancelled);
|
||||
action.setExecutionFailureMessage(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
action.setExecutionStatus(ActionStatus.Failed);
|
||||
action.setExecutionFailureMessage(exception.getMessage());
|
||||
}
|
||||
action.setExecutionStartDate(startedAt);
|
||||
action.setExecutionEndDate(endedAt);
|
||||
action.setExecutionStatus(ActionStatus.Failed);
|
||||
action.setExecutionFailureMessage(message);
|
||||
runtimeActionService.saveActionImpl(actionNode, action);
|
||||
|
||||
if (logger.isDebugEnabled() == true)
|
||||
|
@@ -27,25 +27,28 @@ import org.alfresco.repo.action.ActionCancelledException;
|
||||
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
|
||||
import org.alfresco.repo.lock.JobLockService;
|
||||
import org.alfresco.repo.lock.LockAcquisitionException;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transfer.ChildAssociatedNodeFinder;
|
||||
import org.alfresco.repo.transfer.ContentClassFilter;
|
||||
import org.alfresco.service.cmr.action.Action;
|
||||
import org.alfresco.service.cmr.action.ActionTrackingService;
|
||||
import org.alfresco.service.cmr.action.ParameterDefinition;
|
||||
import org.alfresco.service.cmr.replication.ReplicationDefinition;
|
||||
import org.alfresco.service.cmr.replication.ReplicationService;
|
||||
import org.alfresco.service.cmr.replication.ReplicationServiceException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.transfer.NodeCrawler;
|
||||
import org.alfresco.service.cmr.transfer.NodeCrawlerFactory;
|
||||
import org.alfresco.service.cmr.transfer.TransferCallback;
|
||||
import org.alfresco.service.cmr.transfer.TransferCancelledException;
|
||||
import org.alfresco.service.cmr.transfer.TransferDefinition;
|
||||
import org.alfresco.service.cmr.transfer.TransferEndEvent;
|
||||
import org.alfresco.service.cmr.transfer.TransferEvent;
|
||||
import org.alfresco.service.cmr.transfer.TransferEventBegin;
|
||||
import org.alfresco.service.cmr.transfer.TransferEventCancelled;
|
||||
import org.alfresco.service.cmr.transfer.TransferEventEnterState;
|
||||
import org.alfresco.service.cmr.transfer.TransferEventReport;
|
||||
import org.alfresco.service.cmr.transfer.TransferService;
|
||||
import org.alfresco.service.cmr.transfer.TransferEventError;
|
||||
import org.alfresco.service.cmr.transfer.TransferFailureException;
|
||||
import org.alfresco.service.cmr.transfer.TransferService2;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
@@ -60,10 +63,11 @@ public class ReplicationActionExecutor extends ActionExecuterAbstractBase {
|
||||
private static Log logger = LogFactory.getLog(ReplicationActionExecutor.class);
|
||||
|
||||
private JobLockService jobLockService;
|
||||
private TransferService transferService;
|
||||
private ReplicationService replicationService;
|
||||
private TransferService2 transferService;
|
||||
private NodeCrawlerFactory nodeCrawlerFactory;
|
||||
private ActionTrackingService actionTrackingService;
|
||||
private TransactionService transactionService;
|
||||
private ReplicationDefinitionPersisterImpl replicationDefinitionPersister;
|
||||
|
||||
/**
|
||||
* By default, we lock for 30 minutes
|
||||
@@ -80,22 +84,12 @@ public class ReplicationActionExecutor extends ActionExecuterAbstractBase {
|
||||
this.jobLockService = jobLockService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects the ReplicationService bean.
|
||||
*
|
||||
* @param nodeService the ReplicationService.
|
||||
*/
|
||||
public void setReplicationService(ReplicationService replicationService)
|
||||
{
|
||||
this.replicationService = replicationService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects the TransferService bean.
|
||||
*
|
||||
* @param transferService the TransferService.
|
||||
*/
|
||||
public void setTransferService(TransferService transferService)
|
||||
public void setTransferService(TransferService2 transferService)
|
||||
{
|
||||
this.transferService = transferService;
|
||||
}
|
||||
@@ -120,6 +114,25 @@ public class ReplicationActionExecutor extends ActionExecuterAbstractBase {
|
||||
this.actionTrackingService = actionTrackingService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects the TransactionService bean.
|
||||
*
|
||||
* @param transactionService the TransactionService.
|
||||
*/
|
||||
public void setTransactionService(TransactionService transactionService)
|
||||
{
|
||||
this.transactionService = transactionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects the ReplicationDefinitionPersister bean.
|
||||
* @param replicationDefinitionPersister
|
||||
*/
|
||||
public void setReplicationDefinitionPersister(ReplicationDefinitionPersisterImpl replicationDefinitionPersister)
|
||||
{
|
||||
this.replicationDefinitionPersister = replicationDefinitionPersister;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addParameterDefinitions(List<ParameterDefinition> paramList) {
|
||||
// Not used - our definitions hold everything on them
|
||||
@@ -197,8 +210,8 @@ public class ReplicationActionExecutor extends ActionExecuterAbstractBase {
|
||||
}
|
||||
|
||||
// Clear the previous transfer report references
|
||||
replicationDef.setLocalTransferReport(null);
|
||||
replicationDef.setRemoteTransferReport(null);
|
||||
// replicationDef.setLocalTransferReport(null);
|
||||
// replicationDef.setRemoteTransferReport(null);
|
||||
|
||||
// Lock the service - only one instance of the replication
|
||||
// should occur at a time
|
||||
@@ -215,43 +228,78 @@ public class ReplicationActionExecutor extends ActionExecuterAbstractBase {
|
||||
throw new ReplicationServiceException("Error processing payload list - " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
// Holder for reports generated by the transfer
|
||||
ReplicationReportCollector reports = new ReplicationReportCollector();
|
||||
|
||||
// Ask the transfer service to do the replication
|
||||
// work for us
|
||||
try {
|
||||
// Build the definition
|
||||
TransferDefinition transferDefinition =
|
||||
buildTransferDefinition(replicationDef, toTransfer);
|
||||
|
||||
// Off we go
|
||||
transferService.transfer(
|
||||
TransferEndEvent endEvent = null;
|
||||
try
|
||||
{
|
||||
// Build the definition
|
||||
TransferDefinition transferDefinition =
|
||||
buildTransferDefinition(replicationDef, toTransfer);
|
||||
|
||||
// Off we go
|
||||
endEvent = transferService.transfer(
|
||||
replicationDef.getTargetName(),
|
||||
transferDefinition,
|
||||
lock, reports
|
||||
);
|
||||
lock);
|
||||
|
||||
// Record the details of the transfer reports
|
||||
replicationDef.setLocalTransferReport(reports.getLocalReport());
|
||||
replicationDef.setRemoteTransferReport(reports.getRemoteReport());
|
||||
} catch(Exception e) {
|
||||
if(! (e instanceof TransferCancelledException))
|
||||
{
|
||||
lock.close();
|
||||
throw new ReplicationServiceException("Error executing transfer - " + e.getMessage(), e);
|
||||
}
|
||||
if (endEvent instanceof TransferEventCancelled)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Cancelling replication job");
|
||||
|
||||
// If we were cancelled, throw the magic exception so
|
||||
// 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());
|
||||
}
|
||||
|
||||
// All done, release our lock
|
||||
lock.close();
|
||||
|
||||
// If we were cancelled, throw the magic exception so
|
||||
// that this is correctly recorded
|
||||
if(actionTrackingService.isCancellationRequested(replicationDef))
|
||||
catch(Exception e)
|
||||
{
|
||||
throw new ActionCancelledException(replicationDef);
|
||||
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());
|
||||
throw new ReplicationServiceException("Error executing transfer - " + e.getCause().getMessage(), e);
|
||||
}
|
||||
writeDefinitionReports(replicationDef, null, null);
|
||||
throw new ReplicationServiceException("Error executing transfer - " + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeDefinitionReports(final ReplicationDefinition replicationDef, NodeRef sourceReport, NodeRef destinationReport)
|
||||
{
|
||||
replicationDef.setLocalTransferReport(sourceReport);
|
||||
replicationDef.setRemoteTransferReport(destinationReport);
|
||||
|
||||
if (replicationDef.getNodeRef() != null)
|
||||
{
|
||||
// Record details of the transfer reports
|
||||
transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionHelper.RetryingTransactionCallback<Object>()
|
||||
{
|
||||
public Object execute() throws Throwable
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Exception - writing replication def reports");
|
||||
|
||||
replicationDefinitionPersister.saveReplicationDefinition(replicationDef);
|
||||
return null;
|
||||
}
|
||||
}, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -367,53 +415,4 @@ public class ReplicationActionExecutor extends ActionExecuterAbstractBase {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link TransferCallback} which collects the various reports generated by
|
||||
* the transfer.
|
||||
*/
|
||||
protected class ReplicationReportCollector implements TransferCallback
|
||||
{
|
||||
private NodeRef localReport;
|
||||
private NodeRef remoteReport;
|
||||
|
||||
protected ReplicationReportCollector()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect source and destination repository target reports
|
||||
*/
|
||||
public void processEvent(TransferEvent event)
|
||||
{
|
||||
if(event instanceof TransferEventReport)
|
||||
{
|
||||
TransferEventReport reportEvent = (TransferEventReport)event;
|
||||
if (reportEvent.getReportType().equals(TransferEventReport.ReportType.SOURCE))
|
||||
{
|
||||
localReport = reportEvent.getNodeRef();
|
||||
}
|
||||
else if (reportEvent.getReportType().equals(TransferEventReport.ReportType.DESTINATION))
|
||||
{
|
||||
remoteReport = reportEvent.getNodeRef();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return local transfer report
|
||||
*/
|
||||
public NodeRef getLocalReport()
|
||||
{
|
||||
return localReport;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return target transfer report
|
||||
*/
|
||||
public NodeRef getRemoteReport()
|
||||
{
|
||||
return remoteReport;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -23,11 +23,8 @@ import java.util.List;
|
||||
import org.alfresco.service.cmr.action.ActionService;
|
||||
import org.alfresco.service.cmr.action.scheduled.ScheduledPersistedAction;
|
||||
import org.alfresco.service.cmr.action.scheduled.ScheduledPersistedActionService;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.replication.ReplicationDefinition;
|
||||
import org.alfresco.service.cmr.replication.ReplicationService;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.transfer.TransferService;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -40,9 +37,6 @@ public class ReplicationServiceImpl implements ReplicationService, ReplicationDe
|
||||
private static final Log log = LogFactory.getLog(ReplicationServiceImpl.class);
|
||||
|
||||
private ActionService actionService;
|
||||
private DictionaryService dictionaryService;
|
||||
private TransferService transferService;
|
||||
private NodeService nodeService;
|
||||
private ScheduledPersistedActionService scheduledPersistedActionService;
|
||||
|
||||
private ReplicationDefinitionPersisterImpl replicationDefinitionPersister;
|
||||
@@ -56,24 +50,6 @@ public class ReplicationServiceImpl implements ReplicationService, ReplicationDe
|
||||
this.replicationDefinitionPersister = replicationDefinitionPersister;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects the TransferService bean
|
||||
* @param transferService
|
||||
*/
|
||||
public void setTransferService(TransferService transferService)
|
||||
{
|
||||
this.transferService = transferService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects the NodeService bean.
|
||||
* @param nodeService
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects the ActionService bean.
|
||||
* @param actionService
|
||||
@@ -83,15 +59,6 @@ public class ReplicationServiceImpl implements ReplicationService, ReplicationDe
|
||||
this.actionService = actionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects the DictionaryService bean.
|
||||
* @param dictionaryService
|
||||
*/
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects the Scheduled Persisted Action Service bean
|
||||
* @param scheduledPersistedActionService
|
||||
|
@@ -24,7 +24,6 @@ import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.service.cmr.action.ActionService;
|
||||
import org.alfresco.service.cmr.replication.ReplicationDefinition;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
|
||||
/**
|
||||
* @author Nick Burch
|
||||
@@ -32,7 +31,6 @@ import org.alfresco.service.cmr.repository.NodeService;
|
||||
public class ReplicationServiceImplTest extends TestCase
|
||||
{
|
||||
private ActionService actionService = mock(ActionService.class);
|
||||
private NodeService nodeService = mock(NodeService.class);
|
||||
|
||||
private final ReplicationDefinitionPersisterImpl replicationDefinitionPersister = mock(ReplicationDefinitionPersisterImpl.class);
|
||||
private ReplicationServiceImpl replicationService;
|
||||
@@ -45,7 +43,6 @@ public class ReplicationServiceImplTest extends TestCase
|
||||
{
|
||||
replicationService = new ReplicationServiceImpl();
|
||||
replicationService.setActionService(actionService);
|
||||
replicationService.setNodeService(nodeService);
|
||||
replicationService.setReplicationDefinitionPersister(replicationDefinitionPersister);
|
||||
}
|
||||
|
||||
|
@@ -39,7 +39,7 @@ import org.alfresco.repo.model.Repository;
|
||||
import org.alfresco.repo.replication.script.ScriptReplicationDefinition;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.repo.transfer.TransferServiceImpl;
|
||||
import org.alfresco.repo.transfer.TransferServiceImpl2;
|
||||
import org.alfresco.repo.transfer.TransferTransmitter;
|
||||
import org.alfresco.repo.transfer.UnitTestInProcessTransmitterImpl;
|
||||
import org.alfresco.repo.transfer.UnitTestTransferManifestNodeFactory;
|
||||
@@ -66,7 +66,7 @@ import org.alfresco.service.cmr.repository.ScriptService;
|
||||
import org.alfresco.service.cmr.transfer.TransferDefinition;
|
||||
import org.alfresco.service.cmr.transfer.TransferException;
|
||||
import org.alfresco.service.cmr.transfer.TransferReceiver;
|
||||
import org.alfresco.service.cmr.transfer.TransferService;
|
||||
import org.alfresco.service.cmr.transfer.TransferService2;
|
||||
import org.alfresco.service.cmr.transfer.TransferTarget;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
@@ -90,7 +90,7 @@ public class ReplicationServiceIntegrationTest extends TestCase
|
||||
private ReplicationActionExecutor replicationActionExecutor;
|
||||
private ReplicationService replicationService;
|
||||
private TransactionService transactionService;
|
||||
private TransferService transferService;
|
||||
private TransferService2 transferService;
|
||||
private ContentService contentService;
|
||||
private JobLockService jobLockService;
|
||||
private ScriptService scriptService;
|
||||
@@ -130,7 +130,7 @@ public class ReplicationServiceIntegrationTest extends TestCase
|
||||
replicationActionExecutor = (ReplicationActionExecutor) ctx.getBean("replicationActionExecutor");
|
||||
replicationService = (ReplicationService) ctx.getBean("replicationService");
|
||||
transactionService = (TransactionService) ctx.getBean("transactionService");
|
||||
transferService = (TransferService) ctx.getBean("transferService");
|
||||
transferService = (TransferService2) ctx.getBean("transferService2");
|
||||
contentService = (ContentService) ctx.getBean("contentService");
|
||||
jobLockService = (JobLockService) ctx.getBean("jobLockService");
|
||||
actionService = (ActionService) ctx.getBean("actionService");
|
||||
@@ -495,50 +495,61 @@ public class ReplicationServiceIntegrationTest extends TestCase
|
||||
|
||||
// First one with no target, which isn't allowed
|
||||
ReplicationDefinition rd = replicationService.createReplicationDefinition(ACTION_NAME, "Test");
|
||||
UserTransaction txn = transactionService.getUserTransaction();
|
||||
txn.begin();
|
||||
try {
|
||||
actionService.executeAction(rd, replicationRoot);
|
||||
fail("Shouldn't be permitted with no Target defined");
|
||||
} catch(ReplicationServiceException e) {}
|
||||
txn.rollback();
|
||||
|
||||
|
||||
// Now no payload, also not allowed
|
||||
rd.setTargetName(TRANSFER_TARGET);
|
||||
txn = transactionService.getUserTransaction();
|
||||
txn.begin();
|
||||
try {
|
||||
actionService.executeAction(rd, replicationRoot);
|
||||
fail("Shouldn't be permitted with no payload defined");
|
||||
} catch(ReplicationServiceException e) {}
|
||||
|
||||
txn.rollback();
|
||||
|
||||
// Now disabled, not allowed
|
||||
assertEquals(true, rd.isEnabled());
|
||||
rd.setEnabled(false);
|
||||
assertEquals(false, rd.isEnabled());
|
||||
txn = transactionService.getUserTransaction();
|
||||
txn.begin();
|
||||
try {
|
||||
actionService.executeAction(rd, replicationRoot);
|
||||
fail("Shouldn't be permitted when disabled");
|
||||
} catch(ReplicationServiceException e) {}
|
||||
|
||||
txn.rollback();
|
||||
|
||||
// Invalid Transfer Target, not allowed
|
||||
rd = replicationService.createReplicationDefinition(ACTION_NAME, "Test");
|
||||
rd.setTargetName("I am an invalid target that isn't there");
|
||||
rd.getPayload().add( folder1 );
|
||||
txn = transactionService.getUserTransaction();
|
||||
txn.begin();
|
||||
try {
|
||||
actionService.executeAction(rd, replicationRoot);
|
||||
fail("Shouldn't be permitted with an invalid transfer target");
|
||||
} catch(ReplicationServiceException e) {}
|
||||
|
||||
txn.rollback();
|
||||
|
||||
// Can't send Folder2a if Folder2 isn't there, as it
|
||||
// won't have anywhere to put it
|
||||
rd = replicationService.createReplicationDefinition(ACTION_NAME, "Test");
|
||||
rd.setTargetName(TRANSFER_TARGET);
|
||||
rd.getPayload().add( folder2a );
|
||||
txn = transactionService.getUserTransaction();
|
||||
txn.begin();
|
||||
try {
|
||||
actionService.executeAction(rd, replicationRoot);
|
||||
fail("Shouldn't be able to send Folder2a when Folder2 is missing!");
|
||||
} catch(ReplicationServiceException e) {}
|
||||
|
||||
txn.rollback();
|
||||
|
||||
// Next a proper one with a transient definition,
|
||||
// and a sensible set of folders
|
||||
@@ -547,7 +558,7 @@ public class ReplicationServiceIntegrationTest extends TestCase
|
||||
rd.getPayload().add( folder1 );
|
||||
|
||||
// Will execute without error
|
||||
UserTransaction txn = transactionService.getUserTransaction();
|
||||
txn = transactionService.getUserTransaction();
|
||||
txn.begin();
|
||||
actionService.executeAction(rd, replicationRoot);
|
||||
txn.commit();
|
||||
@@ -608,7 +619,7 @@ public class ReplicationServiceIntegrationTest extends TestCase
|
||||
* Take a 10 second lock on the job, then execute.
|
||||
* Ensure that we really wait a little over 10 seconds.
|
||||
*/
|
||||
public void testReplicationExectionLocking() throws Exception
|
||||
public void testReplicationExecutionLocking() throws Exception
|
||||
{
|
||||
// We need the test transfer target for this test
|
||||
makeTransferTarget();
|
||||
@@ -718,6 +729,8 @@ public class ReplicationServiceIntegrationTest extends TestCase
|
||||
|
||||
// Ensure it was cancelled
|
||||
assertEquals(null, rd.getExecutionFailureMessage());
|
||||
assertNotNull(rd.getLocalTransferReport());
|
||||
assertNotNull(rd.getRemoteTransferReport());
|
||||
assertEquals(ActionStatus.Cancelled, rd.getExecutionStatus());
|
||||
}
|
||||
|
||||
@@ -1227,7 +1240,7 @@ public class ReplicationServiceIntegrationTest extends TestCase
|
||||
private void makeTransferServiceLocal() {
|
||||
TransferReceiver receiver = (TransferReceiver)ctx.getBean("transferReceiver");
|
||||
TransferManifestNodeFactory transferManifestNodeFactory = (TransferManifestNodeFactory)ctx.getBean("transferManifestNodeFactory");
|
||||
TransferServiceImpl transferServiceImpl = (TransferServiceImpl) ctx.getBean("transferService");
|
||||
TransferServiceImpl2 transferServiceImpl = (TransferServiceImpl2) ctx.getBean("transferService2");
|
||||
ContentService contentService = (ContentService) ctx.getBean("contentService");
|
||||
|
||||
TransferTransmitter transmitter =
|
||||
|
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.transfer;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.transfer.RangedTransferEvent;
|
||||
import org.alfresco.service.cmr.transfer.TransferEndEvent;
|
||||
import org.alfresco.service.cmr.transfer.TransferEvent;
|
||||
|
||||
/**
|
||||
* An abstract implementation of TransferEndEvent.
|
||||
|
||||
* @see TransferEvent
|
||||
* @see RangedTransferEvent
|
||||
*/
|
||||
public class TransferEndEventImpl extends TransferEventImpl implements TransferEndEvent
|
||||
{
|
||||
private NodeRef sourceReport;
|
||||
private NodeRef destinationReport;
|
||||
|
||||
public void setSourceReport(NodeRef sourceReport)
|
||||
{
|
||||
this.sourceReport = sourceReport;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.transfer.TransferEndEvent#getSourceReport()
|
||||
*/
|
||||
@Override
|
||||
public NodeRef getSourceReport()
|
||||
{
|
||||
return sourceReport;
|
||||
}
|
||||
|
||||
public void setDestinationReport(NodeRef destinationReport)
|
||||
{
|
||||
this.destinationReport = destinationReport;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.transfer.TransferEndEvent#getDestinationReport()
|
||||
*/
|
||||
@Override
|
||||
public NodeRef getDestinationReport()
|
||||
{
|
||||
return destinationReport;
|
||||
}
|
||||
|
||||
}
|
@@ -25,16 +25,15 @@ import java.util.concurrent.LinkedBlockingQueue;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.transfer.TransferCallback;
|
||||
import org.alfresco.service.cmr.transfer.TransferEndEvent;
|
||||
import org.alfresco.service.cmr.transfer.TransferEvent;
|
||||
import org.alfresco.service.cmr.transfer.TransferEventBegin;
|
||||
import org.alfresco.service.cmr.transfer.TransferEventCommittingStatus;
|
||||
import org.alfresco.service.cmr.transfer.TransferEventEndState;
|
||||
import org.alfresco.service.cmr.transfer.TransferEventEnterState;
|
||||
import org.alfresco.service.cmr.transfer.TransferEventError;
|
||||
import org.alfresco.service.cmr.transfer.TransferEventReport;
|
||||
import org.alfresco.service.cmr.transfer.TransferEventSendingContent;
|
||||
import org.alfresco.service.cmr.transfer.TransferEventSendingSnapshot;
|
||||
import org.alfresco.service.cmr.transfer.TransferEventSuccess;
|
||||
import org.alfresco.service.cmr.transfer.TransferEventReport;
|
||||
|
||||
/**
|
||||
* Class to bring together all the transfer event stuff.
|
||||
@@ -45,15 +44,15 @@ import org.alfresco.service.cmr.transfer.TransferEventReport;
|
||||
*
|
||||
* @author Mark Rogers
|
||||
*/
|
||||
|
||||
|
||||
public class TransferEventProcessor
|
||||
{
|
||||
public Set<TransferCallback> observers = new HashSet<TransferCallback>();
|
||||
|
||||
LinkedBlockingQueue<TransferEvent> queue = new LinkedBlockingQueue<TransferEvent>();
|
||||
|
||||
|
||||
public TransferEventProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
public void addObserver(TransferCallback observer)
|
||||
{
|
||||
@@ -65,14 +64,6 @@ public class TransferEventProcessor
|
||||
observers.remove(observer);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public TransferEventProcessor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void begin(String transferId)
|
||||
{
|
||||
setState(TransferEvent.TransferState.START);
|
||||
@@ -80,47 +71,23 @@ public class TransferEventProcessor
|
||||
event.setTransferState(TransferEvent.TransferState.START);
|
||||
event.setMessage("begin transferId:" + transferId);
|
||||
queue.add(event);
|
||||
event.setTransferId(transferId);
|
||||
event.setTransferId(transferId);
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
public void start()
|
||||
{
|
||||
setState(TransferEvent.TransferState.START);
|
||||
setState(TransferEvent.TransferState.START);
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
public void success()
|
||||
|
||||
public void end(TransferEndEvent endEvent)
|
||||
{
|
||||
setState(TransferEvent.TransferState.SUCCESS);
|
||||
|
||||
/**
|
||||
* Write the success event
|
||||
*/
|
||||
TransferEventSuccess event = new TransferEventSuccess();
|
||||
event.setTransferState(TransferEvent.TransferState.SUCCESS);
|
||||
event.setLast(true);
|
||||
event.setMessage("success lastEvent:true");
|
||||
queue.add(event);
|
||||
setState(endEvent.getTransferState());
|
||||
queue.add(endEvent);
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
public void error(Exception exception)
|
||||
{
|
||||
setState(TransferEvent.TransferState.ERROR);
|
||||
|
||||
/**
|
||||
* Write the error event
|
||||
*/
|
||||
TransferEventError event = new TransferEventError();
|
||||
event.setTransferState(TransferEvent.TransferState.ERROR);
|
||||
event.setLast(true);
|
||||
event.setMessage("error lastEvent:true, " + exception.getMessage());
|
||||
event.setException(exception);
|
||||
queue.add(event);
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param data
|
||||
@@ -175,6 +142,7 @@ public class TransferEventProcessor
|
||||
public void writeReport(NodeRef nodeRef, TransferEventReport.ReportType reportType)
|
||||
{
|
||||
TransferEventReport event = new TransferEventReport();
|
||||
event.setTransferState(currentState);
|
||||
event.setNodeRef(nodeRef);
|
||||
event.setReportType(reportType);
|
||||
event.setMessage("report nodeRef:" + nodeRef + ", reportType :" + reportType );
|
||||
@@ -198,13 +166,8 @@ public class TransferEventProcessor
|
||||
event.setMessage("committing " + position + " of " + range);
|
||||
queue.add(event);
|
||||
notifyObservers();
|
||||
|
||||
}
|
||||
|
||||
public void abort()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private TransferEvent.TransferState currentState;
|
||||
|
||||
@@ -217,13 +180,13 @@ public class TransferEventProcessor
|
||||
TransferEventImpl event = new TransferEventEndState();
|
||||
event.setMessage("End State: " + currentState);
|
||||
event.setTransferState(currentState);
|
||||
queue.add(event);
|
||||
queue.add(event);
|
||||
}
|
||||
|
||||
|
||||
TransferEventImpl event = new TransferEventEnterState();
|
||||
event.setMessage("Enter State: " + state);
|
||||
event.setTransferState(state);
|
||||
queue.add(event);
|
||||
queue.add(event);
|
||||
currentState = state;
|
||||
}
|
||||
}
|
||||
|
@@ -18,8 +18,12 @@
|
||||
*/
|
||||
package org.alfresco.repo.transfer;
|
||||
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.OutputStream;
|
||||
@@ -55,7 +59,7 @@ import org.alfresco.service.cmr.transfer.TransferEventSendingSnapshot;
|
||||
import org.alfresco.service.cmr.transfer.TransferEventSuccess;
|
||||
import org.alfresco.service.cmr.transfer.TransferException;
|
||||
import org.alfresco.service.cmr.transfer.TransferProgress;
|
||||
import org.alfresco.service.cmr.transfer.TransferService;
|
||||
import org.alfresco.service.cmr.transfer.TransferService2;
|
||||
import org.alfresco.service.cmr.transfer.TransferTarget;
|
||||
import org.alfresco.service.cmr.transfer.TransferEvent.TransferState;
|
||||
import org.alfresco.service.cmr.transfer.TransferProgress.Status;
|
||||
@@ -74,10 +78,10 @@ public class TransferServiceCallbackTest extends TestCase
|
||||
private static final String TRANSFER_TARGET_NAME = "TransferServiceImplUnitTest";
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
private TransferServiceImpl transferServiceImpl;
|
||||
private TransferServiceImpl2 transferServiceImpl;
|
||||
private AuthenticationComponent authenticationComponent;
|
||||
private TransferTransmitter mockedTransferTransmitter;
|
||||
private TransferService transferService;
|
||||
private TransferService2 transferService;
|
||||
private TransactionService transactionService;
|
||||
private UserTransaction tx;
|
||||
private Repository repository;
|
||||
@@ -103,7 +107,7 @@ public class TransferServiceCallbackTest extends TestCase
|
||||
applicationContext = ApplicationContextHelper.getApplicationContext();
|
||||
|
||||
// Get the required services
|
||||
transferServiceImpl = (TransferServiceImpl) this.applicationContext.getBean("transferService");
|
||||
transferServiceImpl = (TransferServiceImpl2) this.applicationContext.getBean("transferService2");
|
||||
transferService = transferServiceImpl;
|
||||
authenticationComponent = (AuthenticationComponent) applicationContext.getBean("authenticationComponent");
|
||||
transactionService = (TransactionService) applicationContext.getBean("transactionComponent");
|
||||
@@ -266,6 +270,14 @@ public class TransferServiceCallbackTest extends TestCase
|
||||
event.setTransferState(TransferState.COMMITTING);
|
||||
expectedEvents.add(event);
|
||||
|
||||
event = new TransferEventReport();
|
||||
event.setTransferState(TransferState.COMMITTING);
|
||||
expectedEvents.add(event);
|
||||
|
||||
event = new TransferEventReport();
|
||||
event.setTransferState(TransferState.COMMITTING);
|
||||
expectedEvents.add(event);
|
||||
|
||||
event = new TransferEventEndState();
|
||||
event.setTransferState(TransferState.COMMITTING);
|
||||
expectedEvents.add(event);
|
||||
@@ -278,12 +290,6 @@ public class TransferServiceCallbackTest extends TestCase
|
||||
event.setTransferState(TransferState.SUCCESS);
|
||||
expectedEvents.add(event);
|
||||
|
||||
event = new TransferEventReport();
|
||||
expectedEvents.add(event);
|
||||
|
||||
event = new TransferEventReport();
|
||||
expectedEvents.add(event);
|
||||
|
||||
verifyCallback(expectedEvents);
|
||||
}
|
||||
|
||||
@@ -443,6 +449,14 @@ public class TransferServiceCallbackTest extends TestCase
|
||||
event.setTransferState(TransferState.START);
|
||||
expectedEvents.add(event);
|
||||
|
||||
event = new TransferEventReport();
|
||||
event.setTransferState(TransferState.START);
|
||||
expectedEvents.add(event);
|
||||
|
||||
event = new TransferEventReport();
|
||||
event.setTransferState(TransferState.START);
|
||||
expectedEvents.add(event);
|
||||
|
||||
event = new TransferEventEndState();
|
||||
event.setTransferState(TransferState.START);
|
||||
expectedEvents.add(event);
|
||||
@@ -450,15 +464,12 @@ public class TransferServiceCallbackTest extends TestCase
|
||||
event = new TransferEventEnterState();
|
||||
event.setTransferState(TransferState.ERROR);
|
||||
expectedEvents.add(event);
|
||||
|
||||
|
||||
event = new TransferEventError();
|
||||
event.setTransferState(TransferState.ERROR);
|
||||
((TransferEventError)event).setException(ex);
|
||||
expectedEvents.add(event);
|
||||
|
||||
event = new TransferEventReport();
|
||||
expectedEvents.add(event);
|
||||
|
||||
verifyCallback(expectedEvents);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
1402
source/java/org/alfresco/repo/transfer/TransferServiceImpl2.java
Normal file
1402
source/java/org/alfresco/repo/transfer/TransferServiceImpl2.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -39,6 +39,7 @@ import javax.xml.validation.SchemaFactory;
|
||||
import javax.xml.validation.Validator;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.transfer.manifest.TransferManifestNodeFactory;
|
||||
@@ -95,7 +96,7 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
|
||||
{
|
||||
private TransferService transferService;
|
||||
private ContentService contentService;
|
||||
private TransferServiceImpl transferServiceImpl;
|
||||
private TransferServiceImpl2 transferServiceImpl;
|
||||
private SearchService searchService;
|
||||
private TransactionService transactionService;
|
||||
private TransferReceiver receiver;
|
||||
@@ -130,7 +131,7 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
|
||||
// Get the required services
|
||||
this.transferService = (TransferService)this.applicationContext.getBean("TransferService");
|
||||
this.contentService = (ContentService)this.applicationContext.getBean("ContentService");
|
||||
this.transferServiceImpl = (TransferServiceImpl)this.applicationContext.getBean("transferService");
|
||||
this.transferServiceImpl = (TransferServiceImpl2)this.applicationContext.getBean("transferService2");
|
||||
this.searchService = (SearchService)this.applicationContext.getBean("SearchService");
|
||||
this.transactionService = (TransactionService)this.applicationContext.getBean("TransactionService");
|
||||
this.nodeService = (NodeService) this.applicationContext.getBean("nodeService");
|
||||
@@ -1803,7 +1804,7 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
|
||||
*/
|
||||
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 ERROR", transferReport.get(transferReport.size()-2).getTransferState().equals(TransferEvent.TransferState.ERROR));
|
||||
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.
|
||||
}
|
||||
finally
|
||||
@@ -2057,16 +2058,18 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
|
||||
// Now validate the destination side transfer report against the XSD
|
||||
ContentReader reader = contentService.getReader(reportNode, ContentModel.PROP_CONTENT);
|
||||
assertNotNull("transfer reader is null", reader);
|
||||
|
||||
Source transferReportSource = new StreamSource(reader.getContentInputStream());
|
||||
try
|
||||
if (reader.getMimetype().equals(MimetypeMap.MIMETYPE_XML))
|
||||
{
|
||||
validator.validate(transferReportSource);
|
||||
Source transferReportSource = new StreamSource(reader.getContentInputStream());
|
||||
try
|
||||
{
|
||||
validator.validate(transferReportSource);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
fail("Destination Transfer Report reportNode:" + reportNode + " message :" + e.getMessage() );
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
fail("Destination Transfer Report reportNode:" + reportNode + " message :" + e.getMessage() );
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
@@ -23,8 +23,6 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Serializable;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -38,7 +36,6 @@ import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.transfer.Transfer;
|
||||
import org.alfresco.repo.transfer.TransferModel;
|
||||
import org.alfresco.repo.transfer.TransferServiceImpl;
|
||||
import org.alfresco.repo.transfer.manifest.TransferManifestDeletedNode;
|
||||
import org.alfresco.repo.transfer.manifest.TransferManifestHeader;
|
||||
import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode;
|
||||
@@ -99,7 +96,7 @@ public class TransferReporterImpl implements TransferReporter
|
||||
{
|
||||
Map<QName, Serializable> properties = new HashMap<QName, Serializable> ();
|
||||
|
||||
String title = transferName + " , error";
|
||||
String title = transferName;
|
||||
String description = "Transfer error report, " + transferName + " targetName " + target.getName();
|
||||
String name = transferName;
|
||||
|
||||
@@ -167,7 +164,7 @@ public class TransferReporterImpl implements TransferReporter
|
||||
{
|
||||
Map<QName, Serializable> properties = new HashMap<QName, Serializable> ();
|
||||
|
||||
String title = transferName + ", success";
|
||||
String title = transferName;
|
||||
String description = "Transfer success report : " + transferName + " targetName: " + target.getName();
|
||||
String name = transferName;
|
||||
|
||||
@@ -290,7 +287,7 @@ public class TransferReporterImpl implements TransferReporter
|
||||
File tempFile)
|
||||
{
|
||||
|
||||
String title = transferName + ", destination, success";
|
||||
String title = transferName + " destination";
|
||||
String description = "Transfer Destination Report, success, targetName : " + target.getName();
|
||||
String name = transferName + " destination";
|
||||
|
||||
|
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.service.cmr.transfer;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
/**
|
||||
* TransferEvents are produced by the Transfer service during an in flight
|
||||
* transfer.
|
||||
*
|
||||
* <p>
|
||||
* The TransferCallback presents TransferEvents for processing.
|
||||
*
|
||||
* @see TransferCallback
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public interface TransferEndEvent extends TransferEvent
|
||||
{
|
||||
/**
|
||||
* Gets the report generated by the transfer source repository
|
||||
*
|
||||
* @return source transfer report
|
||||
*/
|
||||
public NodeRef getSourceReport();
|
||||
|
||||
/**
|
||||
* Gets the report generated by the transfer destination repository
|
||||
*
|
||||
* @return destination transfer report
|
||||
*/
|
||||
public NodeRef getDestinationReport();
|
||||
}
|
@@ -35,7 +35,7 @@ public interface TransferEvent
|
||||
/**
|
||||
* The transfer events will Start with a START event and finish with either SUCCESS or ERROR
|
||||
*/
|
||||
enum TransferState { START, SENDING_SNAPSHOT, SENDING_CONTENT, PREPARING, COMMITTING, SUCCESS, ERROR };
|
||||
enum TransferState { START, SENDING_SNAPSHOT, SENDING_CONTENT, PREPARING, COMMITTING, SUCCESS, ERROR, CANCELLED };
|
||||
|
||||
/**
|
||||
* Get the state of this transfer
|
||||
|
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.service.cmr.transfer;
|
||||
|
||||
import org.alfresco.repo.transfer.TransferEndEventImpl;
|
||||
|
||||
/**
|
||||
* The cancelled event indicates a transfer was aborted
|
||||
*/
|
||||
public class TransferEventCancelled extends TransferEndEventImpl
|
||||
{
|
||||
public String toString()
|
||||
{
|
||||
return "TransferEventCancelled";
|
||||
}
|
||||
}
|
@@ -18,12 +18,12 @@
|
||||
*/
|
||||
package org.alfresco.service.cmr.transfer;
|
||||
|
||||
import org.alfresco.repo.transfer.TransferEventImpl;
|
||||
import org.alfresco.repo.transfer.TransferEndEventImpl;
|
||||
|
||||
/**
|
||||
* Indicates the reason why a transfer failed
|
||||
*/
|
||||
public class TransferEventError extends TransferEventImpl implements TransferEvent
|
||||
public class TransferEventError extends TransferEndEventImpl
|
||||
{
|
||||
private Exception exception;
|
||||
|
||||
|
@@ -1,7 +1,5 @@
|
||||
package org.alfresco.service.cmr.transfer;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.alfresco.repo.transfer.TransferEventImpl;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
|
@@ -18,12 +18,12 @@
|
||||
*/
|
||||
package org.alfresco.service.cmr.transfer;
|
||||
|
||||
import org.alfresco.repo.transfer.TransferEventImpl;
|
||||
import org.alfresco.repo.transfer.TransferEndEventImpl;
|
||||
|
||||
/**
|
||||
* The success event indicates a successfull transfer
|
||||
* The success event indicates a successful transfer
|
||||
*/
|
||||
public class TransferEventSuccess extends TransferEventImpl implements TransferEvent
|
||||
public class TransferEventSuccess extends TransferEndEventImpl
|
||||
{
|
||||
public String toString()
|
||||
{
|
||||
|
@@ -27,7 +27,7 @@ import org.alfresco.error.AlfrescoRuntimeException;
|
||||
*/
|
||||
public class TransferException extends AlfrescoRuntimeException
|
||||
{
|
||||
/**
|
||||
/**
|
||||
* Serial version UID
|
||||
*/
|
||||
private static final long serialVersionUID = 3257571685241467958L;
|
||||
|
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.service.cmr.transfer;
|
||||
|
||||
|
||||
/**
|
||||
* Transfer failure exception
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class TransferFailureException extends TransferException
|
||||
{
|
||||
private static final long serialVersionUID = 9009938314128119981L;
|
||||
|
||||
private TransferEventError event;
|
||||
|
||||
public TransferFailureException(TransferEventError event)
|
||||
{
|
||||
super(event.getMessage(), event.getException());
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the end event (representing the failure)
|
||||
*
|
||||
* @return end event
|
||||
*/
|
||||
public TransferEventError getErrorEvent()
|
||||
{
|
||||
return event;
|
||||
}
|
||||
}
|
@@ -28,12 +28,15 @@ import org.alfresco.service.Auditable;
|
||||
import org.alfresco.service.NotAuditable;
|
||||
|
||||
/**
|
||||
* The transfer service is responsible for transfering nodes between one instance of Alfresco and another remote instance.
|
||||
* as well as the transfer method, this interface also provides methods for managing the
|
||||
* The transfer service is responsible for transferring nodes between one instance of Alfresco and another remote instance.
|
||||
* as well as the transfer method, this interface also provides methods for managing transfer targets.
|
||||
*
|
||||
* @see TransferService2
|
||||
*
|
||||
* @author Mark Rogers
|
||||
*/
|
||||
@PublicService
|
||||
@Deprecated
|
||||
public interface TransferService
|
||||
{
|
||||
|
||||
|
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.alfresco.service.cmr.transfer;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.service.Auditable;
|
||||
import org.alfresco.service.NotAuditable;
|
||||
import org.alfresco.service.PublicService;
|
||||
|
||||
/**
|
||||
* The transfer service is responsible for transferring nodes between one instance of Alfresco and another remote instance.
|
||||
* as well as the transfer method, this interface also provides methods for managing transfer targets.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
@PublicService
|
||||
public interface TransferService2
|
||||
{
|
||||
|
||||
/**
|
||||
* Transfer nodes sync, with callback. This synchronous version of the transfer method waits for the transfer to complete
|
||||
* before returning to the caller. Callbacks are called in the current thread context, so will be associated with the current
|
||||
* transaction and user.
|
||||
*
|
||||
* @param targetName the name of the target to transfer to
|
||||
* @param definition - the definition of the transfer. Specifies which nodes to transfer.
|
||||
* The following properties must be set, nodes
|
||||
* @param callback - a set of callback handlers that will be called as transfer proceeds. May be null.
|
||||
* @throws TransferException
|
||||
* @return transfer end event (in case of success or cancellation)
|
||||
*/
|
||||
@Auditable(parameters={"targetName"})
|
||||
public TransferEndEvent transfer(String targetName, TransferDefinition definition, Collection<TransferCallback> callback) throws TransferFailureException;
|
||||
|
||||
/**
|
||||
* Transfer nodes sync, with callback. This synchronous version of the transfer method waits for the transfer to complete
|
||||
* before returning to the caller. Callbacks are called in the current thread context, so will be associated with the current
|
||||
* transaction and user.
|
||||
*
|
||||
* @param targetName the name of the target to transfer to
|
||||
* @param definition - the definition of the transfer. Specifies which nodes to transfer.
|
||||
* The following properties must be set, nodes
|
||||
* @param callbacks - a list of callback handlers that will be called as transfer proceeds. May be null.
|
||||
* @throws TransferException
|
||||
* @return transfer end event (in case of success or cancellation)
|
||||
*/
|
||||
@Auditable(parameters={"targetName"})
|
||||
public TransferEndEvent transfer(String targetName, TransferDefinition definition, TransferCallback... callbacks) throws TransferFailureException;
|
||||
|
||||
/**
|
||||
* Transfer nodes async with callback. The asynchronous version of the transfer method starts a transfer and returns as
|
||||
* soon as possible.
|
||||
*
|
||||
* The transfer callbacks will be called by a different thread to that used to call the transferAsync method so transaction
|
||||
* context will be different to the calling context. The asychronous transfer does not have access to uncommitted
|
||||
* data in the calling transaction.
|
||||
*
|
||||
* @param targetName the name of the target to transfer to
|
||||
* @param definition - the definition of the transfer. Specifies which nodes to transfer.
|
||||
* The following properties must be set, nodes
|
||||
* @param callback - a collection of callback handlers that will be called as transfer proceeds. May be null.
|
||||
*
|
||||
* @throws TransferException
|
||||
*/
|
||||
@Auditable(parameters={"targetName"})
|
||||
public void transferAsync(String targetName, TransferDefinition definition, Collection<TransferCallback> callback) throws TransferException;
|
||||
|
||||
/**
|
||||
* Transfer nodes async with callback. The asynchronous version of the transfer method starts a transfer and returns as
|
||||
* soon as possible.
|
||||
*
|
||||
* The transfer callbacks will be called by a different thread to that used to call the transferAsync method so transaction
|
||||
* context will be different to the calling context. The asychronous transfer does not have access to uncommitted
|
||||
* data in the calling transaction.
|
||||
*
|
||||
* @param targetName the name of the target to transfer to
|
||||
* @param definition - the definition of the transfer. Specifies which nodes to transfer.
|
||||
* The following properties must be set, nodes
|
||||
* @param callbacks - a collection of callback handlers that will be called as transfer proceeds. May be null.
|
||||
*
|
||||
* @throws TransferException
|
||||
*/
|
||||
@Auditable(parameters={"targetName"})
|
||||
public void transferAsync(String targetName, TransferDefinition definition, TransferCallback... callbacks) throws TransferException;
|
||||
|
||||
/**
|
||||
* Verify a target is available and that the configured credentials are valid.
|
||||
* @throws TransferException
|
||||
*/
|
||||
@NotAuditable
|
||||
public void verify(TransferTarget target) throws TransferException;
|
||||
|
||||
/**
|
||||
* Create and save a new transfer target. Creates and saves a new transfer target with a single, but long, method call.
|
||||
*
|
||||
* @param name, the name of this transfer target, which must be unique
|
||||
* @param title, the display name of this transfer target
|
||||
* @param description,
|
||||
* @param endpointProtocol, either http or https
|
||||
* @param endpointHost,
|
||||
* @param endpointPort,
|
||||
* @param endpointPath,
|
||||
* @param username,
|
||||
* @param password,
|
||||
* @return the newly created transfer target.
|
||||
*/
|
||||
@Auditable
|
||||
public TransferTarget createAndSaveTransferTarget(String name, String title, String description, String endpointProtocol,
|
||||
String endpointHost, int endpointPort, String endpointPath, String username, char[] password) throws TransferException;
|
||||
|
||||
/**
|
||||
* Creates an in memory transfer target. Before it is used it must be populated with the following values and
|
||||
* saved with the saveTransferTarget method. The name of the transfer target must be unique.
|
||||
* <ul>
|
||||
* <li>title</li>
|
||||
* <li>description</li>
|
||||
* <li>endpointProtocol</li>
|
||||
* <li>endpointHost</li>
|
||||
* <li>endpointPort</li>
|
||||
* <li>endpointPath</li>
|
||||
* <li>username</li>
|
||||
* <li>password</li>
|
||||
* </ul>
|
||||
* @return an in memory transfer target
|
||||
*/
|
||||
@Auditable(parameters={"name"})
|
||||
public TransferTarget createTransferTarget(String name);
|
||||
|
||||
/**
|
||||
* Get all the transfer targets
|
||||
*/
|
||||
@NotAuditable
|
||||
public Set<TransferTarget>getTransferTargets() throws TransferException;
|
||||
|
||||
/**
|
||||
* Get All the transfer targets for a particular transfer target group.
|
||||
* @param groupName, the name of the transfer group
|
||||
*/
|
||||
@NotAuditable
|
||||
public Set<TransferTarget>getTransferTargets(String groupName) throws TransferException;
|
||||
|
||||
/**
|
||||
* Get a transfer target by its name
|
||||
* @throws TransferException - target does not exist
|
||||
*/
|
||||
@NotAuditable
|
||||
public TransferTarget getTransferTarget(String name) throws TransferException;
|
||||
|
||||
/**
|
||||
* Test to see if the target with the specified name exists
|
||||
* @param name
|
||||
* @return true if the specified target exists, and false otherwise
|
||||
*/
|
||||
@NotAuditable
|
||||
public boolean targetExists(String name);
|
||||
|
||||
/**
|
||||
* Delete a transfer target. After calling this method the transfer target will no longer exist.
|
||||
* @throws TransferException - target does not exist
|
||||
* @param name, the name of this transfer target,
|
||||
*/
|
||||
@Auditable(parameters={"name"})
|
||||
public void deleteTransferTarget(String name) throws TransferException;
|
||||
|
||||
/**
|
||||
* Save TransferTarget, will create a transfer target if it does not already exist or update an existing transfer target.
|
||||
*
|
||||
* The following properties may be updated:
|
||||
* endpointHost,
|
||||
* endpointPort,
|
||||
* endpointProtocol,
|
||||
* endpointPath,
|
||||
* username,
|
||||
* password,
|
||||
* title,
|
||||
* description
|
||||
*
|
||||
* The following properties may not be updated:
|
||||
* name, must be specified.
|
||||
* nodeRef, if specified will be ignored.
|
||||
*
|
||||
* @param update
|
||||
*/
|
||||
@Auditable
|
||||
public TransferTarget saveTransferTarget(TransferTarget update) throws TransferException;
|
||||
|
||||
/**
|
||||
* Enables/Disables the named transfer target
|
||||
* @param name the name of the transfer target
|
||||
* @param enable (or false=disable)
|
||||
*/
|
||||
@Auditable(parameters={"name", "enable"})
|
||||
public void enableTransferTarget(String name, boolean enable) throws TransferException;
|
||||
|
||||
/**
|
||||
* Asynchronously cancel an in-progress transfer
|
||||
*
|
||||
* This method tells an in-process transfer to give up, rollback and stop as soon as possible.
|
||||
*
|
||||
* Depending upon the state of the in-progress transfer, the transfer may still complete,
|
||||
* despite calling this method, however in most cases the transfer will not complete.
|
||||
*
|
||||
* Calling this method for a transfer that does not exist, possibly because it has already finished, has no
|
||||
* effect and will not throw an exception.
|
||||
*
|
||||
* The transfer identifier can be obtained from the TransferEventBegin event that is passed to registered callbacks when
|
||||
* transfer starts.
|
||||
*
|
||||
* @param transferId the unique identifier of the transfer to cancel.
|
||||
*
|
||||
* @see TransferEventBegin;
|
||||
*/
|
||||
@Auditable(parameters={"transferId"})
|
||||
public void cancelAsync(String transferId);
|
||||
|
||||
}
|
Reference in New Issue
Block a user