Search in sources :

Example 1 with StateMachineEngine

use of io.seata.saga.engine.StateMachineEngine 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 2 with StateMachineEngine

use of io.seata.saga.engine.StateMachineEngine in project seata by seata.

the class StateMachineAsyncDBMockServerTests method initApplicationContext.

@BeforeAll
public static void initApplicationContext() throws InterruptedException {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:saga/spring/statemachine_engine_db_mockserver_test.xml");
    stateMachineEngine = applicationContext.getBean("stateMachineEngine", StateMachineEngine.class);
}
Also used : ApplicationContext(org.springframework.context.ApplicationContext) ClassPathXmlApplicationContext(org.springframework.context.support.ClassPathXmlApplicationContext) StateMachineEngine(io.seata.saga.engine.StateMachineEngine) ClassPathXmlApplicationContext(org.springframework.context.support.ClassPathXmlApplicationContext) BeforeAll(org.junit.jupiter.api.BeforeAll)

Example 3 with StateMachineEngine

use of io.seata.saga.engine.StateMachineEngine in project seata by seata.

the class StateMachineDBTests method initApplicationContext.

@BeforeAll
public static void initApplicationContext() throws InterruptedException {
    startSeataServer();
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:saga/spring/statemachine_engine_db_test.xml");
    stateMachineEngine = applicationContext.getBean("stateMachineEngine", StateMachineEngine.class);
}
Also used : ClassPathXmlApplicationContext(org.springframework.context.support.ClassPathXmlApplicationContext) ApplicationContext(org.springframework.context.ApplicationContext) StateMachineEngine(io.seata.saga.engine.StateMachineEngine) ClassPathXmlApplicationContext(org.springframework.context.support.ClassPathXmlApplicationContext) BeforeAll(org.junit.jupiter.api.BeforeAll)

Example 4 with StateMachineEngine

use of io.seata.saga.engine.StateMachineEngine in project seata by seata.

the class StateMachineDBMockServerTests method initApplicationContext.

@BeforeAll
public static void initApplicationContext() throws InterruptedException {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:saga/spring/statemachine_engine_db_mockserver_test.xml");
    stateMachineEngine = applicationContext.getBean("stateMachineEngine", StateMachineEngine.class);
}
Also used : ApplicationContext(org.springframework.context.ApplicationContext) ClassPathXmlApplicationContext(org.springframework.context.support.ClassPathXmlApplicationContext) StateMachineEngine(io.seata.saga.engine.StateMachineEngine) ClassPathXmlApplicationContext(org.springframework.context.support.ClassPathXmlApplicationContext) BeforeAll(org.junit.jupiter.api.BeforeAll)

Example 5 with StateMachineEngine

use of io.seata.saga.engine.StateMachineEngine in project seata by seata.

the class ServiceTaskStateHandler method process.

