Search in sources :

Example 6 with StateInstruction

use of io.seata.saga.engine.pcext.StateInstruction in project seata by seata.

the class FailEndStateHandler method process.

@Override
public void process(ProcessContext context) throws EngineExecutionException {
    context.setVariable(DomainConstants.VAR_NAME_FAIL_END_STATE_FLAG, true);
    StateInstruction instruction = context.getInstruction(StateInstruction.class);
    FailEndState state = (FailEndState) instruction.getState(context);
    Map<String, Object> contextVariables = (Map<String, Object>) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_CONTEXT);
    contextVariables.put(DomainConstants.VAR_NAME_STATEMACHINE_ERROR_CODE, state.getErrorCode());
    contextVariables.put(DomainConstants.VAR_NAME_STATEMACHINE_ERROR_MSG, state.getMessage());
}
Also used : FailEndState(io.seata.saga.statelang.domain.FailEndState) StateInstruction(io.seata.saga.engine.pcext.StateInstruction) Map(java.util.Map)

Example 7 with StateInstruction

use of io.seata.saga.engine.pcext.StateInstruction in project seata by seata.

the class ScriptTaskStateHandler method process.

@Override
public void process(ProcessContext context) throws EngineExecutionException {
    StateInstruction instruction = context.getInstruction(StateInstruction.class);
    ScriptTaskStateImpl state = (ScriptTaskStateImpl) instruction.getState(context);
    String scriptType = state.getScriptType();
    String scriptContent = state.getScriptContent();
    Object result;
    try {
        List<Object> input = (List<Object>) context.getVariable(DomainConstants.VAR_NAME_INPUT_PARAMS);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug(">>>>>>>>>>>>>>>>>>>>>> Start to execute ScriptTaskState[{}], ScriptType[{}], Input:{}", state.getName(), scriptType, input);
        }
        StateMachineConfig stateMachineConfig = (StateMachineConfig) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_CONFIG);
        ScriptEngine scriptEngine = getScriptEngineFromCache(scriptType, stateMachineConfig.getScriptEngineManager());
        if (scriptEngine == null) {
            throw new EngineExecutionException("No such ScriptType[" + scriptType + "]", FrameworkErrorCode.ObjectNotExists);
        }
        Bindings bindings = null;
        Map<String, Object> inputMap = null;
        if (CollectionUtils.isNotEmpty(input) && input.get(0) instanceof Map) {
            inputMap = (Map<String, Object>) input.get(0);
        }
        List<Object> inputExps = state.getInput();
        if (CollectionUtils.isNotEmpty(inputExps) && inputExps.get(0) instanceof Map) {
            Map<String, Object> inputExpMap = (Map<String, Object>) inputExps.get(0);
            if (inputExpMap.size() > 0) {
                bindings = new SimpleBindings();
                for (String property : inputExpMap.keySet()) {
                    if (inputMap != null && inputMap.containsKey(property)) {
                        bindings.put(property, inputMap.get(property));
                    } else {
                        // if we do not bind the null value property, groovy will throw MissingPropertyException
                        bindings.put(property, null);
                    }
                }
            }
        }
        if (bindings != null) {
            result = scriptEngine.eval(scriptContent, bindings);
        } else {
            result = scriptEngine.eval(scriptContent);
        }
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("<<<<<<<<<<<<<<<<<<<<<< ScriptTaskState[{}], ScriptType[{}], Execute finish. result: {}", state.getName(), scriptType, result);
        }
        if (result != null) {
            ((HierarchicalProcessContext) context).setVariableLocally(DomainConstants.VAR_NAME_OUTPUT_PARAMS, result);
        }
    } catch (Throwable e) {
        LOGGER.error("<<<<<<<<<<<<<<<<<<<<<< ScriptTaskState[{}], ScriptTaskState[{}] Execute failed.", state.getName(), scriptType, e);
        ((HierarchicalProcessContext) context).setVariableLocally(DomainConstants.VAR_NAME_CURRENT_EXCEPTION, e);
        EngineUtils.handleException(context, state, e);
    }
}
Also used : StateInstruction(io.seata.saga.engine.pcext.StateInstruction) HierarchicalProcessContext(io.seata.saga.proctrl.HierarchicalProcessContext) EngineExecutionException(io.seata.saga.engine.exception.EngineExecutionException) Bindings(javax.script.Bindings) SimpleBindings(javax.script.SimpleBindings) ScriptEngine(javax.script.ScriptEngine) ScriptTaskStateImpl(io.seata.saga.statelang.domain.impl.ScriptTaskStateImpl) SimpleBindings(javax.script.SimpleBindings) ArrayList(java.util.ArrayList) List(java.util.List) StateMachineConfig(io.seata.saga.engine.StateMachineConfig) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Map(java.util.Map)

