Search in sources :

Example 6 with AbstractProcessInstance

use of io.automatiko.engine.workflow.AbstractProcessInstance in project automatiko-engine by automatiko-io.

the class Controller method reconcile.

@Override
public synchronized UpdateControl<$DataType$> reconcile($DataType$ resource, Context context) {
    if (!acceptedPayload(resource)) {
        LOGGER.debug("Event has been rejected by the filter expression");
        return UpdateControl.noUpdate();
    }
    String trigger = "$Trigger$";
    IdentityProvider.set(new TrustedIdentityProvider("System<messaging>"));
    final $Type$ model = new $Type$();
    return io.automatiko.engine.services.uow.UnitOfWorkExecutor.executeInUnitOfWork(application.unitOfWorkManager(), () -> {
        try {
            String correlation = resource.getMetadata().getName();
            if (correlation != null) {
                LOGGER.debug("Correlation ({}) is set, attempting to find if there is matching instance already active", correlation);
                Optional<? extends ProcessInstance> possiblyFound = (Optional<? extends ProcessInstance>) process.instances().findById(correlation);
                if (possiblyFound.isPresent()) {
                    ProcessInstance pInstance = (ProcessInstance) possiblyFound.get();
                    LOGGER.debug("Found process instance {} matching correlation {}, signaling instead of starting new instance", pInstance.id(), correlation);
                    pInstance.send(Sig.of("Message-updated", resource));
                    $DataType$ updated = ($DataType$) ((Model) pInstance.variables()).toMap().get("resource");
                    if (updated == null || Boolean.TRUE.equals(((WorkflowProcessInstanceImpl) ((AbstractProcessInstance<?>) pInstance).processInstance()).getVariable("skipResourceUpdate"))) {
                        LOGGER.debug("Signalled and returned updated {} no need to updated custom resource", updated);
                        return UpdateControl.noUpdate();
                    }
                    LOGGER.debug("Signalled and returned updated {} that requires update of the custom resource", updated);
                    return UpdateControl.updateResourceAndStatus(updated);
                }
            }
            if (canStartInstance()) {
                LOGGER.debug("Received message without reference id and no correlation is set/matched, staring new process instance with trigger '{}'", trigger);
                ProcessInstance<?> pi = process.createInstance(correlation, model);
                pi.start(trigger, null, resource);
                $DataType$ updated = ($DataType$) ((Model) pi.variables()).toMap().get("resource");
                if (updated == null || Boolean.TRUE.equals(((WorkflowProcessInstanceImpl) ((AbstractProcessInstance<?>) pi).processInstance()).getVariable("skipResourceUpdate"))) {
                    LOGGER.debug("New instance started and not need to update custom resource");
                    return UpdateControl.noUpdate();
                }
                LOGGER.debug("New instance started and with the need to update custom resource");
                return UpdateControl.updateResourceAndStatus(updated);
            } else {
                LOGGER.warn("Received message without reference id and no correlation is set/matched, for trigger not capable of starting new instance '{}'", trigger);
            }
        } catch (Throwable t) {
            LOGGER.error("Encountered problems while creating/updating instance", t);
        }
        return UpdateControl.noUpdate();
    });
}
Also used : Optional(java.util.Optional) TrustedIdentityProvider(io.automatiko.engine.api.auth.TrustedIdentityProvider) Model(io.automatiko.engine.api.Model) WorkflowProcessInstanceImpl(io.automatiko.engine.workflow.process.instance.impl.WorkflowProcessInstanceImpl) AbstractProcessInstance(io.automatiko.engine.workflow.AbstractProcessInstance) ProcessInstance(io.automatiko.engine.api.workflow.ProcessInstance)

Example 7 with AbstractProcessInstance

use of io.automatiko.engine.workflow.AbstractProcessInstance in project automatiko-engine by automatiko-io.

the class CassandraProcessInstances method create.

