[WIP] Implementing Planning refactoring

This commit is contained in:
Robert von Burg 2020-02-17 14:22:32 +01:00
parent 9b452b1ba3
commit 1bda9df450
62 changed files with 494 additions and 283 deletions

View File

@ -425,7 +425,7 @@ public class StrolchComponent {
* @return the newly created transaction
*/
protected StrolchTransaction openTx(Certificate cert, boolean readOnly) {
return getContainer().getRealm(cert).openTx(cert, this.getClass(), readOnly);
return getContainer().getRealm(cert).openTx(cert, getClass(), readOnly);
}
/**
@ -457,7 +457,7 @@ public class StrolchComponent {
* @return the newly created transaction
*/
protected StrolchTransaction openTx(String realm, Certificate cert, boolean readOnly) {
return getContainer().getRealm(realm).openTx(cert, this.getClass(), readOnly);
return getContainer().getRealm(realm).openTx(cert, getClass(), readOnly);
}
/**

View File

@ -416,13 +416,14 @@ public abstract class AbstractTransaction implements StrolchTransaction {
}
@Override
public <T extends StrolchElement> T findElement(Locator locator) throws StrolchException, ClassCastException {
public <T extends StrolchElement> T findElement(Locator locator) throws StrolchModelException, ClassCastException {
return findElement(locator, false);
}
@SuppressWarnings("unchecked")
@Override
public <T extends StrolchElement> T findElement(Locator locator, boolean allowNull) {
public <T extends StrolchElement> T findElement(Locator locator, boolean allowNull)
throws StrolchModelException, ClassCastException {
// Resource/<type>/<id>
// Resource/<type>/<id>/Bag/<id>
@ -435,7 +436,7 @@ public abstract class AbstractTransaction implements StrolchTransaction {
if (locator.getSize() < 3) {
String msg = "The locator is invalid as it does not have at least three path elements (e.g. Resource/MyType/@id): {0}"; //$NON-NLS-1$
msg = MessageFormat.format(msg, locator.toString());
throw new StrolchException(msg);
throw new StrolchModelException(msg);
}
List<String> elements = locator.getPathElements();
@ -454,14 +455,15 @@ public abstract class AbstractTransaction implements StrolchTransaction {
groupedParameterizedElement = getActivityBy(type, id);
break;
default:
throw new StrolchException(MessageFormat.format("Unknown object class {0}", objectClassType)); //$NON-NLS-1$
throw new StrolchModelException(
MessageFormat.format("Unknown object class {0}", objectClassType)); //$NON-NLS-1$
}
if (groupedParameterizedElement == null) {
if (allowNull)
return null;
String msg = "No top level object could be found with locator {0}"; //$NON-NLS-1$
throw new StrolchException(MessageFormat.format(msg, locator));
throw new StrolchModelException(MessageFormat.format(msg, locator));
}
if (elements.size() == 3)
@ -477,7 +479,7 @@ public abstract class AbstractTransaction implements StrolchTransaction {
if (allowNull)
return null;
String msg = "Could not find ParameterBag for locator {0} on element {1}"; //$NON-NLS-1$
throw new StrolchException(
throw new StrolchModelException(
MessageFormat.format(msg, locator, groupedParameterizedElement.getLocator()));
}
@ -490,7 +492,7 @@ public abstract class AbstractTransaction implements StrolchTransaction {
if (allowNull)
return null;
String msg = "Could not find Parameter for locator {0} on element {1}"; //$NON-NLS-1$
throw new StrolchException(MessageFormat.format(msg, locator, bag.getLocator()));
throw new StrolchModelException(MessageFormat.format(msg, locator, bag.getLocator()));
}
return (T) parameter;
@ -498,9 +500,10 @@ public abstract class AbstractTransaction implements StrolchTransaction {
if (elements.size() != 5) {
String msg = "Missing state Id on locator {0}"; //$NON-NLS-1$
throw new StrolchException(MessageFormat.format(msg, locator));
throw new StrolchModelException(MessageFormat.format(msg, locator));
}
@SuppressWarnings("ConstantConditions")
Resource resource = (Resource) groupedParameterizedElement;
String stateId = elements.get(4);
@ -518,7 +521,7 @@ public abstract class AbstractTransaction implements StrolchTransaction {
if (!(element instanceof Activity)) {
String msg = "Invalid locator {0} with part {1} as not an Activity but deeper element specified"; //$NON-NLS-1$
throw new StrolchException(MessageFormat.format(msg, locator, next));
throw new StrolchModelException(MessageFormat.format(msg, locator, next));
}
element = ((Activity) element).getElement(next);
@ -531,7 +534,7 @@ public abstract class AbstractTransaction implements StrolchTransaction {
return null;
String msg = "Invalid locator {0} with part {1}"; //$NON-NLS-1$
throw new StrolchException(MessageFormat.format(msg, locator, stateOrBagOrActivity));
throw new StrolchModelException(MessageFormat.format(msg, locator, stateOrBagOrActivity));
}
@Override

View File

@ -534,11 +534,11 @@ public interface StrolchTransaction extends AutoCloseable {
* Used to find a {@link StrolchElement} by a {@link Locator}, throwing exception if the element is not found
* </p>
*
* @throws StrolchException
* @throws StrolchModelException
* if the element could not be found
* @see #findElement(Locator, boolean)
*/
<T extends StrolchElement> T findElement(Locator locator) throws StrolchException, ClassCastException;
<T extends StrolchElement> T findElement(Locator locator) throws StrolchModelException, ClassCastException;
/**
* <p>
@ -565,14 +565,14 @@ public interface StrolchTransaction extends AutoCloseable {
* an inexistant {@link Resource} or an inexistand {@link Parameter} on a Resource, then a {@link StrolchException}
* is thrown
*
* @throws StrolchException
* @throws StrolchModelException
* if the element could not be found and {@code allowNull} is false
* @throws ClassCastException
* if the querying code is not asking for the correct instance. Do not query a {@link Parameter} if the variable
* to which the result is to be is stored is a {@link Resource}, etc.
*/
<T extends StrolchElement> T findElement(Locator locator, boolean allowNull)
throws StrolchException, ClassCastException;
throws StrolchModelException, ClassCastException;
/**
* <p>Finds a parameter with the given @bagKey and @paramKey on the given @element, but if it does not exists

View File

@ -304,11 +304,12 @@ public abstract class Command implements Restrictable {
/**
* <p>
* Should the transaction fail, either due to a {@link Command} throwing an exception when {@link #validate()} is
* called, or while committing the transaction, then this method should properly undo any changes it has done. It is
* imperative that this method does not throw further exceptions and that the state to be rolled back is remembered
* in the Command during committing
* This method can be used to undo actions peformed during the command, should the TX fail. In earlier versions of
* Strolch this was important to undo model changes, but the model changes are only visible after a commit succeeds,
* so this is no longer necessary.
* </p>
*/
public abstract void undo();
public void undo() {
// do nothing
}
}