Example 8 with StateInstruction

use of io.seata.saga.engine.pcext.StateInstruction in project seata by seata.

the class ProcessCtrlStateMachineEngine method compensateInternal.

public StateMachineInstance compensateInternal(String stateMachineInstId, Map<String, Object> replaceParams, boolean async, AsyncCallback callback) throws EngineExecutionException {
    StateMachineInstance stateMachineInstance = reloadStateMachineInstance(stateMachineInstId);
    if (stateMachineInstance == null) {
        throw new EngineExecutionException("StateMachineInstance is not exits", FrameworkErrorCode.StateMachineInstanceNotExists);
    }
    if (ExecutionStatus.SU.equals(stateMachineInstance.getCompensationStatus())) {
        return stateMachineInstance;
    }
    if (stateMachineInstance.getCompensationStatus() != null) {
        ExecutionStatus[] denyStatus = new ExecutionStatus[] { ExecutionStatus.SU };
        checkStatus(stateMachineInstance, null, denyStatus, null, stateMachineInstance.getCompensationStatus(), "compensate");
    }
    if (replaceParams != null) {
        stateMachineInstance.getEndParams().putAll(replaceParams);
    }
    ProcessContextBuilder contextBuilder = ProcessContextBuilder.create().withProcessType(ProcessType.STATE_LANG).withOperationName(DomainConstants.OPERATION_NAME_COMPENSATE).withAsyncCallback(callback).withStateMachineInstance(stateMachineInstance).withStateMachineConfig(getStateMachineConfig()).withStateMachineEngine(this);
    contextBuilder.withIsAsyncExecution(async);
    ProcessContext context = contextBuilder.build();
    Map<String, Object> contextVariables = getStateMachineContextVariables(stateMachineInstance);
    if (replaceParams != null) {
        contextVariables.putAll(replaceParams);
    }
    putBusinesskeyToContextariables(stateMachineInstance, contextVariables);
    ConcurrentHashMap<String, Object> concurrentContextVariables = new ConcurrentHashMap<>(contextVariables.size());
    nullSafeCopy(contextVariables, concurrentContextVariables);
    context.setVariable(DomainConstants.VAR_NAME_STATEMACHINE_CONTEXT, concurrentContextVariables);
    stateMachineInstance.setContext(concurrentContextVariables);
    CompensationTriggerStateImpl tempCompensationTriggerState = new CompensationTriggerStateImpl();
    tempCompensationTriggerState.setStateMachine(stateMachineInstance.getStateMachine());
    stateMachineInstance.setRunning(true);
    if (LOGGER.isInfoEnabled()) {
        LOGGER.info("Operation [compensate] start.  stateMachineInstance[id:" + stateMachineInstance.getId() + "]");
    }
    if (stateMachineInstance.getStateMachine().isPersist()) {
        stateMachineConfig.getStateLogStore().recordStateMachineRestarted(stateMachineInstance, context);
    }
    try {
        StateInstruction inst = new StateInstruction();
        inst.setTenantId(stateMachineInstance.getTenantId());
        inst.setStateMachineName(stateMachineInstance.getStateMachine().getName());
        inst.setTemporaryState(tempCompensationTriggerState);
        context.setInstruction(inst);
        if (async) {
            stateMachineConfig.getAsyncProcessCtrlEventPublisher().publish(context);
        } else {
            stateMachineConfig.getProcessCtrlEventPublisher().publish(context);
        }
    } catch (EngineExecutionException e) {
        LOGGER.error("Operation [compensate] failed", e);
        throw e;
    }
    return stateMachineInstance;
}
Also used : CompensationTriggerStateImpl(io.seata.saga.statelang.domain.impl.CompensationTriggerStateImpl) StateInstruction(io.seata.saga.engine.pcext.StateInstruction) EngineExecutionException(io.seata.saga.engine.exception.EngineExecutionException) ProcessContext(io.seata.saga.proctrl.ProcessContext) StateMachineInstance(io.seata.saga.statelang.domain.StateMachineInstance) ProcessContextBuilder(io.seata.saga.engine.utils.ProcessContextBuilder) ExecutionStatus(io.seata.saga.statelang.domain.ExecutionStatus) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 9 with StateInstruction

