Search in sources :

Example 16 with ContextContainer

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;
}
Also used : Context(io.automatiko.engine.workflow.base.core.Context) ContextContainer(io.automatiko.engine.workflow.base.core.ContextContainer) ContextInstance(io.automatiko.engine.workflow.base.instance.ContextInstance)

Example 17 with ContextContainer

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;
    });
}
Also used : Produces(javax.ws.rs.Produces) Path(javax.ws.rs.Path) LoggerFactory(org.slf4j.LoggerFactory) ProcessInstanceExporter(io.automatiko.engine.addons.process.management.export.ProcessInstanceExporter) MediaType(javax.ws.rs.core.MediaType) Application(io.automatiko.engine.api.Application) QueryParam(javax.ws.rs.QueryParam) ProcessImageNotFoundException(io.automatiko.engine.api.workflow.ProcessImageNotFoundException) ContextContainer(io.automatiko.engine.workflow.base.core.ContextContainer) SchemaType(org.eclipse.microprofile.openapi.annotations.enums.SchemaType) VariableNotFoundException(io.automatiko.engine.api.workflow.VariableNotFoundException) Map(java.util.Map) DefaultValue(javax.ws.rs.DefaultValue) APIResponse(org.eclipse.microprofile.openapi.annotations.responses.APIResponse) Instance(javax.enterprise.inject.Instance) DELETE(javax.ws.rs.DELETE) JsonExportedProcessInstance(io.automatiko.engine.addons.process.management.model.JsonExportedProcessInstance) IoUtils(io.automatiko.engine.services.utils.IoUtils) Context(javax.ws.rs.core.Context) Model(io.automatiko.engine.api.Model) IdentityProvider(io.automatiko.engine.api.auth.IdentityProvider) Operation(org.eclipse.microprofile.openapi.annotations.Operation) ProcessInstance(io.automatiko.engine.api.workflow.ProcessInstance) VariableScope(io.automatiko.engine.workflow.base.core.context.variable.VariableScope) Collectors(java.util.stream.Collectors) List(java.util.List) Response(javax.ws.rs.core.Response) Parameter(org.eclipse.microprofile.openapi.annotations.parameters.Parameter) ProcessInstanceDTO(io.automatiko.engine.addons.process.management.model.ProcessInstanceDTO) ProcessInstanceReadMode(io.automatiko.engine.api.workflow.ProcessInstanceReadMode) Optional(java.util.Optional) Tag(org.eclipse.microprofile.openapi.annotations.tags.Tag) Variable(io.automatiko.engine.workflow.base.core.context.variable.Variable) UriInfo(javax.ws.rs.core.UriInfo) ProcessInstanceNotFoundException(io.automatiko.engine.api.workflow.ProcessInstanceNotFoundException) PathParam(javax.ws.rs.PathParam) AbstractProcessInstance(io.automatiko.engine.workflow.AbstractProcessInstance) ByteArrayOutputStream(java.io.ByteArrayOutputStream) GET(javax.ws.rs.GET) ProcessInstanceDetailsDTO(io.automatiko.engine.addons.process.management.model.ProcessInstanceDetailsDTO) ArrayList(java.util.ArrayList) Inject(javax.inject.Inject) ArchivedProcessInstance(io.automatiko.engine.api.workflow.ArchivedProcessInstance) JsonArchiveBuilder(io.automatiko.engine.workflow.json.JsonArchiveBuilder) IdentitySupplier(io.automatiko.engine.api.auth.IdentitySupplier) ErrorInfoDTO(io.automatiko.engine.addons.process.management.model.ErrorInfoDTO) WorkflowProcess(io.automatiko.engine.workflow.process.core.WorkflowProcess) Process(io.automatiko.engine.api.workflow.Process) ProcessDTO(io.automatiko.engine.addons.process.management.model.ProcessDTO) Content(org.eclipse.microprofile.openapi.annotations.media.Content) AbstractProcess(io.automatiko.engine.workflow.AbstractProcess) Status(javax.ws.rs.core.Response.Status) ResponseBuilder(javax.ws.rs.core.Response.ResponseBuilder) UnitOfWorkExecutor(io.automatiko.engine.services.uow.UnitOfWorkExecutor) POST(javax.ws.rs.POST) Logger(org.slf4j.Logger) Schema(org.eclipse.microprofile.openapi.annotations.media.Schema) IOException(java.io.IOException) ExternalDocumentation(org.eclipse.microprofile.openapi.annotations.ExternalDocumentation) APIResponses(org.eclipse.microprofile.openapi.annotations.responses.APIResponses) Collections(java.util.Collections) ProcessInstanceDetailsDTO(io.automatiko.engine.addons.process.management.model.ProcessInstanceDetailsDTO) ErrorInfoDTO(io.automatiko.engine.addons.process.management.model.ErrorInfoDTO) AbstractProcess(io.automatiko.engine.workflow.AbstractProcess) VariableScope(io.automatiko.engine.workflow.base.core.context.variable.VariableScope) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces) APIResponses(org.eclipse.microprofile.openapi.annotations.responses.APIResponses) Operation(org.eclipse.microprofile.openapi.annotations.Operation)

