diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/action/running-action.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/action/running-action.get.desc.xml new file mode 100644 index 0000000000..dd78990640 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/action/running-action.get.desc.xml @@ -0,0 +1,10 @@ + + Get Running Action Details + + Returns (limited) details on a currently running actions. + + /api/running-action/{action_tracking_id} + + admin + required + diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/action/running-action.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/action/running-action.get.json.ftl new file mode 100644 index 0000000000..b9d0a17efb --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/action/running-action.get.json.ftl @@ -0,0 +1,2 @@ +<#import "running-action.lib.ftl" as actionLib /> +<@actionLib.runningActionJSON action=runningAction /> diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml index 2943bea73f..b522357544 100644 --- a/config/alfresco/web-scripts-application-context.xml +++ b/config/alfresco/web-scripts-application-context.xml @@ -897,6 +897,12 @@ + + + + . + */ +package org.alfresco.repo.web.scripts.action; + +import java.util.Map; + +import org.alfresco.service.cmr.action.ExecutionSummary; +import org.springframework.extensions.webscripts.Cache; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * @author Nick Burch + * @since 3.4 + */ +public class RunningActionGet extends AbstractActionWebscript +{ + @Override + protected Map buildModel( + RunningActionModelBuilder modelBuilder, WebScriptRequest req, + Status status, Cache cache) { + // Which action did they ask for? + String actionTrackingId = + req.getServiceMatch().getTemplateVars().get("action_tracking_id"); + + ExecutionSummary action = + getSummaryFromKey(actionTrackingId); + + // Get the details, if we can + Map model = modelBuilder.buildSimpleModel(action); + + if(model == null) { + throw new WebScriptException( + Status.STATUS_NOT_FOUND, + "No Running Action found with that tracking id" + ); + } + + return model; + } +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/action/RunningActionModelBuilder.java b/source/java/org/alfresco/repo/web/scripts/action/RunningActionModelBuilder.java index 57e69b8218..1a99914ce0 100644 --- a/source/java/org/alfresco/repo/web/scripts/action/RunningActionModelBuilder.java +++ b/source/java/org/alfresco/repo/web/scripts/action/RunningActionModelBuilder.java @@ -19,7 +19,6 @@ package org.alfresco.repo.web.scripts.action; import java.util.ArrayList; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -28,7 +27,6 @@ import org.alfresco.service.cmr.action.ActionService; import org.alfresco.service.cmr.action.ActionTrackingService; import org.alfresco.service.cmr.action.ExecutionDetails; import org.alfresco.service.cmr.action.ExecutionSummary; -import org.alfresco.service.cmr.replication.ReplicationDefinition; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.util.ISO8601DateFormat; @@ -66,6 +64,20 @@ public class RunningActionModelBuilder } + /** + * Build a model containing a single running action + */ + protected Map buildSimpleModel(ExecutionSummary summary) + { + Map ram = buildModel(summary); + if(ram != null) { + Map model = new HashMap(); + model.put(MODEL_DATA_ITEM, ram); + return model; + } + return null; + } + /** * Build a model containing a list of running actions for the given * list of Running Actions @@ -75,22 +87,8 @@ public class RunningActionModelBuilder List> models = new ArrayList>(); for(ExecutionSummary summary : runningActions) { - ExecutionDetails details = actionTrackingService.getExecutionDetails(summary); - - // Only record if still running - may have finished - // between getting the list and now - if(details != null) { - Map ram = new HashMap(); - ram.put(ACTION_ID, summary.getActionId()); - ram.put(ACTION_TYPE, summary.getActionType()); - ram.put(ACTION_INSTANCE, summary.getExecutionInstance()); - ram.put(ACTION_KEY, AbstractActionWebscript.getRunningId(summary)); - - ram.put(ACTION_NODE_REF, details.getPersistedActionRef()); - ram.put(ACTION_STARTED_AT, ISO8601DateFormat.format(details.getStartedAt())); - ram.put(ACTION_RUNNING_ON, details.getRunningOn()); - ram.put(ACTION_CANCEL_REQUESTED, details.isCancelRequested()); - + Map ram = buildModel(summary); + if(ram != null) { models.add(ram); } } @@ -100,4 +98,36 @@ public class RunningActionModelBuilder model.put(MODEL_DATA_LIST, models); return model; } + + /** + * Build a model for a single action + */ + private Map buildModel(ExecutionSummary summary) + { + if(summary == null) { + return null; + } + + // Get the details, if we can + ExecutionDetails details = actionTrackingService.getExecutionDetails(summary); + + // Only record if still running - may have finished + // between getting the list and now + if(details != null) { + Map ram = new HashMap(); + ram.put(ACTION_ID, summary.getActionId()); + ram.put(ACTION_TYPE, summary.getActionType()); + ram.put(ACTION_INSTANCE, summary.getExecutionInstance()); + ram.put(ACTION_KEY, AbstractActionWebscript.getRunningId(summary)); + + ram.put(ACTION_NODE_REF, details.getPersistedActionRef()); + ram.put(ACTION_STARTED_AT, ISO8601DateFormat.format(details.getStartedAt())); + ram.put(ACTION_RUNNING_ON, details.getRunningOn()); + ram.put(ACTION_CANCEL_REQUESTED, details.isCancelRequested()); + + return ram; + } + + return null; + } } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/action/RunningActionRestApiTest.java b/source/java/org/alfresco/repo/web/scripts/action/RunningActionRestApiTest.java index 795593e20a..510dd279db 100644 --- a/source/java/org/alfresco/repo/web/scripts/action/RunningActionRestApiTest.java +++ b/source/java/org/alfresco/repo/web/scripts/action/RunningActionRestApiTest.java @@ -367,6 +367,113 @@ public class RunningActionRestApiTest extends BaseWebScriptTest } + public void testRunningActionGet() throws Exception + { + Response response; + + + // Not allowed if you're not an admin + AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getGuestUserName()); + response = sendRequest(new GetRequest(URL_RUNNING_ACTION + "MadeUp"), Status.STATUS_UNAUTHORIZED); + assertEquals(Status.STATUS_UNAUTHORIZED, response.getStatus()); + + AuthenticationUtil.setFullyAuthenticatedUser(USER_NORMAL); + response = sendRequest(new GetRequest(URL_RUNNING_ACTION + "MadeUp"), Status.STATUS_UNAUTHORIZED); + assertEquals(Status.STATUS_UNAUTHORIZED, response.getStatus()); + + + // If not found, you get a 404 + AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); + response = sendRequest(new GetRequest(URL_RUNNING_ACTION + "MadeUp"), Status.STATUS_NOT_FOUND); + assertEquals(Status.STATUS_NOT_FOUND, response.getStatus()); + + + // Create one + ReplicationDefinition rd = replicationService.createReplicationDefinition("Test1", "Testing"); + replicationService.saveReplicationDefinition(rd); + actionTrackingService.recordActionExecuting(rd); + String id = rd.getId(); + String instance = Integer.toString( ((ActionImpl)rd).getExecutionInstance() ); + String startedAt = ISO8601DateFormat.format(rd.getExecutionStartDate()); + String key1 = "replicationActionExecutor=" + id + "=" + instance; + + + // Fetch the details of it + response = sendRequest(new GetRequest(URL_RUNNING_ACTION + key1), Status.STATUS_OK); + assertEquals(Status.STATUS_OK, response.getStatus()); + + String jsonStr = response.getContentAsString(); + JSONObject jsonRD = new JSONObject(jsonStr); + assertNotNull(jsonRD); + assertEquals(id, jsonRD.get("actionId")); + assertEquals("replicationActionExecutor", jsonRD.get("actionType")); + assertEquals(instance, jsonRD.get("actionInstance")); + assertEquals(rd.getNodeRef().toString(), jsonRD.get("actionNodeRef")); + assertEquals(startedAt, jsonRD.get("startedAt")); + assertEquals(false, jsonRD.getBoolean("cancelRequested")); + assertEquals("/" + URL_RUNNING_ACTION + key1, jsonRD.get("details")); + + + // Ensure we didn't get any unexpected data back, + // only the keys we should have done + JSONArray keys = jsonRD.names(); + for(int i=0; i