Replication service unit tests

Refactor the executor to make testing easier, and add unit tests for many parts of the executor


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21011 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Nick Burch
2010-07-08 16:54:10 +00:00
parent 04d2ef2391
commit 283d66c7eb
2 changed files with 149 additions and 14 deletions

View File

@@ -28,6 +28,7 @@ import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.repo.lock.JobLockService; import org.alfresco.repo.lock.JobLockService;
import org.alfresco.repo.lock.LockAcquisitionException; import org.alfresco.repo.lock.LockAcquisitionException;
import org.alfresco.repo.transfer.ChildAssociatedNodeFinder; 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.Action;
import org.alfresco.service.cmr.action.ActionDefinition; import org.alfresco.service.cmr.action.ActionDefinition;
import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.action.ParameterDefinition;
@@ -39,6 +40,7 @@ import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.transfer.NodeCrawler; import org.alfresco.service.cmr.transfer.NodeCrawler;
import org.alfresco.service.cmr.transfer.NodeCrawlerFactory; import org.alfresco.service.cmr.transfer.NodeCrawlerFactory;
import org.alfresco.service.cmr.transfer.TransferCallback; import org.alfresco.service.cmr.transfer.TransferCallback;
import org.alfresco.service.cmr.transfer.TransferDefinition;
import org.alfresco.service.cmr.transfer.TransferEvent; import org.alfresco.service.cmr.transfer.TransferEvent;
import org.alfresco.service.cmr.transfer.TransferService; import org.alfresco.service.cmr.transfer.TransferService;
@@ -53,7 +55,10 @@ public class ReplicationActionExecutor extends ActionExecuterAbstractBase {
private ReplicationService replicationService; private ReplicationService replicationService;
private NodeCrawlerFactory nodeCrawlerFactory; private NodeCrawlerFactory nodeCrawlerFactory;
private long replicationActionLockDuration = 10*60*1000; /**
* By default, we lock for 30 minutes
*/
private long replicationActionLockDuration = 30*60*1000;
/** /**
* Injects the NodeService bean. * Injects the NodeService bean.
@@ -107,7 +112,48 @@ public class ReplicationActionExecutor extends ActionExecuterAbstractBase {
@Override @Override
protected void addParameterDefinitions(List<ParameterDefinition> paramList) { protected void addParameterDefinitions(List<ParameterDefinition> paramList) {
// TODO // TODO Is this needed?
}
/**
* Takes a {@link ReplicationDefinition}, which contains one or
* more payloads {@link NodeRef}s, and expands them into a
* full list of nodes to be transfered.
*/
protected Set<NodeRef> expandPayload(ReplicationDefinition replicationDef) {
// Turn our payload list of root nodes into something that
// the transfer service can work with
Set<NodeRef> toTransfer = new HashSet<NodeRef>(89);
NodeCrawler crawler = nodeCrawlerFactory.getNodeCrawler();
crawler.setNodeFinders(new ChildAssociatedNodeFinder(ContentModel.ASSOC_CONTAINS));
crawler.setNodeFilters(new ContentClassFilter(
ContentModel.TYPE_FOLDER,
ContentModel.TYPE_CONTENT
));
for(NodeRef payload : replicationDef.getPayload()) {
Set<NodeRef> crawledNodes = crawler.crawl(payload);
toTransfer.addAll(crawledNodes);
}
return toTransfer;
}
/**
* Takes a {@link ReplicationDefinition} and a list of
* {@link NodeRef}s, and returns the
* {@link TransferDefinition} which will allow the
* replication to be run.
*/
protected TransferDefinition buildTransferDefinition(
ReplicationDefinition replicationDef, Set<NodeRef> toTransfer
) {
TransferDefinition transferDefinition =
new TransferDefinition();
transferDefinition.setNodes(toTransfer);
transferDefinition.setComplete(true);
return transferDefinition;
} }
@Override @Override
@@ -130,15 +176,9 @@ public class ReplicationActionExecutor extends ActionExecuterAbstractBase {
// Turn our payload list of root nodes into something that // Turn our payload list of root nodes into something that
// the transfer service can work with // the transfer service can work with
Set<NodeRef> toTransfer = new HashSet<NodeRef>(89); Set<NodeRef> toTransfer;
try { try {
NodeCrawler crawler = nodeCrawlerFactory.getNodeCrawler(); toTransfer = expandPayload(replicationDef);
crawler.setNodeFinders(new ChildAssociatedNodeFinder(ContentModel.ASSOC_CONTAINS));
for(NodeRef payload : replicationDef.getPayload()) {
Set<NodeRef> crawledNodes = crawler.crawl(payload);
toTransfer.addAll(crawledNodes);
}
} catch(Exception e) { } catch(Exception e) {
// TODO - Record the error // TODO - Record the error
System.err.println(e); System.err.println(e);
@@ -149,9 +189,16 @@ public class ReplicationActionExecutor extends ActionExecuterAbstractBase {
// Ask the transfer service to do the replication // Ask the transfer service to do the replication
// work for us // work for us
try { try {
// TODO // Build the definition
System.err.println("TODO - Execute '" + replicationDef.getReplicationName() + "'"); TransferDefinition transferDefinition =
buildTransferDefinition(replicationDef, toTransfer);
// Off we go
// transferService.transfer(
// replicationDef.getTargetName(),
// transferDefinition,
// lock
// );
} catch(Exception e) { } catch(Exception e) {
// TODO - Record the error // TODO - Record the error
System.err.println(e); System.err.println(e);

View File

@@ -21,7 +21,9 @@ package org.alfresco.repo.replication;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.lock.JobLockService; import org.alfresco.repo.lock.JobLockService;
@@ -33,6 +35,7 @@ import org.alfresco.service.cmr.replication.ReplicationServiceException;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.transfer.TransferDefinition;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.BaseAlfrescoSpringTest; import org.alfresco.util.BaseAlfrescoSpringTest;
@@ -43,6 +46,7 @@ import org.alfresco.util.GUID;
*/ */
public class ReplicationServiceIntegrationTest extends BaseAlfrescoSpringTest public class ReplicationServiceIntegrationTest extends BaseAlfrescoSpringTest
{ {
private ReplicationActionExecutor replicationActionExecutor;
private ReplicationService replicationService; private ReplicationService replicationService;
private JobLockService jobLockService; private JobLockService jobLockService;
private NodeService nodeService; private NodeService nodeService;
@@ -56,9 +60,11 @@ public class ReplicationServiceIntegrationTest extends BaseAlfrescoSpringTest
private NodeRef folder2b; private NodeRef folder2b;
private NodeRef content1_1; private NodeRef content1_1;
private NodeRef content1_2; private NodeRef content1_2;
private NodeRef thumbnail1_3; private NodeRef thumbnail1_3; // Thumbnail extends content
private NodeRef authority1_4; // Authority doesn't
private NodeRef content2a_1; private NodeRef content2a_1;
private NodeRef thumbnail2a_2; private NodeRef thumbnail2a_2; // Thumbnail extends content
private NodeRef zone2a_3; // Zone doesn't
private final QName ACTION_NAME = QName.createQName(NamespaceService.ALFRESCO_URI, "testName"); private final QName ACTION_NAME = QName.createQName(NamespaceService.ALFRESCO_URI, "testName");
private final QName ACTION_NAME2 = QName.createQName(NamespaceService.ALFRESCO_URI, "testName2"); private final QName ACTION_NAME2 = QName.createQName(NamespaceService.ALFRESCO_URI, "testName2");
@@ -67,6 +73,7 @@ public class ReplicationServiceIntegrationTest extends BaseAlfrescoSpringTest
protected void onSetUpInTransaction() throws Exception protected void onSetUpInTransaction() throws Exception
{ {
super.onSetUpInTransaction(); super.onSetUpInTransaction();
replicationActionExecutor = (ReplicationActionExecutor) this.applicationContext.getBean("replicationActionExecutor");
replicationService = (ReplicationService) this.applicationContext.getBean("replicationService"); replicationService = (ReplicationService) this.applicationContext.getBean("replicationService");
jobLockService = (JobLockService) this.applicationContext.getBean("jobLockService"); jobLockService = (JobLockService) this.applicationContext.getBean("jobLockService");
nodeService = (NodeService) this.applicationContext.getBean("nodeService"); nodeService = (NodeService) this.applicationContext.getBean("nodeService");
@@ -93,8 +100,10 @@ public class ReplicationServiceIntegrationTest extends BaseAlfrescoSpringTest
content1_1 = makeNode(folder1, ContentModel.TYPE_CONTENT); content1_1 = makeNode(folder1, ContentModel.TYPE_CONTENT);
content1_2 = makeNode(folder1, ContentModel.TYPE_CONTENT); content1_2 = makeNode(folder1, ContentModel.TYPE_CONTENT);
thumbnail1_3 = makeNode(folder1, ContentModel.TYPE_THUMBNAIL); thumbnail1_3 = makeNode(folder1, ContentModel.TYPE_THUMBNAIL);
authority1_4 = makeNode(folder1, ContentModel.TYPE_AUTHORITY);
content2a_1 = makeNode(folder2a, ContentModel.TYPE_CONTENT); content2a_1 = makeNode(folder2a, ContentModel.TYPE_CONTENT);
thumbnail2a_2 = makeNode(folder2a, ContentModel.TYPE_THUMBNAIL); thumbnail2a_2 = makeNode(folder2a, ContentModel.TYPE_THUMBNAIL);
zone2a_3 = makeNode(folder2a, ContentModel.TYPE_ZONE);
} }
@Override @Override
@@ -258,6 +267,85 @@ public class ReplicationServiceIntegrationTest extends BaseAlfrescoSpringTest
); );
} }
/**
* Test that we turn a list of payload node starting points
* into the correct set of nodes to pass to the
* transfer service.
*/
public void testReplicationPayloadExpansion() throws Exception
{
ReplicationDefinition rd = replicationService.createReplicationDefinition(ACTION_NAME, "Test");
Set<NodeRef> expanded;
// Empty folder -> just itself
rd.getPayload().clear();
rd.getPayload().add(folder2b);
expanded = replicationActionExecutor.expandPayload(rd);
assertEquals(1, expanded.size());
assertTrue(expanded.contains(folder2b));
// Folder with content and thumbnails - just content + thumbnail + folder
rd.getPayload().clear();
rd.getPayload().add(folder1);
expanded = replicationActionExecutor.expandPayload(rd);
assertEquals(4, expanded.size());
assertTrue(expanded.contains(folder1));
assertTrue(expanded.contains(content1_1));
assertTrue(expanded.contains(content1_2));
assertTrue(expanded.contains(thumbnail1_3));
assertFalse(expanded.contains(authority1_4)); // Wrong type, won't be there
// Folder with folders - descends properly
rd.getPayload().clear();
rd.getPayload().add(folder2);
expanded = replicationActionExecutor.expandPayload(rd);
assertEquals(5, expanded.size());
assertTrue(expanded.contains(folder2));
assertTrue(expanded.contains(folder2a));
assertTrue(expanded.contains(content2a_1));
assertTrue(expanded.contains(thumbnail2a_2));
assertFalse(expanded.contains(zone2a_3)); // Wrong type, won't be there
assertTrue(expanded.contains(folder2b));
// Multiple things - gets each in turn
rd.getPayload().clear();
rd.getPayload().add(folder1);
rd.getPayload().add(folder2);
expanded = replicationActionExecutor.expandPayload(rd);
assertEquals(9, expanded.size());
assertTrue(expanded.contains(folder1));
assertTrue(expanded.contains(content1_1));
assertTrue(expanded.contains(content1_2));
assertTrue(expanded.contains(thumbnail1_3));
assertTrue(expanded.contains(folder2));
assertTrue(expanded.contains(folder2a));
assertTrue(expanded.contains(content2a_1));
assertTrue(expanded.contains(thumbnail2a_2));
assertTrue(expanded.contains(folder2b));
// TODO Test how options like permissions and renditions
// affects what gets sent back
}
/**
* Test that we turn a replication definition correctly
* into a transfer definition
*/
public void testTransferDefinitionBuilding() throws Exception
{
ReplicationDefinition rd = replicationService.createReplicationDefinition(ACTION_NAME, "Test");
Set<NodeRef> nodes = new HashSet<NodeRef>();
nodes.add(folder1);
nodes.add(content1_1);
TransferDefinition td = replicationActionExecutor.buildTransferDefinition(rd, nodes);
assertEquals(true, td.isComplete());
assertEquals(2, td.getNodes().size());
assertEquals(true, td.getNodes().contains(folder1));
assertEquals(true, td.getNodes().contains(content1_1));
}
/** /**
* Test that, with a mock transfer service, we * Test that, with a mock transfer service, we
* pick the right things to replicate and call * pick the right things to replicate and call