use of io.automatiko.engine.workflow.base.core.ContextContainer in project automatiko-engine by automatiko-io.
the class ProcessInstanceImpl method getContextInstance.
public ContextInstance getContextInstance(String contextId) {
ContextInstance contextInstance = this.contextInstances.get(contextId);
if (contextInstance != null) {
return contextInstance;
}
Context context = ((ContextContainer) getProcess()).getDefaultContext(contextId);
if (context != null) {
contextInstance = getContextInstance(context);
return contextInstance;
}
return null;
}
use of io.automatiko.engine.workflow.base.core.ContextContainer in project automatiko-engine by automatiko-io.
the class ProcessInstanceManagementResource method importInstance.
@APIResponses(value = { @APIResponse(responseCode = "404", description = "In case of instance with given process id was not found", content = @Content(mediaType = "application/json")), @APIResponse(responseCode = "200", description = "Exported process instance", content = @Content(mediaType = "application/json")) })
@Operation(summary = "Imports exported process instance and returns its details after the import")
@POST
@Path("/{processId}/instances")
@Produces(MediaType.APPLICATION_JSON)
public ProcessInstanceDetailsDTO importInstance(@Context UriInfo uriInfo, @Parameter(description = "Unique identifier of the process", required = true) @PathParam("processId") String processId, @Parameter(description = "User identifier as alternative autroization info", required = false, hidden = true) @QueryParam("user") final String user, @Parameter(description = "Groups as alternative autroization info", required = false, hidden = true) @QueryParam("group") final List<String> groups, @Parameter(description = "The input model for orders instance", schema = @Schema(type = SchemaType.OBJECT, implementation = Map.class)) JsonExportedProcessInstance instance) {
identitySupplier.buildIdentityProvider(user, groups);
return UnitOfWorkExecutor.executeInUnitOfWork(application.unitOfWorkManager(), () -> {
ProcessInstance<?> pi = exporter.importInstance(instance);
ProcessInstanceDetailsDTO details = new ProcessInstanceDetailsDTO();
details.setId(pi.id());
details.setProcessId(processId);
details.setBusinessKey(pi.businessKey());
details.setDescription(pi.description());
details.setFailed(pi.errors().isPresent());
if (pi.errors().isPresent()) {
details.setErrors(pi.errors().get().errors().stream().map(e -> new ErrorInfoDTO(e.failedNodeId(), e.errorId(), e.errorMessage(), e.errorDetails())).collect(Collectors.toList()));
}
details.setImage(uriInfo.getBaseUri().toString() + "management/processes/" + processId + "/instances/" + pi.id() + "/image");
details.setTags(pi.tags().values());
details.setVariables(pi.variables());
VariableScope variableScope = (VariableScope) ((ContextContainer) ((AbstractProcess<?>) pi.process()).process()).getDefaultContext(VariableScope.VARIABLE_SCOPE);
details.setVersionedVariables(variableScope.getVariables().stream().filter(v -> v.hasTag(Variable.VERSIONED_TAG)).map(v -> v.getName()).collect(Collectors.toList()));
return details;
});
}
use of io.automatiko.engine.workflow.base.core.ContextContainer in project automatiko-engine by automatiko-io.
the class CompensationEventListener method signalEvent.
/**
* When signaling compensation, you can do that in 1 of 2 ways: 1.
* signalEvent("Compensation", <node-with-compensation-handler-id>) This is
* specific compensation, that only possibly triggers the compensation handler
* attached to the node referred to by the <node-with-compensation-handler-id>.
* 2. signalEvent("Compensation", "implicit:" +
* <node-container-containing-compensation-scope-id> ) This is implicit or
* general compensation, in which you trigger all visible compensation handlers
* (in the proper order, etc.) in the (sub-)process referred to by the
* <node-container-containing-compensation-scope-id>.
*/
public void signalEvent(String compensationType, Object activityRefStr) {
if (!(activityRefStr instanceof String)) {
throw new WorkflowRuntimeException(null, getProcessInstance(), "Compensation can only be triggered with String events, not an event of type " + (activityRefStr == null ? "null" : activityRefStr.getClass().getSimpleName()));
}
// 1. parse the activity ref (is it general or specific compensation?)
String activityRef = (String) activityRefStr;
String toCompensateNodeId = activityRef;
boolean generalCompensation = false;
if (activityRef.startsWith(IMPLICIT_COMPENSATION_PREFIX)) {
toCompensateNodeId = activityRef.substring(IMPLICIT_COMPENSATION_PREFIX.length());
generalCompensation = true;
}
io.automatiko.engine.workflow.base.core.Process process = (io.automatiko.engine.workflow.base.core.Process) instance.getProcess();
// 2. for specific compensation: find the node that will be compensated
// for general compensation: find the compensation scope container that contains
// all the visible compensation handlers
Node toCompensateNode = null;
ContextContainer compensationScopeContainer = null;
if (generalCompensation) {
if (toCompensateNodeId.equals(instance.getProcessId())) {
compensationScopeContainer = process;
} else {
compensationScopeContainer = (ContextContainer) findNode(toCompensateNodeId);
}
} else {
toCompensateNode = findNode(toCompensateNodeId);
}
// c. handle the exception (which also cleans up the generated node instances)
if (toCompensateNode != null || compensationScopeContainer != null) {
CompensationScope compensationScope = null;
if (compensationScopeContainer != null) {
compensationScope = (CompensationScope) compensationScopeContainer.getDefaultContext(COMPENSATION_SCOPE);
} else {
compensationScope = (CompensationScope) ((NodeImpl) toCompensateNode).resolveContext(COMPENSATION_SCOPE, toCompensateNodeId);
}
assert compensationScope != null : "Compensation scope for node [" + toCompensateNodeId + "] could not be found!";
CompensationScopeInstance scopeInstance;
if (compensationScope.getContextContainerId().equals(process.getId())) {
// process level compensation
scopeInstance = (CompensationScopeInstance) instance.getContextInstance(compensationScope);
} else {
// nested compensation
Stack<NodeInstance> generatedInstances;
if (toCompensateNode == null) {
// logic is the same if it's specific or general
generatedInstances = createNodeInstanceContainers((Node) compensationScopeContainer, true);
} else {
generatedInstances = createNodeInstanceContainers(toCompensateNode, false);
}
NodeInstance nodeInstanceContainer = generatedInstances.peek();
scopeInstance = ((CompensationScopeInstance) ((ContextInstanceContainer) nodeInstanceContainer).getContextInstance(compensationScope));
scopeInstance.addCompensationInstances(generatedInstances);
}
scopeInstance.handleException(null, activityRef, null);
}
}
use of io.automatiko.engine.workflow.base.core.ContextContainer in project automatiko-engine by automatiko-io.
the class ExecutableProcessFactory method addCompensationScope.
protected void addCompensationScope(final ExecutableProcess process, final Node node, final io.automatiko.engine.api.definition.process.NodeContainer parentContainer, final String compensationHandlerId) {
process.getMetaData().put("Compensation", true);
assert parentContainer instanceof ContextContainer : "Expected parent node to be a CompositeContextNode, not a " + parentContainer.getClass().getSimpleName();
ContextContainer contextContainer = (ContextContainer) parentContainer;
CompensationScope scope = null;
boolean addScope = false;
if (contextContainer.getContexts(CompensationScope.COMPENSATION_SCOPE) == null) {
addScope = true;
} else {
scope = (CompensationScope) contextContainer.getContexts(CompensationScope.COMPENSATION_SCOPE).get(0);
if (scope == null) {
addScope = true;
}
}
if (addScope) {
scope = new CompensationScope();
contextContainer.addContext(scope);
contextContainer.setDefaultContext(scope);
scope.setContextContainer(contextContainer);
}
CompensationHandler handler = new CompensationHandler();
handler.setNode(node);
if (scope.getExceptionHandler(compensationHandlerId) != null) {
throw new IllegalArgumentException("More than one compensation handler per node (" + compensationHandlerId + ")" + " is not supported!");
}
scope.setExceptionHandler(compensationHandlerId, handler);
}
Aggregations