[New] Extended ExecutionHandler to be paused, persisted over reboots
This commit is contained in:
parent
d09fb9fa4b
commit
67d77bafea
|
@ -64,6 +64,7 @@ public class StrolchModelConstants {
|
|||
public static final String BAG_PARAMETERS = "parameters";
|
||||
public static final String TYPE_PARAMETERS = "Parameters";
|
||||
public static final String TYPE_ENUMERATION = "Enumeration";
|
||||
public static final String TYPE_CONFIGURATION = "Configuration";
|
||||
|
||||
/**
|
||||
* ID of the admin role which has access to all resources
|
||||
|
|
|
@ -1,29 +1,31 @@
|
|||
package li.strolch.rest.endpoint;
|
||||
|
||||
import static li.strolch.execution.ExecutionHandler.PARAM_STATE;
|
||||
import static li.strolch.rest.StrolchRestfulConstants.STROLCH_CERTIFICATE;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.*;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonArray;
|
||||
import li.strolch.execution.ExecutionHandler;
|
||||
import li.strolch.execution.ExecutionHandlerState;
|
||||
import li.strolch.execution.service.*;
|
||||
import li.strolch.model.Locator;
|
||||
import li.strolch.model.State;
|
||||
import li.strolch.model.activity.Activity;
|
||||
import li.strolch.model.json.StrolchElementToJsonVisitor;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
import li.strolch.privilege.model.Certificate;
|
||||
import li.strolch.rest.RestfulStrolchComponent;
|
||||
import li.strolch.rest.StrolchRestfulConstants;
|
||||
import li.strolch.rest.helper.ResponseUtil;
|
||||
import li.strolch.service.LocatorArgument;
|
||||
import li.strolch.service.StringMapArgument;
|
||||
import li.strolch.service.api.ServiceArgument;
|
||||
import li.strolch.service.api.ServiceHandler;
|
||||
import li.strolch.service.api.ServiceResult;
|
||||
|
||||
@Path("strolch/control")
|
||||
|
@ -42,26 +44,27 @@ public class ControlResource {
|
|||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response getActivities(@Context HttpServletRequest request, @QueryParam("realm") String realm) {
|
||||
|
||||
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
|
||||
Certificate cert = (Certificate) request.getAttribute(STROLCH_CERTIFICATE);
|
||||
|
||||
StrolchElementToJsonVisitor visitor = new StrolchElementToJsonVisitor().withVersion().withLocator();
|
||||
|
||||
List<JsonElement> activities;
|
||||
try (StrolchTransaction tx = openTx(cert, realm)) {
|
||||
activities = tx.getContainer().getComponent(ExecutionHandler.class).getActiveActivitiesLocator(realm)
|
||||
.stream().map(locator -> tx.getActivityBy(locator.get(1), locator.get(2))).filter(Objects::nonNull)
|
||||
ExecutionHandler executionHandler = tx.getContainer().getComponent(ExecutionHandler.class);
|
||||
JsonArray activitiesJ = executionHandler.getActiveActivitiesLocator(realm).stream()
|
||||
.map(locator -> tx.getActivityBy(locator.get(1), locator.get(2))).filter(Objects::nonNull)
|
||||
.sorted(Comparator.comparing(Activity::getId)).map(activity -> activity.accept(visitor))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
.collect(JsonArray::new, JsonArray::add, JsonArray::addAll);
|
||||
|
||||
return ResponseUtil.toResponse(activities);
|
||||
ExecutionHandlerState state = executionHandler.getState(tx.getRealmName());
|
||||
return ResponseUtil.toResponse(PARAM_STATE, state.name(), activitiesJ);
|
||||
}
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("all")
|
||||
public Response clearAllActivities(@Context HttpServletRequest request, @QueryParam("realm") String realm) {
|
||||
|
||||
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
|
||||
Certificate cert = (Certificate) request.getAttribute(STROLCH_CERTIFICATE);
|
||||
|
||||
RestfulStrolchComponent instance = RestfulStrolchComponent.getInstance();
|
||||
|
||||
|
@ -79,7 +82,7 @@ public class ControlResource {
|
|||
public Response executeActivity(@Context HttpServletRequest request, @QueryParam("realm") String realm,
|
||||
@QueryParam("locator") String locatorS, @QueryParam("state") String stateS) {
|
||||
|
||||
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
|
||||
Certificate cert = (Certificate) request.getAttribute(STROLCH_CERTIFICATE);
|
||||
|
||||
Locator locator = Locator.valueOf(locatorS);
|
||||
|
||||
|
@ -99,7 +102,7 @@ public class ControlResource {
|
|||
public Response removeActivityFromExecution(@Context HttpServletRequest request, @QueryParam("realm") String realm,
|
||||
@QueryParam("locator") String locatorS) {
|
||||
|
||||
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
|
||||
Certificate cert = (Certificate) request.getAttribute(STROLCH_CERTIFICATE);
|
||||
|
||||
RestfulStrolchComponent instance = RestfulStrolchComponent.getInstance();
|
||||
|
||||
|
@ -115,151 +118,48 @@ public class ControlResource {
|
|||
return ResponseUtil.toResponse(svcResult);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("executionHandler/state")
|
||||
public Response getExecutionHandlerState(@Context HttpServletRequest request, @QueryParam("realm") String realm) {
|
||||
|
||||
ExecutionHandler executionHandler = RestfulStrolchComponent.getInstance().getComponent(ExecutionHandler.class);
|
||||
String state = executionHandler.getState(realm).name();
|
||||
|
||||
return ResponseUtil.toResponse(PARAM_STATE, state);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("state")
|
||||
@Path("executionHandler/state")
|
||||
public Response setExecutionHandlerState(@Context HttpServletRequest request, @QueryParam("realm") String realm,
|
||||
@QueryParam("state") String stateS) {
|
||||
|
||||
Certificate cert = (Certificate) request.getAttribute(STROLCH_CERTIFICATE);
|
||||
|
||||
SetExecutionHandlerStateService svc = new SetExecutionHandlerStateService();
|
||||
StringMapArgument arg = svc.getArgumentInstance();
|
||||
arg.realm = realm;
|
||||
arg.map.put("state", stateS);
|
||||
|
||||
ServiceHandler serviceHandler = RestfulStrolchComponent.getInstance().getServiceHandler();
|
||||
ServiceResult svcResult = serviceHandler.doService(cert, svc, arg);
|
||||
return ResponseUtil.toResponse(svcResult);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("activity/state")
|
||||
public Response setElementState(@Context HttpServletRequest request, @QueryParam("realm") String realm,
|
||||
@QueryParam("locator") String locatorS, @QueryParam("state") String stateS) {
|
||||
|
||||
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
|
||||
Certificate cert = (Certificate) request.getAttribute(STROLCH_CERTIFICATE);
|
||||
|
||||
RestfulStrolchComponent instance = RestfulStrolchComponent.getInstance();
|
||||
|
||||
if (stateS.equals("Trigger")) {
|
||||
|
||||
TriggerExecutionForRealmService svc = new TriggerExecutionForRealmService();
|
||||
ServiceArgument arg = svc.getArgumentInstance();
|
||||
arg.realm = realm;
|
||||
|
||||
ServiceResult svcResult = instance.getServiceHandler().doService(cert, svc, arg);
|
||||
return ResponseUtil.toResponse(svcResult);
|
||||
|
||||
} else if (stateS.equals("ReloadActivities")) {
|
||||
|
||||
ReloadActivitiesInExecutionService svc = new ReloadActivitiesInExecutionService();
|
||||
ServiceArgument arg = svc.getArgumentInstance();
|
||||
arg.realm = realm;
|
||||
|
||||
ServiceResult svcResult = instance.getServiceHandler().doService(cert, svc, arg);
|
||||
return ResponseUtil.toResponse(svcResult);
|
||||
}
|
||||
|
||||
State state = State.parse(stateS);
|
||||
Locator locator = Locator.valueOf(locatorS);
|
||||
|
||||
ServiceResult svcResult;
|
||||
switch (state) {
|
||||
case CREATED: {
|
||||
|
||||
SetActionToCreatedService svc = new SetActionToCreatedService();
|
||||
LocatorArgument arg = svc.getArgumentInstance();
|
||||
arg.realm = realm;
|
||||
arg.locator = locator;
|
||||
|
||||
svcResult = instance.getServiceHandler().doService(cert, svc, arg);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PLANNING: {
|
||||
|
||||
SetActionToPlanningService svc = new SetActionToPlanningService();
|
||||
LocatorArgument arg = svc.getArgumentInstance();
|
||||
arg.realm = realm;
|
||||
arg.locator = locator;
|
||||
|
||||
svcResult = instance.getServiceHandler().doService(cert, svc, arg);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PLANNED: {
|
||||
|
||||
SetActionToPlannedService svc = new SetActionToPlannedService();
|
||||
LocatorArgument arg = svc.getArgumentInstance();
|
||||
arg.realm = realm;
|
||||
arg.locator = locator;
|
||||
|
||||
svcResult = instance.getServiceHandler().doService(cert, svc, arg);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case EXECUTION: {
|
||||
|
||||
SetToExecutionService svc = new SetToExecutionService();
|
||||
LocatorArgument arg = svc.getArgumentInstance();
|
||||
arg.realm = realm;
|
||||
arg.locator = locator;
|
||||
|
||||
svcResult = instance.getServiceHandler().doService(cert, svc, arg);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case WARNING: {
|
||||
|
||||
SetActionToWarningService svc = new SetActionToWarningService();
|
||||
LocatorArgument arg = svc.getArgumentInstance();
|
||||
arg.realm = realm;
|
||||
arg.locator = locator;
|
||||
|
||||
svcResult = instance.getServiceHandler().doService(cert, svc, arg);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ERROR: {
|
||||
|
||||
SetActionToErrorService svc = new SetActionToErrorService();
|
||||
LocatorArgument arg = svc.getArgumentInstance();
|
||||
arg.realm = realm;
|
||||
arg.locator = locator;
|
||||
|
||||
svcResult = instance.getServiceHandler().doService(cert, svc, arg);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case STOPPED: {
|
||||
|
||||
SetActionToStoppedService svc = new SetActionToStoppedService();
|
||||
LocatorArgument arg = svc.getArgumentInstance();
|
||||
arg.realm = realm;
|
||||
arg.locator = locator;
|
||||
|
||||
svcResult = instance.getServiceHandler().doService(cert, svc, arg);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case EXECUTED: {
|
||||
|
||||
SetActionToExecutedService svc = new SetActionToExecutedService();
|
||||
LocatorArgument arg = svc.getArgumentInstance();
|
||||
arg.realm = realm;
|
||||
arg.locator = locator;
|
||||
|
||||
svcResult = instance.getServiceHandler().doService(cert, svc, arg);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CLOSED: {
|
||||
|
||||
SetActionToClosedService svc = new SetActionToClosedService();
|
||||
LocatorArgument arg = svc.getArgumentInstance();
|
||||
arg.realm = realm;
|
||||
arg.locator = locator;
|
||||
|
||||
svcResult = instance.getServiceHandler().doService(cert, svc, arg);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unhandled state " + state);
|
||||
}
|
||||
SetActionStateService svc = new SetActionStateService();
|
||||
StringMapArgument arg = svc.getArgumentInstance();
|
||||
arg.realm = realm;
|
||||
arg.map.put("locator", locatorS);
|
||||
arg.map.put("state", stateS);
|
||||
|
||||
ServiceHandler serviceHandler = RestfulStrolchComponent.getInstance().getServiceHandler();
|
||||
ServiceResult svcResult = serviceHandler.doService(cert, svc, arg);
|
||||
return ResponseUtil.toResponse(svcResult);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
package li.strolch.execution;
|
||||
|
||||
import static li.strolch.model.StrolchModelConstants.*;
|
||||
import static li.strolch.runtime.StrolchConstants.SYSTEM_USER_AGENT;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import li.strolch.agent.api.ComponentContainer;
|
||||
|
@ -16,13 +14,17 @@ import li.strolch.handler.operationslog.LogMessage;
|
|||
import li.strolch.handler.operationslog.LogSeverity;
|
||||
import li.strolch.handler.operationslog.OperationsLog;
|
||||
import li.strolch.model.Locator;
|
||||
import li.strolch.model.ParameterBag;
|
||||
import li.strolch.model.Resource;
|
||||
import li.strolch.model.State;
|
||||
import li.strolch.model.activity.Action;
|
||||
import li.strolch.model.activity.Activity;
|
||||
import li.strolch.model.activity.IActivityElement;
|
||||
import li.strolch.model.parameter.StringParameter;
|
||||
import li.strolch.model.policy.PolicyDef;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
import li.strolch.policy.PolicyHandler;
|
||||
import li.strolch.privilege.model.Certificate;
|
||||
import li.strolch.privilege.model.PrivilegeContext;
|
||||
import li.strolch.runtime.configuration.ComponentConfiguration;
|
||||
import li.strolch.utils.collections.MapOfSets;
|
||||
|
@ -39,6 +41,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
|||
private static final String KEY_DEFAULT_ACTIVITY_ARCHIVAL = "key:DefaultActivityArchival";
|
||||
private static final String PROP_RESTART_EXECUTION = "restartExecution";
|
||||
|
||||
private Map<String, ExecutionHandlerState> statesByRealm;
|
||||
private MapOfSets<String, Locator> registeredActivities;
|
||||
|
||||
private DelayedExecutionTimer delayedExecutionTimer;
|
||||
|
@ -58,6 +61,8 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
|||
@Override
|
||||
public void start() throws Exception {
|
||||
|
||||
evaluateStateByRealm();
|
||||
|
||||
this.delayedExecutionTimer = new SimpleDurationExecutionTimer(getContainer().getAgent());
|
||||
|
||||
// restart execution of activities already in execution
|
||||
|
@ -94,6 +99,12 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
|||
|
||||
@Override
|
||||
public void addForExecution(String realm, Locator activityLoc) {
|
||||
|
||||
ExecutionHandlerState state = this.statesByRealm.getOrDefault(realm, ExecutionHandlerState.Running);
|
||||
if (state == ExecutionHandlerState.HaltNew)
|
||||
throw new IllegalStateException(
|
||||
"ExecutionHandler state is " + state + ", can not add activities for execution!");
|
||||
|
||||
Locator rootElemLoc = activityLoc.trim(3);
|
||||
synchronized (this.registeredActivities) {
|
||||
this.registeredActivities.addElement(realm, rootElemLoc);
|
||||
|
@ -163,6 +174,13 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
|||
|
||||
@Override
|
||||
public void triggerExecution(String realm) {
|
||||
|
||||
ExecutionHandlerState state = this.statesByRealm.getOrDefault(realm, ExecutionHandlerState.Running);
|
||||
if (state == ExecutionHandlerState.Paused) {
|
||||
logger.warn("Ignoring trigger for paused realm " + realm);
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (this.registeredActivities) {
|
||||
Set<Locator> locators = this.registeredActivities.getSet(realm);
|
||||
if (locators != null) {
|
||||
|
@ -174,8 +192,86 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionHandlerState getState(String realm) {
|
||||
return this.statesByRealm.getOrDefault(realm, ExecutionHandlerState.Running);
|
||||
}
|
||||
|
||||
private void evaluateStateByRealm() throws Exception {
|
||||
|
||||
this.statesByRealm = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
runAsAgent(ctx -> getContainer().getRealmNames().forEach(realm -> {
|
||||
try (StrolchTransaction tx = openTx(realm, ctx.getCertificate(), false)) {
|
||||
Resource executionHandlerConfig = tx
|
||||
.getResourceBy(TYPE_CONFIGURATION, ExecutionHandler.class.getSimpleName());
|
||||
if (executionHandlerConfig == null) {
|
||||
this.statesByRealm.put(realm, ExecutionHandlerState.Running);
|
||||
} else {
|
||||
ParameterBag parameters = executionHandlerConfig.getParameterBag(BAG_PARAMETERS);
|
||||
if (parameters == null) {
|
||||
this.statesByRealm.put(realm, ExecutionHandlerState.Running);
|
||||
} else {
|
||||
StringParameter stateP = parameters.getParameter(PARAM_STATE);
|
||||
if (stateP == null) {
|
||||
this.statesByRealm.put(realm, ExecutionHandlerState.Running);
|
||||
} else {
|
||||
ExecutionHandlerState state;
|
||||
try {
|
||||
state = ExecutionHandlerState.valueOf(stateP.getValue());
|
||||
} catch (Exception e) {
|
||||
state = ExecutionHandlerState.Running;
|
||||
stateP.setValue(ExecutionHandlerState.Running.name());
|
||||
tx.update(executionHandlerConfig);
|
||||
tx.commitOnClose();
|
||||
logger.error("Failed to read unhandled state " + stateP.getValue(), e);
|
||||
}
|
||||
this.statesByRealm.put(realm, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setState(Certificate cert, String realm, ExecutionHandlerState state) {
|
||||
try (StrolchTransaction tx = openTx(realm, cert, false)) {
|
||||
Resource executionHandlerConfig = tx
|
||||
.getResourceBy(TYPE_CONFIGURATION, ExecutionHandler.class.getSimpleName());
|
||||
if (executionHandlerConfig == null) {
|
||||
executionHandlerConfig = new Resource(ExecutionHandler.class.getSimpleName(),
|
||||
"ExecutionHandler Configuration", TYPE_CONFIGURATION);
|
||||
}
|
||||
ParameterBag parameters = executionHandlerConfig.getParameterBag(BAG_PARAMETERS);
|
||||
if (parameters == null) {
|
||||
parameters = new ParameterBag(BAG_PARAMETERS, "Parameters", TYPE_PARAMETERS);
|
||||
executionHandlerConfig.addParameterBag(parameters);
|
||||
}
|
||||
StringParameter stateP = parameters.getParameter(PARAM_STATE);
|
||||
if (stateP == null) {
|
||||
stateP = new StringParameter(PARAM_STATE, "State", state);
|
||||
parameters.addParameter(stateP);
|
||||
}
|
||||
|
||||
stateP.setValueE(state);
|
||||
|
||||
tx.addOrUpdate(executionHandlerConfig);
|
||||
tx.commitOnClose();
|
||||
|
||||
this.statesByRealm.put(realm, state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toExecution(String realm, Locator locator) {
|
||||
|
||||
ExecutionHandlerState state = this.statesByRealm.getOrDefault(realm, ExecutionHandlerState.Running);
|
||||
if (state == ExecutionHandlerState.Paused) {
|
||||
logger.warn("Ignoring execution of " + locator + " for paused realm " + realm);
|
||||
return;
|
||||
}
|
||||
|
||||
getExecutor().execute(() -> {
|
||||
try {
|
||||
runAsAgent(ctx -> {
|
||||
|
@ -392,15 +488,21 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
|||
|
||||
} else {
|
||||
|
||||
// otherwise execute any next action(s) for this action's activity
|
||||
ExecutionHandlerState state = this.statesByRealm.getOrDefault(realm, ExecutionHandlerState.Running);
|
||||
if (state == ExecutionHandlerState.Paused) {
|
||||
logger.warn("Ignoring trigger for paused realm " + realm);
|
||||
} else {
|
||||
|
||||
ExecuteActivityCommand execCommand = new ExecuteActivityCommand(getContainer(), tx);
|
||||
execCommand.setActivity(activity);
|
||||
execCommand.validate();
|
||||
execCommand.doCommand();
|
||||
// otherwise execute any next action(s) for this action's activity
|
||||
|
||||
// flush so we can see the changes performed
|
||||
tx.flush();
|
||||
ExecuteActivityCommand execCommand = new ExecuteActivityCommand(getContainer(), tx);
|
||||
execCommand.setActivity(activity);
|
||||
execCommand.validate();
|
||||
execCommand.doCommand();
|
||||
|
||||
// flush so we can see the changes performed
|
||||
tx.flush();
|
||||
}
|
||||
}
|
||||
|
||||
tx.commitOnClose();
|
||||
|
|
|
@ -11,6 +11,7 @@ import li.strolch.model.State;
|
|||
import li.strolch.model.activity.Action;
|
||||
import li.strolch.model.activity.Activity;
|
||||
import li.strolch.model.activity.TimeOrdering;
|
||||
import li.strolch.privilege.model.Certificate;
|
||||
import li.strolch.privilege.model.PrivilegeContext;
|
||||
|
||||
/**
|
||||
|
@ -37,6 +38,8 @@ public abstract class ExecutionHandler extends StrolchComponent {
|
|||
super(container, componentName);
|
||||
}
|
||||
|
||||
public static final String PARAM_STATE = "state";
|
||||
|
||||
/**
|
||||
* Registers the given {@link Locator} of an {@link Activity} for execution, and submits it for execution
|
||||
* immediately in an asynchronous manner
|
||||
|
@ -84,6 +87,28 @@ public abstract class ExecutionHandler extends StrolchComponent {
|
|||
*/
|
||||
public abstract void triggerExecution(String realm);
|
||||
|
||||
/**
|
||||
* Get the sate of the execution handler
|
||||
*
|
||||
* @param realm
|
||||
* the realm for which to get the state
|
||||
*
|
||||
* @return the state of the execution handler
|
||||
*/
|
||||
public abstract ExecutionHandlerState getState(String realm);
|
||||
|
||||
/**
|
||||
* Set the state for the given realm
|
||||
*
|
||||
* @param cert
|
||||
* certificate to use
|
||||
* @param realm
|
||||
* the realm to halt execution for
|
||||
* @param state
|
||||
* the state to set
|
||||
*/
|
||||
public abstract void setState(Certificate cert, String realm, ExecutionHandlerState state);
|
||||
|
||||
/**
|
||||
* Archives the given {@link Activity}
|
||||
*
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package li.strolch.execution;
|
||||
|
||||
public enum ExecutionHandlerState {
|
||||
Running,
|
||||
HaltNew,
|
||||
Paused;
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
package li.strolch.execution.service;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
|
||||
import li.strolch.exception.StrolchException;
|
||||
import li.strolch.execution.ExecutionHandler;
|
||||
import li.strolch.execution.command.*;
|
||||
import li.strolch.model.Locator;
|
||||
import li.strolch.model.State;
|
||||
import li.strolch.model.activity.Action;
|
||||
import li.strolch.model.activity.IActivityElement;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
import li.strolch.service.StringMapArgument;
|
||||
import li.strolch.service.api.AbstractService;
|
||||
import li.strolch.service.api.ServiceResult;
|
||||
import li.strolch.service.api.ServiceResultState;
|
||||
|
||||
public class SetActionStateService extends AbstractService<StringMapArgument, ServiceResult> {
|
||||
|
||||
@Override
|
||||
protected ServiceResult getResultInstance() {
|
||||
return new ServiceResult(ServiceResultState.FAILED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringMapArgument getArgumentInstance() {
|
||||
return new StringMapArgument();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServiceResult internalDoService(StringMapArgument arg) throws Exception {
|
||||
|
||||
State state = State.parse(arg.map.get("state"));
|
||||
Locator locator = Locator.valueOf(arg.map.get("locator"));
|
||||
|
||||
try (StrolchTransaction tx = openArgOrUserTx(arg)) {
|
||||
|
||||
Action action = tx.findElement(locator);
|
||||
|
||||
switch (state) {
|
||||
case CREATED: {
|
||||
|
||||
SetActionToCreatedCommand command = new SetActionToCreatedCommand(getContainer(), tx);
|
||||
command.setAction(action);
|
||||
tx.addCommand(command);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PLANNING: {
|
||||
|
||||
SetActionToPlanningCommand command = new SetActionToPlanningCommand(getContainer(), tx);
|
||||
command.setAction(action);
|
||||
tx.addCommand(command);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PLANNED: {
|
||||
|
||||
SetActionToPlannedCommand command = new SetActionToPlannedCommand(getContainer(), tx);
|
||||
command.setAction(action);
|
||||
tx.addCommand(command);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case EXECUTION: {
|
||||
|
||||
tx.lock(locator);
|
||||
|
||||
IActivityElement element = tx.findElement(locator);
|
||||
if (!element.getState().canSetToExecution()) {
|
||||
String msg = "Current state is {0} and can not be changed to {1} for action {2}";
|
||||
msg = MessageFormat.format(msg, element.getState(), State.EXECUTION, element.getLocator());
|
||||
throw new StrolchException(msg);
|
||||
}
|
||||
|
||||
ExecutionHandler executionHandler = getContainer().getComponent(ExecutionHandler.class);
|
||||
executionHandler.toExecution(tx.getRealmName(), locator);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case WARNING: {
|
||||
|
||||
SetActionToWarningCommand command = new SetActionToWarningCommand(getContainer(), tx);
|
||||
command.setAction(action);
|
||||
tx.addCommand(command);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ERROR: {
|
||||
|
||||
SetActionToErrorCommand command = new SetActionToErrorCommand(getContainer(), tx);
|
||||
command.setAction(action);
|
||||
tx.addCommand(command);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case STOPPED: {
|
||||
|
||||
SetActionToStoppedCommand command = new SetActionToStoppedCommand(getContainer(), tx);
|
||||
command.setAction(action);
|
||||
tx.addCommand(command);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case EXECUTED: {
|
||||
|
||||
SetActionToExecutedCommand command = new SetActionToExecutedCommand(getContainer(), tx);
|
||||
command.setAction(action);
|
||||
tx.addCommand(command);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CLOSED: {
|
||||
|
||||
SetActionToClosedCommand command = new SetActionToClosedCommand(getContainer(), tx);
|
||||
command.setAction(action);
|
||||
tx.addCommand(command);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unhandled state " + state);
|
||||
}
|
||||
|
||||
tx.commitOnClose();
|
||||
}
|
||||
|
||||
return ServiceResult.success();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package li.strolch.execution.service;
|
||||
|
||||
import li.strolch.execution.ExecutionHandler;
|
||||
import li.strolch.execution.ExecutionHandlerState;
|
||||
import li.strolch.runtime.StrolchConstants;
|
||||
import li.strolch.service.StringMapArgument;
|
||||
import li.strolch.service.api.AbstractService;
|
||||
import li.strolch.service.api.ServiceResult;
|
||||
import li.strolch.service.api.ServiceResultState;
|
||||
import li.strolch.utils.helper.StringHelper;
|
||||
|
||||
public class SetExecutionHandlerStateService extends AbstractService<StringMapArgument, ServiceResult> {
|
||||
|
||||
@Override
|
||||
protected ServiceResult getResultInstance() {
|
||||
return new ServiceResult(ServiceResultState.FAILED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringMapArgument getArgumentInstance() {
|
||||
return new StringMapArgument();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServiceResult internalDoService(StringMapArgument arg) throws Exception {
|
||||
|
||||
String realm = StringHelper.isEmpty(arg.realm) ? StrolchConstants.DEFAULT_REALM : arg.realm;
|
||||
String state = arg.map.get("state");
|
||||
|
||||
switch (state) {
|
||||
case "Running": {
|
||||
|
||||
ExecutionHandler executionHandler = getContainer().getComponent(ExecutionHandler.class);
|
||||
executionHandler.setState(getCertificate(), realm, ExecutionHandlerState.Running);
|
||||
|
||||
break;
|
||||
}
|
||||
case "HaltNew": {
|
||||
|
||||
ExecutionHandler executionHandler = getContainer().getComponent(ExecutionHandler.class);
|
||||
executionHandler.setState(getCertificate(), realm, ExecutionHandlerState.HaltNew);
|
||||
|
||||
break;
|
||||
}
|
||||
case "Paused": {
|
||||
|
||||
ExecutionHandler executionHandler = getContainer().getComponent(ExecutionHandler.class);
|
||||
executionHandler.setState(getCertificate(), realm, ExecutionHandlerState.Paused);
|
||||
|
||||
break;
|
||||
}
|
||||
case "Trigger": {
|
||||
|
||||
ExecutionHandler executionHandler = getContainer().getComponent(ExecutionHandler.class);
|
||||
executionHandler.triggerExecution(realm);
|
||||
|
||||
break;
|
||||
}
|
||||
case "ReloadActivities": {
|
||||
|
||||
ExecutionHandler executionHandler = getContainer().getComponent(ExecutionHandler.class);
|
||||
executionHandler.reloadActivitiesInExecution(getPrivilegeContext(), realm);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unhandled state " + state);
|
||||
}
|
||||
|
||||
return ServiceResult.success();
|
||||
}
|
||||
}
|
|
@ -1,8 +1,12 @@
|
|||
package li.strolch.execution.service;
|
||||
|
||||
import static li.strolch.service.I18nServiceBundle.i18nServiceBundle;
|
||||
|
||||
import li.strolch.execution.ExecutionHandler;
|
||||
import li.strolch.execution.ExecutionHandlerState;
|
||||
import li.strolch.runtime.StrolchConstants;
|
||||
import li.strolch.service.LocatorArgument;
|
||||
import li.strolch.service.StrolchRootElementResult;
|
||||
import li.strolch.service.api.AbstractService;
|
||||
import li.strolch.service.api.ServiceResult;
|
||||
import li.strolch.service.api.ServiceResultState;
|
||||
|
@ -26,6 +30,12 @@ public class StartActivityExecutionService extends AbstractService<LocatorArgume
|
|||
String realm = StringHelper.isEmpty(arg.realm) ? StrolchConstants.DEFAULT_REALM : arg.realm;
|
||||
|
||||
ExecutionHandler executionHandler = getContainer().getComponent(ExecutionHandler.class);
|
||||
ExecutionHandlerState executionHandlerState = executionHandler.getState(getRealmName());
|
||||
if (executionHandlerState != ExecutionHandlerState.Running)
|
||||
return new StrolchRootElementResult(ServiceResultState.WARNING,
|
||||
"ExecutionHandler is not running, can not start new jobs!")
|
||||
.i18n(i18nServiceBundle, "execution.handler.invalidState", "state", executionHandlerState);
|
||||
|
||||
executionHandler.addForExecution(realm, arg.locator);
|
||||
|
||||
return ServiceResult.success();
|
||||
|
|
Loading…
Reference in New Issue