@Override
public void process(ProcessContext context) throws EngineExecutionException {
    StateInstruction instruction = context.getInstruction(StateInstruction.class);
    ServiceTaskStateImpl state = (ServiceTaskStateImpl) instruction.getState(context);
    String serviceName = state.getServiceName();
    String methodName = state.getServiceMethod();
    StateInstance stateInstance = (StateInstance) context.getVariable(DomainConstants.VAR_NAME_STATE_INST);
    Object result;
    try {
        List<Object> input = (List<Object>) context.getVariable(DomainConstants.VAR_NAME_INPUT_PARAMS);
        // Set the current task execution status to RU (Running)
        stateInstance.setStatus(ExecutionStatus.RU);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug(">>>>>>>>>>>>>>>>>>>>>> Start to execute State[{}], ServiceName[{}], Method[{}], Input:{}", state.getName(), serviceName, methodName, input);
        }
        if (state instanceof CompensateSubStateMachineState) {
            // If it is the compensation of the substate machine,
            // directly call the state machine's compensate method
            result = compensateSubStateMachine(context, state, input, stateInstance, (StateMachineEngine) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_ENGINE));
        } else {
            StateMachineConfig stateMachineConfig = (StateMachineConfig) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_CONFIG);
            ServiceInvoker serviceInvoker = stateMachineConfig.getServiceInvokerManager().getServiceInvoker(state.getServiceType());
            if (serviceInvoker == null) {
                throw new EngineExecutionException("No such ServiceInvoker[" + state.getServiceType() + "]", FrameworkErrorCode.ObjectNotExists);
            }
            if (serviceInvoker instanceof ApplicationContextAware) {
                ((ApplicationContextAware) serviceInvoker).setApplicationContext(stateMachineConfig.getApplicationContext());
            }
            result = serviceInvoker.invoke(state, input.toArray());
        }
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("<<<<<<<<<<<<<<<<<<<<<< State[{}], ServiceName[{}], Method[{}] Execute finish. result: {}", state.getName(), serviceName, methodName, result);
        }
        if (result != null) {
            stateInstance.setOutputParams(result);
            ((HierarchicalProcessContext) context).setVariableLocally(DomainConstants.VAR_NAME_OUTPUT_PARAMS, result);
        }
    } catch (Throwable e) {
        LOGGER.error("<<<<<<<<<<<<<<<<<<<<<< State[{}], ServiceName[{}], Method[{}] Execute failed.", state.getName(), serviceName, methodName, e);
        ((HierarchicalProcessContext) context).setVariableLocally(DomainConstants.VAR_NAME_CURRENT_EXCEPTION, e);
        EngineUtils.handleException(context, state, e);
    }
}
Also used : StateMachineEngine(io.seata.saga.engine.StateMachineEngine) ApplicationContextAware(org.springframework.context.ApplicationContextAware) StateInstruction(io.seata.saga.engine.pcext.StateInstruction) HierarchicalProcessContext(io.seata.saga.proctrl.HierarchicalProcessContext) CompensateSubStateMachineState(io.seata.saga.statelang.domain.CompensateSubStateMachineState) EngineExecutionException(io.seata.saga.engine.exception.EngineExecutionException) ServiceTaskStateImpl(io.seata.saga.statelang.domain.impl.ServiceTaskStateImpl) ArrayList(java.util.ArrayList) List(java.util.List) StateMachineConfig(io.seata.saga.engine.StateMachineConfig) ServiceInvoker(io.seata.saga.engine.invoker.ServiceInvoker) StateInstance(io.seata.saga.statelang.domain.StateInstance)

Aggregations

StateMachineEngine (io.seata.saga.engine.StateMachineEngine)6 ClassPathXmlApplicationContext (org.springframework.context.support.ClassPathXmlApplicationContext)4 BeforeAll (org.junit.jupiter.api.BeforeAll)3 ApplicationContext (org.springframework.context.ApplicationContext)3 EngineExecutionException (io.seata.saga.engine.exception.EngineExecutionException)2 StateInstruction (io.seata.saga.engine.pcext.StateInstruction)2 StateInstance (io.seata.saga.statelang.domain.StateInstance)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 StateMachineConfig (io.seata.saga.engine.StateMachineConfig)1 ForwardInvalidException (io.seata.saga.engine.exception.ForwardInvalidException)1 ServiceInvoker (io.seata.saga.engine.invoker.ServiceInvoker)1 HierarchicalProcessContext (io.seata.saga.proctrl.HierarchicalProcessContext)1 CompensateSubStateMachineState (io.seata.saga.statelang.domain.CompensateSubStateMachineState)1 ExecutionStatus (io.seata.saga.statelang.domain.ExecutionStatus)1 StateMachineInstance (io.seata.saga.statelang.domain.StateMachineInstance)1 ServiceTaskStateImpl (io.seata.saga.statelang.domain.impl.ServiceTaskStateImpl)1 SubStateMachineImpl (io.seata.saga.statelang.domain.impl.SubStateMachineImpl)1 ApplicationKeeper (io.seata.samples.saga.ApplicationKeeper)1 HashMap (java.util.HashMap)1