diff --git a/source/java/org/alfresco/repo/action/ActionTrackingServiceImplTest.java b/source/java/org/alfresco/repo/action/ActionTrackingServiceImplTest.java index 93ec6c89dc..bfc0171417 100644 --- a/source/java/org/alfresco/repo/action/ActionTrackingServiceImplTest.java +++ b/source/java/org/alfresco/repo/action/ActionTrackingServiceImplTest.java @@ -22,6 +22,8 @@ import static org.alfresco.repo.action.ActionServiceImplTest.assertBefore; import java.net.InetAddress; import java.util.Date; +import java.util.HashMap; +import java.util.Map; import javax.transaction.UserTransaction; @@ -33,6 +35,7 @@ import org.alfresco.repo.action.ActionServiceImplTest.SleepActionExecuter; import org.alfresco.repo.action.executer.MoveActionExecuter; import org.alfresco.repo.cache.EhCacheAdapter; import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.repo.jscript.ClasspathScriptLocation; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ActionService; @@ -43,6 +46,8 @@ import org.alfresco.service.cmr.action.ExecutionSummary; import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.ScriptLocation; +import org.alfresco.service.cmr.repository.ScriptService; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.namespace.QName; import org.alfresco.service.transaction.TransactionService; @@ -67,6 +72,7 @@ public class ActionTrackingServiceImplTest extends TestCase private NodeRef folder; private NodeService nodeService; private ActionService actionService; + private ScriptService scriptService; private TransactionService transactionService; private RuntimeActionService runtimeActionService; private ActionTrackingService actionTrackingService; @@ -76,6 +82,7 @@ public class ActionTrackingServiceImplTest extends TestCase @SuppressWarnings("unchecked") protected void setUp() throws Exception { this.nodeService = (NodeService)ctx.getBean("nodeService"); + this.scriptService = (ScriptService)ctx.getBean("scriptService"); this.actionService = (ActionService)ctx.getBean("actionService"); this.runtimeActionService = (RuntimeActionService)ctx.getBean("actionService"); this.actionTrackingService = (ActionTrackingService)ctx.getBean("actionTrackingService"); @@ -1073,6 +1080,52 @@ public class ActionTrackingServiceImplTest extends TestCase assertNotNull(action.getExecutionFailureMessage()); assertEquals(ActionStatus.Failed, action.getExecutionStatus()); } + + public void testJavascriptAPI() throws Exception + { + // We need a background action to sleep for long enough for + // it still to be running when the JS fires off + final SleepActionExecuter sleepActionExec = + (SleepActionExecuter)ctx.getBean(SleepActionExecuter.NAME); + sleepActionExec.setSleepMs(2000); + + ActionImpl sleepAction; + ActionImpl action; + + // Create three test actions: + ((ActionTrackingServiceImpl)actionTrackingService).resetNextExecutionId(); + + // Sleep one that will still be running + UserTransaction txn = transactionService.getUserTransaction(); + txn.begin(); + sleepAction = (ActionImpl)createWorkingSleepAction(null); + sleepAction.setNodeRef(nodeRef); // This isn't true! + this.actionService.executeAction(sleepAction, null, false, true); + txn.commit(); + + // Move one that will appear to be "running" + action = (ActionImpl)createFailingMoveAction(); + actionTrackingService.recordActionExecuting(action); + + // Finally one that has "failed" + // (Shouldn't show up in any lists) + txn = transactionService.getUserTransaction(); + txn.begin(); + action = (ActionImpl)createWorkingSleepAction(null); + action.setExecutionStartDate(new Date(1234)); + action.setExecutionEndDate(new Date(54321)); + action.setExecutionStatus(ActionStatus.Failed); + this.actionService.saveAction(this.nodeRef, action); + txn.commit(); + + // Call the test + Map model = new HashMap(); + model.put("NodeRef", nodeRef.toString()); + model.put("SleepAction", sleepAction); + + ScriptLocation location = new ClasspathScriptLocation("org/alfresco/repo/action/script/test_actionTrackingService.js"); + this.scriptService.executeScript(location, model); + } // =================================================================== // diff --git a/source/java/org/alfresco/repo/action/script/ScriptActionTrackingService.java b/source/java/org/alfresco/repo/action/script/ScriptActionTrackingService.java index 79da4272be..9018898039 100644 --- a/source/java/org/alfresco/repo/action/script/ScriptActionTrackingService.java +++ b/source/java/org/alfresco/repo/action/script/ScriptActionTrackingService.java @@ -113,7 +113,7 @@ public class ScriptActionTrackingService extends BaseScopableProcessorExtension ExecutionDetails detail = actionTrackingService.getExecutionDetails(summary); if(detail != null) { - details.add( new ScriptExecutionDetails(detail) ); + details.add( new ScriptExecutionDetails(detail, serviceRegistry) ); } } diff --git a/source/java/org/alfresco/repo/action/script/ScriptExecutionDetails.java b/source/java/org/alfresco/repo/action/script/ScriptExecutionDetails.java index b05157b8b4..c7c86a9c4c 100644 --- a/source/java/org/alfresco/repo/action/script/ScriptExecutionDetails.java +++ b/source/java/org/alfresco/repo/action/script/ScriptExecutionDetails.java @@ -22,9 +22,10 @@ import java.io.Serializable; import java.util.Date; import org.alfresco.repo.jscript.Scopeable; +import org.alfresco.repo.jscript.ScriptNode; +import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.action.ExecutionDetails; import org.alfresco.service.cmr.action.ExecutionSummary; -import org.alfresco.service.cmr.repository.NodeRef; import org.mozilla.javascript.Scriptable; /** @@ -43,10 +44,14 @@ public final class ScriptExecutionDetails implements Serializable, Scopeable /** The details we wrap */ private ExecutionDetails details; - - public ScriptExecutionDetails(ExecutionDetails details) + + /** Services, used when building Script objects */ + private ServiceRegistry services; + + public ScriptExecutionDetails(ExecutionDetails details, ServiceRegistry services) { this.details = details; + this.services = services; } protected ExecutionDetails getExecutionDetails() @@ -67,8 +72,8 @@ public final class ScriptExecutionDetails implements Serializable, Scopeable return details.getExecutionInstance(); } - public NodeRef getPersistedActionRef() { - return details.getPersistedActionRef(); + public ScriptNode getPersistedActionRef() { + return new ScriptNode(details.getPersistedActionRef(), services); } public String getRunningOn() { diff --git a/source/java/org/alfresco/repo/action/script/test_actionTrackingService.js b/source/java/org/alfresco/repo/action/script/test_actionTrackingService.js new file mode 100644 index 0000000000..a329be78f6 --- /dev/null +++ b/source/java/org/alfresco/repo/action/script/test_actionTrackingService.js @@ -0,0 +1,94 @@ +var sleepActionType = "sleep-action"; +var moveActionType = "move"; + +// Checks the details of one action +function testExecutionDetails() +{ + var definitions = actionTrackingService.getExecutingActions(sleepActionType); + test.assertEquals(1, definitions.length); + + var definition = definitions[0]; + test.assertEquals(sleepActionType, definition.actionType); + test.assertEquals(1, definition.executionInstance); + test.assertEquals(NodeRef, definition.persistedActionRef.nodeRef.toString()); + test.assertEquals(false, definition.cancelRequested); +} + +// Checks that we can list different actions +function testGetAllExecuting() +{ + var definitions; + definitions = actionTrackingService.getAllExecutingActions(); + test.assertEquals(2, definitions.length); + + // Check for the two, but be aware that + // we don't know what order they'll be in + var foundSleep = false; + var foundMove = false; + + for(var i in definitions) + { + var definition = definitions[i]; + if(definition.actionType == sleepActionType) + { + foundSleep = true; + } + if(definition.actionType == moveActionType) + { + foundMove = true; + } + } + + test.assertEquals(true, foundSleep); + test.assertEquals(true, foundMove); +} + +// Test we can fetch by type +function testGetOfType() +{ + var definitions; + + // By name + definitions = actionTrackingService.getExecutingActions(sleepActionType); + test.assertEquals(1, definitions.length); + test.assertEquals(sleepActionType, definitions[0].actionType); + + definitions = actionTrackingService.getExecutingActions(moveActionType); + test.assertEquals(1, definitions.length); + test.assertEquals(moveActionType, definitions[0].actionType); + + definitions = actionTrackingService.getExecutingActions("MADE UP"); + test.assertEquals(0, definitions.length); + + // By action + definitions = actionTrackingService.getExecutingActions(SleepAction); + test.assertEquals(1, definitions.length); + test.assertEquals(sleepActionType, definitions[0].actionType); +} + +// Test the we can request the cancellation +function testCancel() +{ + // Check + var definitions = actionTrackingService.getExecutingActions(sleepActionType); + test.assertEquals(1, definitions.length); + + var definition = definitions[0]; + test.assertEquals(false, definition.cancelRequested); + + // Cancel + actionTrackingService.requestActionCancellation(definition); + + // Ensure it worked + definitions = actionTrackingService.getExecutingActions(sleepActionType); + test.assertEquals(1, definitions.length); + + definition = definitions[0]; + test.assertEquals(true, definition.cancelRequested); +} + +// Execute Tests +testExecutionDetails(); +testGetAllExecuting(); +testGetOfType(); +testCancel(); \ No newline at end of file