@Override
public void create(String id, ProcessInstance instance) {
    String resolvedId = resolveId(id, instance);
    if (isActive(instance)) {
        LOGGER.debug("create() called for instance {}", resolvedId);
        byte[] data = codec.encode(marshaller.marhsallProcessInstance(instance));
        if (data == null) {
            return;
        }
        Collection<String> tags = new LinkedHashSet<>(instance.tags().values());
        tags.add(resolvedId);
        if (instance.businessKey() != null) {
            tags.add(instance.businessKey());
        }
        Insert insert = insertInto(config.keyspace().orElse("automatiko"), tableName).value(INSTANCE_ID_FIELD, literal(resolvedId)).value(VERSION_FIELD, literal(((AbstractProcessInstance<?>) instance).getVersionTracker())).value(STATUS_FIELD, literal(((AbstractProcessInstance<?>) instance).status())).value(CONTENT_FIELD, bindMarker()).value(TAGS_FIELD, bindMarker()).ifNotExists();
        try {
            ResultSet rs = cqlSession.execute(cqlSession.prepare(insert.build()).bind(ByteBuffer.wrap(data), tags));
            if (!rs.wasApplied()) {
                throw new ProcessInstanceDuplicatedException(id);
            }
        } catch (QueryExecutionException e) {
            throw new ProcessInstanceDuplicatedException(id);
        } finally {
            cachedInstances.remove(resolvedId);
            cachedInstances.remove(id);
            disconnect(instance);
        }
    } else if (isPending(instance)) {
        if (cachedInstances.putIfAbsent(resolvedId, instance) != null) {
            throw new ProcessInstanceDuplicatedException(id);
        }
    } else {
        cachedInstances.remove(resolvedId);
        cachedInstances.remove(id);
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) AbstractProcessInstance(io.automatiko.engine.workflow.AbstractProcessInstance) ProcessInstanceDuplicatedException(io.automatiko.engine.api.workflow.ProcessInstanceDuplicatedException) QueryExecutionException(com.datastax.oss.driver.api.core.servererrors.QueryExecutionException) ResultSet(com.datastax.oss.driver.api.core.cql.ResultSet) Insert(com.datastax.oss.driver.api.querybuilder.insert.Insert)

Example 8 with AbstractProcessInstance

use of io.automatiko.engine.workflow.AbstractProcessInstance in project automatiko-engine by automatiko-io.

the class DatabaseProcessInstances method disconnect.

protected void disconnect(ProcessInstance<ProcessInstanceEntity> instance) {
    ((AbstractProcessInstance<?>) instance).internalRemoveProcessInstance(() -> {
        try {
            ProcessInstanceEntity entity = (ProcessInstanceEntity) JpaOperations.INSTANCE.findById(type, resolveId(instance.id(), instance));
            byte[] reloaded = codec.decode(entity.content);
            WorkflowProcessInstance wpi = marshaller.unmarshallWorkflowProcessInstance(reloaded, process);
            entity.toMap().forEach((k, v) -> {
                if (v != null) {
                    v.toString();
                    VariableScopeInstance variableScopeInstance = (VariableScopeInstance) ((ProcessInstanceImpl) wpi).getContextInstance(VariableScope.VARIABLE_SCOPE);
                    variableScopeInstance.internalSetVariable(k, v);
                }
            });
            return wpi;
        } catch (RuntimeException e) {
            LOGGER.error("Unexpected exception thrown when reloading process instance {}", instance.id(), e);
            return null;
        }
    });
}
Also used : AbstractProcessInstance(io.automatiko.engine.workflow.AbstractProcessInstance) ProcessInstanceEntity(io.automatiko.engine.addons.persistence.db.model.ProcessInstanceEntity) VariableScopeInstance(io.automatiko.engine.workflow.base.instance.context.variable.VariableScopeInstance) WorkflowProcessInstance(io.automatiko.engine.api.runtime.process.WorkflowProcessInstance)

Example 9 with AbstractProcessInstance

use of io.automatiko.engine.workflow.AbstractProcessInstance in project automatiko-engine by automatiko-io.

the class DynamoDBProcessInstances method update.

@Override
public void update(String id, ProcessInstance instance) {
    String resolvedId = resolveId(id, instance);
    if (isActive(instance)) {
        LOGGER.debug("update() called for instance {}", resolvedId);
        byte[] data = codec.encode(marshaller.marhsallProcessInstance(instance));
        if (data == null) {
            return;
        }
        HashMap<String, AttributeValue> itemKey = new HashMap<String, AttributeValue>();
        itemKey.put(INSTANCE_ID_FIELD, AttributeValue.builder().s(resolvedId).build());
        Map<String, AttributeValueUpdate> updatedValues = new HashMap<String, AttributeValueUpdate>();
        updatedValues.put(CONTENT_FIELD, AttributeValueUpdate.builder().value(AttributeValue.builder().b(SdkBytes.fromByteArray(data)).build()).action(AttributeAction.PUT).build());
        updatedValues.put(VERSION_FIELD, AttributeValueUpdate.builder().value(AttributeValue.builder().n(String.valueOf(((AbstractProcessInstance<?>) instance).getVersionTracker() + 1)).build()).action(AttributeAction.PUT).build());
        updatedValues.put(STATUS_FIELD, AttributeValueUpdate.builder().value(AttributeValue.builder().n(String.valueOf(((AbstractProcessInstance<?>) instance).status())).build()).action(AttributeAction.PUT).build());
        Collection<String> tags = new ArrayList(instance.tags().values());
        tags.add(resolvedId);
        if (instance.businessKey() != null) {
            tags.add(instance.businessKey());
        }
        updatedValues.put(TAGS_FIELD, AttributeValueUpdate.builder().value(AttributeValue.builder().ss(tags).build()).action(AttributeAction.PUT).build());
        UpdateItemRequest request = UpdateItemRequest.builder().tableName(tableName).key(itemKey).attributeUpdates(updatedValues).conditionExpression(VERSION_FIELD + " = " + ((AbstractProcessInstance<?>) instance).getVersionTracker()).build();
        try {
            dynamodb.updateItem(request);
        } catch (ConditionalCheckFailedException e) {
            throw new ConflictingVersionException("Process instance with id '" + instance.id() + "' has older version than the stored one");
        } finally {
            disconnect(instance);
        }
    }
    cachedInstances.remove(resolvedId);
}
Also used : AbstractProcessInstance(io.automatiko.engine.workflow.AbstractProcessInstance) ConflictingVersionException(io.automatiko.engine.api.workflow.ConflictingVersionException) AttributeValue(software.amazon.awssdk.services.dynamodb.model.AttributeValue) UpdateItemRequest(software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest) AttributeValueUpdate(software.amazon.awssdk.services.dynamodb.model.AttributeValueUpdate) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ConditionalCheckFailedException(software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException)

Example 10 with AbstractProcessInstance

use of io.automatiko.engine.workflow.AbstractProcessInstance in project automatiko-engine by automatiko-io.

the class DynamoDBProcessInstances method create.

@Override
public void create(String id, ProcessInstance instance) {
    String resolvedId = resolveId(id, instance);
    if (isActive(instance)) {
        LOGGER.debug("create() called for instance {}", resolvedId);
        byte[] data = codec.encode(marshaller.marhsallProcessInstance(instance));
        if (data == null) {
            return;
        }
        Map<String, AttributeValue> itemValues = new HashMap<String, AttributeValue>();
        itemValues.put(INSTANCE_ID_FIELD, AttributeValue.builder().s(resolvedId).build());
        itemValues.put(VERSION_FIELD, AttributeValue.builder().n(String.valueOf(((AbstractProcessInstance<?>) instance).getVersionTracker())).build());
        itemValues.put(STATUS_FIELD, AttributeValue.builder().n(String.valueOf(((AbstractProcessInstance<?>) instance).status())).build());
        itemValues.put(CONTENT_FIELD, AttributeValue.builder().b(SdkBytes.fromByteArray(data)).build());
        Collection<String> tags = new ArrayList(instance.tags().values());
        tags.add(resolvedId);
        if (instance.businessKey() != null) {
            tags.add(instance.businessKey());
        }
        itemValues.put(TAGS_FIELD, AttributeValue.builder().ss(tags).build());
        PutItemRequest request = PutItemRequest.builder().tableName(tableName).conditionExpression("attribute_not_exists(" + INSTANCE_ID_FIELD + ")").item(itemValues).build();
        try {
            dynamodb.putItem(request);
        } catch (ConditionalCheckFailedException e) {
            throw new ProcessInstanceDuplicatedException(id);
        } finally {
            cachedInstances.remove(resolvedId);
            cachedInstances.remove(id);
            disconnect(instance);
        }
    } else if (isPending(instance)) {
        if (cachedInstances.putIfAbsent(resolvedId, instance) != null) {
            throw new ProcessInstanceDuplicatedException(id);
        }
    } else {
        cachedInstances.remove(resolvedId);
        cachedInstances.remove(id);
    }
}
Also used : AbstractProcessInstance(io.automatiko.engine.workflow.AbstractProcessInstance) AttributeValue(software.amazon.awssdk.services.dynamodb.model.AttributeValue) ProcessInstanceDuplicatedException(io.automatiko.engine.api.workflow.ProcessInstanceDuplicatedException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) PutItemRequest(software.amazon.awssdk.services.dynamodb.model.PutItemRequest) ConditionalCheckFailedException(software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException)

Aggregations

AbstractProcessInstance (io.automatiko.engine.workflow.AbstractProcessInstance)18 Model (io.automatiko.engine.api.Model)7 ProcessInstance (io.automatiko.engine.api.workflow.ProcessInstance)6 HashMap (java.util.HashMap)6 IOException (java.io.IOException)5 WorkflowProcessInstance (io.automatiko.engine.api.runtime.process.WorkflowProcessInstance)4 ProcessInstanceDuplicatedException (io.automatiko.engine.api.workflow.ProcessInstanceDuplicatedException)4 WorkflowProcessInstanceImpl (io.automatiko.engine.workflow.process.instance.impl.WorkflowProcessInstanceImpl)4 Application (io.automatiko.engine.api.Application)3 Process (io.automatiko.engine.api.workflow.Process)3 UncheckedIOException (java.io.UncheckedIOException)3 LinkedHashSet (java.util.LinkedHashSet)3 List (java.util.List)3 Map (java.util.Map)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 Document (org.bson.Document)3 AttributeValue (software.amazon.awssdk.services.dynamodb.model.AttributeValue)3 ResultSet (com.datastax.oss.driver.api.core.cql.ResultSet)2 IdentityProvider (io.automatiko.engine.api.auth.IdentityProvider)2 SecurityPolicy (io.automatiko.engine.api.auth.SecurityPolicy)2