use of io.seata.saga.engine.pcext.StateInstruction in project seata by seata.

the class SubStateMachineHandler method process.

@Override
public void process(ProcessContext context) throws EngineExecutionException {
    StateInstruction instruction = context.getInstruction(StateInstruction.class);
    SubStateMachineImpl subStateMachine = (SubStateMachineImpl) instruction.getState(context);
    StateMachineEngine engine = (StateMachineEngine) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_ENGINE);
    StateMachineInstance stateMachineInstance = (StateMachineInstance) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_INST);
    StateInstance stateInstance = (StateInstance) context.getVariable(DomainConstants.VAR_NAME_STATE_INST);
    Object inputParamsObj = context.getVariable(DomainConstants.VAR_NAME_INPUT_PARAMS);
    Map<String, Object> startParams = new HashMap<>(0);
    if (inputParamsObj instanceof List) {
        List<Object> listInputParams = (List<Object>) inputParamsObj;
        if (listInputParams.size() > 0) {
            startParams = (Map<String, Object>) listInputParams.get(0);
        }
    } else if (inputParamsObj instanceof Map) {
        startParams = (Map<String, Object>) inputParamsObj;
    }
    startParams.put(DomainConstants.VAR_NAME_PARENT_ID, EngineUtils.generateParentId(stateInstance));
    try {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug(">>>>>>>>>>>>>>>>>>>>>> Start to execute SubStateMachine [{}] by state[{}]", subStateMachine.getStateMachineName(), subStateMachine.getName());
        }
        StateMachineInstance subStateMachineInstance = callSubStateMachine(startParams, engine, context, stateInstance, subStateMachine);
        Map<String, Object> outputParams = subStateMachineInstance.getEndParams();
        boolean isForward = DomainConstants.OPERATION_NAME_FORWARD.equals(context.getVariable(DomainConstants.VAR_NAME_OPERATION_NAME));
        ExecutionStatus callSubMachineStatus = decideStatus(subStateMachineInstance, isForward);
        stateInstance.setStatus(callSubMachineStatus);
        outputParams.put(DomainConstants.VAR_NAME_SUB_STATEMACHINE_EXEC_STATUE, callSubMachineStatus.toString());
        context.setVariable(DomainConstants.VAR_NAME_OUTPUT_PARAMS, outputParams);
        stateInstance.setOutputParams(outputParams);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("<<<<<<<<<<<<<<<<<<<<<< SubStateMachine[{}] execute finish with status[{}], compensateStatus[{}]", subStateMachine.getStateMachineName(), subStateMachineInstance.getStatus(), subStateMachineInstance.getCompensationStatus());
        }
    } catch (Exception e) {
        LOGGER.error("SubStateMachine[{}] execute failed by state[name:{}]", subStateMachine.getStateMachineName(), subStateMachine.getName(), e);
        if (e instanceof ForwardInvalidException) {
            String retriedId = stateInstance.getStateIdRetriedFor();
            StateInstance stateToBeRetried = null;
            for (StateInstance stateInst : stateMachineInstance.getStateList()) {
                if (retriedId.equals(stateInst.getId())) {
                    stateToBeRetried = stateInst;
                    break;
                }
            }
            if (stateToBeRetried != null) {
                stateInstance.setStatus(stateToBeRetried.getStatus());
            }
        }
        context.setVariable(DomainConstants.VAR_NAME_CURRENT_EXCEPTION, e);
        EngineUtils.handleException(context, subStateMachine, e);
    }
}
Also used : StateMachineEngine(io.seata.saga.engine.StateMachineEngine) StateInstruction(io.seata.saga.engine.pcext.StateInstruction) HashMap(java.util.HashMap) ForwardInvalidException(io.seata.saga.engine.exception.ForwardInvalidException) EngineExecutionException(io.seata.saga.engine.exception.EngineExecutionException) ForwardInvalidException(io.seata.saga.engine.exception.ForwardInvalidException) StateMachineInstance(io.seata.saga.statelang.domain.StateMachineInstance) ExecutionStatus(io.seata.saga.statelang.domain.ExecutionStatus) ArrayList(java.util.ArrayList) List(java.util.List) SubStateMachineImpl(io.seata.saga.statelang.domain.impl.SubStateMachineImpl) HashMap(java.util.HashMap) Map(java.util.Map) StateInstance(io.seata.saga.statelang.domain.StateInstance)

