use of io.automatiko.engine.services.time.TimerInstance in project automatiko-engine by automatiko-io.
the class WorkflowProcessInstanceImpl method configureSLA.
@Override
public void configureSLA() {
String slaDueDateExpression = (String) getProcess().getMetaData().get(CUSTOM_SLA_DUE_DATE);
if (slaDueDateExpression != null) {
TimerInstance timer = configureSLATimer(slaDueDateExpression);
if (timer != null) {
this.slaTimerId = timer.getId();
this.slaDueDate = new Date(System.currentTimeMillis() + timer.getDelay());
this.slaCompliance = SLA_PENDING;
logger.debug("SLA for process instance {} is PENDING with due date {}", this.getId(), this.slaDueDate);
}
}
}
use of io.automatiko.engine.services.time.TimerInstance in project automatiko-engine by automatiko-io.
the class WorkflowProcessInstanceImpl method configureSLATimer.
public TimerInstance configureSLATimer(String slaDueDateExpression) {
// setup SLA if provided
slaDueDateExpression = resolveVariable(slaDueDateExpression);
if (slaDueDateExpression == null || slaDueDateExpression.trim().isEmpty()) {
logger.debug("Sla due date expression resolved to no value '{}'", slaDueDateExpression);
return null;
}
logger.debug("SLA due date is set to {}", slaDueDateExpression);
long duration = DateTimeUtils.parseDuration(slaDueDateExpression);
TimerInstance timerInstance = new TimerInstance();
timerInstance.setTimerId(-1);
timerInstance.setDelay(duration);
timerInstance.setPeriod(0);
if (useTimerSLATracking()) {
String parentProcessInstanceId = getParentProcessInstanceId();
if (parentProcessInstanceId != null && !parentProcessInstanceId.isEmpty()) {
parentProcessInstanceId += ":";
} else {
parentProcessInstanceId = "";
}
String id = parentProcessInstanceId + getId();
ProcessInstanceJobDescription description = ProcessInstanceJobDescription.of(-1L, DurationExpirationTime.after(duration), id, getProcessId(), getProcess().getVersion());
timerInstance.setId(getProcessRuntime().getJobsService().scheduleProcessInstanceJob(description));
}
return timerInstance;
}
use of io.automatiko.engine.services.time.TimerInstance in project automatiko-engine by automatiko-io.
the class StateBasedNodeInstance method configureSla.
@Override
protected void configureSla() {
String slaDueDateExpression = (String) getNode().getMetaData().get("customSLADueDate");
if (slaDueDateExpression != null) {
TimerInstance timer = ((WorkflowProcessInstanceImpl) getProcessInstance()).configureSLATimer(slaDueDateExpression);
if (timer != null) {
this.slaTimerId = timer.getId();
this.slaDueDate = new Date(System.currentTimeMillis() + timer.getDelay());
this.slaCompliance = io.automatiko.engine.api.runtime.process.ProcessInstance.SLA_PENDING;
logger.debug("SLA for node instance {} is PENDING with due date {}", this.getId(), this.slaDueDate);
addTimerListener();
}
}
}
use of io.automatiko.engine.services.time.TimerInstance in project automatiko-engine by automatiko-io.
the class EventNodeInstance method signalEvent.
public void signalEvent(String type, Object event) {
if ("timerTriggered".equals(type)) {
TimerInstance timerInstance = (TimerInstance) event;
if (timerInstance.getId().equals(slaTimerId)) {
handleSLAViolation();
}
} else if (("slaViolation:" + getId()).equals(type)) {
handleSLAViolation();
} else {
String variableName = getEventNode().getVariableName();
if (!getEventNode().getOutAssociations().isEmpty()) {
for (DataAssociation association : getEventNode().getOutAssociations()) {
if (association.getAssignments() == null || association.getAssignments().isEmpty()) {
VariableScopeInstance variableScopeInstance = (VariableScopeInstance) resolveContextInstance(VARIABLE_SCOPE, association.getTarget());
if (variableScopeInstance != null) {
Variable varDef = variableScopeInstance.getVariableScope().findVariable(association.getTarget());
DataType dataType = varDef.getType();
// exclude java.lang.Object as it is considered unknown type
if (!dataType.getStringType().endsWith("java.lang.Object") && !dataType.getStringType().endsWith("Object") && event instanceof String) {
event = dataType.readValue((String) event);
} else {
variableScopeInstance.getVariableScope().validateVariable(getProcessInstance().getProcessName(), association.getTarget(), event);
}
variableScopeInstance.setVariable(this, association.getTarget(), event);
} else {
String output = association.getSources().get(0);
String target = association.getTarget();
Matcher matcher = PatternConstants.PARAMETER_MATCHER.matcher(target);
if (matcher.find()) {
String paramName = matcher.group(1);
String expression = VariableUtil.transformDotNotation(paramName, output);
NodeInstanceResolverFactory resolver = new NodeInstanceResolverFactory(this);
resolver.addExtraParameters(Collections.singletonMap(association.getSources().get(0), event));
Serializable compiled = MVEL.compileExpression(expression);
MVEL.executeExpression(compiled, resolver);
String varName = VariableUtil.nameFromDotNotation(paramName);
variableScopeInstance = (VariableScopeInstance) resolveContextInstance(VARIABLE_SCOPE, varName);
variableScopeInstance.setVariable(this, varName, variableScopeInstance.getVariable(varName));
} else {
logger.warn("Could not find variable scope for variable {}", association.getTarget());
logger.warn("when trying to complete start node {}", getEventNode().getName());
logger.warn("Continuing without setting variable.");
}
}
} else {
Object data = event;
association.getAssignments().stream().forEach(assignment -> handleAssignment(assignment, data));
}
}
} else if (variableName != null) {
VariableScopeInstance variableScopeInstance = (VariableScopeInstance) resolveContextInstance(VariableScope.VARIABLE_SCOPE, variableName);
if (variableScopeInstance != null) {
EventTransformer transformer = getEventNode().getEventTransformer();
if (transformer != null) {
event = transformer.transformEvent(event);
}
variableScopeInstance.setVariable(this, variableName, event);
} else {
String output = "event";
Matcher matcher = PatternConstants.PARAMETER_MATCHER.matcher(variableName);
if (matcher.find()) {
String paramName = matcher.group(1);
String expression = VariableUtil.transformDotNotation(paramName, output);
NodeInstanceResolverFactory resolver = new NodeInstanceResolverFactory(this);
resolver.addExtraParameters(Collections.singletonMap("event", event));
Serializable compiled = MVEL.compileExpression(expression);
MVEL.executeExpression(compiled, resolver);
String varName = VariableUtil.nameFromDotNotation(paramName);
variableScopeInstance = (VariableScopeInstance) resolveContextInstance(VARIABLE_SCOPE, varName);
variableScopeInstance.setVariable(this, varName, variableScopeInstance.getVariable(varName));
} else {
logger.warn("Could not find variable scope for variable {}", variableName);
logger.warn("when trying to complete start node {}", getEventNode().getName());
logger.warn("Continuing without setting variable.");
}
}
}
triggerCompleted();
}
}
use of io.automatiko.engine.services.time.TimerInstance in project automatiko-engine by automatiko-io.
the class WorkflowProcessInstanceImpl method signalEvent.
@Override
@SuppressWarnings("unchecked")
public void signalEvent(String type, Object event) {
logger.debug("Signal {} received with data {} in process instance {}", type, event, getId());
synchronized (this) {
if (getState() != ProcessInstance.STATE_ACTIVE) {
return;
}
InternalProcessRuntime processRuntime = getProcessRuntime();
processRuntime.getProcessEventSupport().fireBeforeProcessSignaled(type, event, this, processRuntime);
if ("timerTriggered".equals(type)) {
TimerInstance timer = (TimerInstance) event;
if (timer.getId().equals(slaTimerId)) {
handleSLAViolation();
// no need to pass the event along as it was purely for SLA tracking
return;
}
}
if ("slaViolation".equals(type)) {
handleSLAViolation();
// no need to pass the event along as it was purely for SLA tracking
return;
}
List<NodeInstance> currentView = new ArrayList<>(this.nodeInstances);
try {
this.activatingNodeIds = new ArrayList<>();
List<EventListener> listeners = eventListeners.get(type);
if (listeners != null) {
for (EventListener listener : listeners) {
listener.signalEvent(type, event);
}
}
listeners = externalEventListeners.get(type);
if (listeners != null) {
for (EventListener listener : listeners) {
listener.signalEvent(type, event);
}
}
if (!type.startsWith("Compensation")) {
for (Node node : getWorkflowProcess().getNodes()) {
if (node instanceof EventNodeInterface && ((EventNodeInterface) node).acceptsEvent(type, event, getResolver(node, currentView))) {
if (node instanceof EventNode && ((EventNode) node).getFrom() == null) {
EventNodeInstance eventNodeInstance = (EventNodeInstance) getNodeInstance(node);
eventNodeInstance.signalEvent(type, event);
} else {
if (node instanceof EventSubProcessNode && (resolveVariables(((EventSubProcessNode) node).getEvents()).contains(type))) {
EventSubProcessNodeInstance eventNodeInstance = (EventSubProcessNodeInstance) getNodeInstance(node);
eventNodeInstance.signalEvent(type, event);
} else {
List<NodeInstance> nodeInstances = getNodeInstances(node.getId(), currentView);
if (nodeInstances != null && !nodeInstances.isEmpty()) {
for (NodeInstance nodeInstance : nodeInstances) {
((EventNodeInstanceInterface) nodeInstance).signalEvent(type, event);
}
}
}
}
} else if (node instanceof StartNode && ((StartNode) node).getTriggers() != null) {
boolean accepted = ((StartNode) node).getTriggers().stream().filter(EventTrigger.class::isInstance).anyMatch(t -> ((EventTrigger) t).getEventFilters().stream().anyMatch(e -> e.acceptsEvent(type, event)));
if (accepted && node.getMetaData().get("acceptStartSignal") != null) {
StartNodeInstance startNodeInstance = (StartNodeInstance) getNodeInstance(node);
startNodeInstance.signalEvent(type, event);
}
}
}
if (((io.automatiko.engine.workflow.process.core.WorkflowProcess) getWorkflowProcess()).isDynamic()) {
for (Node node : getWorkflowProcess().getNodes()) {
if (node.hasMatchingEventListner(type) && node.getIncomingConnections().isEmpty()) {
NodeInstance nodeInstance = getNodeInstance(node);
if (nodeInstance != null) {
if (event != null) {
Map<String, Object> dynamicParams = new HashMap<>(getVariables());
if (event instanceof Map) {
dynamicParams.putAll((Map<String, Object>) event);
} else if (event instanceof WorkflowProcessInstance) {
// ignore variables of process instance type
} else {
dynamicParams.put("Data", event);
}
nodeInstance.setDynamicParameters(dynamicParams);
}
nodeInstance.trigger(null, io.automatiko.engine.workflow.process.core.Node.CONNECTION_DEFAULT_TYPE);
}
} else if (this instanceof ExecutableProcessInstance && node instanceof CompositeNode) {
Optional<NodeInstance> instance = this.nodeInstances.stream().filter(ni -> ni.getNodeId() == node.getId()).findFirst();
instance.ifPresent(n -> ((CompositeNodeInstance) n).signalEvent(type, event));
}
}
}
}
} finally {
processRuntime.getProcessEventSupport().fireAfterProcessSignaled(type, event, this, processRuntime);
if (this.activatingNodeIds != null) {
this.activatingNodeIds.clear();
this.activatingNodeIds = null;
}
}
}
}
Aggregations