Merge branch 'feature/planning' into develop
This commit is contained in:
commit
c312f4b5b0
|
@ -425,7 +425,7 @@ public class StrolchComponent {
|
||||||
* @return the newly created transaction
|
* @return the newly created transaction
|
||||||
*/
|
*/
|
||||||
protected StrolchTransaction openTx(Certificate cert, boolean readOnly) {
|
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
|
* @return the newly created transaction
|
||||||
*/
|
*/
|
||||||
protected StrolchTransaction openTx(String realm, Certificate cert, boolean readOnly) {
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -319,6 +319,10 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addCommand(Command command) {
|
public void addCommand(Command command) {
|
||||||
|
add(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(Command command) {
|
||||||
assertNotReadOnly();
|
assertNotReadOnly();
|
||||||
this.commands.add(command);
|
this.commands.add(command);
|
||||||
}
|
}
|
||||||
|
@ -416,13 +420,14 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return findElement(locator, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@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>
|
||||||
// Resource/<type>/<id>/Bag/<id>
|
// Resource/<type>/<id>/Bag/<id>
|
||||||
|
@ -435,7 +440,7 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
||||||
if (locator.getSize() < 3) {
|
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$
|
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());
|
msg = MessageFormat.format(msg, locator.toString());
|
||||||
throw new StrolchException(msg);
|
throw new StrolchModelException(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> elements = locator.getPathElements();
|
List<String> elements = locator.getPathElements();
|
||||||
|
@ -454,14 +459,15 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
||||||
groupedParameterizedElement = getActivityBy(type, id);
|
groupedParameterizedElement = getActivityBy(type, id);
|
||||||
break;
|
break;
|
||||||
default:
|
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 (groupedParameterizedElement == null) {
|
||||||
if (allowNull)
|
if (allowNull)
|
||||||
return null;
|
return null;
|
||||||
String msg = "No top level object could be found with locator {0}"; //$NON-NLS-1$
|
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)
|
if (elements.size() == 3)
|
||||||
|
@ -477,7 +483,7 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
||||||
if (allowNull)
|
if (allowNull)
|
||||||
return null;
|
return null;
|
||||||
String msg = "Could not find ParameterBag for locator {0} on element {1}"; //$NON-NLS-1$
|
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()));
|
MessageFormat.format(msg, locator, groupedParameterizedElement.getLocator()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,7 +496,7 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
||||||
if (allowNull)
|
if (allowNull)
|
||||||
return null;
|
return null;
|
||||||
String msg = "Could not find Parameter for locator {0} on element {1}"; //$NON-NLS-1$
|
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;
|
return (T) parameter;
|
||||||
|
|
||||||
|
@ -498,9 +504,10 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
||||||
|
|
||||||
if (elements.size() != 5) {
|
if (elements.size() != 5) {
|
||||||
String msg = "Missing state Id on locator {0}"; //$NON-NLS-1$
|
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;
|
Resource resource = (Resource) groupedParameterizedElement;
|
||||||
String stateId = elements.get(4);
|
String stateId = elements.get(4);
|
||||||
|
|
||||||
|
@ -518,7 +525,7 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
||||||
|
|
||||||
if (!(element instanceof Activity)) {
|
if (!(element instanceof Activity)) {
|
||||||
String msg = "Invalid locator {0} with part {1} as not an Activity but deeper element specified"; //$NON-NLS-1$
|
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);
|
element = ((Activity) element).getElement(next);
|
||||||
|
@ -531,7 +538,7 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
String msg = "Invalid locator {0} with part {1}"; //$NON-NLS-1$
|
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
|
@Override
|
||||||
|
@ -1044,6 +1051,14 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
||||||
return getActivitiesBy(refsP, assertExists);
|
return getActivitiesBy(refsP, assertExists);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeFromCache(Locator locator) {
|
||||||
|
if (this.resourceCache != null)
|
||||||
|
this.resourceCache.removeElement(locator.get(1), locator.get(2));
|
||||||
|
if (this.objectFilter != null)
|
||||||
|
this.objectFilter.removeObjectCache(locator.get(0), locator);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Resource getCachedResource(String type, String id) {
|
public Resource getCachedResource(String type, String id) {
|
||||||
if (this.resourceCache == null)
|
if (this.resourceCache == null)
|
||||||
|
|
|
@ -445,6 +445,24 @@ public interface StrolchTransaction extends AutoCloseable {
|
||||||
*/
|
*/
|
||||||
void addCommand(Command command);
|
void addCommand(Command command);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the given {@link Command} to the transaction. Using this method guarantees that a {@link Command} is
|
||||||
|
* executed properly:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link Command#validate()}</li>
|
||||||
|
* <li>{@link Command#doCommand()}</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* and if an exception occurs:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link Command#undo()}</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param command
|
||||||
|
* the command to add
|
||||||
|
*/
|
||||||
|
void add(Command command);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to create an {@link Audit} with the given arguments. The audit can then be saved by calling {@link
|
* Helper method to create an {@link Audit} with the given arguments. The audit can then be saved by calling {@link
|
||||||
* AuditTrail#add(StrolchTransaction, Audit)}
|
* AuditTrail#add(StrolchTransaction, Audit)}
|
||||||
|
@ -534,11 +552,11 @@ public interface StrolchTransaction extends AutoCloseable {
|
||||||
* Used to find a {@link StrolchElement} by a {@link Locator}, throwing exception if the element is not found
|
* Used to find a {@link StrolchElement} by a {@link Locator}, throwing exception if the element is not found
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @throws StrolchException
|
* @throws StrolchModelException
|
||||||
* if the element could not be found
|
* if the element could not be found
|
||||||
* @see #findElement(Locator, boolean)
|
* @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>
|
* <p>
|
||||||
|
@ -565,14 +583,14 @@ public interface StrolchTransaction extends AutoCloseable {
|
||||||
* an inexistant {@link Resource} or an inexistand {@link Parameter} on a Resource, then a {@link StrolchException}
|
* an inexistant {@link Resource} or an inexistand {@link Parameter} on a Resource, then a {@link StrolchException}
|
||||||
* is thrown
|
* is thrown
|
||||||
*
|
*
|
||||||
* @throws StrolchException
|
* @throws StrolchModelException
|
||||||
* if the element could not be found and {@code allowNull} is false
|
* if the element could not be found and {@code allowNull} is false
|
||||||
* @throws ClassCastException
|
* @throws ClassCastException
|
||||||
* if the querying code is not asking for the correct instance. Do not query a {@link Parameter} if the variable
|
* 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.
|
* to which the result is to be is stored is a {@link Resource}, etc.
|
||||||
*/
|
*/
|
||||||
<T extends StrolchElement> T findElement(Locator locator, boolean allowNull)
|
<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
|
* <p>Finds a parameter with the given @bagKey and @paramKey on the given @element, but if it does not exists
|
||||||
|
@ -1361,6 +1379,14 @@ public interface StrolchTransaction extends AutoCloseable {
|
||||||
List<Order> getOrdersByRelation(StrolchRootElement element, String refId, boolean assertExists)
|
List<Order> getOrdersByRelation(StrolchRootElement element, String refId, boolean assertExists)
|
||||||
throws StrolchException;
|
throws StrolchException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows to evict a {@link Locator} from the transaction's cache and object filter
|
||||||
|
*
|
||||||
|
* @param locator
|
||||||
|
* the locator of the object to remove from cache
|
||||||
|
*/
|
||||||
|
void removeFromCache(Locator locator);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the cached resource with the given type and id, or null if not yet fetched
|
* Returns the cached resource with the given type and id, or null if not yet fetched
|
||||||
*
|
*
|
||||||
|
|
|
@ -16,20 +16,15 @@
|
||||||
package li.strolch.policy;
|
package li.strolch.policy;
|
||||||
|
|
||||||
import static li.strolch.runtime.StrolchConstants.PolicyConstants.PARAM_ORDER;
|
import static li.strolch.runtime.StrolchConstants.PolicyConstants.PARAM_ORDER;
|
||||||
import static li.strolch.utils.helper.StringHelper.DASH;
|
|
||||||
|
|
||||||
import li.strolch.model.Order;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
import li.strolch.agent.api.ComponentContainer;
|
||||||
import li.strolch.agent.api.StrolchComponent;
|
import li.strolch.agent.api.StrolchComponent;
|
||||||
import li.strolch.exception.StrolchException;
|
import li.strolch.model.Order;
|
||||||
import li.strolch.model.Resource;
|
|
||||||
import li.strolch.model.activity.Action;
|
import li.strolch.model.activity.Action;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
import li.strolch.service.api.Command;
|
import li.strolch.service.api.Command;
|
||||||
import li.strolch.utils.helper.StringHelper;
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for all Strolch policies, which are instantiated by the {@link PolicyHandler}
|
* Interface for all Strolch policies, which are instantiated by the {@link PolicyHandler}
|
||||||
|
@ -86,30 +81,6 @@ public abstract class StrolchPolicy {
|
||||||
return this.tx;
|
return this.tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the defined {@link Resource} on the given {@link Action}
|
|
||||||
*
|
|
||||||
* @param action
|
|
||||||
* the action for which to get the {@link Resource}
|
|
||||||
*
|
|
||||||
* @return the {@link Resource}
|
|
||||||
*
|
|
||||||
* @throws IllegalArgumentException
|
|
||||||
* if the resource is not defined on the action, i.e. fields are empty or a dash
|
|
||||||
* @throws StrolchException
|
|
||||||
* if the resource does not exist, which is referenced by the action
|
|
||||||
*/
|
|
||||||
protected Resource getResource(Action action) throws IllegalArgumentException, StrolchException {
|
|
||||||
String resourceId = action.getResourceId();
|
|
||||||
if (StringHelper.isEmpty(resourceId) || resourceId.equals(DASH))
|
|
||||||
throw new IllegalArgumentException("No resourceId defined on action " + action.getLocator());
|
|
||||||
String resourceType = action.getResourceType();
|
|
||||||
if (StringHelper.isEmpty(resourceType) || resourceType.equals(DASH))
|
|
||||||
throw new IllegalArgumentException("No resourceType defined on action " + action.getLocator());
|
|
||||||
|
|
||||||
return this.tx.getResourceBy(resourceType, resourceId, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Order getOrder(Action action) {
|
protected Order getOrder(Action action) {
|
||||||
return tx().getOrderByRelation(action.getRootElement(), PARAM_ORDER, true);
|
return tx().getOrderByRelation(action.getRootElement(), PARAM_ORDER, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -304,11 +304,12 @@ public abstract class Command implements Restrictable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Should the transaction fail, either due to a {@link Command} throwing an exception when {@link #validate()} is
|
* This method can be used to undo actions peformed during the command, should the TX fail. In earlier versions of
|
||||||
* called, or while committing the transaction, then this method should properly undo any changes it has done. It is
|
* Strolch this was important to undo model changes, but the model changes are only visible after a commit succeeds,
|
||||||
* imperative that this method does not throw further exceptions and that the state to be rolled back is remembered
|
* so this is no longer necessary.
|
||||||
* in the Command during committing
|
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public abstract void undo();
|
public void undo() {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,9 +32,4 @@ public class TestNoConfirmationPolicy extends TestConfirmationPolicy {
|
||||||
public void confirm(Action action) {
|
public void confirm(Action action) {
|
||||||
action.setState(State.CLOSED);
|
action.setState(State.CLOSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void undo() {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,9 +32,4 @@ public class TestSimplePlanningPolicy extends TestPlanningPolicy {
|
||||||
public void plan(Action action) {
|
public void plan(Action action) {
|
||||||
action.setState(State.PLANNED);
|
action.setState(State.PLANNED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void undo() {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,9 +32,4 @@ public class TestSimulatedExecutionPolicy extends TestExecutionPolicy {
|
||||||
public void execute(Action action) {
|
public void execute(Action action) {
|
||||||
action.setState(State.EXECUTION);
|
action.setState(State.EXECUTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void undo() {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,6 +154,20 @@ public class Order extends AbstractStrolchRootElement implements StrolchRootElem
|
||||||
return getPolicyDefs().getPolicyDef(type);
|
return getPolicyDefs().getPolicyDef(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PolicyDef getPolicyDef(Class<?> clazz, PolicyDef defaultDef) {
|
||||||
|
if (!hasPolicyDefs())
|
||||||
|
return defaultDef;
|
||||||
|
return getPolicyDefs().getPolicyDef(clazz.getSimpleName(), defaultDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PolicyDef getPolicyDef(String type, PolicyDef defaultDef) {
|
||||||
|
if (!hasPolicyDefs())
|
||||||
|
return defaultDef;
|
||||||
|
return getPolicyDefs().getPolicyDef(type, defaultDef);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasPolicyDefs() {
|
public boolean hasPolicyDefs() {
|
||||||
return this.policyDefs != null;
|
return this.policyDefs != null;
|
||||||
|
|
|
@ -20,12 +20,12 @@ public interface PolicyContainer {
|
||||||
* @throws StrolchPolicyException
|
* @throws StrolchPolicyException
|
||||||
* if no {@link PolicyDefs} are available
|
* if no {@link PolicyDefs} are available
|
||||||
*/
|
*/
|
||||||
public PolicyDefs getPolicyDefs() throws StrolchPolicyException;
|
PolicyDefs getPolicyDefs() throws StrolchPolicyException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if this container has {@link PolicyDefs}, false if not
|
* @return true if this container has {@link PolicyDefs}, false if not
|
||||||
*/
|
*/
|
||||||
public boolean hasPolicyDefs();
|
boolean hasPolicyDefs();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this container has the {@link PolicyDef} with the given type, false if not
|
* Returns true if this container has the {@link PolicyDef} with the given type, false if not
|
||||||
|
@ -35,7 +35,7 @@ public interface PolicyContainer {
|
||||||
*
|
*
|
||||||
* @return true if this container has the {@link PolicyDef} with the given type, false if not
|
* @return true if this container has the {@link PolicyDef} with the given type, false if not
|
||||||
*/
|
*/
|
||||||
public boolean hasPolicyDef(String type);
|
boolean hasPolicyDef(String type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link PolicyDef} for the given type
|
* Returns the {@link PolicyDef} for the given type
|
||||||
|
@ -45,7 +45,19 @@ public interface PolicyContainer {
|
||||||
*
|
*
|
||||||
* @return the policy def of the given type
|
* @return the policy def of the given type
|
||||||
*/
|
*/
|
||||||
public PolicyDef getPolicyDef(String type);
|
PolicyDef getPolicyDef(String type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link PolicyDef} for the given type
|
||||||
|
*
|
||||||
|
* @param type
|
||||||
|
* the type of policy def to return
|
||||||
|
* @param defaultDef
|
||||||
|
* the default policy definition to return if the given type is not defined
|
||||||
|
*
|
||||||
|
* @return the policy def of the given type
|
||||||
|
*/
|
||||||
|
PolicyDef getPolicyDef(String type, PolicyDef defaultDef);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link PolicyDef} for the given class
|
* Returns the {@link PolicyDef} for the given class
|
||||||
|
@ -55,7 +67,19 @@ public interface PolicyContainer {
|
||||||
*
|
*
|
||||||
* @return the policy def of the given class
|
* @return the policy def of the given class
|
||||||
*/
|
*/
|
||||||
public PolicyDef getPolicyDef(Class<?> clazz);
|
PolicyDef getPolicyDef(Class<?> clazz);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link PolicyDef} for the given class
|
||||||
|
*
|
||||||
|
* @param clazz
|
||||||
|
* the type of policy def to return
|
||||||
|
* @param defaultDef
|
||||||
|
* the default policy definition to return if the given type is not defined
|
||||||
|
*
|
||||||
|
* @return the policy def of the given class
|
||||||
|
*/
|
||||||
|
PolicyDef getPolicyDef(Class<?> clazz, PolicyDef defaultDef);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the reference to the {@link PolicyDefs}
|
* Set the reference to the {@link PolicyDefs}
|
||||||
|
@ -63,5 +87,5 @@ public interface PolicyContainer {
|
||||||
* @param policyDefs
|
* @param policyDefs
|
||||||
* the {@link PolicyDefs} to set
|
* the {@link PolicyDefs} to set
|
||||||
*/
|
*/
|
||||||
public void setPolicyDefs(PolicyDefs policyDefs);
|
void setPolicyDefs(PolicyDefs policyDefs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,6 +252,20 @@ public class Resource extends AbstractStrolchRootElement implements StrolchRootE
|
||||||
return getPolicyDefs().getPolicyDef(type);
|
return getPolicyDefs().getPolicyDef(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PolicyDef getPolicyDef(Class<?> clazz, PolicyDef defaultDef) {
|
||||||
|
if (!hasPolicyDefs())
|
||||||
|
return defaultDef;
|
||||||
|
return getPolicyDefs().getPolicyDef(clazz.getSimpleName(), defaultDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PolicyDef getPolicyDef(String type, PolicyDef defaultDef) {
|
||||||
|
if (!hasPolicyDefs())
|
||||||
|
return defaultDef;
|
||||||
|
return getPolicyDefs().getPolicyDef(type, defaultDef);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasPolicyDefs() {
|
public boolean hasPolicyDefs() {
|
||||||
return this.policyDefs != null;
|
return this.policyDefs != null;
|
||||||
|
|
|
@ -30,6 +30,7 @@ public enum State {
|
||||||
CREATED("Created"), //$NON-NLS-1$
|
CREATED("Created"), //$NON-NLS-1$
|
||||||
PLANNING("Planning"), //$NON-NLS-1$
|
PLANNING("Planning"), //$NON-NLS-1$
|
||||||
PLANNED("Planned"), //$NON-NLS-1$
|
PLANNED("Planned"), //$NON-NLS-1$
|
||||||
|
EXECUTABLE("Executable"), //$NON-NLS-1$
|
||||||
EXECUTION("Execution"), //$NON-NLS-1$
|
EXECUTION("Execution"), //$NON-NLS-1$
|
||||||
WARNING("Warning"), //$NON-NLS-1$
|
WARNING("Warning"), //$NON-NLS-1$
|
||||||
ERROR("Error"), //$NON-NLS-1$
|
ERROR("Error"), //$NON-NLS-1$
|
||||||
|
@ -39,7 +40,7 @@ public enum State {
|
||||||
|
|
||||||
private String state;
|
private String state;
|
||||||
|
|
||||||
private State(String state) {
|
State(String state) {
|
||||||
this.state = 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
|
* @return true if the state is one of {@link #EXECUTABLE} {@link #EXECUTION}, {@link #STOPPED}, {@link #WARNING},
|
||||||
* {@link #EXECUTED}
|
* {@link #ERROR} or {@link #EXECUTED}
|
||||||
*/
|
*/
|
||||||
public boolean inExecutionPhase() {
|
public boolean inExecutionPhase() {
|
||||||
return this == EXECUTION || this == STOPPED || this == WARNING || this == ERROR;
|
return this == EXECUTION || this == STOPPED || this == WARNING || this == ERROR;
|
||||||
|
@ -168,10 +169,24 @@ 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 #STOPPED}
|
||||||
*/
|
*/
|
||||||
public boolean canSetToExecution() {
|
public boolean canSetToExecutable() {
|
||||||
return this == CREATED || this == PLANNING || this == PLANNED || this == EXECUTION || this == State.STOPPED;
|
return this == PLANNED || this == EXECUTABLE || this == State.STOPPED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if {@link #PLANNED} or {@link #EXECUTABLE} or {@link #EXECUTION}
|
||||||
|
*/
|
||||||
|
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 +264,7 @@ public enum State {
|
||||||
return WARNING;
|
return WARNING;
|
||||||
|
|
||||||
// execution
|
// execution
|
||||||
if (states.contains(EXECUTION))
|
if (states.contains(EXECUTABLE) || states.contains(EXECUTION))
|
||||||
return EXECUTION;
|
return EXECUTION;
|
||||||
if (states.contains(EXECUTED) && (states.contains(CREATED) || states.contains(PLANNING) || states
|
if (states.contains(EXECUTED) && (states.contains(CREATED) || states.contains(PLANNING) || states
|
||||||
.contains(PLANNED)))
|
.contains(PLANNED)))
|
||||||
|
@ -275,4 +290,5 @@ public enum State {
|
||||||
// should never happen, unless new state is introduced
|
// should never happen, unless new state is introduced
|
||||||
throw new IllegalStateException("Unhandled situation with states: " + states.stream().map(e -> e.state)
|
throw new IllegalStateException("Unhandled situation with states: " + states.stream().map(e -> e.state)
|
||||||
.collect(Collectors.joining(", ")));
|
.collect(Collectors.joining(", ")));
|
||||||
}}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package li.strolch.model.activity;
|
package li.strolch.model.activity;
|
||||||
|
|
||||||
|
import static li.strolch.utils.helper.StringHelper.isNotEmpty;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@ -142,6 +144,16 @@ public class Action extends GroupedParameterizedElement implements IActivityElem
|
||||||
this.resourceId = resource.getId();
|
this.resourceId = resource.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasResourceDefined() {
|
||||||
|
return isNotEmpty(this.resourceType) && isNotEmpty(this.resourceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Locator getResourceLocator() {
|
||||||
|
if (!hasResourceDefined())
|
||||||
|
throw new IllegalStateException("Resource not set on " + getLocator());
|
||||||
|
return Resource.locatorFor(this.resourceType, this.resourceId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this {@link Action} contains any {@link IValueChange changes}, false if not
|
* Returns true if this {@link Action} contains any {@link IValueChange changes}, false if not
|
||||||
*
|
*
|
||||||
|
@ -245,6 +257,20 @@ public class Action extends GroupedParameterizedElement implements IActivityElem
|
||||||
return getPolicyDefs().getPolicyDef(clazz.getSimpleName());
|
return getPolicyDefs().getPolicyDef(clazz.getSimpleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PolicyDef getPolicyDef(Class<?> clazz, PolicyDef defaultDef) {
|
||||||
|
if (!hasPolicyDefs())
|
||||||
|
return defaultDef;
|
||||||
|
return getPolicyDefs().getPolicyDef(clazz.getSimpleName(), defaultDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PolicyDef getPolicyDef(String type, PolicyDef defaultDef) {
|
||||||
|
if (!hasPolicyDefs())
|
||||||
|
return defaultDef;
|
||||||
|
return getPolicyDefs().getPolicyDef(type, defaultDef);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasPolicyDef(String type) {
|
public boolean hasPolicyDef(String type) {
|
||||||
return this.policyDefs != null && policyDefs.hasPolicyDef(type);
|
return this.policyDefs != null && policyDefs.hasPolicyDef(type);
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.*;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import li.strolch.exception.StrolchElementNotFoundException;
|
||||||
import li.strolch.exception.StrolchException;
|
import li.strolch.exception.StrolchException;
|
||||||
import li.strolch.exception.StrolchModelException;
|
import li.strolch.exception.StrolchModelException;
|
||||||
import li.strolch.exception.StrolchPolicyException;
|
import li.strolch.exception.StrolchPolicyException;
|
||||||
|
@ -381,6 +382,29 @@ 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);
|
||||||
|
if (element == null)
|
||||||
|
throw new StrolchElementNotFoundException(locator + " does not exist!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@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
|
* @return the iterator for entries, which include the id as key and the {@link IActivityElement} as value
|
||||||
*/
|
*/
|
||||||
|
@ -449,6 +473,20 @@ public class Activity extends AbstractStrolchRootElement
|
||||||
return getPolicyDefs().getPolicyDef(type);
|
return getPolicyDefs().getPolicyDef(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PolicyDef getPolicyDef(Class<?> clazz, PolicyDef defaultDef) {
|
||||||
|
if (!hasPolicyDefs())
|
||||||
|
return defaultDef;
|
||||||
|
return getPolicyDefs().getPolicyDef(clazz.getSimpleName(), defaultDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PolicyDef getPolicyDef(String type, PolicyDef defaultDef) {
|
||||||
|
if (!hasPolicyDefs())
|
||||||
|
return defaultDef;
|
||||||
|
return getPolicyDefs().getPolicyDef(type, defaultDef);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasPolicyDefs() {
|
public boolean hasPolicyDefs() {
|
||||||
return this.policyDefs != null;
|
return this.policyDefs != null;
|
||||||
|
|
|
@ -55,7 +55,14 @@ public class PolicyDefs {
|
||||||
}
|
}
|
||||||
|
|
||||||
public PolicyDef getPolicyDef(String type) {
|
public PolicyDef getPolicyDef(String type) {
|
||||||
|
return getPolicyDef(type, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PolicyDef getPolicyDef(String type, PolicyDef defaultDef) {
|
||||||
if (!this.policyDefMap.containsKey(type)) {
|
if (!this.policyDefMap.containsKey(type)) {
|
||||||
|
if (defaultDef != null)
|
||||||
|
return defaultDef;
|
||||||
|
|
||||||
throw new StrolchPolicyException(
|
throw new StrolchPolicyException(
|
||||||
"The PolicyDef does not exist with type " + type + " on " + this.parent.getLocator());
|
"The PolicyDef does not exist with type " + type + " on " + this.parent.getLocator());
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import li.strolch.execution.ExecutionHandler;
|
||||||
import li.strolch.execution.ExecutionHandlerState;
|
import li.strolch.execution.ExecutionHandlerState;
|
||||||
import li.strolch.execution.service.*;
|
import li.strolch.execution.service.*;
|
||||||
import li.strolch.model.Locator;
|
import li.strolch.model.Locator;
|
||||||
|
import li.strolch.model.State;
|
||||||
import li.strolch.model.activity.Activity;
|
import li.strolch.model.activity.Activity;
|
||||||
import li.strolch.model.json.StrolchElementToJsonVisitor;
|
import li.strolch.model.json.StrolchElementToJsonVisitor;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
|
@ -133,15 +134,84 @@ public class ControlResource {
|
||||||
@QueryParam("locator") String locatorS, @QueryParam("state") String stateS) {
|
@QueryParam("locator") String locatorS, @QueryParam("state") String stateS) {
|
||||||
|
|
||||||
Certificate cert = (Certificate) request.getAttribute(STROLCH_CERTIFICATE);
|
Certificate cert = (Certificate) request.getAttribute(STROLCH_CERTIFICATE);
|
||||||
|
State state = State.parse(stateS);
|
||||||
|
Locator locator = Locator.valueOf(locatorS);
|
||||||
|
|
||||||
SetActionStateService svc = new SetActionStateService();
|
LocatorArgument arg = new LocatorArgument();
|
||||||
StringMapArgument arg = svc.getArgumentInstance();
|
arg.locator = locator;
|
||||||
arg.realm = realm;
|
|
||||||
arg.map.put("locator", locatorS);
|
|
||||||
arg.map.put("state", stateS);
|
|
||||||
|
|
||||||
ServiceHandler serviceHandler = RestfulStrolchComponent.getInstance().getServiceHandler();
|
ServiceHandler serviceHandler = RestfulStrolchComponent.getInstance().getServiceHandler();
|
||||||
ServiceResult svcResult = serviceHandler.doService(cert, svc, arg);
|
ServiceResult svcResult;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case CREATED: {
|
||||||
|
|
||||||
|
SetActionToCreatedService svc = new SetActionToCreatedService();
|
||||||
|
svcResult = serviceHandler.doService(cert, svc, arg);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PLANNED: {
|
||||||
|
|
||||||
|
SetActionToPlannedService svc = new SetActionToPlannedService();
|
||||||
|
svcResult = serviceHandler.doService(cert, svc, arg);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EXECUTION: {
|
||||||
|
|
||||||
|
ExecuteActionService svc = new ExecuteActionService();
|
||||||
|
svcResult = serviceHandler.doService(cert, svc, arg);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WARNING: {
|
||||||
|
|
||||||
|
SetActionToWarningService svc = new SetActionToWarningService();
|
||||||
|
svcResult = serviceHandler.doService(cert, svc, arg);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ERROR: {
|
||||||
|
|
||||||
|
SetActionToErrorService svc = new SetActionToErrorService();
|
||||||
|
svcResult = serviceHandler.doService(cert, svc, arg);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case STOPPED: {
|
||||||
|
|
||||||
|
SetActionToStoppedService svc = new SetActionToStoppedService();
|
||||||
|
svcResult = serviceHandler.doService(cert, svc, arg);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EXECUTED: {
|
||||||
|
|
||||||
|
SetActionToExecutedService svc = new SetActionToExecutedService();
|
||||||
|
svcResult = serviceHandler.doService(cert, svc, arg);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CLOSED: {
|
||||||
|
|
||||||
|
SetActionToClosedService svc = new SetActionToClosedService();
|
||||||
|
svcResult = serviceHandler.doService(cert, svc, arg);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("Unhandled state " + state);
|
||||||
|
}
|
||||||
|
|
||||||
return ResponseUtil.toResponse(svcResult);
|
return ResponseUtil.toResponse(svcResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package li.strolch.execution;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import li.strolch.agent.api.StrolchAgent;
|
import li.strolch.agent.api.StrolchAgent;
|
||||||
|
import li.strolch.execution.command.ArchiveActivityCommand;
|
||||||
import li.strolch.job.JobMode;
|
import li.strolch.job.JobMode;
|
||||||
import li.strolch.job.StrolchJob;
|
import li.strolch.job.StrolchJob;
|
||||||
import li.strolch.model.State;
|
import li.strolch.model.State;
|
||||||
|
@ -23,13 +24,16 @@ public class ArchiveExecutedActivitiesJob extends StrolchJob {
|
||||||
@Override
|
@Override
|
||||||
protected void execute(PrivilegeContext ctx) {
|
protected void execute(PrivilegeContext ctx) {
|
||||||
|
|
||||||
ExecutionHandler executionHandler = getComponent(ExecutionHandler.class);
|
try (StrolchTransaction tx = openTx(ctx.getCertificate())) {
|
||||||
|
|
||||||
try (StrolchTransaction tx = openTx(ctx.getCertificate(), true)) {
|
|
||||||
tx.streamActivities().forEach(activity -> {
|
tx.streamActivities().forEach(activity -> {
|
||||||
if (activity.getState() == State.EXECUTED)
|
if (activity.getState() == State.EXECUTED) {
|
||||||
executionHandler.archiveActivity(tx.getRealmName(), activity.getLocator());
|
ArchiveActivityCommand command = new ArchiveActivityCommand(tx);
|
||||||
|
command.setActivityLoc(activity.getLocator());
|
||||||
|
tx.addCommand(command);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tx.commitOnClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,331 @@
|
||||||
|
package li.strolch.execution;
|
||||||
|
|
||||||
|
import static li.strolch.runtime.StrolchConstants.SYSTEM_USER_AGENT;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
import li.strolch.agent.api.ComponentContainer;
|
||||||
|
import li.strolch.agent.api.ObserverEvent;
|
||||||
|
import li.strolch.agent.api.StrolchRealm;
|
||||||
|
import li.strolch.execution.command.*;
|
||||||
|
import li.strolch.execution.policy.ExecutionPolicy;
|
||||||
|
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.Resource;
|
||||||
|
import li.strolch.model.State;
|
||||||
|
import li.strolch.model.Tags;
|
||||||
|
import li.strolch.model.activity.Action;
|
||||||
|
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.runtime.privilege.PrivilegedRunnable;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class Controller {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(Controller.class);
|
||||||
|
|
||||||
|
private final String realm;
|
||||||
|
private ComponentContainer container;
|
||||||
|
private ExecutionHandler executionHandler;
|
||||||
|
|
||||||
|
private final String activityType;
|
||||||
|
private final String activityId;
|
||||||
|
private final Locator locator;
|
||||||
|
|
||||||
|
private Activity activity;
|
||||||
|
|
||||||
|
private Map<Locator, ExecutionPolicy> inExecution;
|
||||||
|
|
||||||
|
public Controller(String realm, ExecutionHandler executionHandler, Activity activity) {
|
||||||
|
this.realm = realm;
|
||||||
|
this.container = executionHandler.getContainer();
|
||||||
|
this.executionHandler = executionHandler;
|
||||||
|
this.locator = activity.getLocator();
|
||||||
|
this.activityType = activity.getType();
|
||||||
|
this.activityId = activity.getId();
|
||||||
|
this.activity = activity;
|
||||||
|
this.inExecution = Collections.synchronizedMap(new HashMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRealm() {
|
||||||
|
return this.realm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStopped(Locator locator) {
|
||||||
|
ExecutionPolicy executionPolicy = this.inExecution.get(locator);
|
||||||
|
return executionPolicy == null || executionPolicy.isStopped();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Locator getLocator() {
|
||||||
|
return this.locator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Activity getActivity() {
|
||||||
|
return this.activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecutionPolicy getExecutionPolicy(StrolchTransaction tx, Action action) {
|
||||||
|
ExecutionPolicy executionPolicy = this.inExecution.computeIfAbsent(action.getLocator(), e -> {
|
||||||
|
Resource resource = tx.getResourceFor(action, true);
|
||||||
|
return tx.getPolicy(resource.getPolicyDef(ExecutionPolicy.class));
|
||||||
|
});
|
||||||
|
|
||||||
|
// always update the TX and controller
|
||||||
|
executionPolicy.setController(tx, this);
|
||||||
|
return executionPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected StrolchTransaction openTx(Certificate cert) {
|
||||||
|
return this.executionHandler.openTx(this.realm, cert, getClass(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void runAsAgent(PrivilegedRunnable runnable) throws PrivilegeException, Exception {
|
||||||
|
this.executionHandler.runAsAgent(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean refreshActivity(StrolchTransaction tx) {
|
||||||
|
Activity activity = tx.getActivityBy(this.activityType, this.activityId, false);
|
||||||
|
if (activity == null) {
|
||||||
|
logger.error("Element " + this.locator + " does not exist anymore. Removing from execution");
|
||||||
|
this.executionHandler.removeFromExecution(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.activity = activity;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the execution of this {@link Activity}
|
||||||
|
*/
|
||||||
|
public void execute() throws Exception {
|
||||||
|
boolean[] trigger = new boolean[1];
|
||||||
|
this.executionHandler.runAsAgent(ctx -> {
|
||||||
|
try (StrolchTransaction tx = openTx(ctx.getCertificate())) {
|
||||||
|
tx.lock(this.locator);
|
||||||
|
trigger[0] = execute(tx);
|
||||||
|
if (tx.needsCommit()) {
|
||||||
|
tx.commitOnClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (trigger[0])
|
||||||
|
this.executionHandler.triggerExecution(this.realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean execute(StrolchTransaction tx) {
|
||||||
|
if (!refreshActivity(tx))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (this.activity.getState().isExecuted()) {
|
||||||
|
this.executionHandler.removeFromExecution(this);
|
||||||
|
logger.info("Archiving executed activity " + this.locator + " with state " + this.activity.getState());
|
||||||
|
this.executionHandler.archiveActivity(this.realm, this.activity);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExecutionHandlerState state = this.executionHandler.getState(this.realm);
|
||||||
|
if (state == ExecutionHandlerState.Paused) {
|
||||||
|
logger.warn("Ignoring trigger for paused realm " + this.realm);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExecuteActivityCommand command = new ExecuteActivityCommand(tx);
|
||||||
|
command.setController(this);
|
||||||
|
command.validate();
|
||||||
|
command.doCommand();
|
||||||
|
|
||||||
|
notifyObserverUpdate();
|
||||||
|
|
||||||
|
return command.needsRetriggerOfExecution();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Completes the execution of the given {@link Action} with the given {@link Locator}
|
||||||
|
*
|
||||||
|
* @param actionLoc
|
||||||
|
* the {@link Locator} of the {@link Action}
|
||||||
|
*/
|
||||||
|
public void toExecuted(Locator actionLoc) throws Exception {
|
||||||
|
this.executionHandler.runAsAgent(ctx -> {
|
||||||
|
try (StrolchTransaction tx = openTx(ctx.getCertificate())) {
|
||||||
|
tx.lock(this.locator);
|
||||||
|
|
||||||
|
if (!refreshActivity(tx))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Action action = this.activity.getElementByLocator(actionLoc);
|
||||||
|
|
||||||
|
// set this action to executed
|
||||||
|
SetActionToExecutedCommand command = new SetActionToExecutedCommand(tx);
|
||||||
|
command.setExecutionPolicy(getExecutionPolicy(tx, action));
|
||||||
|
command.setAction(action);
|
||||||
|
command.validate();
|
||||||
|
command.doCommand();
|
||||||
|
|
||||||
|
notifyObserverUpdate();
|
||||||
|
|
||||||
|
// flush so we can see the changes performed
|
||||||
|
tx.flush();
|
||||||
|
|
||||||
|
// now try and execute the next action(s)
|
||||||
|
execute(tx);
|
||||||
|
|
||||||
|
if (tx.needsCommit())
|
||||||
|
tx.commitOnClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.executionHandler.triggerExecution(this.realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the state of the {@link Action} with the given {@link Locator} to {@link State#STOPPED}
|
||||||
|
*
|
||||||
|
* @param actionLoc
|
||||||
|
* the {@link Locator} of the {@link Action}
|
||||||
|
*/
|
||||||
|
public void toStopped(Locator actionLoc) throws Exception {
|
||||||
|
this.executionHandler.runAsAgent(ctx -> {
|
||||||
|
try (StrolchTransaction tx = openTx(ctx.getCertificate())) {
|
||||||
|
tx.lock(this.locator);
|
||||||
|
|
||||||
|
if (!refreshActivity(tx))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Action action = this.activity.getElementByLocator(actionLoc);
|
||||||
|
|
||||||
|
// set this action to executed
|
||||||
|
SetActionToStoppedCommand command = new SetActionToStoppedCommand(tx);
|
||||||
|
command.setExecutionPolicy(getExecutionPolicy(tx, action));
|
||||||
|
command.setAction(action);
|
||||||
|
command.validate();
|
||||||
|
command.doCommand();
|
||||||
|
|
||||||
|
tx.commitOnClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the state of the {@link Action} with the given {@link Locator} to {@link State#ERROR}
|
||||||
|
*
|
||||||
|
* @param actionLoc
|
||||||
|
* the {@link Locator} of the {@link Action}
|
||||||
|
*/
|
||||||
|
public void toError(Locator actionLoc) throws Exception {
|
||||||
|
this.executionHandler.runAsAgent(ctx -> {
|
||||||
|
try (StrolchTransaction tx = openTx(ctx.getCertificate())) {
|
||||||
|
tx.lock(this.locator);
|
||||||
|
|
||||||
|
if (!refreshActivity(tx))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Action action = this.activity.getElementByLocator(actionLoc);
|
||||||
|
|
||||||
|
// set this action to executed
|
||||||
|
SetActionToErrorCommand command = new SetActionToErrorCommand(tx);
|
||||||
|
command.setExecutionPolicy(getExecutionPolicy(tx, action));
|
||||||
|
command.setAction(action);
|
||||||
|
command.validate();
|
||||||
|
command.doCommand();
|
||||||
|
|
||||||
|
tx.commitOnClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the state of the {@link Action} with the given {@link Locator} to {@link State#WARNING}
|
||||||
|
*
|
||||||
|
* @param actionLoc
|
||||||
|
* the {@link Locator} of the {@link Action}
|
||||||
|
*/
|
||||||
|
public void toWarning(Locator actionLoc) throws Exception {
|
||||||
|
this.executionHandler.runAsAgent(ctx -> {
|
||||||
|
try (StrolchTransaction tx = openTx(ctx.getCertificate())) {
|
||||||
|
tx.lock(this.locator);
|
||||||
|
|
||||||
|
if (!refreshActivity(tx))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Action action = this.activity.getElementByLocator(actionLoc);
|
||||||
|
|
||||||
|
// set this action to executed
|
||||||
|
SetActionToWarningCommand command = new SetActionToWarningCommand(tx);
|
||||||
|
command.setExecutionPolicy(getExecutionPolicy(tx, action));
|
||||||
|
command.setAction(action);
|
||||||
|
command.validate();
|
||||||
|
command.doCommand();
|
||||||
|
|
||||||
|
tx.commitOnClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the state of the {@link Action} with the given {@link Locator} to {@link State#ERROR}
|
||||||
|
*
|
||||||
|
* @param actionLoc
|
||||||
|
* the {@link Locator} of the {@link Action}
|
||||||
|
*/
|
||||||
|
public void asyncToError(Locator actionLoc) {
|
||||||
|
this.executionHandler.getExecutor().submit(() -> {
|
||||||
|
try {
|
||||||
|
toError(actionLoc);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Failed to set " + locator + " to error due to " + e.getMessage(), e);
|
||||||
|
|
||||||
|
if (this.container.hasComponent(OperationsLog.class)) {
|
||||||
|
this.container.getComponent(OperationsLog.class).addMessage(
|
||||||
|
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
|
||||||
|
ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.error")
|
||||||
|
.withException(e).value("reason", e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the state of the {@link Action} with the given {@link Locator} to {@link State#WARNING}
|
||||||
|
*
|
||||||
|
* @param actionLoc
|
||||||
|
* the {@link Locator} of the {@link Action}
|
||||||
|
*/
|
||||||
|
public void asyncToWarning(Locator actionLoc) {
|
||||||
|
this.executionHandler.getExecutor().submit(() -> {
|
||||||
|
try {
|
||||||
|
toWarning(actionLoc);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Failed to set " + locator + " to warning due to " + e.getMessage(), e);
|
||||||
|
|
||||||
|
if (this.container.hasComponent(OperationsLog.class)) {
|
||||||
|
this.container.getComponent(OperationsLog.class).addMessage(
|
||||||
|
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
|
||||||
|
ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.warning")
|
||||||
|
.withException(e).value("reason", e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyObserverUpdate() {
|
||||||
|
StrolchRealm realm = this.executionHandler.getContainer().getRealm(this.realm);
|
||||||
|
if (!realm.isUpdateObservers())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ObserverEvent observerEvent = new ObserverEvent();
|
||||||
|
observerEvent.updated.addElement(Tags.CONTROLLER, this.activity);
|
||||||
|
realm.getObserverHandler().notify(observerEvent);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,16 @@
|
||||||
package li.strolch.execution;
|
package li.strolch.execution;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptySet;
|
||||||
import static li.strolch.model.StrolchModelConstants.*;
|
import static li.strolch.model.StrolchModelConstants.*;
|
||||||
import static li.strolch.runtime.StrolchConstants.SYSTEM_USER_AGENT;
|
import static li.strolch.runtime.StrolchConstants.SYSTEM_USER_AGENT;
|
||||||
|
import static li.strolch.utils.collections.SynchronizedCollections.synchronizedMapOfMaps;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
|
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
import li.strolch.agent.api.ComponentContainer;
|
||||||
import li.strolch.agent.api.ObserverEvent;
|
import li.strolch.agent.api.ObserverEvent;
|
||||||
import li.strolch.execution.command.*;
|
import li.strolch.agent.api.StrolchRealm;
|
||||||
import li.strolch.execution.policy.ActivityArchivalPolicy;
|
import li.strolch.execution.command.ArchiveActivityCommand;
|
||||||
import li.strolch.execution.policy.ExecutionPolicy;
|
import li.strolch.execution.policy.ExecutionPolicy;
|
||||||
import li.strolch.handler.operationslog.LogMessage;
|
import li.strolch.handler.operationslog.LogMessage;
|
||||||
import li.strolch.handler.operationslog.LogSeverity;
|
import li.strolch.handler.operationslog.LogSeverity;
|
||||||
|
@ -17,16 +18,12 @@ import li.strolch.handler.operationslog.OperationsLog;
|
||||||
import li.strolch.model.*;
|
import li.strolch.model.*;
|
||||||
import li.strolch.model.activity.Action;
|
import li.strolch.model.activity.Action;
|
||||||
import li.strolch.model.activity.Activity;
|
import li.strolch.model.activity.Activity;
|
||||||
import li.strolch.model.activity.IActivityElement;
|
|
||||||
import li.strolch.model.parameter.StringParameter;
|
import li.strolch.model.parameter.StringParameter;
|
||||||
import li.strolch.model.policy.PolicyDef;
|
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
import li.strolch.policy.PolicyHandler;
|
|
||||||
import li.strolch.privilege.model.Certificate;
|
import li.strolch.privilege.model.Certificate;
|
||||||
import li.strolch.privilege.model.PrivilegeContext;
|
import li.strolch.privilege.model.PrivilegeContext;
|
||||||
import li.strolch.runtime.configuration.ComponentConfiguration;
|
import li.strolch.runtime.configuration.ComponentConfiguration;
|
||||||
import li.strolch.utils.collections.MapOfSets;
|
import li.strolch.utils.collections.MapOfMaps;
|
||||||
import li.strolch.utils.dbc.DBC;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The event based execution handler waits for events in that the {@link ExecutionPolicy} implementations must call the
|
* The event based execution handler waits for events in that the {@link ExecutionPolicy} implementations must call the
|
||||||
|
@ -36,11 +33,10 @@ import li.strolch.utils.dbc.DBC;
|
||||||
*/
|
*/
|
||||||
public class EventBasedExecutionHandler extends ExecutionHandler {
|
public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
|
|
||||||
private static final String KEY_DEFAULT_ACTIVITY_ARCHIVAL = "key:DefaultActivityArchival";
|
|
||||||
private static final String PROP_RESTART_EXECUTION = "restartExecution";
|
private static final String PROP_RESTART_EXECUTION = "restartExecution";
|
||||||
|
|
||||||
private Map<String, ExecutionHandlerState> statesByRealm;
|
private Map<String, ExecutionHandlerState> statesByRealm;
|
||||||
private MapOfSets<String, Locator> registeredActivities;
|
private MapOfMaps<String, Locator, Controller> controllers;
|
||||||
|
|
||||||
private DelayedExecutionTimer delayedExecutionTimer;
|
private DelayedExecutionTimer delayedExecutionTimer;
|
||||||
|
|
||||||
|
@ -48,11 +44,29 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
super(container, componentName);
|
super(container, componentName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller getController(String realm, Activity activity) {
|
||||||
|
return this.controllers.getElement(realm, activity.getLocator());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller getController(String realm, Locator locator) {
|
||||||
|
return this.controllers.getElement(realm, locator.trim(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@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
|
@Override
|
||||||
public void initialize(ComponentConfiguration configuration) throws Exception {
|
public void initialize(ComponentConfiguration configuration) throws Exception {
|
||||||
|
this.controllers = synchronizedMapOfMaps(new MapOfMaps<>());
|
||||||
this.registeredActivities = new MapOfSets<>();
|
|
||||||
|
|
||||||
super.initialize(configuration);
|
super.initialize(configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,66 +100,46 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Locator> getActiveActivitiesLocator(String realm) {
|
public void toExecution(String realm, Activity activity) {
|
||||||
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);
|
ExecutionHandlerState state = this.statesByRealm.getOrDefault(realm, ExecutionHandlerState.Running);
|
||||||
if (state == ExecutionHandlerState.HaltNew)
|
if (state == ExecutionHandlerState.HaltNew)
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"ExecutionHandler state is " + state + ", can not add activities for execution!");
|
"ExecutionHandler state is " + state + ", can not add activities for execution!");
|
||||||
|
|
||||||
Locator rootElemLoc = activity.getLocator();
|
Controller controller = this.controllers.getElement(realm, activity.getLocator());
|
||||||
synchronized (this.registeredActivities) {
|
if (controller == null) {
|
||||||
this.registeredActivities.addElement(realm, rootElemLoc);
|
controller = new Controller(realm, this, activity);
|
||||||
|
this.controllers.addElement(realm, activity.getLocator(), controller);
|
||||||
|
notifyObserverAdd(controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyObserverAdd(realm, activity);
|
toExecution(controller);
|
||||||
toExecution(realm, rootElemLoc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addForExecution(String realm, Locator activityLoc) {
|
public void removeFromExecution(Controller controller) {
|
||||||
|
logger.info("Removing controller " + controller.getLocator() + " from execution...");
|
||||||
ExecutionHandlerState state = this.statesByRealm.getOrDefault(realm, ExecutionHandlerState.Running);
|
if (this.controllers.removeElement(controller.getRealm(), controller.getLocator()) != null) {
|
||||||
if (state == ExecutionHandlerState.HaltNew)
|
logger.info("Removed controller " + controller.getLocator() + " from execution.");
|
||||||
throw new IllegalStateException(
|
getExecutor().submit(() -> notifyObserverRemove(controller));
|
||||||
"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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeFromExecution(String realm, Locator activityLoc) {
|
public void removeFromExecution(String realm, Locator activityLoc) {
|
||||||
Locator rootElemLoc = activityLoc.trim(3);
|
Locator rootElemLoc = activityLoc.trim(3);
|
||||||
synchronized (this.registeredActivities) {
|
Controller controller = this.controllers.removeElement(realm, rootElemLoc);
|
||||||
this.registeredActivities.removeElement(realm, rootElemLoc);
|
if (controller != null)
|
||||||
}
|
getExecutor().submit(() -> notifyObserverRemove(controller));
|
||||||
getExecutor().submit(() -> notifyObserverRemove(realm, activityLoc));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearAllCurrentExecutions(String realm) {
|
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));
|
getExecutor().submit(() -> notifyObserverRemove(realm, removed));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void restartActivityExecution(PrivilegeContext ctx) {
|
private void restartActivityExecution(PrivilegeContext ctx) {
|
||||||
|
|
||||||
// iterate the realms
|
// iterate the realms
|
||||||
for (String realmName : getContainer().getRealmNames()) {
|
for (String realmName : getContainer().getRealmNames()) {
|
||||||
reloadActivitiesInExecution(ctx, realmName);
|
reloadActivitiesInExecution(ctx, realmName);
|
||||||
|
@ -180,7 +174,8 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
tx.update(activity);
|
tx.update(activity);
|
||||||
|
|
||||||
// register for execution
|
// register for execution
|
||||||
this.registeredActivities.addElement(realmName, activity.getLocator());
|
Controller controller = new Controller(realmName, this, activity);
|
||||||
|
this.controllers.addElement(realmName, activity.getLocator(), controller);
|
||||||
});
|
});
|
||||||
|
|
||||||
// commit changes to state
|
// commit changes to state
|
||||||
|
@ -200,12 +195,12 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized (this.registeredActivities) {
|
synchronized (this.controllers) {
|
||||||
Set<Locator> locators = this.registeredActivities.getSet(realm);
|
Map<Locator, Controller> controllers = this.controllers.getMap(realm);
|
||||||
if (locators != null) {
|
if (controllers != null) {
|
||||||
for (Locator locator : locators) {
|
for (Controller controller : controllers.values()) {
|
||||||
// execute async
|
// execute async
|
||||||
toExecution(realm, locator);
|
toExecution(controller);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,24 +277,26 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void toExecution(Controller controller) {
|
||||||
public void toExecution(String realm, Locator locator) {
|
|
||||||
|
|
||||||
|
String realm = controller.getRealm();
|
||||||
ExecutionHandlerState state = this.statesByRealm.getOrDefault(realm, ExecutionHandlerState.Running);
|
ExecutionHandlerState state = this.statesByRealm.getOrDefault(realm, ExecutionHandlerState.Running);
|
||||||
if (state == ExecutionHandlerState.Paused) {
|
if (state == ExecutionHandlerState.Paused) {
|
||||||
logger.warn("Ignoring execution of " + locator + " for paused realm " + realm);
|
logger.warn("Ignoring execution of " + controller.getLocator() + " for paused realm " + realm);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.info("Adding async " + controller.getLocator() + " for execution!");
|
||||||
|
|
||||||
getExecutor().execute(() -> {
|
getExecutor().execute(() -> {
|
||||||
try {
|
try {
|
||||||
runAsAgent(ctx -> toExecution(realm, locator, ctx));
|
controller.execute();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Failed to set " + locator + " to execution due to " + e.getMessage(), e);
|
logger.error("Failed to set " + controller.getLocator() + " to execution", e);
|
||||||
|
|
||||||
if (getContainer().hasComponent(OperationsLog.class)) {
|
if (getContainer().hasComponent(OperationsLog.class)) {
|
||||||
getComponent(OperationsLog.class).addMessage(
|
getComponent(OperationsLog.class).addMessage(
|
||||||
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
|
new LogMessage(realm, SYSTEM_USER_AGENT, controller.getLocator(), LogSeverity.Exception,
|
||||||
ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.execution")
|
ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.execution")
|
||||||
.withException(e).value("reason", e));
|
.withException(e).value("reason", e));
|
||||||
}
|
}
|
||||||
|
@ -307,17 +304,15 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExecutorService getExecutor() {
|
|
||||||
return getExecutorService("ExecutionHandler");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toExecuted(String realm, Locator locator) {
|
public void toExecuted(String realm, Locator locator) {
|
||||||
getExecutor().execute(() -> {
|
getExecutor().execute(() -> {
|
||||||
try {
|
try {
|
||||||
runAsAgent(ctx -> {
|
|
||||||
toExecuted(realm, locator, ctx);
|
Controller controller = this.controllers.getElement(realm, locator.trim(3));
|
||||||
});
|
if (controller != null)
|
||||||
|
controller.toExecuted(locator);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Failed to set " + locator + " to executed due to " + e.getMessage(), e);
|
logger.error("Failed to set " + locator + " to executed due to " + e.getMessage(), e);
|
||||||
|
|
||||||
|
@ -335,9 +330,11 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
public void toStopped(String realm, Locator locator) {
|
public void toStopped(String realm, Locator locator) {
|
||||||
getExecutor().execute(() -> {
|
getExecutor().execute(() -> {
|
||||||
try {
|
try {
|
||||||
runAsAgent(ctx -> {
|
|
||||||
toStopped(realm, locator, ctx);
|
Controller controller = this.controllers.getElement(realm, locator.trim(3));
|
||||||
});
|
if (controller != null)
|
||||||
|
controller.toStopped(locator);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Failed to set " + locator + " to stopped due to " + e.getMessage(), e);
|
logger.error("Failed to set " + locator + " to stopped due to " + e.getMessage(), e);
|
||||||
|
|
||||||
|
@ -355,9 +352,11 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
public void toError(String realm, Locator locator) {
|
public void toError(String realm, Locator locator) {
|
||||||
getExecutor().execute(() -> {
|
getExecutor().execute(() -> {
|
||||||
try {
|
try {
|
||||||
runAsAgent(ctx -> {
|
|
||||||
toError(realm, locator, ctx);
|
Controller controller = this.controllers.getElement(realm, locator.trim(3));
|
||||||
});
|
if (controller != null)
|
||||||
|
controller.toError(locator);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Failed to set " + locator + " to error due to " + e.getMessage(), e);
|
logger.error("Failed to set " + locator + " to error due to " + e.getMessage(), e);
|
||||||
|
|
||||||
|
@ -375,9 +374,11 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
public void toWarning(String realm, Locator locator) {
|
public void toWarning(String realm, Locator locator) {
|
||||||
getExecutor().execute(() -> {
|
getExecutor().execute(() -> {
|
||||||
try {
|
try {
|
||||||
runAsAgent(ctx -> {
|
|
||||||
toWarning(realm, locator, ctx);
|
Controller controller = this.controllers.getElement(realm, locator.trim(3));
|
||||||
});
|
if (controller != null)
|
||||||
|
controller.toWarning(locator);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Failed to set " + locator + " to warning due to " + e.getMessage(), e);
|
logger.error("Failed to set " + locator + " to warning due to " + e.getMessage(), e);
|
||||||
|
|
||||||
|
@ -392,42 +393,24 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void archiveActivity(String realm, Locator activityLoc) {
|
public void archiveActivity(String realm, Activity activity) {
|
||||||
getExecutor().execute(() -> {
|
getExecutor().execute(() -> {
|
||||||
try {
|
try {
|
||||||
runAsAgent(ctx -> {
|
runAsAgent(ctx -> {
|
||||||
try (StrolchTransaction tx = openTx(realm, ctx.getCertificate(), ActivityArchivalPolicy.class,
|
try (StrolchTransaction tx = openTx(realm, ctx.getCertificate(), ArchiveActivityCommand.class,
|
||||||
false)) {
|
false)) {
|
||||||
tx.lock(activityLoc);
|
ArchiveActivityCommand command = new ArchiveActivityCommand(tx);
|
||||||
|
command.setActivityLoc(activity.getLocator());
|
||||||
Activity activity = tx.findElement(activityLoc, true);
|
tx.addCommand(command);
|
||||||
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);
|
|
||||||
|
|
||||||
tx.commitOnClose();
|
tx.commitOnClose();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} 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)) {
|
if (getContainer().hasComponent(OperationsLog.class)) {
|
||||||
getComponent(OperationsLog.class).addMessage(
|
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")
|
ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.archive")
|
||||||
.withException(e).value("reason", e));
|
.withException(e).value("reason", e));
|
||||||
}
|
}
|
||||||
|
@ -435,255 +418,36 @@ public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toExecution(String realm, Locator elementLoc, PrivilegeContext ctx) {
|
private void notifyObserverAdd(Controller controller) {
|
||||||
try (StrolchTransaction tx = openTx(realm, ctx.getCertificate(), ExecuteActivityCommand.class, false)) {
|
StrolchRealm realm = getContainer().getRealm(controller.getRealm());
|
||||||
|
if (!realm.isUpdateObservers())
|
||||||
Locator activityLoc = elementLoc.trim(3);
|
|
||||||
tx.lock(activityLoc);
|
|
||||||
|
|
||||||
Activity activity = tx.findElement(activityLoc, true);
|
|
||||||
if (activity == null) {
|
|
||||||
logger.error("Element for locator " + elementLoc + " does not exist!");
|
|
||||||
synchronized (this.registeredActivities) {
|
|
||||||
this.registeredActivities.removeElement(realm, activityLoc);
|
|
||||||
}
|
|
||||||
notifyObserverRemove(realm, activityLoc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activity.getState().isExecuted()) {
|
|
||||||
|
|
||||||
synchronized (this.registeredActivities) {
|
|
||||||
if (!this.registeredActivities.removeElement(realm, activityLoc))
|
|
||||||
logger.warn("Activity " + activityLoc + " already removed from registered activities!");
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyObserverRemove(tx, activity);
|
|
||||||
|
|
||||||
logger.info("Archiving activity " + activityLoc + " with state " + activity.getState());
|
|
||||||
archiveActivity(realm, activity.getLocator());
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
ExecuteActivityCommand command = new ExecuteActivityCommand(getContainer(), tx);
|
|
||||||
command.setActivity(activity);
|
|
||||||
command.validate();
|
|
||||||
command.doCommand();
|
|
||||||
|
|
||||||
notifyObserverUpdate(tx, activity);
|
|
||||||
tx.commitOnClose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void toExecuted(String realm, Locator actionLoc, PrivilegeContext ctx) {
|
|
||||||
|
|
||||||
Locator activityLoc = actionLoc.trim(3);
|
|
||||||
|
|
||||||
try (StrolchTransaction tx = openTx(realm, ctx.getCertificate(), SetActionToExecutedCommand.class, false)) {
|
|
||||||
|
|
||||||
tx.lock(activityLoc);
|
|
||||||
|
|
||||||
Action action = tx.findElement(actionLoc);
|
|
||||||
|
|
||||||
// set this action to executed
|
|
||||||
SetActionToExecutedCommand command = new SetActionToExecutedCommand(getContainer(), tx);
|
|
||||||
command.setAction(action);
|
|
||||||
command.validate();
|
|
||||||
command.doCommand();
|
|
||||||
|
|
||||||
notifyObserverUpdate(tx, action.getRootElement());
|
|
||||||
|
|
||||||
// flush so we can see the changes performed
|
|
||||||
tx.flush();
|
|
||||||
|
|
||||||
// if the activity is now executed, remove it from the registered activities
|
|
||||||
Activity activity = action.getRootElement().getClone(true);
|
|
||||||
if (activity.getState().isExecuted()) {
|
|
||||||
|
|
||||||
synchronized (this.registeredActivities) {
|
|
||||||
if (!this.registeredActivities.removeElement(realm, activityLoc))
|
|
||||||
logger.warn("Activity " + activityLoc + " already removed from registered activities!");
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyObserverRemove(tx, action.getRootElement());
|
|
||||||
|
|
||||||
logger.info("Archiving activity " + activityLoc + " with state " + activity.getState());
|
|
||||||
archiveActivity(realm, activity.getLocator());
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
ExecutionHandlerState state = this.statesByRealm.getOrDefault(realm, ExecutionHandlerState.Running);
|
|
||||||
if (state == ExecutionHandlerState.Paused) {
|
|
||||||
logger.warn("Ignoring trigger for paused realm " + realm);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// otherwise execute any next action(s) for this action's activity
|
|
||||||
|
|
||||||
ExecuteActivityCommand execCommand = new ExecuteActivityCommand(getContainer(), tx);
|
|
||||||
execCommand.setActivity(activity);
|
|
||||||
execCommand.validate();
|
|
||||||
execCommand.doCommand();
|
|
||||||
|
|
||||||
notifyObserverUpdate(tx, action.getRootElement());
|
|
||||||
|
|
||||||
// flush so we can see the changes performed
|
|
||||||
tx.flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tx.commitOnClose();
|
|
||||||
}
|
|
||||||
|
|
||||||
// now trigger a further execution of any other activities needed execution in this realm
|
|
||||||
triggerExecution(realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void toWarning(String realm, Locator actionLoc, PrivilegeContext ctx) {
|
|
||||||
try (StrolchTransaction tx = openTx(realm, ctx.getCertificate(), SetActionToExecutedCommand.class, false)) {
|
|
||||||
Locator rootElemLoc = actionLoc.trim(3);
|
|
||||||
tx.lock(rootElemLoc);
|
|
||||||
|
|
||||||
IActivityElement elem = tx.findElement(actionLoc);
|
|
||||||
DBC.INTERIM.assertEquals("toWarning only for Action!", Action.class, elem.getClass());
|
|
||||||
|
|
||||||
SetActionToWarningCommand command = new SetActionToWarningCommand(getContainer(), tx);
|
|
||||||
command.setAction((Action) elem);
|
|
||||||
command.validate();
|
|
||||||
command.doCommand();
|
|
||||||
|
|
||||||
notifyObserverUpdate(tx, elem.getRootElement());
|
|
||||||
tx.commitOnClose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void toError(String realm, Locator actionLoc, PrivilegeContext ctx) {
|
|
||||||
try (StrolchTransaction tx = openTx(realm, ctx.getCertificate(), SetActionToExecutedCommand.class, false)) {
|
|
||||||
Locator rootElemLoc = actionLoc.trim(3);
|
|
||||||
tx.lock(rootElemLoc);
|
|
||||||
|
|
||||||
IActivityElement elem = tx.findElement(actionLoc);
|
|
||||||
DBC.INTERIM.assertEquals("toError only for Action!", Action.class, elem.getClass());
|
|
||||||
|
|
||||||
SetActionToErrorCommand command = new SetActionToErrorCommand(getContainer(), tx);
|
|
||||||
command.setAction((Action) elem);
|
|
||||||
command.validate();
|
|
||||||
command.doCommand();
|
|
||||||
|
|
||||||
notifyObserverUpdate(tx, elem.getRootElement());
|
|
||||||
tx.commitOnClose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void toStopped(String realm, Locator actionLoc, PrivilegeContext ctx) {
|
|
||||||
try (StrolchTransaction tx = openTx(realm, ctx.getCertificate(), SetActionToStoppedCommand.class, false)) {
|
|
||||||
Locator rootElemLoc = actionLoc.trim(3);
|
|
||||||
tx.lock(rootElemLoc);
|
|
||||||
|
|
||||||
IActivityElement elem = tx.findElement(actionLoc);
|
|
||||||
DBC.INTERIM.assertEquals("toStopped only for Action!", Action.class, elem.getClass());
|
|
||||||
|
|
||||||
SetActionToStoppedCommand command = new SetActionToStoppedCommand(getContainer(), tx);
|
|
||||||
command.setAction((Action) elem);
|
|
||||||
command.validate();
|
|
||||||
command.doCommand();
|
|
||||||
|
|
||||||
notifyObserverUpdate(tx, elem.getRootElement());
|
|
||||||
tx.commitOnClose();
|
|
||||||
}
|
|
||||||
|
|
||||||
// now trigger a further execution of any other activities needed execution in this realm
|
|
||||||
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) {
|
|
||||||
if (!getContainer().getRealm(realm).isUpdateObservers())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ObserverEvent observerEvent = new ObserverEvent();
|
ObserverEvent observerEvent = new ObserverEvent();
|
||||||
observerEvent.added.addElement(Tags.CONTROLLER, rootElement);
|
observerEvent.added.addElement(Tags.CONTROLLER, controller.getActivity());
|
||||||
getContainer().getRealm(realm).getObserverHandler().notify(observerEvent);
|
realm.getObserverHandler().notify(observerEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyObserverUpdate(StrolchTransaction tx, Activity rootElement) {
|
private void notifyObserverRemove(Controller controller) {
|
||||||
if (!getContainer().getRealm(tx.getRealmName()).isUpdateObservers())
|
StrolchRealm realm = getContainer().getRealm(controller.getRealm());
|
||||||
|
if (!realm.isUpdateObservers())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ObserverEvent observerEvent = new ObserverEvent();
|
ObserverEvent observerEvent = new ObserverEvent();
|
||||||
observerEvent.updated.addElement(Tags.CONTROLLER, rootElement);
|
observerEvent.removed.addElement(Tags.CONTROLLER, controller.getActivity());
|
||||||
tx.getContainer().getRealm(tx.getRealmName()).getObserverHandler().notify(observerEvent);
|
realm.getObserverHandler().notify(observerEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyObserverRemove(StrolchTransaction tx, Activity rootElement) {
|
private void notifyObserverRemove(String realmName, Map<Locator, Controller> removed) {
|
||||||
if (!getContainer().getRealm(tx.getRealmName()).isUpdateObservers())
|
StrolchRealm realm = getContainer().getRealm(realmName);
|
||||||
|
if (!realm.isUpdateObservers())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ObserverEvent observerEvent = new ObserverEvent();
|
ObserverEvent observerEvent = new ObserverEvent();
|
||||||
observerEvent.removed.addElement(Tags.CONTROLLER, rootElement);
|
for (Controller controller : removed.values()) {
|
||||||
tx.getContainer().getRealm(tx.getRealmName()).getObserverHandler().notify(observerEvent);
|
observerEvent.removed.addElement(Tags.CONTROLLER, controller.getActivity());
|
||||||
}
|
|
||||||
|
|
||||||
private void notifyObserverRemove(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.removed.addElement(Tags.CONTROLLER, activity);
|
|
||||||
getContainer().getRealm(realm).getObserverHandler().notify(observerEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("Failed to notify observers of removed controller " + activityLoc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void notifyObserverRemove(String realm, Set<Locator> activityLocs) {
|
|
||||||
if (!getContainer().getRealm(realm).isUpdateObservers())
|
|
||||||
return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
runAsAgent(ctx -> {
|
|
||||||
try (StrolchTransaction tx = openTx(realm, ctx.getCertificate(), true)) {
|
|
||||||
ObserverEvent observerEvent = new ObserverEvent();
|
|
||||||
|
|
||||||
for (Locator activityLoc : activityLocs) {
|
|
||||||
Activity activity = tx.findElement(activityLoc, true);
|
|
||||||
if (activity != null)
|
|
||||||
observerEvent.removed.addElement(Tags.CONTROLLER, activity);
|
|
||||||
}
|
|
||||||
|
|
||||||
getContainer().getRealm(realm).getObserverHandler().notify(observerEvent);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("Failed to notify observers of removed controllers " + activityLocs);
|
|
||||||
}
|
}
|
||||||
|
realm.getObserverHandler().notify(observerEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package li.strolch.execution;
|
package li.strolch.execution;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
import li.strolch.agent.api.ComponentContainer;
|
||||||
import li.strolch.agent.api.StrolchComponent;
|
import li.strolch.agent.api.StrolchComponent;
|
||||||
|
@ -11,8 +12,11 @@ import li.strolch.model.State;
|
||||||
import li.strolch.model.activity.Action;
|
import li.strolch.model.activity.Action;
|
||||||
import li.strolch.model.activity.Activity;
|
import li.strolch.model.activity.Activity;
|
||||||
import li.strolch.model.activity.TimeOrdering;
|
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.Certificate;
|
||||||
import li.strolch.privilege.model.PrivilegeContext;
|
import li.strolch.privilege.model.PrivilegeContext;
|
||||||
|
import li.strolch.runtime.privilege.PrivilegedRunnable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -21,7 +25,7 @@ import li.strolch.privilege.model.PrivilegeContext;
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* To start the execution of an {@link Activity} add it to the {@link ExecutionHandler} by calling {@link
|
* To start the execution of an {@link Activity} add it to the {@link ExecutionHandler} by calling {@link
|
||||||
* #addForExecution(String, Activity)} or {@link #addForExecution(String, Locator)}. Actual execution is asynchronously
|
* #toExecution(String, Activity)} or {@link #toExecution(String, Activity)}. Actual execution is asynchronously
|
||||||
* performed and the {@link ExecutionPolicy} of the resources of the {@link Action Actions} will perform the actual
|
* performed and the {@link ExecutionPolicy} of the resources of the {@link Action Actions} will perform the actual
|
||||||
* execution.
|
* execution.
|
||||||
* </p>
|
* </p>
|
||||||
|
@ -41,16 +45,41 @@ public abstract class ExecutionHandler extends StrolchComponent {
|
||||||
|
|
||||||
public static final String PARAM_STATE = "state";
|
public static final String PARAM_STATE = "state";
|
||||||
|
|
||||||
|
public StrolchTransaction openTx(String realm, Certificate cert, Class<?> action, boolean readOnly) {
|
||||||
|
return super.openTx(realm, cert, action.getName(), readOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void runAsAgent(PrivilegedRunnable runnable) throws PrivilegeException, Exception {
|
||||||
|
super.runAsAgent(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecutorService getExecutor() {
|
||||||
|
return getExecutorService("ExecutionHandler");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers the given {@link Locator} of an {@link Activity} for execution, and submits it for execution
|
* Returns the controller for the given realm and activity, null if it does not exist
|
||||||
* immediately in an asynchronous manner
|
|
||||||
*
|
*
|
||||||
* @param realm
|
* @param realm
|
||||||
* the realm where the {@link Activity} resides
|
* the realm for which to get the controller
|
||||||
* @param activityLoc
|
* @param activity
|
||||||
* the {@link Locator} of the {@link Activity}
|
* the activity for which to get the controller
|
||||||
|
*
|
||||||
|
* @return the controller, or null if it does not exist
|
||||||
*/
|
*/
|
||||||
public abstract void addForExecution(String realm, Locator activityLoc);
|
public abstract Controller getController(String realm, Activity activity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the controller for the given realm and activity, null if it does not exist
|
||||||
|
*
|
||||||
|
* @param realm
|
||||||
|
* the realm for which to get the controller
|
||||||
|
* @param locator
|
||||||
|
* the locator of the activity for which to get the controller
|
||||||
|
*
|
||||||
|
* @return the controller, or null if it does not exist
|
||||||
|
*/
|
||||||
|
public abstract Controller getController(String realm, Locator locator);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers the given {@link Activity} for execution, and submits it for execution immediately in an asynchronous
|
* Registers the given {@link Activity} for execution, and submits it for execution immediately in an asynchronous
|
||||||
|
@ -61,7 +90,15 @@ public abstract class ExecutionHandler extends StrolchComponent {
|
||||||
* @param activity
|
* @param activity
|
||||||
* the the {@link Activity}
|
* the the {@link Activity}
|
||||||
*/
|
*/
|
||||||
public abstract void addForExecution(String realm, Activity activity);
|
public abstract void toExecution(String realm, Activity activity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the given {@link Controller} from execution, so it is not executed further
|
||||||
|
*
|
||||||
|
* @param controller
|
||||||
|
* the controller to remove
|
||||||
|
*/
|
||||||
|
public abstract void removeFromExecution(Controller controller);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the given {@link Locator} for an {@link Activity} from execution, so it is not executed further
|
* Removes the given {@link Locator} for an {@link Activity} from execution, so it is not executed further
|
||||||
|
@ -92,7 +129,7 @@ public abstract class ExecutionHandler extends StrolchComponent {
|
||||||
public abstract void clearAllCurrentExecutions(String realm);
|
public abstract void clearAllCurrentExecutions(String realm);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers a to execution for all registered activities in the given realm
|
* Triggers execution for all registered activities in the given realm
|
||||||
*
|
*
|
||||||
* @param realm
|
* @param realm
|
||||||
* the realm to trigger execution for
|
* the realm to trigger execution for
|
||||||
|
@ -126,10 +163,10 @@ public abstract class ExecutionHandler extends StrolchComponent {
|
||||||
*
|
*
|
||||||
* @param realm
|
* @param realm
|
||||||
* the realm where the activity resides
|
* the realm where the activity resides
|
||||||
* @param activityLoc
|
* @param activity
|
||||||
* the {@link Locator} of the {@link 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
|
* Returns the {@link Set} of {@link Locator Locators} of {@link Activity Activities} which are registered for
|
||||||
|
@ -148,24 +185,14 @@ public abstract class ExecutionHandler extends StrolchComponent {
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* The {@link DelayedExecutionTimer} allows to delay the {@link #toExecuted(String, Locator)} call by a given time.
|
* The {@link DelayedExecutionTimer} allows to delay the {@link Controller#toExecuted(Locator)} call by a given
|
||||||
* See the {@link DurationExecution} policy
|
* time. See the {@link DurationExecution} policy
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @return the {@link DelayedExecutionTimer}
|
* @return the {@link DelayedExecutionTimer}
|
||||||
*/
|
*/
|
||||||
public abstract DelayedExecutionTimer getDelayedExecutionTimer();
|
public abstract DelayedExecutionTimer getDelayedExecutionTimer();
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the execution of the given {@link Activity} with the given {@link Locator}
|
|
||||||
*
|
|
||||||
* @param realm
|
|
||||||
* the realm where the {@link Activity} resides
|
|
||||||
* @param activityLoc
|
|
||||||
* the {@link Locator} of the {@link Activity}
|
|
||||||
*/
|
|
||||||
public abstract void toExecution(String realm, Locator activityLoc);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Completes the execution of the given {@link Action} with the given {@link Locator}
|
* Completes the execution of the given {@link Action} with the given {@link Locator}
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,14 +1,20 @@
|
||||||
package li.strolch.execution;
|
package li.strolch.execution;
|
||||||
|
|
||||||
|
import static li.strolch.runtime.StrolchConstants.SYSTEM_USER_AGENT;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
import li.strolch.agent.api.ComponentContainer;
|
||||||
import li.strolch.agent.api.StrolchAgent;
|
import li.strolch.agent.api.StrolchAgent;
|
||||||
|
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.Locator;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -65,7 +71,22 @@ public class SimpleDurationExecutionTimer implements DelayedExecutionTimer {
|
||||||
|
|
||||||
this.simulationTasks.remove(locator);
|
this.simulationTasks.remove(locator);
|
||||||
ExecutionHandler executionHandler = container.getComponent(ExecutionHandler.class);
|
ExecutionHandler executionHandler = container.getComponent(ExecutionHandler.class);
|
||||||
executionHandler.toExecuted(realm, locator);
|
Controller controller = executionHandler.getController(realm, locator);
|
||||||
|
if (controller != null) {
|
||||||
|
try {
|
||||||
|
if (!controller.isStopped(locator))
|
||||||
|
controller.toExecuted(locator);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Failed to set " + locator + " to executed due to " + e.getMessage(), e);
|
||||||
|
|
||||||
|
if (this.agent.getContainer().hasComponent(OperationsLog.class)) {
|
||||||
|
this.agent.getContainer().getComponent(OperationsLog.class).addMessage(
|
||||||
|
new LogMessage(realm, SYSTEM_USER_AGENT, locator, LogSeverity.Exception,
|
||||||
|
ResourceBundle.getBundle("strolch-service"), "execution.handler.failed.executed")
|
||||||
|
.withException(e).value("reason", e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SimulationTask implements Runnable {
|
private class SimulationTask implements Runnable {
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package li.strolch.execution.command;
|
||||||
|
|
||||||
|
import li.strolch.execution.policy.ExecutionPolicy;
|
||||||
|
import li.strolch.model.activity.Action;
|
||||||
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
|
import li.strolch.utils.dbc.DBC;
|
||||||
|
|
||||||
|
public abstract class ActionExecutionCommand extends BasePlanningAndExecutionCommand {
|
||||||
|
|
||||||
|
protected Action action;
|
||||||
|
private ExecutionPolicy executionPolicy;
|
||||||
|
|
||||||
|
public ActionExecutionCommand(StrolchTransaction tx) {
|
||||||
|
super(tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAction(Action action) {
|
||||||
|
this.action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExecutionPolicy(ExecutionPolicy executionPolicy) {
|
||||||
|
this.executionPolicy = executionPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ExecutionPolicy getExecutionPolicy(Action action) {
|
||||||
|
if (this.executionPolicy != null)
|
||||||
|
return this.executionPolicy;
|
||||||
|
return tx().getPolicy(action.getPolicyDef(ExecutionPolicy.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validate() {
|
||||||
|
DBC.PRE.assertNotNull("action can not be null", this.action);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package li.strolch.execution.command;
|
||||||
|
|
||||||
|
import static li.strolch.execution.policy.ActivityArchivalPolicy.DEFAULT_ACTIVITY_ARCHIVAL;
|
||||||
|
|
||||||
|
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.service.api.Command;
|
||||||
|
import li.strolch.utils.dbc.DBC;
|
||||||
|
|
||||||
|
public class ArchiveActivityCommand extends Command {
|
||||||
|
|
||||||
|
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() {
|
||||||
|
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 = activity.getPolicyDef(ActivityArchivalPolicy.class, DEFAULT_ACTIVITY_ARCHIVAL);
|
||||||
|
ActivityArchivalPolicy archivalPolicy = tx().getPolicy(policyDef);
|
||||||
|
archivalPolicy.archive(activity);
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,8 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package li.strolch.execution.command;
|
package li.strolch.execution.command;
|
||||||
|
|
||||||
import static li.strolch.execution.command.ExecutionCommand.updateOrderState;
|
import static li.strolch.execution.policy.NoPlanning.DEFAULT_PLANNING;
|
||||||
import static li.strolch.execution.policy.NoPlanning.NO_PLANNING;
|
|
||||||
|
|
||||||
import li.strolch.execution.policy.PlanningPolicy;
|
import li.strolch.execution.policy.PlanningPolicy;
|
||||||
import li.strolch.model.Resource;
|
import li.strolch.model.Resource;
|
||||||
|
@ -69,14 +68,9 @@ public class AssignActionCommand extends PlanningCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doCommand() {
|
public void doCommand() {
|
||||||
validate();
|
|
||||||
|
|
||||||
Activity rootElement = this.action.getRootElement();
|
Activity rootElement = this.action.getRootElement();
|
||||||
tx().lock(rootElement);
|
|
||||||
|
|
||||||
State currentState = rootElement.getState();
|
State currentState = rootElement.getState();
|
||||||
this.action.accept(this);
|
this.action.accept(this);
|
||||||
|
|
||||||
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +79,7 @@ public class AssignActionCommand extends PlanningCommand {
|
||||||
|
|
||||||
// unplan the action
|
// unplan the action
|
||||||
if (action.getState() == State.PLANNED) {
|
if (action.getState() == State.PLANNED) {
|
||||||
PlanningPolicy planningPolicy = tx().getPolicy(action.findPolicy(PlanningPolicy.class, NO_PLANNING));
|
PlanningPolicy planningPolicy = tx().getPolicy(action.findPolicy(PlanningPolicy.class, DEFAULT_PLANNING));
|
||||||
planningPolicy.unplan(action);
|
planningPolicy.unplan(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +88,7 @@ public class AssignActionCommand extends PlanningCommand {
|
||||||
action.setResourceType(this.targetResourceType);
|
action.setResourceType(this.targetResourceType);
|
||||||
|
|
||||||
// finally plan the action to the assigned resource
|
// finally plan the action to the assigned resource
|
||||||
PlanningPolicy planningPolicy = tx().getPolicy(action.findPolicy(PlanningPolicy.class, NO_PLANNING));
|
PlanningPolicy planningPolicy = tx().getPolicy(action.findPolicy(PlanningPolicy.class, DEFAULT_PLANNING));
|
||||||
planningPolicy.plan(action);
|
planningPolicy.plan(action);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
package li.strolch.execution.command;
|
||||||
|
|
||||||
|
import static li.strolch.execution.policy.ConfirmationPolicy.DEFAULT_CONFIRMATION;
|
||||||
|
import static li.strolch.execution.policy.NoPlanning.DEFAULT_PLANNING;
|
||||||
|
import static li.strolch.runtime.StrolchConstants.PolicyConstants.PARAM_ORDER;
|
||||||
|
|
||||||
|
import li.strolch.execution.policy.ConfirmationPolicy;
|
||||||
|
import li.strolch.execution.policy.PlanningPolicy;
|
||||||
|
import li.strolch.model.Locator;
|
||||||
|
import li.strolch.model.Order;
|
||||||
|
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.policy.PolicyDef;
|
||||||
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
|
import li.strolch.policy.PolicyHandler;
|
||||||
|
import li.strolch.service.api.Command;
|
||||||
|
|
||||||
|
public abstract class BasePlanningAndExecutionCommand extends Command {
|
||||||
|
|
||||||
|
public BasePlanningAndExecutionCommand(StrolchTransaction tx) {
|
||||||
|
super(tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Resource getResource(Action action) {
|
||||||
|
Locator resourceLocator = action.getResourceLocator();
|
||||||
|
return tx().getResourceBy(resourceLocator.get(1), resourceLocator.get(2), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void updateOrderState(StrolchTransaction tx, Activity rootElement, State currentState,
|
||||||
|
State newState) {
|
||||||
|
if (currentState == newState)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Order order = tx.getOrderByRelation(rootElement, PARAM_ORDER);
|
||||||
|
if (order == null) {
|
||||||
|
logger.warn("Did not find activity order by relation " + PARAM_ORDER + " for activity " + rootElement
|
||||||
|
.getLocator() + ", trying by Activity type and id");
|
||||||
|
order = tx.getOrderBy(rootElement.getType(), rootElement.getId());
|
||||||
|
if (order == null) {
|
||||||
|
logger.error("Could not find order by Activity type and id either, not updating order state!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
order.setState(rootElement.getState());
|
||||||
|
|
||||||
|
tx.update(order);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ConfirmationPolicy getConfirmationPolicy(Action action) {
|
||||||
|
Resource resource = getResource(action);
|
||||||
|
PolicyDef executionPolicyDef = resource.getPolicyDefs()
|
||||||
|
.getPolicyDef(ConfirmationPolicy.class.getSimpleName(), DEFAULT_CONFIRMATION);
|
||||||
|
return getComponent(PolicyHandler.class).getPolicy(executionPolicyDef, tx());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected PlanningPolicy getPlanningPolicy(Action action) {
|
||||||
|
PolicyDef planningPolicyDef = action.findPolicy(PlanningPolicy.class, DEFAULT_PLANNING);
|
||||||
|
return getComponent(PolicyHandler.class).getPolicy(planningPolicyDef, tx());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,42 +1,186 @@
|
||||||
package li.strolch.execution.command;
|
package li.strolch.execution.command;
|
||||||
|
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
import java.util.Iterator;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import li.strolch.execution.Controller;
|
||||||
|
import li.strolch.execution.policy.ConfirmationPolicy;
|
||||||
|
import li.strolch.execution.policy.ExecutionPolicy;
|
||||||
import li.strolch.model.State;
|
import li.strolch.model.State;
|
||||||
|
import li.strolch.model.activity.Action;
|
||||||
import li.strolch.model.activity.Activity;
|
import li.strolch.model.activity.Activity;
|
||||||
|
import li.strolch.model.activity.IActivityElement;
|
||||||
|
import li.strolch.model.activity.TimeOrderingVisitor;
|
||||||
|
import li.strolch.model.visitor.IActivityElementVisitor;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
import li.strolch.utils.dbc.DBC;
|
import li.strolch.utils.dbc.DBC;
|
||||||
|
|
||||||
public class ExecuteActivityCommand extends ExecutionCommand {
|
public class ExecuteActivityCommand extends BasePlanningAndExecutionCommand
|
||||||
|
implements TimeOrderingVisitor, IActivityElementVisitor<Void> {
|
||||||
|
|
||||||
private Activity activity;
|
private Controller controller;
|
||||||
|
private boolean needsRetriggerOfExecution;
|
||||||
|
|
||||||
public ExecuteActivityCommand(ComponentContainer container, StrolchTransaction tx) {
|
public ExecuteActivityCommand(StrolchTransaction tx) {
|
||||||
super(container, tx);
|
super(tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setActivity(Activity activity) {
|
public void setController(Controller controller) {
|
||||||
this.activity = activity;
|
this.controller = controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExecutionPolicy getExecutionPolicy(Action action) {
|
||||||
|
return this.controller.getExecutionPolicy(tx(), action);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean needsRetriggerOfExecution() {
|
||||||
|
return this.needsRetriggerOfExecution;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validate() {
|
public void validate() {
|
||||||
DBC.PRE.assertNotNull("activity can not be null!", this.activity);
|
DBC.PRE.assertNotNull("controller can not be null!", this.controller);
|
||||||
tx().lock(this.activity.getRootElement());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doCommand() {
|
public void doCommand() {
|
||||||
Activity rootElement = this.activity.getRootElement();
|
Activity activity = this.controller.getActivity();
|
||||||
tx().lock(rootElement);
|
State currentState = activity.getState();
|
||||||
|
activity.accept(this);
|
||||||
State currentState = rootElement.getState();
|
updateOrderState(tx(), activity, currentState, activity.getState());
|
||||||
this.activity.accept(this);
|
|
||||||
|
|
||||||
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void undo() {
|
public Void visitAction(Action action) {
|
||||||
// can't undo execution
|
execute(action);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void execute(Action action) {
|
||||||
|
|
||||||
|
// first plan
|
||||||
|
if (action.getState().compareTo(State.PLANNED) < 0) {
|
||||||
|
getPlanningPolicy(action).plan(action);
|
||||||
|
if (action.getState() != State.PLANNED) {
|
||||||
|
logger.info("Action " + action.getLocator() + " was not planned, can thus not executed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tx().lock(action.getResourceLocator());
|
||||||
|
tx().removeFromCache(action.getResourceLocator());
|
||||||
|
|
||||||
|
ConfirmationPolicy confirmationPolicy = getConfirmationPolicy(action);
|
||||||
|
ExecutionPolicy executionPolicy = getExecutionPolicy(action);
|
||||||
|
|
||||||
|
if (!executionPolicy.isExecutable(action)) {
|
||||||
|
logger.info("Action " + action.getLocator() + " is not yet executable.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Action " + action.getLocator() + " is now being executed...");
|
||||||
|
|
||||||
|
// we catch all exceptions because we can't undo, thus need to set the state to ERROR in this case
|
||||||
|
// this is only required because we execute actions in same TX as we set to executed any previous actions
|
||||||
|
try {
|
||||||
|
executionPolicy.initialize(action);
|
||||||
|
executionPolicy.toExecution(action);
|
||||||
|
confirmationPolicy.toExecution(action);
|
||||||
|
|
||||||
|
if (action.getState() == State.EXECUTED)
|
||||||
|
this.needsRetriggerOfExecution = true;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Failed to set " + action.getLocator() + " to execution due to " + e.getMessage(), e);
|
||||||
|
|
||||||
|
try {
|
||||||
|
executionPolicy.stop();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Failed to stop execution policy for " + action.getLocator(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
action.setState(State.ERROR);
|
||||||
|
tx().update(action.getRootElement());
|
||||||
|
|
||||||
|
confirmationPolicy.toError(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isExecutable(IActivityElement element) {
|
||||||
|
State state = element.getState();
|
||||||
|
if (state.compareTo(State.EXECUTED) >= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (element instanceof Activity)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// not yet in execution
|
||||||
|
if (state.compareTo(State.EXECUTION) < 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// in stopped, means we can re-execute
|
||||||
|
if (state == State.STOPPED)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// if in ERROR, then must first be handled
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitSeries(Activity activity) {
|
||||||
|
|
||||||
|
if (activity.getState().compareTo(State.EXECUTED) >= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Iterator<Entry<String, IActivityElement>> iter = activity.elementIterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
IActivityElement element = iter.next().getValue();
|
||||||
|
State state = element.getState();
|
||||||
|
if (element.getState().compareTo(State.EXECUTED) >= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// in series we can never have two Actions in execution, so if we found the action in execution, we stop
|
||||||
|
if (element instanceof Action //
|
||||||
|
&& (state == State.EXECUTION //
|
||||||
|
|| state == State.WARNING //
|
||||||
|
|| state == State.ERROR)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean canExecute = isExecutable(element);
|
||||||
|
if (canExecute) {
|
||||||
|
element.accept(this);
|
||||||
|
|
||||||
|
// in series we stop when the first action is set to execution
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitParallel(Activity activity) {
|
||||||
|
|
||||||
|
if (activity.getState().compareTo(State.EXECUTED) >= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Iterator<Entry<String, IActivityElement>> iter = activity.elementIterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
IActivityElement element = iter.next().getValue();
|
||||||
|
if (element.getState().isExecuted())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// in parallel we execute all the actions in the activity
|
||||||
|
|
||||||
|
boolean canExecute = isExecutable(element);
|
||||||
|
if (canExecute) {
|
||||||
|
element.accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visitActivity(Activity activity) {
|
||||||
|
activity.getTimeOrdering().accept(this, activity);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
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;
|
|
||||||
import li.strolch.model.activity.Activity;
|
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
|
||||||
import li.strolch.utils.dbc.DBC;
|
|
||||||
|
|
||||||
public class ExecuteStoppedActionCommand extends ExecutionCommand {
|
|
||||||
|
|
||||||
private Action action;
|
|
||||||
|
|
||||||
public ExecuteStoppedActionCommand(ComponentContainer container, StrolchTransaction tx) {
|
|
||||||
super(container, tx);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAction(Action action) {
|
|
||||||
this.action = action;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void validate() {
|
|
||||||
DBC.PRE.assertNotNull("action can not be null", this.action);
|
|
||||||
|
|
||||||
tx().lock(this.action.getRootElement());
|
|
||||||
tx().lock(getResourceLocator(this.action));
|
|
||||||
|
|
||||||
if (this.action.getState() != State.STOPPED) {
|
|
||||||
String msg = "Action {0} is not in state " + State.STOPPED + " and can thus not be put into execution!";
|
|
||||||
msg = MessageFormat.format(msg, this.action.getState(), State.ERROR, this.action.getLocator());
|
|
||||||
throw new StrolchException(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doCommand() {
|
|
||||||
Activity rootElement = this.action.getRootElement();
|
|
||||||
tx().lock(rootElement);
|
|
||||||
tx().lock(getResourceLocator(this.action));
|
|
||||||
|
|
||||||
State currentState = rootElement.getState();
|
|
||||||
rootElement.accept(this);
|
|
||||||
|
|
||||||
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void undo() {
|
|
||||||
// can't undo execution
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,209 +0,0 @@
|
||||||
package li.strolch.execution.command;
|
|
||||||
|
|
||||||
import static li.strolch.execution.policy.NoPlanning.NO_PLANNING;
|
|
||||||
import static li.strolch.runtime.StrolchConstants.PolicyConstants.PARAM_ORDER;
|
|
||||||
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.agent.api.ComponentContainer;
|
|
||||||
import li.strolch.exception.StrolchException;
|
|
||||||
import li.strolch.execution.policy.ConfirmationPolicy;
|
|
||||||
import li.strolch.execution.policy.ExecutionPolicy;
|
|
||||||
import li.strolch.execution.policy.PlanningPolicy;
|
|
||||||
import li.strolch.model.Locator;
|
|
||||||
import li.strolch.model.Order;
|
|
||||||
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.activity.TimeOrderingVisitor;
|
|
||||||
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;
|
|
||||||
|
|
||||||
public abstract class ExecutionCommand extends Command implements TimeOrderingVisitor, IActivityElementVisitor<Void> {
|
|
||||||
|
|
||||||
public ExecutionCommand(ComponentContainer container, StrolchTransaction tx) {
|
|
||||||
super(container, tx);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Locator getResourceLocator(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 Resource.locatorFor(resourceType, resourceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 static void updateOrderState(StrolchTransaction tx, Activity rootElement, State currentState,
|
|
||||||
State newState) {
|
|
||||||
if (currentState == newState)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Order order = tx.getOrderByRelation(rootElement, PARAM_ORDER);
|
|
||||||
if (order == null) {
|
|
||||||
logger.warn("Did not find activity order by relation " + PARAM_ORDER + " for activity " + rootElement
|
|
||||||
.getLocator() + ", trying by Activity type and id");
|
|
||||||
order = tx.getOrderBy(rootElement.getType(), rootElement.getId());
|
|
||||||
if (order == null) {
|
|
||||||
logger.error("Could not find order by Activity type and id either, not updating order state!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
order.setState(rootElement.getState());
|
|
||||||
|
|
||||||
tx.update(order);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ExecutionPolicy getExecutionPolicy(Action action) {
|
|
||||||
Resource resource = getResource(action);
|
|
||||||
PolicyDef executionPolicyDef = resource.getPolicyDefs().getPolicyDef(ExecutionPolicy.class.getSimpleName());
|
|
||||||
return getComponent(PolicyHandler.class).getPolicy(executionPolicyDef, tx());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ConfirmationPolicy getConfirmationPolicy(Action action) {
|
|
||||||
Resource resource = getResource(action);
|
|
||||||
PolicyDef executionPolicyDef = resource.getPolicyDefs().getPolicyDef(ConfirmationPolicy.class.getSimpleName());
|
|
||||||
return getComponent(PolicyHandler.class).getPolicy(executionPolicyDef, tx());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitSeries(Activity activity) {
|
|
||||||
|
|
||||||
if (activity.getState().compareTo(State.EXECUTED) >= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Iterator<Entry<String, IActivityElement>> iter = activity.elementIterator();
|
|
||||||
while (iter.hasNext()) {
|
|
||||||
IActivityElement element = iter.next().getValue();
|
|
||||||
State state = element.getState();
|
|
||||||
if (element.getState().compareTo(State.EXECUTED) >= 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// in series we can never have two Actions in execution, so if we found the action in execution, we stop
|
|
||||||
if (element instanceof Action //
|
|
||||||
&& (state == State.EXECUTION //
|
|
||||||
|| state == State.WARNING //
|
|
||||||
|| state == State.ERROR)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean canExecute = isExecutable(element);
|
|
||||||
if (canExecute) {
|
|
||||||
element.accept(this);
|
|
||||||
|
|
||||||
// in series we stop when the first action is set to execution
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitParallel(Activity activity) {
|
|
||||||
|
|
||||||
if (activity.getState().compareTo(State.EXECUTED) >= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Iterator<Entry<String, IActivityElement>> iter = activity.elementIterator();
|
|
||||||
while (iter.hasNext()) {
|
|
||||||
IActivityElement element = iter.next().getValue();
|
|
||||||
if (element.getState().isExecuted())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// in parallel we execute all the actions in the activity
|
|
||||||
|
|
||||||
boolean canExecute = isExecutable(element);
|
|
||||||
if (canExecute) {
|
|
||||||
element.accept(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isExecutable(IActivityElement element) {
|
|
||||||
State state = element.getState();
|
|
||||||
if (state.compareTo(State.EXECUTED) >= 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (element instanceof Activity)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// not yet in execution
|
|
||||||
if (state.compareTo(State.EXECUTION) < 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// in stopped, means we can re-execute
|
|
||||||
if (state == State.STOPPED)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// if in ERROR, then must first be handled
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void visitActivity(Activity activity) {
|
|
||||||
activity.getTimeOrdering().accept(this, activity);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void visitAction(Action action) {
|
|
||||||
|
|
||||||
// first plan
|
|
||||||
if (action.getState().compareTo(State.PLANNED) < 0) {
|
|
||||||
PlanningPolicy planningPolicy = tx().getPolicy(action.findPolicy(PlanningPolicy.class, NO_PLANNING));
|
|
||||||
planningPolicy.plan(action);
|
|
||||||
if (action.getState() != State.PLANNED) {
|
|
||||||
logger.info("Action " + action.getLocator() + " was not planned, can thus not executed.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ExecutionPolicy executionPolicy = getExecutionPolicy(action);
|
|
||||||
|
|
||||||
tx().lock(getResourceLocator(action));
|
|
||||||
|
|
||||||
if (!executionPolicy.isExecutable(action)) {
|
|
||||||
logger.info("Action " + action.getLocator() + " is not yet executable.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("Action " + action.getLocator() + " is now being executed...");
|
|
||||||
|
|
||||||
// we catch all exceptions because we can't undo, thus need to set the state to ERROR in this case
|
|
||||||
// this is only required because we execute actions in same TX as we set to executed any previous actions
|
|
||||||
try {
|
|
||||||
executionPolicy.toExecution(action);
|
|
||||||
getConfirmationPolicy(action).toExecution(action);
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("Failed to set " + action.getLocator() + " to execution due to " + e.getMessage(), e);
|
|
||||||
action.setState(State.ERROR);
|
|
||||||
|
|
||||||
tx().update(action.getRootElement());
|
|
||||||
|
|
||||||
getConfirmationPolicy(action).toError(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -15,8 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package li.strolch.execution.command;
|
package li.strolch.execution.command;
|
||||||
|
|
||||||
import static li.strolch.execution.command.ExecutionCommand.updateOrderState;
|
import static li.strolch.execution.policy.NoPlanning.DEFAULT_PLANNING;
|
||||||
import static li.strolch.execution.policy.NoPlanning.NO_PLANNING;
|
|
||||||
|
|
||||||
import li.strolch.execution.policy.PlanningPolicy;
|
import li.strolch.execution.policy.PlanningPolicy;
|
||||||
import li.strolch.model.Resource;
|
import li.strolch.model.Resource;
|
||||||
|
@ -59,21 +58,18 @@ public class PlanActionCommand extends PlanningCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doCommand() {
|
public void doCommand() {
|
||||||
validate();
|
|
||||||
|
|
||||||
Activity rootElement = this.action.getRootElement();
|
Activity rootElement = this.action.getRootElement();
|
||||||
tx().lock(rootElement);
|
|
||||||
|
|
||||||
State currentState = rootElement.getState();
|
State currentState = rootElement.getState();
|
||||||
this.action.accept(this);
|
this.action.accept(this);
|
||||||
|
|
||||||
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visitAction(Action action) {
|
public Void visitAction(Action action) {
|
||||||
PlanningPolicy planningPolicy = tx().getPolicy(action.findPolicy(PlanningPolicy.class, NO_PLANNING));
|
PlanningPolicy planningPolicy = tx().getPolicy(action.findPolicy(PlanningPolicy.class, DEFAULT_PLANNING));
|
||||||
planningPolicy.plan(action);
|
planningPolicy.plan(action);
|
||||||
|
if (action.getState() == State.PLANNED)
|
||||||
|
getConfirmationPolicy(action).toPlanned(action);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package li.strolch.execution.command;
|
package li.strolch.execution.command;
|
||||||
|
|
||||||
import static li.strolch.execution.command.ExecutionCommand.updateOrderState;
|
import static li.strolch.execution.policy.NoPlanning.DEFAULT_PLANNING;
|
||||||
import static li.strolch.execution.policy.NoPlanning.NO_PLANNING;
|
|
||||||
|
|
||||||
import li.strolch.execution.policy.PlanningPolicy;
|
import li.strolch.execution.policy.PlanningPolicy;
|
||||||
import li.strolch.model.Resource;
|
import li.strolch.model.Resource;
|
||||||
|
@ -59,21 +58,18 @@ public class PlanActivityCommand extends PlanningCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doCommand() {
|
public void doCommand() {
|
||||||
validate();
|
|
||||||
|
|
||||||
Activity rootElement = this.activity.getRootElement();
|
Activity rootElement = this.activity.getRootElement();
|
||||||
tx().lock(rootElement);
|
|
||||||
|
|
||||||
State currentState = rootElement.getState();
|
State currentState = rootElement.getState();
|
||||||
this.activity.accept(this);
|
this.activity.accept(this);
|
||||||
|
|
||||||
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visitAction(Action action) {
|
public Void visitAction(Action action) {
|
||||||
PlanningPolicy planningPolicy = tx().getPolicy(action.findPolicy(PlanningPolicy.class, NO_PLANNING));
|
PlanningPolicy planningPolicy = tx().getPolicy(action.findPolicy(PlanningPolicy.class, DEFAULT_PLANNING));
|
||||||
planningPolicy.plan(action);
|
planningPolicy.plan(action);
|
||||||
|
if (action.getState() == State.PLANNED)
|
||||||
|
getConfirmationPolicy(action).toPlanned(action);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,22 +23,16 @@ import li.strolch.model.activity.Activity;
|
||||||
import li.strolch.model.activity.IActivityElement;
|
import li.strolch.model.activity.IActivityElement;
|
||||||
import li.strolch.model.visitor.IActivityElementVisitor;
|
import li.strolch.model.visitor.IActivityElementVisitor;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
import li.strolch.service.api.Command;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Martin Smock <martin.smock@bluewin.ch>
|
* @author Martin Smock <martin.smock@bluewin.ch>
|
||||||
*/
|
*/
|
||||||
public abstract class PlanningCommand extends Command implements IActivityElementVisitor<Void> {
|
public abstract class PlanningCommand extends BasePlanningAndExecutionCommand implements IActivityElementVisitor<Void> {
|
||||||
|
|
||||||
public PlanningCommand(StrolchTransaction tx) {
|
public PlanningCommand(StrolchTransaction tx) {
|
||||||
super(tx);
|
super(tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void undo() {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visitActivity(Activity activity) {
|
public Void visitActivity(Activity activity) {
|
||||||
if (activity.getState().compareTo(State.PLANNED) >= 0)
|
if (activity.getState().compareTo(State.PLANNED) >= 0)
|
||||||
|
|
|
@ -2,7 +2,6 @@ package li.strolch.execution.command;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
|
||||||
import li.strolch.exception.StrolchException;
|
import li.strolch.exception.StrolchException;
|
||||||
import li.strolch.model.State;
|
import li.strolch.model.State;
|
||||||
import li.strolch.model.activity.Action;
|
import li.strolch.model.activity.Action;
|
||||||
|
@ -10,12 +9,12 @@ import li.strolch.model.activity.Activity;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
import li.strolch.utils.dbc.DBC;
|
import li.strolch.utils.dbc.DBC;
|
||||||
|
|
||||||
public class SetActionToClosedCommand extends ExecutionCommand {
|
public class SetActionToClosedCommand extends BasePlanningAndExecutionCommand {
|
||||||
|
|
||||||
private Action action;
|
private Action action;
|
||||||
|
|
||||||
public SetActionToClosedCommand(ComponentContainer container, StrolchTransaction tx) {
|
public SetActionToClosedCommand(StrolchTransaction tx) {
|
||||||
super(container, tx);
|
super(tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAction(Action action) {
|
public void setAction(Action action) {
|
||||||
|
@ -26,9 +25,6 @@ public class SetActionToClosedCommand extends ExecutionCommand {
|
||||||
public void validate() {
|
public void validate() {
|
||||||
DBC.PRE.assertNotNull("action can not be null", this.action);
|
DBC.PRE.assertNotNull("action can not be null", this.action);
|
||||||
|
|
||||||
tx().lock(this.action.getRootElement());
|
|
||||||
tx().lock(getResourceLocator(this.action));
|
|
||||||
|
|
||||||
if (!this.action.getState().canSetToClosed()) {
|
if (!this.action.getState().canSetToClosed()) {
|
||||||
String msg = "Current state is {0} and can not be changed to {1} for action {2}";
|
String msg = "Current state is {0} and can not be changed to {1} for action {2}";
|
||||||
msg = MessageFormat.format(msg, this.action.getState(), State.CLOSED, this.action.getLocator());
|
msg = MessageFormat.format(msg, this.action.getState(), State.CLOSED, this.action.getLocator());
|
||||||
|
@ -38,15 +34,12 @@ public class SetActionToClosedCommand extends ExecutionCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doCommand() {
|
public void doCommand() {
|
||||||
Activity rootElement = this.action.getRootElement();
|
|
||||||
tx().lock(rootElement);
|
|
||||||
tx().lock(getResourceLocator(this.action));
|
|
||||||
|
|
||||||
if (this.action.getState() == State.CLOSED) {
|
if (this.action.getState() == State.CLOSED) {
|
||||||
logger.warn("Action " + this.action.getLocator() + " is already in state CLOSED! Not changing.");
|
logger.warn("Action " + this.action.getLocator() + " is already in state CLOSED! Not changing.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Activity rootElement = this.action.getRootElement();
|
||||||
State currentState = rootElement.getState();
|
State currentState = rootElement.getState();
|
||||||
|
|
||||||
this.action.setState(State.CLOSED);
|
this.action.setState(State.CLOSED);
|
||||||
|
@ -55,9 +48,4 @@ public class SetActionToClosedCommand extends ExecutionCommand {
|
||||||
|
|
||||||
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void undo() {
|
|
||||||
// can not undo
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package li.strolch.execution.command;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
|
||||||
import li.strolch.exception.StrolchException;
|
import li.strolch.exception.StrolchException;
|
||||||
import li.strolch.model.State;
|
import li.strolch.model.State;
|
||||||
import li.strolch.model.activity.Action;
|
import li.strolch.model.activity.Action;
|
||||||
|
@ -10,12 +9,12 @@ import li.strolch.model.activity.Activity;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
import li.strolch.utils.dbc.DBC;
|
import li.strolch.utils.dbc.DBC;
|
||||||
|
|
||||||
public class SetActionToCreatedCommand extends ExecutionCommand {
|
public class SetActionToCreatedCommand extends BasePlanningAndExecutionCommand {
|
||||||
|
|
||||||
private Action action;
|
private Action action;
|
||||||
|
|
||||||
public SetActionToCreatedCommand(ComponentContainer container, StrolchTransaction tx) {
|
public SetActionToCreatedCommand(StrolchTransaction tx) {
|
||||||
super(container, tx);
|
super(tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAction(Action action) {
|
public void setAction(Action action) {
|
||||||
|
@ -26,9 +25,6 @@ public class SetActionToCreatedCommand extends ExecutionCommand {
|
||||||
public void validate() {
|
public void validate() {
|
||||||
DBC.PRE.assertNotNull("action can not be null", this.action);
|
DBC.PRE.assertNotNull("action can not be null", this.action);
|
||||||
|
|
||||||
tx().lock(this.action.getRootElement());
|
|
||||||
tx().lock(getResourceLocator(this.action));
|
|
||||||
|
|
||||||
if (!this.action.getState().canSetToCreated()) {
|
if (!this.action.getState().canSetToCreated()) {
|
||||||
String msg = "Current state is {0} and can not be changed to {1} for action {2}";
|
String msg = "Current state is {0} and can not be changed to {1} for action {2}";
|
||||||
msg = MessageFormat.format(msg, this.action.getState(), State.CREATED, this.action.getLocator());
|
msg = MessageFormat.format(msg, this.action.getState(), State.CREATED, this.action.getLocator());
|
||||||
|
@ -38,15 +34,12 @@ public class SetActionToCreatedCommand extends ExecutionCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doCommand() {
|
public void doCommand() {
|
||||||
Activity rootElement = this.action.getRootElement();
|
|
||||||
tx().lock(rootElement);
|
|
||||||
tx().lock(getResourceLocator(this.action));
|
|
||||||
|
|
||||||
if (this.action.getState() == State.CREATED) {
|
if (this.action.getState() == State.CREATED) {
|
||||||
logger.warn("Action " + this.action.getLocator() + " is already in state CREATED! Not changing.");
|
logger.warn("Action " + this.action.getLocator() + " is already in state CREATED! Not changing.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Activity rootElement = this.action.getRootElement();
|
||||||
State currentState = rootElement.getState();
|
State currentState = rootElement.getState();
|
||||||
|
|
||||||
this.action.setState(State.CREATED);
|
this.action.setState(State.CREATED);
|
||||||
|
@ -55,9 +48,4 @@ public class SetActionToCreatedCommand extends ExecutionCommand {
|
||||||
|
|
||||||
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void undo() {
|
|
||||||
// can not undo
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,32 +2,20 @@ package li.strolch.execution.command;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
|
||||||
import li.strolch.exception.StrolchException;
|
import li.strolch.exception.StrolchException;
|
||||||
import li.strolch.model.State;
|
import li.strolch.model.State;
|
||||||
import li.strolch.model.activity.Action;
|
|
||||||
import li.strolch.model.activity.Activity;
|
import li.strolch.model.activity.Activity;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
import li.strolch.utils.dbc.DBC;
|
|
||||||
|
|
||||||
public class SetActionToErrorCommand extends ExecutionCommand {
|
public class SetActionToErrorCommand extends ActionExecutionCommand {
|
||||||
|
|
||||||
private Action action;
|
public SetActionToErrorCommand(StrolchTransaction tx) {
|
||||||
|
super(tx);
|
||||||
public SetActionToErrorCommand(ComponentContainer container, StrolchTransaction tx) {
|
|
||||||
super(container, tx);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAction(Action action) {
|
|
||||||
this.action = action;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validate() {
|
public void validate() {
|
||||||
DBC.PRE.assertNotNull("action can not be null", this.action);
|
super.validate();
|
||||||
|
|
||||||
tx().lock(this.action.getRootElement());
|
|
||||||
tx().lock(getResourceLocator(this.action));
|
|
||||||
|
|
||||||
if (!this.action.getState().canSetToError()) {
|
if (!this.action.getState().canSetToError()) {
|
||||||
String msg = "Current state is {0} and can not be changed to {1} for action {2}";
|
String msg = "Current state is {0} and can not be changed to {1} for action {2}";
|
||||||
|
@ -38,15 +26,12 @@ public class SetActionToErrorCommand extends ExecutionCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doCommand() {
|
public void doCommand() {
|
||||||
Activity rootElement = this.action.getRootElement();
|
|
||||||
tx().lock(rootElement);
|
|
||||||
tx().lock(getResourceLocator(this.action));
|
|
||||||
|
|
||||||
if (this.action.getState() == State.ERROR) {
|
if (this.action.getState() == State.ERROR) {
|
||||||
logger.warn("Action " + this.action.getLocator() + " is already in state ERROR! Not changing.");
|
logger.warn("Action " + this.action.getLocator() + " is already in state ERROR! Not changing.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Activity rootElement = this.action.getRootElement();
|
||||||
State currentState = rootElement.getState();
|
State currentState = rootElement.getState();
|
||||||
|
|
||||||
getExecutionPolicy(this.action).toError(this.action);
|
getExecutionPolicy(this.action).toError(this.action);
|
||||||
|
@ -54,9 +39,4 @@ public class SetActionToErrorCommand extends ExecutionCommand {
|
||||||
|
|
||||||
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void undo() {
|
|
||||||
// can not undo
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
package li.strolch.execution.command;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
|
import li.strolch.exception.StrolchException;
|
||||||
|
import li.strolch.model.State;
|
||||||
|
import li.strolch.model.activity.Activity;
|
||||||
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
|
|
||||||
|
public class SetActionToExecutableCommand extends ActionExecutionCommand {
|
||||||
|
|
||||||
|
public SetActionToExecutableCommand(StrolchTransaction tx) {
|
||||||
|
super(tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validate() {
|
||||||
|
super.validate();
|
||||||
|
|
||||||
|
if (!this.action.getState().canSetToExecutable()) {
|
||||||
|
String msg = "Current state is {0} and can not be changed to {1} for action {2}";
|
||||||
|
msg = MessageFormat.format(msg, this.action.getState(), State.EXECUTABLE, this.action.getLocator());
|
||||||
|
throw new StrolchException(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doCommand() {
|
||||||
|
if (this.action.getState() == State.EXECUTABLE) {
|
||||||
|
logger.warn("Action " + this.action.getLocator() + " is already in state EXECUTABLE! Not changing.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Activity rootElement = this.action.getRootElement();
|
||||||
|
State currentState = rootElement.getState();
|
||||||
|
|
||||||
|
this.action.setState(State.EXECUTABLE);
|
||||||
|
|
||||||
|
getConfirmationPolicy(this.action).toExecutable(this.action);
|
||||||
|
|
||||||
|
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,32 +2,20 @@ package li.strolch.execution.command;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
|
||||||
import li.strolch.exception.StrolchException;
|
import li.strolch.exception.StrolchException;
|
||||||
import li.strolch.model.State;
|
import li.strolch.model.State;
|
||||||
import li.strolch.model.activity.Action;
|
|
||||||
import li.strolch.model.activity.Activity;
|
import li.strolch.model.activity.Activity;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
import li.strolch.utils.dbc.DBC;
|
|
||||||
|
|
||||||
public class SetActionToExecutedCommand extends ExecutionCommand {
|
public class SetActionToExecutedCommand extends ActionExecutionCommand {
|
||||||
|
|
||||||
private Action action;
|
public SetActionToExecutedCommand(StrolchTransaction tx) {
|
||||||
|
super(tx);
|
||||||
public SetActionToExecutedCommand(ComponentContainer container, StrolchTransaction tx) {
|
|
||||||
super(container, tx);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAction(Action action) {
|
|
||||||
this.action = action;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validate() {
|
public void validate() {
|
||||||
DBC.PRE.assertNotNull("action can not be null", this.action);
|
super.validate();
|
||||||
|
|
||||||
tx().lock(this.action.getRootElement());
|
|
||||||
tx().lock(getResourceLocator(this.action));
|
|
||||||
|
|
||||||
if (!this.action.getState().canSetToExecuted()) {
|
if (!this.action.getState().canSetToExecuted()) {
|
||||||
String msg = "Current state is {0} can not be changed to {1} for action {2}";
|
String msg = "Current state is {0} can not be changed to {1} for action {2}";
|
||||||
|
@ -38,15 +26,12 @@ public class SetActionToExecutedCommand extends ExecutionCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doCommand() {
|
public void doCommand() {
|
||||||
Activity rootElement = this.action.getRootElement();
|
|
||||||
tx().lock(rootElement);
|
|
||||||
tx().lock(getResourceLocator(this.action));
|
|
||||||
|
|
||||||
if (this.action.getState() == State.EXECUTED) {
|
if (this.action.getState() == State.EXECUTED) {
|
||||||
logger.warn("Action " + this.action.getLocator() + " is already in state EXECUTED! Not changing.");
|
logger.warn("Action " + this.action.getLocator() + " is already in state EXECUTED! Not changing.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Activity rootElement = this.action.getRootElement();
|
||||||
State currentState = rootElement.getState();
|
State currentState = rootElement.getState();
|
||||||
|
|
||||||
getExecutionPolicy(this.action).toExecuted(this.action);
|
getExecutionPolicy(this.action).toExecuted(this.action);
|
||||||
|
@ -54,9 +39,4 @@ public class SetActionToExecutedCommand extends ExecutionCommand {
|
||||||
|
|
||||||
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void undo() {
|
|
||||||
// can not undo
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package li.strolch.execution.command;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
|
||||||
import li.strolch.exception.StrolchException;
|
import li.strolch.exception.StrolchException;
|
||||||
import li.strolch.model.State;
|
import li.strolch.model.State;
|
||||||
import li.strolch.model.activity.Action;
|
import li.strolch.model.activity.Action;
|
||||||
|
@ -10,12 +9,12 @@ import li.strolch.model.activity.Activity;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
import li.strolch.utils.dbc.DBC;
|
import li.strolch.utils.dbc.DBC;
|
||||||
|
|
||||||
public class SetActionToPlannedCommand extends ExecutionCommand {
|
public class SetActionToPlannedCommand extends BasePlanningAndExecutionCommand {
|
||||||
|
|
||||||
private Action action;
|
private Action action;
|
||||||
|
|
||||||
public SetActionToPlannedCommand(ComponentContainer container, StrolchTransaction tx) {
|
public SetActionToPlannedCommand(StrolchTransaction tx) {
|
||||||
super(container, tx);
|
super(tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAction(Action action) {
|
public void setAction(Action action) {
|
||||||
|
@ -26,9 +25,6 @@ public class SetActionToPlannedCommand extends ExecutionCommand {
|
||||||
public void validate() {
|
public void validate() {
|
||||||
DBC.PRE.assertNotNull("action can not be null", this.action);
|
DBC.PRE.assertNotNull("action can not be null", this.action);
|
||||||
|
|
||||||
tx().lock(this.action.getRootElement());
|
|
||||||
tx().lock(getResourceLocator(this.action));
|
|
||||||
|
|
||||||
if (!this.action.getState().canSetToPlanned()) {
|
if (!this.action.getState().canSetToPlanned()) {
|
||||||
String msg = "Current state is {0} and can not be changed to {1} for action {2}";
|
String msg = "Current state is {0} and can not be changed to {1} for action {2}";
|
||||||
msg = MessageFormat.format(msg, this.action.getState(), State.PLANNED, this.action.getLocator());
|
msg = MessageFormat.format(msg, this.action.getState(), State.PLANNED, this.action.getLocator());
|
||||||
|
@ -38,15 +34,12 @@ public class SetActionToPlannedCommand extends ExecutionCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doCommand() {
|
public void doCommand() {
|
||||||
Activity rootElement = this.action.getRootElement();
|
|
||||||
tx().lock(rootElement);
|
|
||||||
tx().lock(getResourceLocator(this.action));
|
|
||||||
|
|
||||||
if (this.action.getState() == State.PLANNED) {
|
if (this.action.getState() == State.PLANNED) {
|
||||||
logger.warn("Action " + this.action.getLocator() + " is already in state PLANNED! Not changing.");
|
logger.warn("Action " + this.action.getLocator() + " is already in state PLANNED! Not changing.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Activity rootElement = this.action.getRootElement();
|
||||||
State currentState = rootElement.getState();
|
State currentState = rootElement.getState();
|
||||||
|
|
||||||
this.action.setState(State.PLANNED);
|
this.action.setState(State.PLANNED);
|
||||||
|
@ -55,9 +48,4 @@ public class SetActionToPlannedCommand extends ExecutionCommand {
|
||||||
|
|
||||||
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void undo() {
|
|
||||||
// can not undo
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
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;
|
|
||||||
import li.strolch.model.activity.Activity;
|
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
|
||||||
import li.strolch.utils.dbc.DBC;
|
|
||||||
|
|
||||||
public class SetActionToPlanningCommand extends ExecutionCommand {
|
|
||||||
|
|
||||||
private Action action;
|
|
||||||
|
|
||||||
public SetActionToPlanningCommand(ComponentContainer container, StrolchTransaction tx) {
|
|
||||||
super(container, tx);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAction(Action action) {
|
|
||||||
this.action = action;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void validate() {
|
|
||||||
DBC.PRE.assertNotNull("action can not be null", this.action);
|
|
||||||
|
|
||||||
tx().lock(this.action.getRootElement());
|
|
||||||
tx().lock(getResourceLocator(this.action));
|
|
||||||
|
|
||||||
if (!this.action.getState().canSetToPlanning()) {
|
|
||||||
String msg = "Current state is {0} and can not be changed to {1} for action {2}";
|
|
||||||
msg = MessageFormat.format(msg, this.action.getState(), State.PLANNING, this.action.getLocator());
|
|
||||||
throw new StrolchException(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doCommand() {
|
|
||||||
Activity rootElement = this.action.getRootElement();
|
|
||||||
tx().lock(rootElement);
|
|
||||||
tx().lock(getResourceLocator(this.action));
|
|
||||||
|
|
||||||
if (this.action.getState() == State.PLANNING) {
|
|
||||||
logger.warn("Action " + this.action.getLocator() + " is already in state PLANNING! Not changing.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
State currentState = rootElement.getState();
|
|
||||||
|
|
||||||
this.action.setState(State.PLANNING);
|
|
||||||
|
|
||||||
getConfirmationPolicy(this.action).toPlanning(this.action);
|
|
||||||
|
|
||||||
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void undo() {
|
|
||||||
// can not undo
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,32 +2,20 @@ package li.strolch.execution.command;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
|
||||||
import li.strolch.exception.StrolchException;
|
import li.strolch.exception.StrolchException;
|
||||||
import li.strolch.model.State;
|
import li.strolch.model.State;
|
||||||
import li.strolch.model.activity.Action;
|
|
||||||
import li.strolch.model.activity.Activity;
|
import li.strolch.model.activity.Activity;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
import li.strolch.utils.dbc.DBC;
|
|
||||||
|
|
||||||
public class SetActionToStoppedCommand extends ExecutionCommand {
|
public class SetActionToStoppedCommand extends ActionExecutionCommand {
|
||||||
|
|
||||||
private Action action;
|
public SetActionToStoppedCommand(StrolchTransaction tx) {
|
||||||
|
super(tx);
|
||||||
public SetActionToStoppedCommand(ComponentContainer container, StrolchTransaction tx) {
|
|
||||||
super(container, tx);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAction(Action action) {
|
|
||||||
this.action = action;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validate() {
|
public void validate() {
|
||||||
DBC.PRE.assertNotNull("action can not be null", this.action);
|
super.validate();
|
||||||
|
|
||||||
tx().lock(this.action.getRootElement());
|
|
||||||
tx().lock(getResourceLocator(this.action));
|
|
||||||
|
|
||||||
if (!this.action.getState().canSetToStopped()) {
|
if (!this.action.getState().canSetToStopped()) {
|
||||||
String msg = "Current state is {0} and can not be changed to {1} for action {2}";
|
String msg = "Current state is {0} and can not be changed to {1} for action {2}";
|
||||||
|
@ -38,15 +26,12 @@ public class SetActionToStoppedCommand extends ExecutionCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doCommand() {
|
public void doCommand() {
|
||||||
Activity rootElement = this.action.getRootElement();
|
|
||||||
tx().lock(rootElement);
|
|
||||||
tx().lock(getResourceLocator(this.action));
|
|
||||||
|
|
||||||
if (this.action.getState() == State.STOPPED) {
|
if (this.action.getState() == State.STOPPED) {
|
||||||
logger.warn("Action " + this.action.getLocator() + " is already in state STOPPED! Not changing.");
|
logger.warn("Action " + this.action.getLocator() + " is already in state STOPPED! Not changing.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Activity rootElement = this.action.getRootElement();
|
||||||
State currentState = rootElement.getState();
|
State currentState = rootElement.getState();
|
||||||
|
|
||||||
getExecutionPolicy(this.action).toStopped(this.action);
|
getExecutionPolicy(this.action).toStopped(this.action);
|
||||||
|
@ -54,9 +39,4 @@ public class SetActionToStoppedCommand extends ExecutionCommand {
|
||||||
|
|
||||||
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void undo() {
|
|
||||||
// can not undo
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,32 +2,20 @@ package li.strolch.execution.command;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
|
||||||
import li.strolch.exception.StrolchException;
|
import li.strolch.exception.StrolchException;
|
||||||
import li.strolch.model.State;
|
import li.strolch.model.State;
|
||||||
import li.strolch.model.activity.Action;
|
|
||||||
import li.strolch.model.activity.Activity;
|
import li.strolch.model.activity.Activity;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
import li.strolch.utils.dbc.DBC;
|
|
||||||
|
|
||||||
public class SetActionToWarningCommand extends ExecutionCommand {
|
public class SetActionToWarningCommand extends ActionExecutionCommand {
|
||||||
|
|
||||||
private Action action;
|
public SetActionToWarningCommand(StrolchTransaction tx) {
|
||||||
|
super(tx);
|
||||||
public SetActionToWarningCommand(ComponentContainer container, StrolchTransaction tx) {
|
|
||||||
super(container, tx);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAction(Action action) {
|
|
||||||
this.action = action;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validate() {
|
public void validate() {
|
||||||
DBC.PRE.assertNotNull("action can not be null", this.action);
|
super.validate();
|
||||||
|
|
||||||
tx().lock(this.action.getRootElement());
|
|
||||||
tx().lock(getResourceLocator(this.action));
|
|
||||||
|
|
||||||
if (!this.action.getState().canSetToWarning()) {
|
if (!this.action.getState().canSetToWarning()) {
|
||||||
String msg = "Current state is {0} and can not be changed to {1} for action {2}";
|
String msg = "Current state is {0} and can not be changed to {1} for action {2}";
|
||||||
|
@ -38,15 +26,12 @@ public class SetActionToWarningCommand extends ExecutionCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doCommand() {
|
public void doCommand() {
|
||||||
Activity rootElement = this.action.getRootElement();
|
|
||||||
tx().lock(rootElement);
|
|
||||||
tx().lock(getResourceLocator(this.action));
|
|
||||||
|
|
||||||
if (this.action.getState() == State.WARNING) {
|
if (this.action.getState() == State.WARNING) {
|
||||||
logger.warn("Action " + this.action.getLocator() + " is already in state WARNING! Not changing.");
|
logger.warn("Action " + this.action.getLocator() + " is already in state WARNING! Not changing.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Activity rootElement = this.action.getRootElement();
|
||||||
State currentState = rootElement.getState();
|
State currentState = rootElement.getState();
|
||||||
|
|
||||||
getExecutionPolicy(this.action).toWarning(this.action);
|
getExecutionPolicy(this.action).toWarning(this.action);
|
||||||
|
@ -54,9 +39,4 @@ public class SetActionToWarningCommand extends ExecutionCommand {
|
||||||
|
|
||||||
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void undo() {
|
|
||||||
// can not undo
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package li.strolch.execution.command;
|
package li.strolch.execution.command;
|
||||||
|
|
||||||
import static li.strolch.execution.command.ExecutionCommand.updateOrderState;
|
import static li.strolch.execution.policy.NoPlanning.DEFAULT_PLANNING;
|
||||||
import static li.strolch.execution.policy.NoPlanning.NO_PLANNING;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -59,14 +58,9 @@ public class ShiftActionCommand extends PlanningCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doCommand() {
|
public void doCommand() {
|
||||||
validate();
|
|
||||||
|
|
||||||
Activity rootElement = this.action.getRootElement();
|
Activity rootElement = this.action.getRootElement();
|
||||||
tx().lock(rootElement);
|
|
||||||
|
|
||||||
State currentState = rootElement.getState();
|
State currentState = rootElement.getState();
|
||||||
this.action.accept(this);
|
this.action.accept(this);
|
||||||
|
|
||||||
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,8 +69,10 @@ public class ShiftActionCommand extends PlanningCommand {
|
||||||
|
|
||||||
// unplan the action
|
// unplan the action
|
||||||
if (action.getState() == State.PLANNED) {
|
if (action.getState() == State.PLANNED) {
|
||||||
PlanningPolicy planningPolicy = tx().getPolicy(action.findPolicy(PlanningPolicy.class, NO_PLANNING));
|
PlanningPolicy planningPolicy = tx().getPolicy(action.findPolicy(PlanningPolicy.class, DEFAULT_PLANNING));
|
||||||
planningPolicy.unplan(action);
|
planningPolicy.unplan(action);
|
||||||
|
if (action.getState() == State.CREATED)
|
||||||
|
getConfirmationPolicy(action).toCreated(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
// iterate all changes and shift
|
// iterate all changes and shift
|
||||||
|
@ -86,8 +82,10 @@ public class ShiftActionCommand extends PlanningCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally plan the action
|
// finally plan the action
|
||||||
PlanningPolicy planningPolicy = tx().getPolicy(action.findPolicy(PlanningPolicy.class, NO_PLANNING));
|
PlanningPolicy planningPolicy = tx().getPolicy(action.findPolicy(PlanningPolicy.class, DEFAULT_PLANNING));
|
||||||
planningPolicy.plan(action);
|
planningPolicy.plan(action);
|
||||||
|
if (action.getState() == State.PLANNED)
|
||||||
|
getConfirmationPolicy(action).toPlanned(action);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package li.strolch.execution.command;
|
package li.strolch.execution.command;
|
||||||
|
|
||||||
import static li.strolch.execution.command.ExecutionCommand.updateOrderState;
|
import static li.strolch.execution.policy.NoPlanning.DEFAULT_PLANNING;
|
||||||
import static li.strolch.execution.policy.NoPlanning.NO_PLANNING;
|
|
||||||
|
|
||||||
import li.strolch.execution.policy.PlanningPolicy;
|
import li.strolch.execution.policy.PlanningPolicy;
|
||||||
import li.strolch.model.Resource;
|
import li.strolch.model.Resource;
|
||||||
|
@ -61,21 +60,18 @@ public class UnplanActionCommand extends PlanningCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doCommand() {
|
public void doCommand() {
|
||||||
validate();
|
|
||||||
|
|
||||||
Activity rootElement = this.action.getRootElement();
|
Activity rootElement = this.action.getRootElement();
|
||||||
tx().lock(rootElement);
|
|
||||||
|
|
||||||
State currentState = rootElement.getState();
|
State currentState = rootElement.getState();
|
||||||
this.action.accept(this);
|
this.action.accept(this);
|
||||||
|
|
||||||
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visitAction(Action action) {
|
public Void visitAction(Action action) {
|
||||||
PlanningPolicy planningPolicy = tx().getPolicy(action.findPolicy(PlanningPolicy.class, NO_PLANNING));
|
PlanningPolicy planningPolicy = tx().getPolicy(action.findPolicy(PlanningPolicy.class, DEFAULT_PLANNING));
|
||||||
planningPolicy.unplan(action);
|
planningPolicy.unplan(action);
|
||||||
|
if (action.getState() == State.CREATED)
|
||||||
|
getConfirmationPolicy(action).toCreated(action);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package li.strolch.execution.command;
|
package li.strolch.execution.command;
|
||||||
|
|
||||||
import static li.strolch.execution.command.ExecutionCommand.updateOrderState;
|
import static li.strolch.execution.policy.NoPlanning.DEFAULT_PLANNING;
|
||||||
import static li.strolch.execution.policy.NoPlanning.NO_PLANNING;
|
|
||||||
|
|
||||||
import li.strolch.execution.policy.PlanningPolicy;
|
import li.strolch.execution.policy.PlanningPolicy;
|
||||||
import li.strolch.model.Resource;
|
import li.strolch.model.Resource;
|
||||||
|
@ -59,21 +58,18 @@ public class UnplanActivityCommand extends PlanningCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doCommand() {
|
public void doCommand() {
|
||||||
validate();
|
|
||||||
|
|
||||||
Activity rootElement = this.activity.getRootElement();
|
Activity rootElement = this.activity.getRootElement();
|
||||||
tx().lock(rootElement);
|
|
||||||
|
|
||||||
State currentState = rootElement.getState();
|
State currentState = rootElement.getState();
|
||||||
this.activity.accept(this);
|
this.activity.accept(this);
|
||||||
|
|
||||||
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
updateOrderState(tx(), rootElement, currentState, rootElement.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visitAction(Action action) {
|
public Void visitAction(Action action) {
|
||||||
PlanningPolicy planningPolicy = tx().getPolicy(action.findPolicy(PlanningPolicy.class, NO_PLANNING));
|
PlanningPolicy planningPolicy = tx().getPolicy(action.findPolicy(PlanningPolicy.class, DEFAULT_PLANNING));
|
||||||
planningPolicy.unplan(action);
|
planningPolicy.unplan(action);
|
||||||
|
if (action.getState() == State.CREATED)
|
||||||
|
getConfirmationPolicy(action).toCreated(action);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package li.strolch.execution.policy;
|
||||||
|
|
||||||
import li.strolch.model.State;
|
import li.strolch.model.State;
|
||||||
import li.strolch.model.activity.Activity;
|
import li.strolch.model.activity.Activity;
|
||||||
|
import li.strolch.model.policy.PolicyDef;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
import li.strolch.policy.StrolchPolicy;
|
import li.strolch.policy.StrolchPolicy;
|
||||||
|
|
||||||
|
@ -14,6 +15,9 @@ import li.strolch.policy.StrolchPolicy;
|
||||||
*/
|
*/
|
||||||
public class ActivityArchivalPolicy extends StrolchPolicy {
|
public class ActivityArchivalPolicy extends StrolchPolicy {
|
||||||
|
|
||||||
|
public static PolicyDef DEFAULT_ACTIVITY_ARCHIVAL = PolicyDef
|
||||||
|
.valueOf(ActivityArchivalPolicy.class.getSimpleName(), "key:DefaultActivityArchival");
|
||||||
|
|
||||||
public ActivityArchivalPolicy(StrolchTransaction tx) {
|
public ActivityArchivalPolicy(StrolchTransaction tx) {
|
||||||
super(tx);
|
super(tx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package li.strolch.execution.policy;
|
package li.strolch.execution.policy;
|
||||||
|
|
||||||
import li.strolch.model.activity.Action;
|
import li.strolch.model.activity.Action;
|
||||||
|
import li.strolch.model.policy.PolicyDef;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
import li.strolch.policy.StrolchPolicy;
|
import li.strolch.policy.StrolchPolicy;
|
||||||
|
|
||||||
|
@ -12,6 +13,9 @@ import li.strolch.policy.StrolchPolicy;
|
||||||
*/
|
*/
|
||||||
public class ConfirmationPolicy extends StrolchPolicy {
|
public class ConfirmationPolicy extends StrolchPolicy {
|
||||||
|
|
||||||
|
public static PolicyDef DEFAULT_CONFIRMATION = PolicyDef
|
||||||
|
.valueOf(ConfirmationPolicy.class.getSimpleName(), "key:DefaultConfirmation");
|
||||||
|
|
||||||
public ConfirmationPolicy(StrolchTransaction tx) {
|
public ConfirmationPolicy(StrolchTransaction tx) {
|
||||||
super(tx);
|
super(tx);
|
||||||
}
|
}
|
||||||
|
@ -20,11 +24,11 @@ public class ConfirmationPolicy extends StrolchPolicy {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
public void toPlanning(Action action) {
|
public void toPlanned(Action action) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
public void toPlanned(Action action) {
|
public void toExecutable(Action action) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@ import li.strolch.runtime.StrolchConstants.PolicyConstants;
|
||||||
*/
|
*/
|
||||||
public class DurationExecution extends SimpleExecution {
|
public class DurationExecution extends SimpleExecution {
|
||||||
|
|
||||||
|
protected Locator actionLoc;
|
||||||
|
|
||||||
public DurationExecution(StrolchTransaction tx) {
|
public DurationExecution(StrolchTransaction tx) {
|
||||||
super(tx);
|
super(tx);
|
||||||
}
|
}
|
||||||
|
@ -27,10 +29,15 @@ public class DurationExecution extends SimpleExecution {
|
||||||
.findParameter(PolicyConstants.BAG_OBJECTIVES, PolicyConstants.PARAM_DURATION, true);
|
.findParameter(PolicyConstants.BAG_OBJECTIVES, PolicyConstants.PARAM_DURATION, true);
|
||||||
|
|
||||||
String realmName = tx().getRealmName();
|
String realmName = tx().getRealmName();
|
||||||
Locator locator = action.getLocator();
|
this.actionLoc = action.getLocator();
|
||||||
logger.info("Executing action " + action.getLocator() + " has a duration of " + durationP.getValueAsString());
|
logger.info("Executing action " + actionLoc + " has a duration of " + durationP.getValueAsString());
|
||||||
getDelayedExecutionTimer().execute(realmName, getContainer(), locator, durationP.toMillis());
|
getDelayedExecutionTimer().execute(realmName, getContainer(), this.actionLoc, durationP.toMillis());
|
||||||
|
|
||||||
super.toExecution(action);
|
super.toExecution(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleStopped() {
|
||||||
|
getDelayedExecutionTimer().cancel(this.actionLoc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,10 @@ package li.strolch.execution.policy;
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
import li.strolch.agent.api.ComponentContainer;
|
||||||
import li.strolch.agent.api.StrolchRealm;
|
import li.strolch.agent.api.StrolchRealm;
|
||||||
import li.strolch.exception.StrolchException;
|
import li.strolch.exception.StrolchException;
|
||||||
|
import li.strolch.execution.Controller;
|
||||||
import li.strolch.execution.DelayedExecutionTimer;
|
import li.strolch.execution.DelayedExecutionTimer;
|
||||||
import li.strolch.execution.ExecutionHandler;
|
import li.strolch.execution.ExecutionHandler;
|
||||||
|
import li.strolch.model.Locator;
|
||||||
import li.strolch.model.State;
|
import li.strolch.model.State;
|
||||||
import li.strolch.model.activity.Action;
|
import li.strolch.model.activity.Action;
|
||||||
import li.strolch.model.activity.Activity;
|
import li.strolch.model.activity.Activity;
|
||||||
|
@ -33,6 +35,12 @@ import li.strolch.runtime.privilege.PrivilegedRunnableWithResult;
|
||||||
*/
|
*/
|
||||||
public abstract class ExecutionPolicy extends StrolchPolicy {
|
public abstract class ExecutionPolicy extends StrolchPolicy {
|
||||||
|
|
||||||
|
private Controller controller;
|
||||||
|
private boolean stopped;
|
||||||
|
|
||||||
|
protected String actionType;
|
||||||
|
protected Locator actionLoc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The TX for this execution policy. The TX needs to be updated when this execution policy has a longer life time
|
* The TX for this execution policy. The TX needs to be updated when this execution policy has a longer life time
|
||||||
* than the actual TX
|
* than the actual TX
|
||||||
|
@ -44,6 +52,19 @@ public abstract class ExecutionPolicy extends StrolchPolicy {
|
||||||
this.tx = tx;
|
this.tx = tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setController(StrolchTransaction tx, Controller controller) {
|
||||||
|
this.tx = tx;
|
||||||
|
this.controller = controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Controller getController() {
|
||||||
|
return this.controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStopped() {
|
||||||
|
return this.stopped;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the TX which is defined on this class, not the one defined on {@link StrolchPolicy}
|
* Returns the TX which is defined on this class, not the one defined on {@link StrolchPolicy}
|
||||||
*/
|
*/
|
||||||
|
@ -76,6 +97,18 @@ public abstract class ExecutionPolicy extends StrolchPolicy {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs any initialization of this {@link ExecutionPolicy} for the given action, this method stores the {@link
|
||||||
|
* Locator} of the action and its type
|
||||||
|
*
|
||||||
|
* @param action
|
||||||
|
* the action for which to initialize
|
||||||
|
*/
|
||||||
|
public void initialize(Action action) {
|
||||||
|
this.actionType = action.getType();
|
||||||
|
this.actionLoc = action.getLocator();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the execution of the given {@link Action}, i.e. sets the state to {@link State#EXECUTION}
|
* Starts the execution of the given {@link Action}, i.e. sets the state to {@link State#EXECUTION}
|
||||||
*
|
*
|
||||||
|
@ -119,6 +152,21 @@ public abstract class ExecutionPolicy extends StrolchPolicy {
|
||||||
*/
|
*/
|
||||||
public abstract void toWarning(Action action);
|
public abstract void toWarning(Action action);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops any active components in this {@link ExecutionPolicy}. This is used to notify the {@link ExecutionPolicy}
|
||||||
|
* that any scheduled actions should be stopped, that listening and observing registrations can be taken back, etc.
|
||||||
|
*/
|
||||||
|
public void stop() {
|
||||||
|
this.stopped = true;
|
||||||
|
try {
|
||||||
|
handleStopped();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Stopping failed for " + this.actionLoc, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void handleStopped();
|
||||||
|
|
||||||
protected void setActionState(Action action, State state) {
|
protected void setActionState(Action action, State state) {
|
||||||
|
|
||||||
action.setState(state);
|
action.setState(state);
|
||||||
|
@ -142,15 +190,6 @@ public abstract class ExecutionPolicy extends StrolchPolicy {
|
||||||
return getComponent(ExecutionHandler.class).getDelayedExecutionTimer();
|
return getComponent(ExecutionHandler.class).getDelayedExecutionTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the execution handler instance
|
|
||||||
*
|
|
||||||
* @return the {@link ExecutionHandler} instance
|
|
||||||
*/
|
|
||||||
protected ExecutionHandler getExecutionHandler() {
|
|
||||||
return getComponent(ExecutionHandler.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a {@link StrolchTransaction} where the realm retrieved using {@link ComponentContainer#getRealm(Certificate)}.
|
* Opens a {@link StrolchTransaction} where the realm retrieved using {@link ComponentContainer#getRealm(Certificate)}.
|
||||||
* This transaction should be used in a try-with-resource clause so it is properly closed.
|
* This transaction should be used in a try-with-resource clause so it is properly closed.
|
||||||
|
@ -206,9 +245,4 @@ public abstract class ExecutionPolicy extends StrolchPolicy {
|
||||||
throws PrivilegeException, Exception {
|
throws PrivilegeException, Exception {
|
||||||
return getContainer().getPrivilegeHandler().runWithResult(StrolchConstants.SYSTEM_USER_AGENT, runnable);
|
return getContainer().getPrivilegeHandler().runWithResult(StrolchConstants.SYSTEM_USER_AGENT, runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void undo() {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import li.strolch.utils.dbc.DBC;
|
||||||
|
|
||||||
public class NoPlanning extends PlanningPolicy {
|
public class NoPlanning extends PlanningPolicy {
|
||||||
|
|
||||||
public static PolicyDef NO_PLANNING = PolicyDef
|
public static PolicyDef DEFAULT_PLANNING = PolicyDef
|
||||||
.valueOf(PlanningPolicy.class.getSimpleName(), "key:DefaultPlanning");
|
.valueOf(PlanningPolicy.class.getSimpleName(), "key:DefaultPlanning");
|
||||||
|
|
||||||
public NoPlanning(StrolchTransaction tx) {
|
public NoPlanning(StrolchTransaction tx) {
|
||||||
|
|
|
@ -52,8 +52,9 @@ public class ReservationExecution extends DurationExecution {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isReserved(Action action) {
|
protected boolean isReserved(Action action) {
|
||||||
|
|
||||||
// get resource
|
// get resource
|
||||||
Resource resource = getResource(action);
|
Resource resource = tx().getResourceFor(action, true);
|
||||||
|
|
||||||
if (!resource.hasParameter(BAG_PARAMETERS, PARAM_RESERVED))
|
if (!resource.hasParameter(BAG_PARAMETERS, PARAM_RESERVED))
|
||||||
throw new StrolchModelException(
|
throw new StrolchModelException(
|
||||||
|
@ -66,55 +67,55 @@ public class ReservationExecution extends DurationExecution {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toExecution(Action action) {
|
public void toExecution(Action action) {
|
||||||
|
switch (action.getType()) {
|
||||||
|
|
||||||
|
case TYPE_RESERVE:
|
||||||
|
case TYPE_RELEASE:
|
||||||
|
|
||||||
// only do if reserve or release
|
|
||||||
boolean isReserve = action.getType().equals(TYPE_RESERVE);
|
boolean isReserve = action.getType().equals(TYPE_RESERVE);
|
||||||
boolean isRelease = action.getType().equals(TYPE_RELEASE);
|
setReservation(action, isReserve);
|
||||||
if (!isReserve && !isRelease) {
|
|
||||||
// otherwise delegate to super class
|
|
||||||
super.toExecution(action);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setReservation(action);
|
|
||||||
|
|
||||||
String realmName = tx().getRealmName();
|
String realmName = tx().getRealmName();
|
||||||
Locator locator = action.getLocator();
|
Locator locator = action.getLocator();
|
||||||
getDelayedExecutionTimer().execute(realmName, getContainer(), locator, 0L);
|
getDelayedExecutionTimer().execute(realmName, getContainer(), locator, 0L);
|
||||||
|
|
||||||
setActionState(action, State.EXECUTION);
|
setActionState(action, State.EXECUTION);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
super.toExecution(action);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toExecuted(Action action) {
|
public void toExecuted(Action action) {
|
||||||
|
|
||||||
// only do if reserve or release
|
switch (action.getType()) {
|
||||||
|
|
||||||
|
case TYPE_RESERVE:
|
||||||
|
case TYPE_RELEASE:
|
||||||
|
|
||||||
boolean isReserve = action.getType().equals(TYPE_RESERVE);
|
boolean isReserve = action.getType().equals(TYPE_RESERVE);
|
||||||
boolean isRelease = action.getType().equals(TYPE_RELEASE);
|
setReservation(action, isReserve);
|
||||||
if (!isReserve && !isRelease) {
|
|
||||||
// otherwise delegate to super class
|
|
||||||
super.toExecuted(action);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setReservation(action);
|
|
||||||
setActionState(action, State.EXECUTED);
|
|
||||||
|
|
||||||
FloatValue value = new FloatValue(isReserve ? 1.0D : 0.0D);
|
FloatValue value = new FloatValue(isReserve ? 1.0D : 0.0D);
|
||||||
action.addChange(new ValueChange<>(System.currentTimeMillis(), value, ""));
|
action.addChange(new ValueChange<>(System.currentTimeMillis(), value, ""));
|
||||||
|
|
||||||
|
setActionState(action, State.EXECUTED);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
super.toExecuted(action);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setReservation(Action action) {
|
private void setReservation(Action action, boolean isReserve) {
|
||||||
|
|
||||||
Resource resource = getResource(action);
|
Resource resource = tx().getResourceFor(action, true);
|
||||||
|
|
||||||
boolean reserved = action.getType().equals(TYPE_RESERVE);
|
|
||||||
|
|
||||||
// release the resource
|
// release the resource
|
||||||
BooleanParameter reservedP = resource.getParameter(BAG_PARAMETERS, PARAM_RESERVED);
|
BooleanParameter reservedP = resource.getParameter(BAG_PARAMETERS, PARAM_RESERVED);
|
||||||
reservedP.setValue(reserved);
|
reservedP.setValue(isReserve);
|
||||||
|
|
||||||
// save changes
|
// save changes
|
||||||
tx().update(resource);
|
tx().update(resource);
|
||||||
|
|
|
@ -36,6 +36,8 @@ public class SimpleExecution extends ExecutionPolicy {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toExecuted(Action action) {
|
public void toExecuted(Action action) {
|
||||||
|
stop();
|
||||||
|
|
||||||
setActionState(action, State.EXECUTED);
|
setActionState(action, State.EXECUTED);
|
||||||
|
|
||||||
FloatValue value = new FloatValue(0.0D);
|
FloatValue value = new FloatValue(0.0D);
|
||||||
|
@ -44,7 +46,8 @@ public class SimpleExecution extends ExecutionPolicy {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toStopped(Action action) {
|
public void toStopped(Action action) {
|
||||||
getDelayedExecutionTimer().cancel(action.getLocator());
|
stop();
|
||||||
|
|
||||||
setActionState(action, State.STOPPED);
|
setActionState(action, State.STOPPED);
|
||||||
|
|
||||||
FloatValue value = new FloatValue(0.0D);
|
FloatValue value = new FloatValue(0.0D);
|
||||||
|
@ -53,7 +56,8 @@ public class SimpleExecution extends ExecutionPolicy {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toError(Action action) {
|
public void toError(Action action) {
|
||||||
getDelayedExecutionTimer().cancel(action.getLocator());
|
stop();
|
||||||
|
|
||||||
setActionState(action, State.ERROR);
|
setActionState(action, State.ERROR);
|
||||||
|
|
||||||
FloatValue value = new FloatValue(0.0D);
|
FloatValue value = new FloatValue(0.0D);
|
||||||
|
@ -68,18 +72,20 @@ public class SimpleExecution extends ExecutionPolicy {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void toError(LogMessage message) {
|
protected void toError(LogMessage message) {
|
||||||
|
stop();
|
||||||
logger.error("Action " + message.getLocator() + " failed because of: " + message.formatMessage());
|
logger.error("Action " + message.getLocator() + " failed because of: " + message.formatMessage());
|
||||||
addMessage(message);
|
addMessage(message);
|
||||||
getExecutionHandler().toError(message.getRealm(), message.getLocator());
|
getController().asyncToError(message.getLocator());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void toWarning(LogMessage message) {
|
protected void toWarning(LogMessage message) {
|
||||||
|
stop();
|
||||||
addMessage(message);
|
addMessage(message);
|
||||||
getExecutionHandler().toWarning(message.getRealm(), message.getLocator());
|
getController().asyncToWarning(message.getLocator());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void undo() {
|
protected void handleStopped() {
|
||||||
logger.error("Can not undo execution policy " + getClass());
|
getDelayedExecutionTimer().cancel(this.actionLoc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,6 @@ public class ToErrorReservationExecution extends ReservationExecution {
|
||||||
@Override
|
@Override
|
||||||
public boolean isExecutable(Action action) {
|
public boolean isExecutable(Action action) {
|
||||||
|
|
||||||
tx().lock(getResource(action));
|
|
||||||
|
|
||||||
if (action.getType().equals(TYPE_RESERVE)) {
|
if (action.getType().equals(TYPE_RESERVE)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -41,14 +39,12 @@ public class ToErrorReservationExecution extends ReservationExecution {
|
||||||
@Override
|
@Override
|
||||||
public void toExecution(Action action) {
|
public void toExecution(Action action) {
|
||||||
|
|
||||||
tx().lock(getResource(action));
|
|
||||||
|
|
||||||
if (action.getType().equals(TYPE_RESERVE) && isReserved(action)) {
|
if (action.getType().equals(TYPE_RESERVE) && isReserved(action)) {
|
||||||
setActionState(action, State.EXECUTION);
|
setActionState(action, State.EXECUTION);
|
||||||
toError(new LogMessage(tx().getRealmName(), tx().getCertificate().getUsername(), action.getLocator(),
|
toError(new LogMessage(tx().getRealmName(), tx().getCertificate().getUsername(), action.getLocator(),
|
||||||
LogSeverity.Error, ResourceBundle.getBundle("strolch-service"),
|
LogSeverity.Error, ResourceBundle.getBundle("strolch-service"),
|
||||||
"execution.policy.reservation.alreadyReserved")
|
"execution.policy.reservation.alreadyReserved")
|
||||||
.value("resourceLoc", getResource(action).getLocator().toString()));
|
.value("resourceLoc", action.getResourceLocator().toString()));
|
||||||
} else {
|
} else {
|
||||||
super.toExecution(action);
|
super.toExecution(action);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
package li.strolch.execution.service;
|
package li.strolch.execution.service;
|
||||||
|
|
||||||
import li.strolch.execution.command.SetActionToPlanningCommand;
|
import li.strolch.execution.ExecutionHandler;
|
||||||
|
import li.strolch.model.State;
|
||||||
import li.strolch.model.activity.Action;
|
import li.strolch.model.activity.Action;
|
||||||
|
import li.strolch.model.activity.Activity;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
import li.strolch.service.LocatorArgument;
|
import li.strolch.service.LocatorArgument;
|
||||||
import li.strolch.service.api.AbstractService;
|
import li.strolch.service.api.AbstractService;
|
||||||
import li.strolch.service.api.ServiceResult;
|
import li.strolch.service.api.ServiceResult;
|
||||||
import li.strolch.service.api.ServiceResultState;
|
import li.strolch.service.api.ServiceResultState;
|
||||||
|
|
||||||
public class SetActionToPlanningService extends AbstractService<LocatorArgument, ServiceResult> {
|
public class ExecuteActionService extends AbstractService<LocatorArgument, ServiceResult> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ServiceResult getResultInstance() {
|
protected ServiceResult getResultInstance() {
|
||||||
|
@ -23,17 +25,27 @@ public class SetActionToPlanningService extends AbstractService<LocatorArgument,
|
||||||
@Override
|
@Override
|
||||||
protected ServiceResult internalDoService(LocatorArgument arg) throws Exception {
|
protected ServiceResult internalDoService(LocatorArgument arg) throws Exception {
|
||||||
|
|
||||||
|
String realm;
|
||||||
|
Activity activity;
|
||||||
try (StrolchTransaction tx = openArgOrUserTx(arg)) {
|
try (StrolchTransaction tx = openArgOrUserTx(arg)) {
|
||||||
|
realm = tx.getRealmName();
|
||||||
|
|
||||||
|
tx.lock(arg.locator.trim(3));
|
||||||
Action action = tx.findElement(arg.locator);
|
Action action = tx.findElement(arg.locator);
|
||||||
|
|
||||||
SetActionToPlanningCommand command = new SetActionToPlanningCommand(getContainer(), tx);
|
// this is so we can re-execute stopped actions
|
||||||
command.setAction(action);
|
if (action.getState() == State.STOPPED) {
|
||||||
tx.addCommand(command);
|
action.setState(State.EXECUTABLE);
|
||||||
|
|
||||||
|
tx.update(action.getRootElement());
|
||||||
tx.commitOnClose();
|
tx.commitOnClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activity = action.getRootElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
getComponent(ExecutionHandler.class).toExecution(realm, activity);
|
||||||
|
|
||||||
return ServiceResult.success();
|
return ServiceResult.success();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,144 +0,0 @@
|
||||||
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"));
|
|
||||||
|
|
||||||
String realm;
|
|
||||||
try (StrolchTransaction tx = openArgOrUserTx(arg)) {
|
|
||||||
realm = tx.getRealmName();
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
ExecutionHandler executionHandler = getContainer().getComponent(ExecutionHandler.class);
|
|
||||||
executionHandler.triggerExecution(realm);
|
|
||||||
|
|
||||||
return ServiceResult.success();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -25,9 +25,11 @@ public class SetActionToClosedService extends AbstractService<LocatorArgument, S
|
||||||
|
|
||||||
try (StrolchTransaction tx = openArgOrUserTx(arg)) {
|
try (StrolchTransaction tx = openArgOrUserTx(arg)) {
|
||||||
|
|
||||||
|
tx.lock(arg.locator.trim(3));
|
||||||
Action action = tx.findElement(arg.locator);
|
Action action = tx.findElement(arg.locator);
|
||||||
|
tx.lock(action.getResourceLocator());
|
||||||
|
|
||||||
SetActionToClosedCommand command = new SetActionToClosedCommand(getContainer(), tx);
|
SetActionToClosedCommand command = new SetActionToClosedCommand(tx);
|
||||||
command.setAction(action);
|
command.setAction(action);
|
||||||
tx.addCommand(command);
|
tx.addCommand(command);
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,12 @@ public class SetActionToCreatedService extends AbstractService<LocatorArgument,
|
||||||
|
|
||||||
try (StrolchTransaction tx = openArgOrUserTx(arg)) {
|
try (StrolchTransaction tx = openArgOrUserTx(arg)) {
|
||||||
|
|
||||||
|
tx.lock(arg.locator.trim(3));
|
||||||
Action action = tx.findElement(arg.locator);
|
Action action = tx.findElement(arg.locator);
|
||||||
|
if (action.hasResourceDefined())
|
||||||
|
tx.lock(action.getResourceLocator());
|
||||||
|
|
||||||
SetActionToCreatedCommand command = new SetActionToCreatedCommand(getContainer(), tx);
|
SetActionToCreatedCommand command = new SetActionToCreatedCommand(tx);
|
||||||
command.setAction(action);
|
command.setAction(action);
|
||||||
tx.addCommand(command);
|
tx.addCommand(command);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package li.strolch.execution.service;
|
package li.strolch.execution.service;
|
||||||
|
|
||||||
|
import li.strolch.execution.Controller;
|
||||||
|
import li.strolch.execution.ExecutionHandler;
|
||||||
import li.strolch.execution.command.SetActionToErrorCommand;
|
import li.strolch.execution.command.SetActionToErrorCommand;
|
||||||
import li.strolch.model.activity.Action;
|
import li.strolch.model.activity.Action;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
|
@ -25,11 +27,20 @@ public class SetActionToErrorService extends AbstractService<LocatorArgument, Se
|
||||||
|
|
||||||
try (StrolchTransaction tx = openArgOrUserTx(arg)) {
|
try (StrolchTransaction tx = openArgOrUserTx(arg)) {
|
||||||
|
|
||||||
|
tx.lock(arg.locator.trim(3));
|
||||||
Action action = tx.findElement(arg.locator);
|
Action action = tx.findElement(arg.locator);
|
||||||
|
tx.lock(action.getResourceLocator());
|
||||||
|
|
||||||
SetActionToErrorCommand command = new SetActionToErrorCommand(getContainer(), tx);
|
ExecutionHandler executionHandler = getComponent(ExecutionHandler.class);
|
||||||
|
Controller controller = executionHandler.getController(tx.getRealmName(), action.getRootElement());
|
||||||
|
if (controller != null) {
|
||||||
|
controller.toError(action.getLocator());
|
||||||
|
} else {
|
||||||
|
|
||||||
|
SetActionToErrorCommand command = new SetActionToErrorCommand(tx);
|
||||||
command.setAction(action);
|
command.setAction(action);
|
||||||
tx.addCommand(command);
|
tx.addCommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
tx.commitOnClose();
|
tx.commitOnClose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package li.strolch.execution.service;
|
package li.strolch.execution.service;
|
||||||
|
|
||||||
|
import li.strolch.execution.Controller;
|
||||||
|
import li.strolch.execution.ExecutionHandler;
|
||||||
import li.strolch.execution.command.SetActionToExecutedCommand;
|
import li.strolch.execution.command.SetActionToExecutedCommand;
|
||||||
import li.strolch.model.activity.Action;
|
import li.strolch.model.activity.Action;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
|
@ -25,11 +27,19 @@ public class SetActionToExecutedService extends AbstractService<LocatorArgument,
|
||||||
|
|
||||||
try (StrolchTransaction tx = openArgOrUserTx(arg)) {
|
try (StrolchTransaction tx = openArgOrUserTx(arg)) {
|
||||||
|
|
||||||
|
tx.lock(arg.locator.trim(3));
|
||||||
Action action = tx.findElement(arg.locator);
|
Action action = tx.findElement(arg.locator);
|
||||||
|
tx.lock(action.getResourceLocator());
|
||||||
|
|
||||||
SetActionToExecutedCommand command = new SetActionToExecutedCommand(getContainer(), tx);
|
ExecutionHandler executionHandler = getComponent(ExecutionHandler.class);
|
||||||
|
Controller controller = executionHandler.getController(tx.getRealmName(), action.getRootElement());
|
||||||
|
if (controller != null) {
|
||||||
|
controller.toExecuted(action.getLocator());
|
||||||
|
} else {
|
||||||
|
SetActionToExecutedCommand command = new SetActionToExecutedCommand(tx);
|
||||||
command.setAction(action);
|
command.setAction(action);
|
||||||
tx.addCommand(command);
|
tx.addCommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
tx.commitOnClose();
|
tx.commitOnClose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,12 @@ public class SetActionToPlannedService extends AbstractService<LocatorArgument,
|
||||||
|
|
||||||
try (StrolchTransaction tx = openArgOrUserTx(arg)) {
|
try (StrolchTransaction tx = openArgOrUserTx(arg)) {
|
||||||
|
|
||||||
|
tx.lock(arg.locator.trim(3));
|
||||||
Action action = tx.findElement(arg.locator);
|
Action action = tx.findElement(arg.locator);
|
||||||
|
if (!action.hasResourceDefined())
|
||||||
|
return ServiceResult.error("Resource not defined for " + action.getLocator());
|
||||||
|
|
||||||
SetActionToPlannedCommand command = new SetActionToPlannedCommand(getContainer(), tx);
|
SetActionToPlannedCommand command = new SetActionToPlannedCommand(tx);
|
||||||
command.setAction(action);
|
command.setAction(action);
|
||||||
tx.addCommand(command);
|
tx.addCommand(command);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package li.strolch.execution.service;
|
package li.strolch.execution.service;
|
||||||
|
|
||||||
|
import li.strolch.execution.Controller;
|
||||||
|
import li.strolch.execution.ExecutionHandler;
|
||||||
import li.strolch.execution.command.SetActionToStoppedCommand;
|
import li.strolch.execution.command.SetActionToStoppedCommand;
|
||||||
import li.strolch.model.activity.Action;
|
import li.strolch.model.activity.Action;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
|
@ -25,11 +27,19 @@ public class SetActionToStoppedService extends AbstractService<LocatorArgument,
|
||||||
|
|
||||||
try (StrolchTransaction tx = openArgOrUserTx(arg)) {
|
try (StrolchTransaction tx = openArgOrUserTx(arg)) {
|
||||||
|
|
||||||
|
tx.lock(arg.locator.trim(3));
|
||||||
Action action = tx.findElement(arg.locator);
|
Action action = tx.findElement(arg.locator);
|
||||||
|
tx.lock(action.getResourceLocator());
|
||||||
|
|
||||||
SetActionToStoppedCommand command = new SetActionToStoppedCommand(getContainer(), tx);
|
ExecutionHandler executionHandler = getComponent(ExecutionHandler.class);
|
||||||
|
Controller controller = executionHandler.getController(tx.getRealmName(), action.getRootElement());
|
||||||
|
if (controller != null) {
|
||||||
|
controller.toStopped(action.getLocator());
|
||||||
|
} else {
|
||||||
|
SetActionToStoppedCommand command = new SetActionToStoppedCommand(tx);
|
||||||
command.setAction(action);
|
command.setAction(action);
|
||||||
tx.addCommand(command);
|
tx.addCommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
tx.commitOnClose();
|
tx.commitOnClose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package li.strolch.execution.service;
|
package li.strolch.execution.service;
|
||||||
|
|
||||||
|
import li.strolch.execution.Controller;
|
||||||
|
import li.strolch.execution.ExecutionHandler;
|
||||||
import li.strolch.execution.command.SetActionToWarningCommand;
|
import li.strolch.execution.command.SetActionToWarningCommand;
|
||||||
import li.strolch.model.activity.Action;
|
import li.strolch.model.activity.Action;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
|
@ -25,11 +27,19 @@ public class SetActionToWarningService extends AbstractService<LocatorArgument,
|
||||||
|
|
||||||
try (StrolchTransaction tx = openArgOrUserTx(arg)) {
|
try (StrolchTransaction tx = openArgOrUserTx(arg)) {
|
||||||
|
|
||||||
|
tx.lock(arg.locator.trim(3));
|
||||||
Action action = tx.findElement(arg.locator);
|
Action action = tx.findElement(arg.locator);
|
||||||
|
tx.lock(action.getResourceLocator());
|
||||||
|
|
||||||
SetActionToWarningCommand command = new SetActionToWarningCommand(getContainer(), tx);
|
ExecutionHandler executionHandler = getComponent(ExecutionHandler.class);
|
||||||
|
Controller controller = executionHandler.getController(tx.getRealmName(), action.getRootElement());
|
||||||
|
if (controller != null) {
|
||||||
|
controller.toWarning(action.getLocator());
|
||||||
|
} else {
|
||||||
|
SetActionToWarningCommand command = new SetActionToWarningCommand(tx);
|
||||||
command.setAction(action);
|
command.setAction(action);
|
||||||
tx.addCommand(command);
|
tx.addCommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
tx.commitOnClose();
|
tx.commitOnClose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
package li.strolch.execution.service;
|
|
||||||
|
|
||||||
import static li.strolch.utils.helper.StringHelper.isEmpty;
|
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
|
||||||
|
|
||||||
import li.strolch.exception.StrolchException;
|
|
||||||
import li.strolch.execution.ExecutionHandler;
|
|
||||||
import li.strolch.model.State;
|
|
||||||
import li.strolch.model.activity.IActivityElement;
|
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
|
||||||
import li.strolch.runtime.StrolchConstants;
|
|
||||||
import li.strolch.service.LocatorArgument;
|
|
||||||
import li.strolch.service.api.AbstractService;
|
|
||||||
import li.strolch.service.api.ServiceResult;
|
|
||||||
import li.strolch.service.api.ServiceResultState;
|
|
||||||
|
|
||||||
public class SetToExecutionService extends AbstractService<LocatorArgument, ServiceResult> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ServiceResult getResultInstance() {
|
|
||||||
return new ServiceResult(ServiceResultState.FAILED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LocatorArgument getArgumentInstance() {
|
|
||||||
return new LocatorArgument();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ServiceResult internalDoService(LocatorArgument arg) throws Exception {
|
|
||||||
|
|
||||||
String realm = isEmpty(arg.realm) ? StrolchConstants.DEFAULT_REALM : arg.realm;
|
|
||||||
|
|
||||||
try (StrolchTransaction tx = openTx(realm)) {
|
|
||||||
tx.lock(arg.locator);
|
|
||||||
|
|
||||||
IActivityElement element = tx.findElement(arg.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(realm, arg.locator);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ServiceResult.success();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,6 +4,8 @@ import static li.strolch.service.I18nService.i18nService;
|
||||||
|
|
||||||
import li.strolch.execution.ExecutionHandler;
|
import li.strolch.execution.ExecutionHandler;
|
||||||
import li.strolch.execution.ExecutionHandlerState;
|
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.runtime.StrolchConstants;
|
||||||
import li.strolch.service.LocatorArgument;
|
import li.strolch.service.LocatorArgument;
|
||||||
import li.strolch.service.StrolchRootElementResult;
|
import li.strolch.service.StrolchRootElementResult;
|
||||||
|
@ -36,7 +38,12 @@ public class StartActivityExecutionService extends AbstractService<LocatorArgume
|
||||||
"ExecutionHandler is not running, can not start new jobs!")
|
"ExecutionHandler is not running, can not start new jobs!")
|
||||||
.i18n(i18nService, "execution.handler.invalidState", "state", executionHandlerState);
|
.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.toExecution(realm, activity);
|
||||||
|
|
||||||
return ServiceResult.success();
|
return ServiceResult.success();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
execution.handler.invalidState=ExecutionHandler has state {state}, can not start new jobs!
|
execution.handler.invalidState=ExecutionHandler has state {state}, can not start new jobs!
|
||||||
execution.handler.failed.execution=Failed to set to execution due to {reason}
|
execution.handler.failed.execution=Failed to set to execution due to {reason}
|
||||||
execution.handler.failed.executed=Failed to set to execution due to {reason}
|
execution.handler.failed.executed=Failed to set to executed due to {reason}
|
||||||
execution.handler.failed.stopped=Failed to set to execution due to {reason}
|
execution.handler.failed.stopped=Failed to set to execution due to {reason}
|
||||||
execution.handler.failed.error=Failed to set to execution due to {reason}
|
execution.handler.failed.error=Failed to set to execution due to {reason}
|
||||||
execution.handler.failed.warning=Failed to set to execution due to {reason}
|
execution.handler.failed.warning=Failed to set to execution due to {reason}
|
||||||
|
|
|
@ -23,9 +23,13 @@ import li.strolch.testbase.runtime.RuntimeMock;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class ReservationExecutionTest extends RuntimeMock {
|
public class ReservationExecutionTest extends RuntimeMock {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(ReservationExecutionTest.class);
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() {
|
public void before() {
|
||||||
mockRuntime(new File("target/" + ReservationExecutionTest.class.getName()),
|
mockRuntime(new File("target/" + ReservationExecutionTest.class.getName()),
|
||||||
|
@ -83,6 +87,7 @@ public class ReservationExecutionTest extends RuntimeMock {
|
||||||
// verify that the machine is not reserved
|
// verify that the machine is not reserved
|
||||||
Resource machine = tx.getResourceBy("Machine", "machine1");
|
Resource machine = tx.getResourceBy("Machine", "machine1");
|
||||||
BooleanParameter reservedP = machine.getParameter(BAG_PARAMETERS, PARAM_RESERVED);
|
BooleanParameter reservedP = machine.getParameter(BAG_PARAMETERS, PARAM_RESERVED);
|
||||||
|
logger.info("Checking machine is not reserved initially");
|
||||||
assertFalse(reservedP.getValue());
|
assertFalse(reservedP.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +110,7 @@ public class ReservationExecutionTest extends RuntimeMock {
|
||||||
// verify that the machine is reserved
|
// verify that the machine is reserved
|
||||||
Resource machine = tx.getResourceBy("Machine", "machine1");
|
Resource machine = tx.getResourceBy("Machine", "machine1");
|
||||||
BooleanParameter reservedP = machine.getParameter(BAG_PARAMETERS, PARAM_RESERVED);
|
BooleanParameter reservedP = machine.getParameter(BAG_PARAMETERS, PARAM_RESERVED);
|
||||||
|
logger.info("Checking machine is reserved, after reserve action is executed.");
|
||||||
assertTrue(reservedP.getValue());
|
assertTrue(reservedP.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,6 +126,7 @@ public class ReservationExecutionTest extends RuntimeMock {
|
||||||
// verify that the machine is not reserved anymore
|
// verify that the machine is not reserved anymore
|
||||||
Resource machine = tx.getResourceBy("Machine", "machine1");
|
Resource machine = tx.getResourceBy("Machine", "machine1");
|
||||||
BooleanParameter reservedP = machine.getParameter(BAG_PARAMETERS, PARAM_RESERVED);
|
BooleanParameter reservedP = machine.getParameter(BAG_PARAMETERS, PARAM_RESERVED);
|
||||||
|
logger.info("Checking machine is released, after release action is executed.");
|
||||||
assertFalse(reservedP.getValue());
|
assertFalse(reservedP.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,10 @@ public class SynchronizedCollections {
|
||||||
@Override
|
@Override
|
||||||
public List<U> getList(T t) {
|
public List<U> getList(T t) {
|
||||||
synchronized (this.mutex) {
|
synchronized (this.mutex) {
|
||||||
return new SynchronizedList<>(this.m.getList(t), this.mutex);
|
List<U> list = this.m.getList(t);
|
||||||
|
if (list == null)
|
||||||
|
return null;
|
||||||
|
return new SynchronizedList<>(list, this.mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +197,10 @@ public class SynchronizedCollections {
|
||||||
@Override
|
@Override
|
||||||
public Map<U, V> getMap(T t) {
|
public Map<U, V> getMap(T t) {
|
||||||
synchronized (this.mutex) {
|
synchronized (this.mutex) {
|
||||||
return new SynchronizedMap<>(this.m.getMap(t), this.mutex);
|
Map<U, V> map = this.m.getMap(t);
|
||||||
|
if (map == null)
|
||||||
|
return null;
|
||||||
|
return new SynchronizedMap<>(map, this.mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,7 +364,10 @@ public class SynchronizedCollections {
|
||||||
@Override
|
@Override
|
||||||
public Set<U> getSet(T t) {
|
public Set<U> getSet(T t) {
|
||||||
synchronized (this.mutex) {
|
synchronized (this.mutex) {
|
||||||
return new SynchronizedSet<>(this.m.getSet(t), this.mutex);
|
Set<U> set = this.m.getSet(t);
|
||||||
|
if (set == null)
|
||||||
|
return null;
|
||||||
|
return new SynchronizedSet<>(set, this.mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -463,6 +463,19 @@ public class ObjectFilter {
|
||||||
return this.cache.containsElement(key, objectKey);
|
return this.cache.containsElement(key, objectKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows clearing the object cache for an element
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* the key under which it was registered
|
||||||
|
* @param objectKey
|
||||||
|
* the objectKey
|
||||||
|
*/
|
||||||
|
public void removeObjectCache(String key, Object objectKey) {
|
||||||
|
this.keySet.remove(key);
|
||||||
|
this.cache.removeElement(key, objectKey);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all objects that were registered under the given key and that have as a resulting final action an addition.
|
* Get all objects that were registered under the given key and that have as a resulting final action an addition.
|
||||||
*
|
*
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li class="active"><a href="api.html">API</a></li>
|
<li class="active"><a href="api.html">API</a></li>
|
||||||
<li><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li class="active"><a href="development.html">Development</a></li>
|
<li class="active"><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li class="active"><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li class="active"><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li class="active"><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li class="active"><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li class="active"><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li class="active"><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li class="active"><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li class="active"><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li class="active"><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li class="active"><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li class="active"><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li class="active"><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li class="active"><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li class="active"><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li class="active"><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li class="active"><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li class="active"><a href="downloads.html">Downloads</a></li>
|
<li class="active"><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li class="active"><a href="index.html">Overview</a></li>
|
<li class="active"><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li class="active"><a href="index.html">Overview</a></li>
|
<li class="active"><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li><a href="documentation.html">Documentation</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="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -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">© 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>
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li><a href="documentation.html">Documentation</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 class="active"><a href="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li><a href="documentation.html">Documentation</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 class="active"><a href="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li><a href="documentation.html">Documentation</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 class="active"><a href="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<li><a href="index.html">Overview</a></li>
|
<li><a href="index.html">Overview</a></li>
|
||||||
<li><a href="api.html">API</a></li>
|
<li><a href="api.html">API</a></li>
|
||||||
<li><a href="documentation.html">Documentation</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 class="active"><a href="tutorial.html">Tutorial</a></li>
|
||||||
<li><a href="downloads.html">Downloads</a></li>
|
<li><a href="downloads.html">Downloads</a></li>
|
||||||
<li><a href="development.html">Development</a></li>
|
<li><a href="development.html">Development</a></li>
|
||||||
|
|
7
pom.xml
7
pom.xml
|
@ -97,7 +97,6 @@
|
||||||
<!-- test time dependencies -->
|
<!-- test time dependencies -->
|
||||||
<junit.version>4.12</junit.version>
|
<junit.version>4.12</junit.version>
|
||||||
<hamcrest.version>2.1</hamcrest.version>
|
<hamcrest.version>2.1</hamcrest.version>
|
||||||
<mockito.version>2.28.2</mockito.version>
|
|
||||||
|
|
||||||
<!-- maven plug-in dependencies -->
|
<!-- maven plug-in dependencies -->
|
||||||
<maven-scm-plugin.version>1.11.2</maven-scm-plugin.version>
|
<maven-scm-plugin.version>1.11.2</maven-scm-plugin.version>
|
||||||
|
@ -328,12 +327,6 @@
|
||||||
<version>${hamcrest.version}</version>
|
<version>${hamcrest.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.mockito</groupId>
|
|
||||||
<artifactId>mockito-core</artifactId>
|
|
||||||
<version>${mockito.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
Loading…
Reference in New Issue