use of io.automatiko.engine.workflow.process.instance.node.StateBasedNodeInstance in project automatiko-engine by automatiko-io.
the class ProcessInstanceMarshaller method importProcessInstance.
@SuppressWarnings({ "rawtypes", "unchecked" })
public ProcessInstance importProcessInstance(ExportedProcessInstance<?> instance, Process process) {
List<Map<String, String>> timers = instance.convertTimers();
WorkflowProcessInstance wpi = importWorkflowProcessInstance((String) instance.getHeader(), (String) instance.getInstance(), timers, process);
Model model = ((AbstractProcess) process).createModel();
model.fromMap(wpi.getVariables());
ProcessInstance processInstance = ((AbstractProcess) process).createInstance(wpi, model, 1);
if (timers != null && !timers.isEmpty()) {
String parentProcessInstanceId = wpi.getParentProcessInstanceId();
if (parentProcessInstanceId != null && !parentProcessInstanceId.isEmpty()) {
parentProcessInstanceId += ":";
} else {
parentProcessInstanceId = "";
}
JobsService jobService = ((WorkflowProcessInstanceImpl) wpi).getProcessRuntime().getJobsService();
Collection<io.automatiko.engine.workflow.process.instance.NodeInstance> nodes = ((WorkflowProcessInstanceImpl) wpi).getNodeInstances(true);
// keeps iterator for statebased node instance timers
Map<String, Iterator<Timer>> nodeInstanceTimers = new LinkedHashMap<>();
for (Map<String, String> timer : timers) {
String nodeInstanceId = timer.get("nodeInstanceId");
for (io.automatiko.engine.workflow.process.instance.NodeInstance ni : nodes) {
if (ni.getId().equals(nodeInstanceId)) {
ExpirationTime expirationTime = null;
long timerNodeId = 0;
if (((NodeInstanceImpl) ni).getRetryJobId() != null && ((NodeInstanceImpl) ni).getRetryJobId().equals(timer.get("timerId"))) {
jobService.scheduleProcessInstanceJob(ProcessInstanceJobDescription.of(timer.get("timerId"), ni.getNodeId(), "retry:" + ni.getId(), expirationTime, ((NodeInstanceImpl) ni).getProcessInstanceIdWithParent(), ni.getProcessInstance().getRootProcessInstanceId(), ni.getProcessInstance().getProcessId(), ni.getProcessInstance().getProcess().getVersion(), ni.getProcessInstance().getRootProcessId()));
break;
} else if (ni instanceof TimerNodeInstance) {
TimerNodeInstance nodeInstance = (TimerNodeInstance) ni;
timerNodeId = nodeInstance.getTimerNode().getTimer().getId();
expirationTime = nodeInstance.createTimerInstance(nodeInstance.getTimerNode().getTimer());
expirationTime.reset(ZonedDateTime.parse(timer.get("scheduledAt")));
} else if (ni instanceof StateBasedNodeInstance) {
StateBasedNodeInstance nodeInstance = (StateBasedNodeInstance) ni;
if (nodeInstance.getTimerInstances().contains(timer.get("timerId"))) {
Iterator<Timer> it = nodeInstanceTimers.computeIfAbsent(nodeInstanceId, k -> nodeInstance.getEventBasedNode().getTimers().keySet().iterator());
expirationTime = nodeInstance.createTimerInstance(it.next());
expirationTime.reset(ZonedDateTime.parse(timer.get("scheduledAt")));
}
}
// lastly schedule timer on calculated expiration time
jobService.scheduleProcessInstanceJob(ProcessInstanceJobDescription.of(timer.get("timerId"), timerNodeId, expirationTime, ((NodeInstanceImpl) ni).getProcessInstanceIdWithParent(), wpi.getRootProcessInstanceId(), wpi.getProcessId(), wpi.getProcess().getVersion(), wpi.getRootProcessId()));
break;
}
}
}
}
return processInstance;
}
use of io.automatiko.engine.workflow.process.instance.node.StateBasedNodeInstance in project automatiko-engine by automatiko-io.
the class ProcessInstanceMarshaller method exportProcessInstance.
public ExportedProcessInstance<?> exportProcessInstance(ProcessInstance<?> processInstance) {
io.automatiko.engine.api.runtime.process.ProcessInstance pi = ((AbstractProcessInstance<?>) processInstance).internalGetProcessInstance();
if (pi == null) {
return null;
}
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
Map<String, Object> localEnv = new HashMap<String, Object>(env);
localEnv.put("_export_", true);
ProcessMarshallerWriteContext context = new ProcessMarshallerWriteContext(baos, ((io.automatiko.engine.workflow.base.instance.ProcessInstance) pi).getProcessRuntime(), null, localEnv);
context.setProcessInstanceId(pi.getId());
context.setState(pi.getState());
String processType = pi.getProcess().getType();
context.stream.writeUTF(processType);
io.automatiko.engine.workflow.marshalling.impl.ProcessInstanceMarshaller marshaller = ProcessMarshallerRegistry.INSTANCE.getMarshaller(processType);
Object result = marshaller.writeProcessInstance(context, pi);
AutomatikoMessages.Header.Builder _header = AutomatikoMessages.Header.newBuilder();
_header.setVersion(AutomatikoMessages.Version.newBuilder().setVersionMajor(1).setVersionMinor(0).setVersionRevision(0).build());
PersisterHelper.writeStrategiesIndex(context, _header);
String header = JsonFormat.printer().print(_header);
context.close();
// collect all information about timers
Collection<io.automatiko.engine.workflow.process.instance.NodeInstance> nodes = ((WorkflowProcessInstanceImpl) pi).getNodeInstances(true);
StringBuilder timers = new StringBuilder("[");
for (io.automatiko.engine.workflow.process.instance.NodeInstance ni : nodes) {
String timerId = null;
if (ni instanceof TimerNodeInstance) {
timerId = ((TimerNodeInstance) ni).getTimerId();
} else if (ni instanceof StateBasedNodeInstance) {
if (((StateBasedNodeInstance) ni).getTimerInstances() != null) {
((StateBasedNodeInstance) ni).getTimerInstances().forEach(timer -> {
ZonedDateTime scheduledTime = context.processRuntime.getJobsService().getScheduledTime(timer);
timers.append("{\"timerId\":\"").append(timer).append("\",\"scheduledAt\":\"").append(scheduledTime.toString()).append("\",\"nodeInstanceId\":\"").append(ni.getId()).append("\"}");
});
}
}
if (timerId != null) {
ZonedDateTime scheduledTime = context.processRuntime.getJobsService().getScheduledTime(timerId);
timers.append("{\"timerId\":\"").append(timerId).append("\",\"scheduledAt\":\"").append(scheduledTime.toString()).append("\",\"nodeInstanceId\":\"").append(ni.getId()).append("\"}");
}
if (((NodeInstanceImpl) ni).getRetryJobId() != null && !((NodeInstanceImpl) ni).getRetryJobId().isEmpty()) {
ZonedDateTime scheduledTime = context.processRuntime.getJobsService().getScheduledTime(((NodeInstanceImpl) ni).getRetryJobId());
timers.append("{\"timerId\":\"").append(((NodeInstanceImpl) ni).getRetryJobId()).append("\",\"scheduledAt\":\"").append(scheduledTime.toString()).append("\",\"nodeInstanceId\":\"").append(ni.getId()).append("\"}");
}
}
timers.append("]");
return StringExportedProcessInstance.of(header, JsonFormat.printer().print((MessageOrBuilder) result), timers.toString(), null);
} catch (Exception e) {
throw new RuntimeException("Error while marshalling process instance", e);
}
}
use of io.automatiko.engine.workflow.process.instance.node.StateBasedNodeInstance in project automatiko-engine by automatiko-io.
the class WorkflowProcessInstanceImpl method getEventDescriptions.
@Override
public Set<EventDescription<?>> getEventDescriptions() {
if (getState() == ProcessInstance.STATE_COMPLETED || getState() == ProcessInstance.STATE_ABORTED) {
return Collections.emptySet();
}
VariableScope variableScope = (VariableScope) ((ContextContainer) getProcess()).getDefaultContext(VariableScope.VARIABLE_SCOPE);
Set<EventDescription<?>> eventDesciptions = new LinkedHashSet<>();
List<EventListener> activeListeners = eventListeners.values().stream().flatMap(List::stream).collect(Collectors.toList());
activeListeners.addAll(externalEventListeners.values().stream().flatMap(List::stream).collect(Collectors.toList()));
activeListeners.forEach(el -> eventDesciptions.addAll(el.getEventDescriptions()));
((io.automatiko.engine.workflow.process.core.WorkflowProcess) getProcess()).getNodesRecursively().stream().filter(n -> n instanceof EventNodeInterface).forEach(n -> {
NamedDataType dataType = null;
if (((EventNodeInterface) n).getVariableName() != null) {
Map<String, Object> dataOutputs = (Map<String, Object>) n.getMetaData().get("DataOutputs");
if (dataOutputs != null) {
for (Entry<String, Object> dOut : dataOutputs.entrySet()) {
dataType = new NamedDataType(dOut.getKey(), dOut.getValue());
}
} else {
Variable eventVar = variableScope.findVariable(((EventNodeInterface) n).getVariableName());
if (eventVar != null) {
dataType = new NamedDataType(eventVar.getName(), eventVar.getType());
}
}
}
if (n instanceof BoundaryEventNode) {
BoundaryEventNode boundaryEventNode = (BoundaryEventNode) n;
StateBasedNodeInstance attachedToNodeInstance = (StateBasedNodeInstance) getNodeInstances(true).stream().filter(ni -> ni.getNode().getMetaData().get(UNIQUE_ID).equals(boundaryEventNode.getAttachedToNodeId())).findFirst().orElse(null);
if (attachedToNodeInstance != null) {
Map<String, String> properties = new HashMap<>();
properties.put("AttachedToID", attachedToNodeInstance.getNodeDefinitionId());
properties.put("AttachedToName", attachedToNodeInstance.getNodeName());
String eventType = EVENT_TYPE_SIGNAL;
String eventName = boundaryEventNode.getType();
Map<String, String> timerProperties = attachedToNodeInstance.extractTimerEventInformation();
if (timerProperties != null) {
properties.putAll(timerProperties);
eventType = "timer";
eventName = "timerTriggered";
}
eventDesciptions.add(new BaseEventDescription(eventName, (String) n.getMetaData().get(UNIQUE_ID), n.getName(), eventType, null, getId(), dataType, properties));
}
} else if (n instanceof EventSubProcessNode) {
EventSubProcessNode eventSubProcessNode = (EventSubProcessNode) n;
boolean isContainerActive = false;
if (eventSubProcessNode.getParentContainer() instanceof WorkflowProcess) {
isContainerActive = true;
} else if (eventSubProcessNode.getParentContainer() instanceof CompositeNode) {
isContainerActive = !getNodeInstances(((CompositeNode) eventSubProcessNode.getParentContainer()).getId()).isEmpty();
}
if (isContainerActive) {
Node startNode = eventSubProcessNode.findStartNode();
Map<Timer, ProcessAction> timers = eventSubProcessNode.getTimers();
if (timers != null && !timers.isEmpty()) {
getNodeInstances(eventSubProcessNode.getId()).forEach(ni -> {
Map<String, String> timerProperties = ((StateBasedNodeInstance) ni).extractTimerEventInformation();
if (timerProperties != null) {
eventDesciptions.add(new BaseEventDescription("timerTriggered", (String) startNode.getMetaData().get("UniqueId"), startNode.getName(), "timer", ni.getId(), getId(), null, timerProperties));
}
});
} else {
for (String eventName : eventSubProcessNode.getEvents()) {
if ("variableChanged".equals(eventName)) {
continue;
}
eventDesciptions.add(new BaseEventDescription(eventName, (String) startNode.getMetaData().get("UniqueId"), startNode.getName(), "signal", null, getId(), dataType));
}
}
}
} else if (n instanceof EventNode) {
NamedDataType finalDataType = dataType;
getNodeInstances(n.getId()).forEach(ni -> eventDesciptions.add(new BaseEventDescription(((EventNode) n).getType(), (String) n.getMetaData().get(UNIQUE_ID), n.getName(), (String) n.getMetaData().getOrDefault(EVENT_TYPE, EVENT_TYPE_SIGNAL), ni.getId(), getId(), finalDataType)));
} else if (n instanceof StateNode) {
getNodeInstances(n.getId()).forEach(ni -> eventDesciptions.add(new BaseEventDescription((String) n.getMetaData().get(CONDITION), (String) n.getMetaData().get(UNIQUE_ID), n.getName(), (String) n.getMetaData().getOrDefault(EVENT_TYPE, EVENT_TYPE_SIGNAL), ni.getId(), getId(), null)));
}
});
return eventDesciptions;
}
Aggregations