Example 10 with StateInstruction

use of io.seata.saga.engine.pcext.StateInstruction in project seata by seata.

the class LoopTaskHandlerInterceptor method preProcess.

@Override
public void preProcess(ProcessContext context) throws EngineExecutionException {
    if (context.hasVariable(DomainConstants.VAR_NAME_IS_LOOP_STATE)) {
        StateInstruction instruction = context.getInstruction(StateInstruction.class);
        AbstractTaskState currentState = (AbstractTaskState) instruction.getState(context);
        int loopCounter;
        Loop loop;
        // get loop config
        if (context.hasVariable(DomainConstants.VAR_NAME_CURRENT_COMPEN_TRIGGER_STATE)) {
            // compensate condition should get stateToBeCompensated 's config
            CompensationHolder compensationHolder = CompensationHolder.getCurrent(context, true);
            StateInstance stateToBeCompensated = compensationHolder.getStatesNeedCompensation().get(currentState.getName());
            AbstractTaskState compensateState = (AbstractTaskState) stateToBeCompensated.getStateMachineInstance().getStateMachine().getState(EngineUtils.getOriginStateName(stateToBeCompensated));
            loop = compensateState.getLoop();
            loopCounter = LoopTaskUtils.reloadLoopCounter(stateToBeCompensated.getName());
        } else {
            loop = currentState.getLoop();
            loopCounter = (int) context.getVariable(DomainConstants.LOOP_COUNTER);
        }
        Collection collection = LoopContextHolder.getCurrent(context, true).getCollection();
        Map<String, Object> contextVariables = (Map<String, Object>) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_CONTEXT);
        Map<String, Object> copyContextVariables = new ConcurrentHashMap<>(contextVariables);
        copyContextVariables.put(loop.getElementIndexName(), loopCounter);
        copyContextVariables.put(loop.getElementVariableName(), iterator(collection, loopCounter));
        ((HierarchicalProcessContext) context).setVariableLocally(DomainConstants.VAR_NAME_STATEMACHINE_CONTEXT, copyContextVariables);
    }
}
Also used : Loop(io.seata.saga.statelang.domain.TaskState.Loop) CompensationHolder(io.seata.saga.engine.pcext.utils.CompensationHolder) StateInstruction(io.seata.saga.engine.pcext.StateInstruction) HierarchicalProcessContext(io.seata.saga.proctrl.HierarchicalProcessContext) AbstractTaskState(io.seata.saga.statelang.domain.impl.AbstractTaskState) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Map(java.util.Map) StateInstance(io.seata.saga.statelang.domain.StateInstance)

Aggregations

StateInstruction (io.seata.saga.engine.pcext.StateInstruction)23 EngineExecutionException (io.seata.saga.engine.exception.EngineExecutionException)15 StateMachineInstance (io.seata.saga.statelang.domain.StateMachineInstance)14 StateMachineConfig (io.seata.saga.engine.StateMachineConfig)11 StateInstance (io.seata.saga.statelang.domain.StateInstance)10 Map (java.util.Map)10 HierarchicalProcessContext (io.seata.saga.proctrl.HierarchicalProcessContext)7 AbstractTaskState (io.seata.saga.statelang.domain.impl.AbstractTaskState)5 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)5 ProcessContext (io.seata.saga.proctrl.ProcessContext)4 Loop (io.seata.saga.statelang.domain.TaskState.Loop)4 ServiceTaskStateImpl (io.seata.saga.statelang.domain.impl.ServiceTaskStateImpl)4 ArrayList (java.util.ArrayList)4 Date (java.util.Date)4 ForwardInvalidException (io.seata.saga.engine.exception.ForwardInvalidException)3 ProcessContextBuilder (io.seata.saga.engine.utils.ProcessContextBuilder)3 CompensateSubStateMachineState (io.seata.saga.statelang.domain.CompensateSubStateMachineState)3 ExecutionStatus (io.seata.saga.statelang.domain.ExecutionStatus)3 State (io.seata.saga.statelang.domain.State)3 StateMachine (io.seata.saga.statelang.domain.StateMachine)3