use of org.alfresco.service.cmr.replication.ReplicationServiceException in project alfresco-repository by Alfresco.
the class ReplicationServiceIntegrationTest method testReplicationExecutionLocking.
/**
* Check that the locking works.
* Take a 10 second lock on the job, then execute.
* Ensure that we really wait a little over 10 seconds.
*/
public void testReplicationExecutionLocking() throws Exception {
// We need the test transfer target for this test
makeTransferTarget();
// Create a task
ReplicationDefinition rd = replicationService.createReplicationDefinition(ACTION_NAME, "Test");
rd.setTargetName(TRANSFER_TARGET);
rd.getPayload().add(folder1);
rd.getPayload().add(folder2);
// Get the lock, and run
long start = System.currentTimeMillis();
String token = jobLockService.getLock(rd.getReplicationQName(), 10 * 1000, 1, 1);
UserTransaction txn = transactionService.getUserTransaction();
txn.begin();
try {
actionService.executeAction(rd, replicationRoot);
} catch (ReplicationServiceException e) {
// This shouldn't happen normally! Something is wrong!
// Tidy up before we throw the exception
txn.rollback();
throw e;
}
txn.commit();
long end = System.currentTimeMillis();
assertTrue("Should wait for the lock, but didn't (waited " + ((end - start) / 1000.0) + " seconds, not 10)", end - start > 10000);
}
use of org.alfresco.service.cmr.replication.ReplicationServiceException in project alfresco-repository by Alfresco.
the class ReplicationServiceIntegrationTest method testBasicExecution.
/**
* Test that the action service can find the executor
* for us, and that it has everything it needs
*/
public void testBasicExecution() throws Exception {
// We need the test transfer target for this test
makeTransferTarget();
// Ensure the destination is empty
// (don't want to get confused with older runs)
assertEquals(0, nodeService.getChildAssocs(destinationFolder).size());
// 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();
// 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
rd = replicationService.createReplicationDefinition(ACTION_NAME, "Test");
rd.setTargetName(TRANSFER_TARGET);
rd.getPayload().add(folder1);
// A deleted folder is fine, will be skipped
rd.getPayload().add(deletedFolder);
// Will execute without error
txn = transactionService.getUserTransaction();
txn.begin();
try {
actionService.executeAction(rd, replicationRoot);
} catch (ReplicationServiceException e) {
// This shouldn't happen normally! Something is wrong!
// Tidy up before we throw the exception
txn.rollback();
throw e;
}
txn.commit();
// Now with one that's in the repo
ReplicationDefinition rd2 = replicationService.createReplicationDefinition(ACTION_NAME2, "Test");
rd2.setTargetName(TRANSFER_TARGET);
rd2.getPayload().add(folder2);
replicationService.saveReplicationDefinition(rd2);
rd2 = replicationService.loadReplicationDefinition(ACTION_NAME2);
// Again no errors
txn = transactionService.getUserTransaction();
txn.begin();
actionService.executeAction(rd2, replicationRoot);
txn.commit();
// 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) {
// check if throwed exception is of expected type
assertTrue(e instanceof DisabledReplicationJobException);
assertTrue(actionService instanceof RuntimeActionService);
if (actionService instanceof RuntimeActionService) {
RuntimeActionService runtimeActionService = (RuntimeActionService) actionService;
// check if throwed exception is considered handled
assertTrue(runtimeActionService.onLogException(rd, log, e, e.getMessage()));
}
}
txn.rollback();
rd.setEnabled(true);
// Schedule it for 0.5 seconds into the future
// Ensure that it is run to completion
txn = transactionService.getUserTransaction();
txn.begin();
((ActionImpl) rd2).setExecutionStatus(ActionStatus.New);
replicationService.enableScheduling(rd2);
rd2.setScheduleStart(new Date(System.currentTimeMillis() + 500));
replicationService.saveReplicationDefinition(rd2);
txn.commit();
// Wait for it to run
Thread.sleep(2000);
for (int i = 0; i < 100; i++) {
txn = transactionService.getUserTransaction();
txn.begin();
rd2 = replicationService.loadReplicationDefinition(ACTION_NAME2);
txn.commit();
if (rd2.getExecutionStatus().equals(ActionStatus.New) || rd2.getExecutionStatus().equals(ActionStatus.Pending) || rd2.getExecutionStatus().equals(ActionStatus.Running)) {
Thread.sleep(50);
}
}
// Check it worked
assertEquals(ActionStatus.Completed, rd2.getExecutionStatus());
}
use of org.alfresco.service.cmr.replication.ReplicationServiceException in project alfresco-repository by Alfresco.
the class ReplicationServiceIntegrationTest method testRenaming.
/**
* Tests that we can rename definitions
*/
public void testRenaming() throws Exception {
// Create one instance
ReplicationDefinition rdTT = replicationService.createReplicationDefinition(ACTION_NAME, "Test");
rdTT.setTargetName("TestTarget");
replicationService.saveReplicationDefinition(rdTT);
assertEquals(1, replicationService.loadReplicationDefinitions().size());
// Rename it
replicationService.renameReplicationDefinition(ACTION_NAME, ACTION_NAME2);
assertEquals(1, replicationService.loadReplicationDefinitions().size());
assertEquals(null, replicationService.loadReplicationDefinition(ACTION_NAME));
rdTT = replicationService.loadReplicationDefinition(ACTION_NAME2);
assertNotNull(rdTT);
assertEquals(ACTION_NAME2, rdTT.getReplicationName());
assertEquals(ACTION_QNAME2, rdTT.getReplicationQName());
// If the source name doesn't exist, does nothing
replicationService.renameReplicationDefinition(ACTION_NAME, ACTION_NAME2);
assertEquals(1, replicationService.loadReplicationDefinitions().size());
assertEquals(null, replicationService.loadReplicationDefinition(ACTION_NAME));
rdTT = replicationService.loadReplicationDefinition(ACTION_NAME2);
assertNotNull(rdTT);
assertEquals(ACTION_NAME2, rdTT.getReplicationName());
assertEquals(ACTION_QNAME2, rdTT.getReplicationQName());
// Renaming to a duplicate name breaks
rdTT = replicationService.createReplicationDefinition(ACTION_NAME, "Test");
rdTT.setTargetName("TestTarget");
replicationService.saveReplicationDefinition(rdTT);
assertEquals(2, replicationService.loadReplicationDefinitions().size());
try {
replicationService.renameReplicationDefinition(ACTION_NAME, ACTION_NAME2);
fail("Shouldn't be able to rename onto a duplicate name");
} catch (ReplicationServiceException e) {
}
}
use of org.alfresco.service.cmr.replication.ReplicationServiceException in project alfresco-repository by Alfresco.
the class ReplicationServiceIntegrationTest method testExecutionResult.
/**
* Test that when we execute a replication task, the
* right stuff ends up being moved for us
*/
public void testExecutionResult() throws Exception {
UserTransaction txn = transactionService.getUserTransaction();
txn.begin();
// Destination is empty
assertEquals(0, nodeService.getChildAssocs(destinationFolder).size());
// We need the test transfer target for this test
makeTransferTarget();
// Put in Folder 2, so we can send Folder 2a
String folder2Name = (String) nodeService.getProperties(folder2).get(ContentModel.PROP_NAME);
NodeRef folderT2 = makeNode(destinationFolder, ContentModel.TYPE_FOLDER, folder2Name);
txn.commit();
// Run a transfer
ReplicationDefinition rd = replicationService.createReplicationDefinition(ACTION_NAME, "Test");
rd.setTargetName(TRANSFER_TARGET);
rd.getPayload().add(folder1);
rd.getPayload().add(folder2a);
assertEquals(null, rd.getLocalTransferReport());
assertEquals(null, rd.getRemoteTransferReport());
txn = transactionService.getUserTransaction();
txn.begin();
try {
actionService.executeAction(rd, replicationRoot);
} catch (ReplicationServiceException e) {
// This shouldn't happen normally! Something is wrong!
// Tidy up before we throw the exception
txn.rollback();
throw e;
}
txn.commit();
// Correct things have turned up
assertEquals(2, nodeService.getChildAssocs(destinationFolder).size());
NodeRef c1 = nodeService.getChildAssocs(destinationFolder).get(0).getChildRef();
NodeRef c2 = nodeService.getChildAssocs(destinationFolder).get(1).getChildRef();
// The destination should have folder 1 (transfered)
// and folder 2 (created). folder 2 will have
// folder 2a (transfered) but not 2b
NodeRef folderT1 = null;
boolean foundT1 = false;
boolean foundT2 = false;
if (nodeService.getProperty(folder1, ContentModel.PROP_NAME).equals(nodeService.getProperty(c1, ContentModel.PROP_NAME))) {
folderT1 = c1;
foundT1 = true;
}
if (nodeService.getProperty(folder1, ContentModel.PROP_NAME).equals(nodeService.getProperty(c2, ContentModel.PROP_NAME))) {
folderT1 = c2;
foundT1 = true;
}
if (c1.equals(folderT2) || c2.equals(folderT2)) {
foundT2 = true;
}
if (!foundT1) {
fail("Folder 1 not found in the destination");
}
if (!foundT2) {
fail("Folder 2 not found in the destination");
}
// Folder 1 has 2*content + thumbnail
assertEquals(3, nodeService.getChildAssocs(folderT1).size());
// Won't have the authority, as that gets skipped
for (ChildAssociationRef r : nodeService.getChildAssocs(folderT1)) {
if (nodeService.getType(r.getChildRef()).equals(ContentModel.TYPE_AUTHORITY)) {
fail("Found authority as " + r.getChildRef() + " but it shouldn't be transfered!");
}
}
// Folder 2 has 2a but not 2b, since only
// 2a was transfered
assertEquals(1, nodeService.getChildAssocs(folderT2).size());
NodeRef folderT2a = nodeService.getChildAssocs(folderT2).get(0).getChildRef();
assertEquals(nodeService.getProperty(folder2a, ContentModel.PROP_NAME), nodeService.getProperty(folderT2a, ContentModel.PROP_NAME));
// Won't have Folder 2b, as it wasn't on the payload
for (ChildAssociationRef r : nodeService.getChildAssocs(folderT2)) {
assertNotSame(nodeService.getProperty(folder2b, ContentModel.PROP_NAME), nodeService.getProperty(r.getChildRef(), ContentModel.PROP_NAME));
}
// Folder 2a has content + thumbnail
assertEquals(2, nodeService.getChildAssocs(folderT2a).size());
// Won't have the zone, as that gets skipped
for (ChildAssociationRef r : nodeService.getChildAssocs(folderT2a)) {
if (nodeService.getType(r.getChildRef()).equals(ContentModel.TYPE_ZONE)) {
fail("Found zone as " + r.getChildRef() + " but it shouldn't be transfered!");
}
}
// Check we got transfer reports, and they look sensible
NodeRef localReport = rd.getLocalTransferReport();
assertNotNull(localReport);
NodeRef remoteReport = rd.getRemoteTransferReport();
assertNotNull(remoteReport);
txn = transactionService.getUserTransaction();
txn.begin();
ContentReader localReader = contentService.getReader(localReport, ContentModel.PROP_CONTENT);
String localReportContent = localReader.getContentString();
assertTrue("XML not found in:\n" + localReportContent, localReportContent.contains("<?xml"));
assertTrue("Report XML not found in:\n" + localReportContent, localReportContent.contains("<report:transferReport"));
ContentReader remoteReader = contentService.getReader(remoteReport, ContentModel.PROP_CONTENT);
String remoteReportContent = remoteReader.getContentString();
assertTrue("XML not found in:\n" + remoteReportContent, remoteReportContent.contains("<?xml"));
assertTrue("Report Status not found in:\n" + remoteReportContent, remoteReportContent.contains("state=\"COMPLETE\""));
txn.commit();
}
use of org.alfresco.service.cmr.replication.ReplicationServiceException 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();
}
}
Aggregations