View File

@ -30,6 +30,7 @@ public enum State {
CREATED("Created"), //$NON-NLS-1$
PLANNING("Planning"), //$NON-NLS-1$
PLANNED("Planned"), //$NON-NLS-1$
EXECUTABLE("Executable"), //$NON-NLS-1$
EXECUTION("Execution"), //$NON-NLS-1$
WARNING("Warning"), //$NON-NLS-1$
ERROR("Error"), //$NON-NLS-1$
@ -39,7 +40,7 @@ public enum State {
private String state;
private State(String state) {
State(String state) {
this.state = state;
}
@ -62,8 +63,8 @@ public enum State {
}
/**
* @return true if the state is one of {@link #EXECUTION}, {@link #STOPPED}, {@link #WARNING}, {@link #ERROR} or
* {@link #EXECUTED}
* @return true if the state is one of {@link #EXECUTABLE} {@link #EXECUTION}, {@link #STOPPED}, {@link #WARNING},
* {@link #ERROR} or {@link #EXECUTED}
*/
public boolean inExecutionPhase() {
return this == EXECUTION || this == STOPPED || this == WARNING || this == ERROR;
@ -168,10 +169,17 @@ public enum State {
}
/**
* @return true if {@link #CREATED} or {@link #PLANNING} or {@link #PLANNED} or {@link #EXECUTION} or {@link #STOPPED}
* @return true if {@link #PLANNED} or {@link #EXECUTABLE} or {@link #EXECUTION}
*/
public boolean canSetToExecution() {
return this == CREATED || this == PLANNING || this == PLANNED || this == EXECUTION || this == State.STOPPED;
public boolean isExecutable() {
return this == PLANNED || this == EXECUTABLE || this == EXECUTION;
}
/**
* @return true if state >= {@link #EXECUTED}
*/
public boolean canNotSetToExecution() {
return this.compareTo(State.EXECUTED) >= 0;
}
/**
@ -249,7 +257,7 @@ public enum State {
return WARNING;
// execution
if (states.contains(EXECUTION))
if (states.contains(EXECUTABLE) || states.contains(EXECUTION))
return EXECUTION;
if (states.contains(EXECUTED) && (states.contains(CREATED) || states.contains(PLANNING) || states
.contains(PLANNED)))
@ -275,4 +283,5 @@ public enum State {
// should never happen, unless new state is introduced
throw new IllegalStateException("Unhandled situation with states: " + states.stream().map(e -> e.state)
.collect(Collectors.joining(", ")));
}}
}
}

View File

@ -381,6 +381,27 @@ public class Activity extends AbstractStrolchRootElement
}
}
public <T extends IActivityElement> T getElementByLocator(Locator locator) {
DBC.PRE.assertEquals("Locator is not for this activity!", getLocator(), locator.trim(3));
DBC.PRE.assertTrue("Locator must have at least 5 parts", locator.getSize() >= 4);
IActivityElement element = this;
for (int i = 3; i < locator.getSize(); i++) {
String next = locator.get(i);
if (!(element instanceof Activity)) {
String msg = "Invalid locator {0} with part {1} as not an Activity but deeper element specified"; //$NON-NLS-1$
throw new StrolchModelException(MessageFormat.format(msg, locator, next));
}
element = ((Activity) element).getElement(next);
}
@SuppressWarnings("unchecked")
T t = (T) element;
return t;
}
/**
* @return the iterator for entries, which include the id as key and the {@link IActivityElement} as value
*/

View File

@ -3,6 +3,7 @@ package li.strolch.execution;
import java.util.concurrent.TimeUnit;
import li.strolch.agent.api.StrolchAgent;
import li.strolch.execution.command.ArchiveActivityCommand;
import li.strolch.job.JobMode;
import li.strolch.job.StrolchJob;
import li.strolch.model.State;
@ -23,13 +24,16 @@ public class ArchiveExecutedActivitiesJob extends StrolchJob {
@Override
protected void execute(PrivilegeContext ctx) {
ExecutionHandler executionHandler = getComponent(ExecutionHandler.class);
try (StrolchTransaction tx = openTx(ctx.getCertificate(), true)) {
try (StrolchTransaction tx = openTx(ctx.getCertificate())) {
tx.streamActivities().forEach(activity -> {
if (activity.getState() == State.EXECUTED)
executionHandler.archiveActivity(tx.getRealmName(), activity.getLocator());
if (activity.getState() == State.EXECUTED) {
ArchiveActivityCommand command = new ArchiveActivityCommand(tx);
command.setActivity(activity);
tx.addCommand(command);
}
});
tx.commitOnClose();
}
}
}

View File

@ -0,0 +1,70 @@
package li.strolch.execution;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import li.strolch.execution.command.ExecuteActivityCommand;
import li.strolch.execution.policy.ExecutionPolicy;
import li.strolch.model.Locator;
import li.strolch.model.State;
import li.strolch.model.activity.Activity;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.privilege.base.PrivilegeException;
import li.strolch.privilege.model.Certificate;
import li.strolch.privilege.model.PrivilegeContext;
import li.strolch.runtime.privilege.PrivilegedRunnable;
public class Controller {
private ExecutionHandler executionHandler;
private Activity activity;
private Map<Locator, ExecutionPolicy> inExecution;
public Controller(ExecutionHandler executionHandler, Activity activity) {
this.executionHandler = executionHandler;
this.activity = activity;
this.inExecution = new HashMap<>();
}
public State getState() {
return this.activity.getState();
}
public Activity getActivity() {
return this.activity;
}
public Set<Locator> getInExecution() {
return this.inExecution.keySet();
}
protected StrolchTransaction openTx(Certificate cert) {
return this.executionHandler.openTx(cert, getClass(), false);
}
protected void runAsAgent(PrivilegedRunnable runnable) throws PrivilegeException, Exception {
this.executionHandler.runAsAgent(runnable);
}
private Activity refreshActivity(StrolchTransaction tx) {
this.activity = tx.getActivityBy(this.activity.getType(), this.activity.getId(), true);
return this.activity;
}
public void execute() {
try (StrolchTransaction tx = openTx(ctx.getCertificate())) {
ExecuteActivityCommand command = new ExecuteActivityCommand(tx);
command.setActivity(refreshActivity(tx));
command.validate();
command.doCommand();
tx.commitOnClose();
}
}
public void stop() {
}
}

View File

@ -1,7 +1,9 @@
package li.strolch.execution;
import static java.util.Collections.emptySet;
import static li.strolch.model.StrolchModelConstants.*;
import static li.strolch.runtime.StrolchConstants.SYSTEM_USER_AGENT;
import static li.strolch.utils.collections.SynchronizedCollections.synchronizedMapOfMaps;
import java.util.*;
import java.util.concurrent.ExecutorService;
@ -9,7 +11,6 @@ import java.util.concurrent.ExecutorService;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.agent.api.ObserverEvent;
import li.strolch.execution.command.*;
import li.strolch.execution.policy.ActivityArchivalPolicy;
import li.strolch.execution.policy.ExecutionPolicy;
import li.strolch.handler.operationslog.LogMessage;
import li.strolch.handler.operationslog.LogSeverity;
@ -19,13 +20,11 @@ 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;
import li.strolch.utils.collections.MapOfMaps;
import li.strolch.utils.dbc.DBC;
/**
@ -36,11 +35,10 @@ import li.strolch.utils.dbc.DBC;
*/
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 MapOfMaps<String, Locator, Controller> controllers;
private DelayedExecutionTimer delayedExecutionTimer;
@ -48,11 +46,23 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
super(container, componentName);
}
private ExecutorService getExecutor() {
return getExecutorService("ExecutionHandler");
}
@Override
public Set<Locator> getActiveActivitiesLocator(String realm) {
if (this.controllers == null)
return emptySet();
Map<Locator, Controller> activities = this.controllers.getMap(realm);
if (activities == null)
return emptySet();
return activities.keySet();
}
@Override
public void initialize(ComponentConfiguration configuration) throws Exception {
this.registeredActivities = new MapOfSets<>();
this.controllers = synchronizedMapOfMaps(new MapOfMaps<>());
super.initialize(configuration);
}
@ -85,67 +95,34 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
super.stop();
}
@Override
public Set<Locator> getActiveActivitiesLocator(String realm) {
if (this.registeredActivities == null || !this.registeredActivities.containsSet(realm))
return Collections.emptySet();
synchronized (this.registeredActivities) {
return new HashSet<>(this.registeredActivities.getSet(realm));
}
}
@Override
public void addForExecution(String realm, Activity activity) {
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 = activity.getLocator();
synchronized (this.registeredActivities) {
this.registeredActivities.addElement(realm, rootElemLoc);
}
notifyObserverAdd(realm, activity);
toExecution(realm, rootElemLoc);
}
@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);
}
getExecutor().submit(() -> notifyObserverAdd(realm, activityLoc));
toExecution(realm, activityLoc);
Controller controller = new Controller(this, activity);
this.controllers.addElement(realm, activity.getLocator(), controller);
notifyObserverAdd(realm, controller);
toExecution(realm, activity);
}
@Override
public void removeFromExecution(String realm, Locator activityLoc) {
Locator rootElemLoc = activityLoc.trim(3);
synchronized (this.registeredActivities) {
this.registeredActivities.removeElement(realm, rootElemLoc);
}
getExecutor().submit(() -> notifyObserverRemove(realm, activityLoc));
Controller controller = this.controllers.removeElement(realm, rootElemLoc);
if (controller != null)
getExecutor().submit(() -> notifyObserverRemove(realm, controller));
}
@Override
public void clearAllCurrentExecutions(String realm) {
Set<Locator> removed = this.registeredActivities.removeSet(realm);
Map<Locator, Controller> removed = this.controllers.removeMap(realm);
getExecutor().submit(() -> notifyObserverRemove(realm, removed));
}
private void restartActivityExecution(PrivilegeContext ctx) {
// iterate the realms
for (String realmName : getContainer().getRealmNames()) {
reloadActivitiesInExecution(ctx, realmName);
@ -180,7 +157,8 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
tx.update(activity);
// register for execution
this.registeredActivities.addElement(realmName, activity.getLocator());
Controller controller = new Controller(this, activity);
this.controllers.addElement(realmName, activity.getLocator(), controller);
});
// commit changes to state
@ -200,12 +178,12 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
return;
}
synchronized (this.registeredActivities) {
Set<Locator> locators = this.registeredActivities.getSet(realm);
if (locators != null) {
for (Locator locator : locators) {
synchronized (this.controllers) {
Map<Locator, Controller> controllers = this.controllers.getMap(realm);
if (controllers != null) {
for (Controller controller : controllers.values()) {
// execute async
toExecution(realm, locator);
toExecution(realm, controller);
}
}
}
@ -283,23 +261,23 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
}
@Override
public void toExecution(String realm, Locator locator) {
public void toExecution(String realm, Activity activity) {
ExecutionHandlerState state = this.statesByRealm.getOrDefault(realm, ExecutionHandlerState.Running);
if (state == ExecutionHandlerState.Paused) {
logger.warn("Ignoring execution of " + locator + " for paused realm " + realm);
logger.warn("Ignoring execution of " + activity.getLocator() + " for paused realm " + realm);
return;
}
getExecutor().execute(() -> {
try {
runAsAgent(ctx -> toExecution(realm, locator, ctx));
runAsAgent(ctx -> toExecution(realm, activity, ctx));
} catch (Exception e) {
logger.error("Failed to set " + locator + " to execution due to " + e.getMessage(), e);
logger.error("Failed to set " + activity.getLocator() + " to execution", e);
if (getContainer().hasComponent(OperationsLog.class)) {
getComponent(OperationsLog.class).addMessage(
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
new LogMessage(realm, SYSTEM_USER_AGENT, activity.getLocator(), LogSeverity.Exception,
ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.execution")
.withException(e).value("reason", e));
}
@ -307,17 +285,11 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
});
}
private ExecutorService getExecutor() {
return getExecutorService("ExecutionHandler");
}
@Override
public void toExecuted(String realm, Locator locator) {
getExecutor().execute(() -> {
try {
runAsAgent(ctx -> {
toExecuted(realm, locator, ctx);
});
runAsAgent(ctx -> toExecuted(realm, locator, ctx));
} catch (Exception e) {
logger.error("Failed to set " + locator + " to executed due to " + e.getMessage(), e);
@ -335,9 +307,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
public void toStopped(String realm, Locator locator) {
getExecutor().execute(() -> {
try {
runAsAgent(ctx -> {
toStopped(realm, locator, ctx);
});
runAsAgent(ctx -> toStopped(realm, locator, ctx));
} catch (Exception e) {
logger.error("Failed to set " + locator + " to stopped due to " + e.getMessage(), e);
@ -355,9 +325,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
public void toError(String realm, Locator locator) {
getExecutor().execute(() -> {
try {
runAsAgent(ctx -> {
toError(realm, locator, ctx);
});
runAsAgent(ctx -> toError(realm, locator, ctx));
} catch (Exception e) {
logger.error("Failed to set " + locator + " to error due to " + e.getMessage(), e);
@ -375,9 +343,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
public void toWarning(String realm, Locator locator) {
getExecutor().execute(() -> {
try {
runAsAgent(ctx -> {
toWarning(realm, locator, ctx);
});
runAsAgent(ctx -> toWarning(realm, locator, ctx));
} catch (Exception e) {
logger.error("Failed to set " + locator + " to warning due to " + e.getMessage(), e);
@ -392,42 +358,24 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
}
@Override
public void archiveActivity(String realm, Locator activityLoc) {
public void archiveActivity(String realm, Activity activity) {
getExecutor().execute(() -> {
try {
runAsAgent(ctx -> {
try (StrolchTransaction tx = openTx(realm, ctx.getCertificate(), ActivityArchivalPolicy.class,
try (StrolchTransaction tx = openTx(realm, ctx.getCertificate(), ArchiveActivityCommand.class,
false)) {
tx.lock(activityLoc);
Activity activity = tx.findElement(activityLoc, true);
if (activity == null) {
return;
}
logger.info("Activity " + activity.getLocator() + " is in state " + activity.getState());
PolicyDef policyDef;
if (activity.hasPolicyDef(ActivityArchivalPolicy.class.getSimpleName())) {
policyDef = activity.getPolicyDef(ActivityArchivalPolicy.class.getSimpleName());
} else {
policyDef = PolicyDef.valueOf(ActivityArchivalPolicy.class.getSimpleName(),
KEY_DEFAULT_ACTIVITY_ARCHIVAL);
}
PolicyHandler policyHandler = getComponent(PolicyHandler.class);
ActivityArchivalPolicy archivalPolicy = policyHandler.getPolicy(policyDef, tx);
archivalPolicy.archive(activity);
ArchiveActivityCommand command = new ArchiveActivityCommand(tx);
command.setActivityLoc(activity.getLocator());
tx.addCommand(command);
tx.commitOnClose();
}
});
} catch (Exception e) {
logger.error("Failed to archive " + activityLoc + " due to " + e.getMessage(), e);
logger.error("Failed to archive " + activity.getLocator() + " due to " + e.getMessage(), e);
if (getContainer().hasComponent(OperationsLog.class)) {
getComponent(OperationsLog.class).addMessage(
new LogMessage(realm, SYSTEM_USER_AGENT, activityLoc, LogSeverity.Exception,
new LogMessage(realm, SYSTEM_USER_AGENT, activity.getLocator(), LogSeverity.Exception,
ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.archive")
.withException(e).value("reason", e));
}
@ -596,27 +544,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
triggerExecution(realm);
}
private void notifyObserverAdd(String realm, Locator activityLoc) {
if (!getContainer().getRealm(realm).isUpdateObservers())
return;
try {
runAsAgent(ctx -> {
try (StrolchTransaction tx = openTx(realm, ctx.getCertificate(), true)) {
Activity activity = tx.findElement(activityLoc, true);
if (activity != null) {
ObserverEvent observerEvent = new ObserverEvent();
observerEvent.added.addElement(Tags.CONTROLLER, activity);
getContainer().getRealm(realm).getObserverHandler().notify(observerEvent);
}
}
});
} catch (Exception e) {
logger.error("Failed to notify observers of new controller " + activityLoc);
}
}
private void notifyObserverAdd(String realm, Activity rootElement) {
private void notifyObserverAdd(String realm, Controller controller) {
if (!getContainer().getRealm(realm).isUpdateObservers())
return;
@ -625,7 +553,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
getContainer().getRealm(realm).getObserverHandler().notify(observerEvent);
}
private void notifyObserverUpdate(StrolchTransaction tx, Activity rootElement) {
private void notifyObserverUpdate(StrolchTransaction tx, Controller controller) {
if (!getContainer().getRealm(tx.getRealmName()).isUpdateObservers())
return;
@ -634,7 +562,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
tx.getContainer().getRealm(tx.getRealmName()).getObserverHandler().notify(observerEvent);
}
private void notifyObserverRemove(StrolchTransaction tx, Activity rootElement) {
private void notifyObserverRemove(StrolchTransaction tx, Controller controller) {
if (!getContainer().getRealm(tx.getRealmName()).isUpdateObservers())
return;
@ -643,7 +571,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
tx.getContainer().getRealm(tx.getRealmName()).getObserverHandler().notify(observerEvent);
}
private void notifyObserverRemove(String realm, Locator activityLoc) {
private void notifyObserverRemove(String realm, Controller controller) {
if (!getContainer().getRealm(realm).isUpdateObservers())
return;
@ -663,7 +591,7 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
}
}
private void notifyObserverRemove(String realm, Set<Locator> activityLocs) {
private void notifyObserverRemove(String realm, Map<Locator, Controller> removed) {
if (!getContainer().getRealm(realm).isUpdateObservers())
return;

View File

@ -11,8 +11,11 @@ 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.persistence.api.StrolchTransaction;
import li.strolch.privilege.base.PrivilegeException;
import li.strolch.privilege.model.Certificate;
import li.strolch.privilege.model.PrivilegeContext;
import li.strolch.runtime.privilege.PrivilegedRunnable;
/**
* <p>
@ -41,16 +44,13 @@ public abstract class ExecutionHandler extends StrolchComponent {
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
*
* @param realm
* the realm where the {@link Activity} resides
* @param activityLoc
* the {@link Locator} of the {@link Activity}
*/
public abstract void addForExecution(String realm, Locator activityLoc);
public StrolchTransaction openTx(Certificate cert, Class<?> action, boolean readOnly) {
return super.openTx(cert, action.getName(), readOnly);
}
public void runAsAgent(PrivilegedRunnable runnable) throws PrivilegeException, Exception {
super.runAsAgent(runnable);
}
/**
* Registers the given {@link Activity} for execution, and submits it for execution immediately in an asynchronous
@ -126,10 +126,10 @@ public abstract class ExecutionHandler extends StrolchComponent {
*
* @param realm
* the realm where the activity resides
* @param activityLoc
* the {@link Locator} of the {@link Activity}
* @param activity
* the {@link Activity}
*/
public abstract void archiveActivity(String realm, Locator activityLoc);
public abstract void archiveActivity(String realm, Activity activity);
/**
* Returns the {@link Set} of {@link Locator Locators} of {@link Activity Activities} which are registered for
@ -157,14 +157,14 @@ public abstract class ExecutionHandler extends StrolchComponent {
public abstract DelayedExecutionTimer getDelayedExecutionTimer();
/**
* Starts the execution of the given {@link Activity} with the given {@link Locator}
* Starts the execution of the given {@link Activity}
*
* @param realm
* the realm where the {@link Activity} resides
* @param activityLoc
* the {@link Locator} of the {@link Activity}
* @param activity
* the {@link Activity}
*/
public abstract void toExecution(String realm, Locator activityLoc);
public abstract void toExecution(String realm, Activity activity);
/**
* Completes the execution of the given {@link Action} with the given {@link Locator}

View File

@ -0,0 +1,54 @@
package li.strolch.execution.command;
import li.strolch.execution.policy.ActivityArchivalPolicy;
import li.strolch.model.Locator;
import li.strolch.model.activity.Activity;
import li.strolch.model.policy.PolicyDef;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.policy.PolicyHandler;
import li.strolch.service.api.Command;
import li.strolch.utils.dbc.DBC;
public class ArchiveActivityCommand extends Command {
private static final String KEY_DEFAULT_ACTIVITY_ARCHIVAL = "key:DefaultActivityArchival";
private Locator activityLoc;
public ArchiveActivityCommand(StrolchTransaction tx) {
super(tx);
}
public void setActivityLoc(Locator activityLoc) {
this.activityLoc = activityLoc;
}
@Override
public void validate() {
DBC.PRE.assertNotNull("activity can not be null!", this.activityLoc);
}
@Override
public void doCommand() {
tx().lock(this.activityLoc);
Activity activity = tx().getActivityBy(this.activityLoc.get(1), this.activityLoc.get(2));
if (activity == null) {
logger.error("Activity " + this.activityLoc + " does not exist anymore, can not archive!");
return;
}
logger.info("Activity " + activity.getLocator() + " is in state " + activity.getState());
PolicyDef policyDef;
if (activity.hasPolicyDef(ActivityArchivalPolicy.class.getSimpleName())) {
policyDef = activity.getPolicyDef(ActivityArchivalPolicy.class.getSimpleName());
} else {
policyDef = PolicyDef.valueOf(ActivityArchivalPolicy.class.getSimpleName(), KEY_DEFAULT_ACTIVITY_ARCHIVAL);
}
PolicyHandler policyHandler = getComponent(PolicyHandler.class);
ActivityArchivalPolicy archivalPolicy = policyHandler.getPolicy(policyDef, tx());
archivalPolicy.archive(activity);
}
}

View File

@ -1,6 +1,5 @@
package li.strolch.execution.command;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.model.State;
import li.strolch.model.activity.Activity;
import li.strolch.persistence.api.StrolchTransaction;
@ -10,8 +9,8 @@ public class ExecuteActivityCommand extends ExecutionCommand {
private Activity activity;
public ExecuteActivityCommand(ComponentContainer container, StrolchTransaction tx) {
super(container, tx);
public ExecuteActivityCommand(StrolchTransaction tx) {
super(tx);
}
public void setActivity(Activity activity) {
@ -21,7 +20,6 @@ public class ExecuteActivityCommand extends ExecutionCommand {
@Override
public void validate() {
DBC.PRE.assertNotNull("activity can not be null!", this.activity);
tx().lock(this.activity.getRootElement());
}
@Override
@ -34,9 +32,4 @@ public class ExecuteActivityCommand extends ExecutionCommand {
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
}
@Override
public void undo() {
// can't undo execution
}
}

View File

@ -2,7 +2,6 @@ package li.strolch.execution.command;
import java.text.MessageFormat;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.exception.StrolchException;
import li.strolch.model.State;
import li.strolch.model.activity.Action;
@ -14,8 +13,8 @@ public class ExecuteStoppedActionCommand extends ExecutionCommand {
private Action action;
public ExecuteStoppedActionCommand(ComponentContainer container, StrolchTransaction tx) {
super(container, tx);
public ExecuteStoppedActionCommand(StrolchTransaction tx) {
super(tx);
}
public void setAction(Action action) {
@ -47,9 +46,4 @@ public class ExecuteStoppedActionCommand extends ExecutionCommand {
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
}
@Override
public void undo() {
// can't undo execution
}
}

View File

@ -8,7 +8,6 @@ import static li.strolch.utils.helper.StringHelper.isEmpty;
import java.util.Iterator;
import java.util.Map.Entry;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.exception.StrolchException;
import li.strolch.execution.policy.ConfirmationPolicy;
import li.strolch.execution.policy.ExecutionPolicy;
@ -29,8 +28,8 @@ import li.strolch.service.api.Command;
public abstract class ExecutionCommand extends Command implements TimeOrderingVisitor, IActivityElementVisitor<Void> {
public ExecutionCommand(ComponentContainer container, StrolchTransaction tx) {
super(container, tx);
public ExecutionCommand(StrolchTransaction tx) {
super(tx);
}
protected Locator getResourceLocator(Action action) {

View File

@ -72,8 +72,13 @@ public class PlanActionCommand extends PlanningCommand {
@Override
public Void visitAction(Action action) {
PlanningPolicy planningPolicy = tx().getPolicy(action.findPolicy(PlanningPolicy.class, NO_PLANNING));
planningPolicy.plan(action);
if (action.getState() == State.PLANNED)
getConfirmationPolicy(action).toPlanned(action);
return null;
}
}

View File

@ -15,14 +15,23 @@
*/
package li.strolch.execution.command;
import static li.strolch.utils.helper.StringHelper.DASH;
import static li.strolch.utils.helper.StringHelper.isEmpty;
import java.util.Iterator;
import java.util.Map.Entry;
import li.strolch.exception.StrolchException;
import li.strolch.execution.policy.ConfirmationPolicy;
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.policy.PolicyDef;
import li.strolch.model.visitor.IActivityElementVisitor;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.policy.PolicyHandler;
import li.strolch.service.api.Command;
/**
@ -52,4 +61,22 @@ public abstract class PlanningCommand extends Command implements IActivityElemen
}
return null;
}
protected Resource getResource(Action action) {
String resourceId = action.getResourceId();
if (isEmpty(resourceId) || resourceId.equals(DASH))
throw new StrolchException("No resourceId defined on action " + action.getLocator());
String resourceType = action.getResourceType();
if (isEmpty(resourceType) || resourceType.equals(DASH))
throw new StrolchException("No resourceType defined on action " + action.getLocator());
return tx().getResourceBy(resourceType, resourceId, true);
}
protected ConfirmationPolicy getConfirmationPolicy(Action action) {
Resource resource = getResource(action);
PolicyDef executionPolicyDef = resource.getPolicyDefs().getPolicyDef(ConfirmationPolicy.class.getSimpleName());
return getComponent(PolicyHandler.class).getPolicy(executionPolicyDef, tx());
}
}

View File

@ -2,7 +2,6 @@ package li.strolch.execution.command;
import java.text.MessageFormat;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.exception.StrolchException;
import li.strolch.model.State;
import li.strolch.model.activity.Action;
@ -14,8 +13,8 @@ public class SetActionToClosedCommand extends ExecutionCommand {
private Action action;
public SetActionToClosedCommand(ComponentContainer container, StrolchTransaction tx) {
super(container, tx);
public SetActionToClosedCommand(StrolchTransaction tx) {
super(tx);
}
public void setAction(Action action) {
@ -55,9 +54,4 @@ public class SetActionToClosedCommand extends ExecutionCommand {
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
}
@Override
public void undo() {
// can not undo
}
}

View File

@ -2,7 +2,6 @@ package li.strolch.execution.command;
import java.text.MessageFormat;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.exception.StrolchException;
import li.strolch.model.State;
import li.strolch.model.activity.Action;
@ -14,8 +13,8 @@ public class SetActionToCreatedCommand extends ExecutionCommand {
private Action action;
public SetActionToCreatedCommand(ComponentContainer container, StrolchTransaction tx) {
super(container, tx);
public SetActionToCreatedCommand(StrolchTransaction tx) {
super(tx);
}
public void setAction(Action action) {
@ -55,9 +54,4 @@ public class SetActionToCreatedCommand extends ExecutionCommand {
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
}
@Override
public void undo() {
// can not undo
}
}

View File

@ -2,7 +2,6 @@ package li.strolch.execution.command;
import java.text.MessageFormat;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.exception.StrolchException;
import li.strolch.model.State;
import li.strolch.model.activity.Action;
@ -14,8 +13,8 @@ public class SetActionToErrorCommand extends ExecutionCommand {
private Action action;
public SetActionToErrorCommand(ComponentContainer container, StrolchTransaction tx) {
super(container, tx);
public SetActionToErrorCommand(StrolchTransaction tx) {
super(tx);
}
public void setAction(Action action) {
@ -54,9 +53,4 @@ public class SetActionToErrorCommand extends ExecutionCommand {
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
}
@Override
public void undo() {
// can not undo
}
}

View File

@ -2,7 +2,6 @@ package li.strolch.execution.command;
import java.text.MessageFormat;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.exception.StrolchException;
import li.strolch.model.State;
import li.strolch.model.activity.Action;
@ -14,8 +13,8 @@ public class SetActionToExecutedCommand extends ExecutionCommand {
private Action action;
public SetActionToExecutedCommand(ComponentContainer container, StrolchTransaction tx) {
super(container, tx);
public SetActionToExecutedCommand(StrolchTransaction tx) {
super(tx);
}
public void setAction(Action action) {
@ -54,9 +53,4 @@ public class SetActionToExecutedCommand extends ExecutionCommand {
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
}
@Override
public void undo() {
// can not undo
}
}

View File

@ -2,7 +2,6 @@ package li.strolch.execution.command;
import java.text.MessageFormat;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.exception.StrolchException;
import li.strolch.model.State;
import li.strolch.model.activity.Action;
@ -14,8 +13,8 @@ public class SetActionToPlannedCommand extends ExecutionCommand {
private Action action;
public SetActionToPlannedCommand(ComponentContainer container, StrolchTransaction tx) {
super(container, tx);
public SetActionToPlannedCommand(StrolchTransaction tx) {
super(tx);
}
public void setAction(Action action) {
@ -55,9 +54,4 @@ public class SetActionToPlannedCommand extends ExecutionCommand {
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
}
@Override
public void undo() {
// can not undo
}
}

View File

@ -2,7 +2,6 @@ package li.strolch.execution.command;
import java.text.MessageFormat;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.exception.StrolchException;
import li.strolch.model.State;
import li.strolch.model.activity.Action;
@ -14,8 +13,8 @@ public class SetActionToPlanningCommand extends ExecutionCommand {
private Action action;
public SetActionToPlanningCommand(ComponentContainer container, StrolchTransaction tx) {
super(container, tx);
public SetActionToPlanningCommand(StrolchTransaction tx) {
super(tx);
}
public void setAction(Action action) {
@ -55,9 +54,4 @@ public class SetActionToPlanningCommand extends ExecutionCommand {
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
}
@Override
public void undo() {
// can not undo
}
}

View File

@ -2,7 +2,6 @@ package li.strolch.execution.command;
import java.text.MessageFormat;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.exception.StrolchException;
import li.strolch.model.State;
import li.strolch.model.activity.Action;
@ -14,8 +13,8 @@ public class SetActionToStoppedCommand extends ExecutionCommand {
private Action action;
public SetActionToStoppedCommand(ComponentContainer container, StrolchTransaction tx) {
super(container, tx);
public SetActionToStoppedCommand(StrolchTransaction tx) {
super(tx);
}
public void setAction(Action action) {
@ -54,9 +53,4 @@ public class SetActionToStoppedCommand extends ExecutionCommand {
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
}
@Override
public void undo() {
// can not undo
}
}

View File

@ -2,7 +2,6 @@ package li.strolch.execution.command;
import java.text.MessageFormat;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.exception.StrolchException;
import li.strolch.model.State;
import li.strolch.model.activity.Action;
@ -14,8 +13,8 @@ public class SetActionToWarningCommand extends ExecutionCommand {
private Action action;
public SetActionToWarningCommand(ComponentContainer container, StrolchTransaction tx) {
super(container, tx);
public SetActionToWarningCommand(StrolchTransaction tx) {
super(tx);
}
public void setAction(Action action) {
@ -54,9 +53,4 @@ public class SetActionToWarningCommand extends ExecutionCommand {
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
}
@Override
public void undo() {
// can not undo
}
}

View File

@ -42,7 +42,7 @@ public class SetActionStateService extends AbstractService<StringMapArgument, Se
switch (state) {
case CREATED: {
SetActionToCreatedCommand command = new SetActionToCreatedCommand(getContainer(), tx);
SetActionToCreatedCommand command = new SetActionToCreatedCommand(tx);
command.setAction(action);
tx.addCommand(command);
@ -51,7 +51,7 @@ public class SetActionStateService extends AbstractService<StringMapArgument, Se
case PLANNING: {
SetActionToPlanningCommand command = new SetActionToPlanningCommand(getContainer(), tx);
SetActionToPlanningCommand command = new SetActionToPlanningCommand(tx);
command.setAction(action);
tx.addCommand(command);
@ -60,7 +60,7 @@ public class SetActionStateService extends AbstractService<StringMapArgument, Se
case PLANNED: {
SetActionToPlannedCommand command = new SetActionToPlannedCommand(getContainer(), tx);
SetActionToPlannedCommand command = new SetActionToPlannedCommand(tx);
command.setAction(action);
tx.addCommand(command);
@ -72,7 +72,7 @@ public class SetActionStateService extends AbstractService<StringMapArgument, Se
tx.lock(locator);
IActivityElement element = tx.findElement(locator);
if (!element.getState().canSetToExecution()) {
if (element.getState().canNotSetToExecution()) {
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);
@ -86,7 +86,7 @@ public class SetActionStateService extends AbstractService<StringMapArgument, Se
case WARNING: {
SetActionToWarningCommand command = new SetActionToWarningCommand(getContainer(), tx);
SetActionToWarningCommand command = new SetActionToWarningCommand(tx);
command.setAction(action);
tx.addCommand(command);
@ -95,7 +95,7 @@ public class SetActionStateService extends AbstractService<StringMapArgument, Se
case ERROR: {
SetActionToErrorCommand command = new SetActionToErrorCommand(getContainer(), tx);
SetActionToErrorCommand command = new SetActionToErrorCommand(tx);
command.setAction(action);
tx.addCommand(command);
@ -104,7 +104,7 @@ public class SetActionStateService extends AbstractService<StringMapArgument, Se
case STOPPED: {
SetActionToStoppedCommand command = new SetActionToStoppedCommand(getContainer(), tx);
SetActionToStoppedCommand command = new SetActionToStoppedCommand(tx);
command.setAction(action);
tx.addCommand(command);
@ -113,7 +113,7 @@ public class SetActionStateService extends AbstractService<StringMapArgument, Se
case EXECUTED: {
SetActionToExecutedCommand command = new SetActionToExecutedCommand(getContainer(), tx);
SetActionToExecutedCommand command = new SetActionToExecutedCommand(tx);
command.setAction(action);
tx.addCommand(command);
@ -122,7 +122,7 @@ public class SetActionStateService extends AbstractService<StringMapArgument, Se
case CLOSED: {
SetActionToClosedCommand command = new SetActionToClosedCommand(getContainer(), tx);
SetActionToClosedCommand command = new SetActionToClosedCommand(tx);
command.setAction(action);
tx.addCommand(command);

View File

@ -27,7 +27,7 @@ public class SetActionToClosedService extends AbstractService<LocatorArgument, S
Action action = tx.findElement(arg.locator);
SetActionToClosedCommand command = new SetActionToClosedCommand(getContainer(), tx);
SetActionToClosedCommand command = new SetActionToClosedCommand(tx);
command.setAction(action);
tx.addCommand(command);

View File

@ -27,7 +27,7 @@ public class SetActionToCreatedService extends AbstractService<LocatorArgument,
Action action = tx.findElement(arg.locator);
SetActionToCreatedCommand command = new SetActionToCreatedCommand(getContainer(), tx);
SetActionToCreatedCommand command = new SetActionToCreatedCommand(tx);
command.setAction(action);
tx.addCommand(command);

View File

@ -27,7 +27,7 @@ public class SetActionToErrorService extends AbstractService<LocatorArgument, Se
Action action = tx.findElement(arg.locator);
SetActionToErrorCommand command = new SetActionToErrorCommand(getContainer(), tx);
SetActionToErrorCommand command = new SetActionToErrorCommand(tx);
command.setAction(action);
tx.addCommand(command);

View File

@ -27,7 +27,7 @@ public class SetActionToExecutedService extends AbstractService<LocatorArgument,
Action action = tx.findElement(arg.locator);
SetActionToExecutedCommand command = new SetActionToExecutedCommand(getContainer(), tx);
SetActionToExecutedCommand command = new SetActionToExecutedCommand(tx);
command.setAction(action);
tx.addCommand(command);

View File

@ -27,7 +27,7 @@ public class SetActionToPlannedService extends AbstractService<LocatorArgument,
Action action = tx.findElement(arg.locator);
SetActionToPlannedCommand command = new SetActionToPlannedCommand(getContainer(), tx);
SetActionToPlannedCommand command = new SetActionToPlannedCommand(tx);
command.setAction(action);
tx.addCommand(command);

View File

@ -27,7 +27,7 @@ public class SetActionToPlanningService extends AbstractService<LocatorArgument,
Action action = tx.findElement(arg.locator);
SetActionToPlanningCommand command = new SetActionToPlanningCommand(getContainer(), tx);
SetActionToPlanningCommand command = new SetActionToPlanningCommand(tx);
command.setAction(action);
tx.addCommand(command);

View File

@ -27,7 +27,7 @@ public class SetActionToStoppedService extends AbstractService<LocatorArgument,
Action action = tx.findElement(arg.locator);
SetActionToStoppedCommand command = new SetActionToStoppedCommand(getContainer(), tx);
SetActionToStoppedCommand command = new SetActionToStoppedCommand(tx);
command.setAction(action);
tx.addCommand(command);

View File

@ -27,7 +27,7 @@ public class SetActionToWarningService extends AbstractService<LocatorArgument,
Action action = tx.findElement(arg.locator);
SetActionToWarningCommand command = new SetActionToWarningCommand(getContainer(), tx);
SetActionToWarningCommand command = new SetActionToWarningCommand(tx);
command.setAction(action);
tx.addCommand(command);

View File

@ -7,6 +7,8 @@ import java.text.MessageFormat;
import li.strolch.exception.StrolchException;
import li.strolch.execution.ExecutionHandler;
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.persistence.api.StrolchTransaction;
import li.strolch.runtime.StrolchConstants;
@ -32,20 +34,27 @@ public class SetToExecutionService extends AbstractService<LocatorArgument, Serv
String realm = isEmpty(arg.realm) ? StrolchConstants.DEFAULT_REALM : arg.realm;
Activity activity;
try (StrolchTransaction tx = openTx(realm)) {
tx.lock(arg.locator);
IActivityElement element = tx.findElement(arg.locator);
if (!element.getState().canSetToExecution()) {
if (element.getState().canNotSetToExecution()) {
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(realm, arg.locator);
if (element.isAction() && element.getState() == State.STOPPED) {
((Action) element).setState(State.EXECUTABLE);
}
activity = element.getRootElement();
}
ExecutionHandler executionHandler = getContainer().getComponent(ExecutionHandler.class);
executionHandler.addForExecution(realm, activity);
return ServiceResult.success();
}
}

View File

@ -4,6 +4,8 @@ import static li.strolch.service.I18nService.i18nService;
import li.strolch.execution.ExecutionHandler;
import li.strolch.execution.ExecutionHandlerState;
import li.strolch.model.activity.Activity;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.runtime.StrolchConstants;
import li.strolch.service.LocatorArgument;
import li.strolch.service.StrolchRootElementResult;
@ -36,7 +38,12 @@ public class StartActivityExecutionService extends AbstractService<LocatorArgume
"ExecutionHandler is not running, can not start new jobs!")
.i18n(i18nService, "execution.handler.invalidState", "state", executionHandlerState);
executionHandler.addForExecution(realm, arg.locator);
Activity activity;
try (StrolchTransaction tx = openTx(realm, true)) {
activity = tx.getActivityBy(arg.locator.get(1), arg.locator.get(2), true);
}
executionHandler.addForExecution(realm, activity);
return ServiceResult.success();
}

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li class="active"><a href="api.html">API</a></li>
<li><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -33,6 +33,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li class="active"><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li class="active"><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li class="active"><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li class="active"><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li class="active"><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li class="active"><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li class="active"><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li class="active"><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li class="active"><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li class="active"><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li class="active"><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li class="active"><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li class="active"><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li class="active"><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li class="active"><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li class="active"><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li class="active"><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -33,6 +33,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li class="active"><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li class="active"><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li class="active"><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -0,0 +1,109 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="google-site-verification" content="CPhbjooaiTdROm7Vs4E7kuHZvBfkeLUtonGgcVUbTL8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="ico/favicon.ico">
<title>Strolch: PLC</title>
<!-- Bootstrap core CSS -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="css/custom.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --><!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script><![endif]-->
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="index.html">Strolch</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li><a href="documentation.html">Documentation</a></li>
<li class="active"><a href="plc.html">PLC</a></li>
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>
<li><a href="blog.html">Blog</a></li>
</ul>
</div>
<!--/.nav-collapse -->
</div>
</div>
<div class="container">
<div class="page-header">
<h1 class="page-title">Strolch as a PLC</h1>
<p class="lead page-description">This page how Strolch can act as software based PLC with soft realtime.</p>
</div>
<div class="content">
<!-- content here -->
<h2>Overview</h2>
<p>Using Strolch as a PLC has certain advantages and disadvantages. The following is a list of advantages:</p>
<ul>
<li>Same programming model and language for server and PLC</li>
<li>PLC has the same privilege handling as in Strolch</li>
<li>Simulating down to the PLC level is easily possible to quickly test the server logic</li>
</ul>
</div>
<!-- /.content -->
<div id="footer">
<div class="container">
<p class="text-muted">&copy; Strolch / <a href="mailto:eitch@eitchnet.ch">Robert von Burg</a> / Hosting by
<a href="http://www.eitchnet.ch">eitchnet.ch</a></p>
</div>
</div>
</div>
<!-- /.container -->
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual xsd as needed -->
<script src="js/bootstrap.min.js"></script>
<!-- Piwik -->
<script type="text/javascript">
var _paq = _paq || [];
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function () {
var u = (("https:" == document.location.protocol) ? "https" : "http") + "://piwik.eitchnet.ch/";
_paq.push(['setTrackerUrl', u + 'piwik.php']);
_paq.push(['setSiteId', 2]);
var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
g.type = 'text/javascript';
g.defer = true;
g.async = true;
g.src = u + 'piwik.js';
s.parentNode.insertBefore(g, s);
})();
</script>
<noscript><p><img src="http://piwik.eitchnet.ch/piwik.php?idsite=2" style="border:0;" alt="" /></p></noscript>
<!-- End Piwik Code -->
</body>
</html>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li class="active"><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li class="active"><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li class="active"><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>

View File

@ -32,6 +32,7 @@
<li><a href="index.html">Overview</a></li>
<li><a href="api.html">API</a></li>
<li><a href="documentation.html">Documentation</a></li>
<li><a href="plc.html">PLC</a></li>
<li class="active"><a href="tutorial.html">Tutorial</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="development.html">Development</a></li>