Example 18 with ContextContainer

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);
    }
}
Also used : NodeImpl(io.automatiko.engine.workflow.process.core.impl.NodeImpl) CompensationScopeInstance(io.automatiko.engine.workflow.base.instance.context.exception.CompensationScopeInstance) Node(io.automatiko.engine.api.definition.process.Node) ExecutableProcess(io.automatiko.engine.workflow.process.executable.core.ExecutableProcess) WorkflowRuntimeException(io.automatiko.engine.workflow.process.instance.WorkflowRuntimeException) ContextContainer(io.automatiko.engine.workflow.base.core.ContextContainer) CompensationScope(io.automatiko.engine.workflow.base.core.context.exception.CompensationScope) NodeInstance(io.automatiko.engine.workflow.process.instance.NodeInstance) CompositeNodeInstance(io.automatiko.engine.workflow.process.instance.node.CompositeNodeInstance)

Example 19 with ContextContainer

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);
}
Also used : ContextContainer(io.automatiko.engine.workflow.base.core.ContextContainer) CompensationHandler(io.automatiko.engine.workflow.base.core.context.exception.CompensationHandler) CompensationScope(io.automatiko.engine.workflow.base.core.context.exception.CompensationScope)

Aggregations

ContextContainer (io.automatiko.engine.workflow.base.core.ContextContainer)19 Variable (io.automatiko.engine.workflow.base.core.context.variable.Variable)9 VariableScope (io.automatiko.engine.workflow.base.core.context.variable.VariableScope)9 List (java.util.List)8 ProcessAction (io.automatiko.engine.workflow.process.core.ProcessAction)7 Map (java.util.Map)7 ConsequenceAction (io.automatiko.engine.workflow.process.core.impl.ConsequenceAction)6 EventNode (io.automatiko.engine.workflow.process.core.node.EventNode)6 ActionExceptionHandler (io.automatiko.engine.workflow.base.core.context.exception.ActionExceptionHandler)5 CompensationScope (io.automatiko.engine.workflow.base.core.context.exception.CompensationScope)5 ExceptionScope (io.automatiko.engine.workflow.base.core.context.exception.ExceptionScope)5 ArrayList (java.util.ArrayList)5 Logger (org.slf4j.Logger)5 LoggerFactory (org.slf4j.LoggerFactory)5 Node (io.automatiko.engine.api.definition.process.Node)4 CompensationHandler (io.automatiko.engine.workflow.base.core.context.exception.CompensationHandler)4 SignalProcessInstanceAction (io.automatiko.engine.workflow.base.instance.impl.actions.SignalProcessInstanceAction)4 BoundaryEventNode (io.automatiko.engine.workflow.process.core.node.BoundaryEventNode)4 EventTrigger (io.automatiko.engine.workflow.process.core.node.EventTrigger)4 IdentityProvider (io.automatiko.engine.api.auth.IdentityProvider)3