Example usage for org.springframework.statemachine StateMachine addStateListener

List of usage examples for org.springframework.statemachine StateMachine addStateListener

Introduction

In this page you can find the example usage for org.springframework.statemachine StateMachine addStateListener.

Prototype

void addStateListener(StateMachineListener<S, E> listener);

Source Link

Document

Adds the state listener.

Usage

From source file:com.netflix.genie.agent.execution.statemachine.StateMachineAutoConfiguration.java

private void registerListeners(final Collection<JobExecutionListener> listeners,
        final StateMachine<States, Events> stateMachine) {
    // Add state machine listeners
    listeners.forEach(stateMachine::addStateListener);

    // Add state action listeners to each state
    for (JobExecutionListener listener : listeners) {
        stateMachine.addStateListener(listener);
        for (State<States, Events> state : stateMachine.getStates()) {
            state.addActionListener(listener);
        }/*from  w  w  w  . j a va2 s .co  m*/
    }
}

From source file:demo.web.StateMachineController.java

@PostConstruct
public void setup() {

    stateMachine.addStateListener(new StateMachineListenerAdapter<States, Events>() {
        @Override/*from w w w  .j  a  v  a2  s . c o  m*/
        public void stateEntered(State<States, Events> state) {
            StateMachineMessage message = new StateMachineMessage();
            message.setMessage("Enter state " + state.getId().toString());
            simpMessagingTemplate.convertAndSend("/topic/sm.message", message);
        }

        @Override
        public void stateExited(State<States, Events> state) {
            StateMachineMessage message = new StateMachineMessage();
            message.setMessage("Exit state " + state.getId().toString());
            simpMessagingTemplate.convertAndSend("/topic/sm.message", message);
        }

        @Override
        public void stateChanged(State<States, Events> from, State<States, Events> to) {
            Map<Object, Object> variables = stateMachine.getExtendedState().getVariables();
            ArrayList<StateMachineEvent> list = new ArrayList<StateMachineEvent>();
            for (States state : stateMachine.getState().getIds()) {
                list.add(new StateMachineEvent(state.toString()));
            }
            simpMessagingTemplate.convertAndSend("/topic/sm.states", list);
            simpMessagingTemplate.convertAndSend("/topic/sm.variables", variables);
        }

        @Override
        public void transitionEnded(Transition<States, Events> transition) {
            if (transition != null && transition.getKind() == TransitionKind.INTERNAL) {
                Map<Object, Object> variables = stateMachine.getExtendedState().getVariables();
                simpMessagingTemplate.convertAndSend("/topic/sm.variables", variables);
            }
        }

        @Override
        public void stateMachineError(StateMachine<States, Events> stateMachine, Exception exception) {
            handleStateMachineError(new StateMachineException("Received error from machine", exception));
        }

    });

    stateMachineEnsemble.addEnsembleListener(new EnsembleListenerAdapter<States, Events>() {

        @Override
        public void ensembleLeaderGranted(StateMachine<States, Events> stateMachine) {
            StateMachineMessage message = new StateMachineMessage();
            message.setMessage("Leader granted " + stateMachine.getUuid().toString());
            simpMessagingTemplate.convertAndSend("/topic/sm.message", message);
        }

        @Override
        public void ensembleLeaderRevoked(StateMachine<States, Events> stateMachine) {
            StateMachineMessage message = new StateMachineMessage();
            message.setMessage("Leader revoked " + stateMachine.getUuid().toString());
            simpMessagingTemplate.convertAndSend("/topic/sm.message", message);
        }
    });
}

From source file:org.springframework.statemachine.config.AbstractStateMachineFactory.java

/**
 * Main constructor that create a {@link StateMachine}.
 *
 * @param uuid for internal usage. Can be null, in that case a random one will be generated.
 * @param machineId represent a user Id, up to you to set what you want.
 * @return a {@link StateMachine}/*from  ww  w.  j  ava2s.c  om*/
 */
@SuppressWarnings("unchecked")
public StateMachine<S, E> getStateMachine(UUID uuid, String machineId) {
    StateMachineModel<S, E> stateMachineModel = resolveStateMachineModel(machineId);
    if (stateMachineModel.getConfigurationData().isVerifierEnabled()) {
        StateMachineModelVerifier<S, E> verifier = stateMachineModel.getConfigurationData().getVerifier();
        if (verifier == null) {
            verifier = new CompositeStateMachineModelVerifier<S, E>();
        }
        verifier.verify(stateMachineModel);
    }

    // shared
    DefaultExtendedState defaultExtendedState = new DefaultExtendedState();

    StateMachine<S, E> machine = null;

    // we store mappings from state id's to states which gets
    // created during the process. This is needed for transitions to
    // find a correct mappings because they use state id's, not actual
    // states.
    final Map<S, State<S, E>> stateMap = new HashMap<S, State<S, E>>();
    Stack<MachineStackItem<S, E>> regionStack = new Stack<MachineStackItem<S, E>>();
    Stack<StateData<S, E>> stateStack = new Stack<StateData<S, E>>();
    Map<Object, StateMachine<S, E>> machineMap = new HashMap<Object, StateMachine<S, E>>();
    Map<S, StateHolder<S, E>> holderMap = new HashMap<S, StateHolder<S, E>>();

    Iterator<Node<StateData<S, E>>> iterator = buildStateDataIterator(stateMachineModel);
    while (iterator.hasNext()) {
        Node<StateData<S, E>> node = iterator.next();
        StateData<S, E> stateData = node.getData();
        StateData<S, E> peek = stateStack.isEmpty() ? null : stateStack.peek();

        // simply push and continue
        if (stateStack.isEmpty()) {
            stateStack.push(stateData);
            continue;
        }

        boolean stackContainsSameParent = false;
        Iterator<StateData<S, E>> ii = stateStack.iterator();
        while (ii.hasNext()) {
            StateData<S, E> sd = ii.next();
            if (stateData != null && ObjectUtils.nullSafeEquals(stateData.getState(), sd.getParent())) {
                stackContainsSameParent = true;
                break;
            }
        }

        if (stateData != null && !stackContainsSameParent) {
            stateStack.push(stateData);
            continue;
        }

        Collection<StateData<S, E>> stateDatas = popSameParents(stateStack);
        int initialCount = getInitialCount(stateDatas);
        Collection<Collection<StateData<S, E>>> regionsStateDatas = splitIntoRegions(stateDatas);
        Collection<TransitionData<S, E>> transitionsData = getTransitionData(iterator.hasNext(), stateDatas,
                stateMachineModel);

        if (initialCount > 1) {
            for (Collection<StateData<S, E>> regionStateDatas : regionsStateDatas) {
                machine = buildMachine(machineMap, stateMap, holderMap, regionStateDatas, transitionsData,
                        resolveBeanFactory(stateMachineModel), contextEvents, defaultExtendedState,
                        stateMachineModel.getTransitionsData(), resolveTaskExecutor(stateMachineModel),
                        resolveTaskScheduler(stateMachineModel), machineId, null, stateMachineModel);
                regionStack.push(new MachineStackItem<S, E>(machine));
            }

            Collection<Region<S, E>> regions = new ArrayList<Region<S, E>>();
            while (!regionStack.isEmpty()) {
                MachineStackItem<S, E> pop = regionStack.pop();
                regions.add(pop.machine);
            }
            S parent = (S) peek.getParent();
            RegionState<S, E> rstate = buildRegionStateInternal(parent, regions, null,
                    stateData != null ? stateData.getEntryActions() : null,
                    stateData != null ? stateData.getExitActions() : null,
                    new DefaultPseudoState<S, E>(PseudoStateKind.INITIAL));
            if (stateData != null) {
                stateMap.put(stateData.getState(), rstate);
            } else {
                // TODO: don't like that we create a last machine here
                Collection<State<S, E>> states = new ArrayList<State<S, E>>();
                states.add(rstate);
                Transition<S, E> initialTransition = new InitialTransition<S, E>(rstate);
                StateMachine<S, E> m = buildStateMachineInternal(states, new ArrayList<Transition<S, E>>(),
                        rstate, initialTransition, null, defaultExtendedState, null, contextEvents,
                        resolveBeanFactory(stateMachineModel), resolveTaskExecutor(stateMachineModel),
                        resolveTaskScheduler(stateMachineModel), beanName,
                        machineId != null ? machineId : stateMachineModel.getConfigurationData().getMachineId(),
                        uuid, stateMachineModel);
                machine = m;
            }
        } else {
            machine = buildMachine(machineMap, stateMap, holderMap, stateDatas, transitionsData,
                    resolveBeanFactory(stateMachineModel), contextEvents, defaultExtendedState,
                    stateMachineModel.getTransitionsData(), resolveTaskExecutor(stateMachineModel),
                    resolveTaskScheduler(stateMachineModel), machineId, uuid, stateMachineModel);
            if (peek.isInitial() || (!peek.isInitial() && !machineMap.containsKey(peek.getParent()))) {
                machineMap.put(peek.getParent(), machine);
            }
        }

        stateStack.push(stateData);
    }

    // setup autostart for top-level machine
    if (machine instanceof LifecycleObjectSupport) {
        ((LifecycleObjectSupport) machine)
                .setAutoStartup(stateMachineModel.getConfigurationData().isAutoStart());
    }

    // set top-level machine as relay
    final StateMachine<S, E> fmachine = machine;
    fmachine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<S, E>>() {

        @Override
        public void apply(StateMachineAccess<S, E> function) {
            function.setRelay(fmachine);
        }
    });

    // add monitoring hooks
    final StateMachineMonitor<S, E> stateMachineMonitor = stateMachineModel.getConfigurationData()
            .getStateMachineMonitor();
    if (stateMachineMonitor != null || defaultStateMachineMonitor != null) {
        fmachine.getStateMachineAccessor().doWithRegion(new StateMachineFunction<StateMachineAccess<S, E>>() {

            @Override
            public void apply(StateMachineAccess<S, E> function) {
                if (defaultStateMachineMonitor != null) {
                    function.addStateMachineMonitor(defaultStateMachineMonitor);
                }
                if (stateMachineMonitor != null) {
                    function.addStateMachineMonitor(stateMachineMonitor);
                }
            }
        });
    }

    // TODO: should error out if sec is enabled but spring-security is not in cp
    if (stateMachineModel.getConfigurationData().isSecurityEnabled()) {
        final StateMachineSecurityInterceptor<S, E> securityInterceptor = new StateMachineSecurityInterceptor<S, E>(
                stateMachineModel.getConfigurationData().getTransitionSecurityAccessDecisionManager(),
                stateMachineModel.getConfigurationData().getEventSecurityAccessDecisionManager(),
                stateMachineModel.getConfigurationData().getEventSecurityRule());
        log.info("Adding security interceptor " + securityInterceptor);
        fmachine.getStateMachineAccessor()
                .doWithAllRegions(new StateMachineFunction<StateMachineAccess<S, E>>() {

                    @Override
                    public void apply(StateMachineAccess<S, E> function) {
                        function.addStateMachineInterceptor(securityInterceptor);
                    }
                });
    }

    // setup distributed state machine if needed.
    // we wrap previously build machine with a distributed
    // state machine and set it to use given ensemble.
    if (stateMachineModel.getConfigurationData().getStateMachineEnsemble() != null) {
        DistributedStateMachine<S, E> distributedStateMachine = new DistributedStateMachine<S, E>(
                stateMachineModel.getConfigurationData().getStateMachineEnsemble(), machine);
        distributedStateMachine.setAutoStartup(stateMachineModel.getConfigurationData().isAutoStart());
        distributedStateMachine.afterPropertiesSet();
        machine = distributedStateMachine;
    }

    for (StateMachineListener<S, E> listener : stateMachineModel.getConfigurationData()
            .getStateMachineListeners()) {
        machine.addStateListener(listener);
    }

    // go through holders and fix state references which
    // were not known at a time holder was created
    for (Entry<S, StateHolder<S, E>> holder : holderMap.entrySet()) {
        holder.getValue().setState(stateMap.get(holder.getKey()));
    }

    return delegateAutoStartup(machine);
}

From source file:org.springframework.statemachine.recipes.TasksHandlerTests.java

@Test
public void testRunOnceSimpleNoFailures() throws InterruptedException {
    TasksHandler handler = TasksHandler.builder().task("1", sleepRunnable()).task("2", sleepRunnable())
            .task("3", sleepRunnable()).build();

    TestListener listener = new TestListener();
    listener.reset(9, 0, 0);//from   w w  w. ja  v  a 2  s . c  o  m
    StateMachine<String, String> machine = handler.getStateMachine();
    machine.addStateListener(listener);
    machine.start();
    assertThat(listener.stateMachineStartedLatch.await(1, TimeUnit.SECONDS), is(true));

    handler.runTasks();

    assertThat(listener.stateChangedLatch.await(8, TimeUnit.SECONDS), is(true));
    assertThat(listener.stateChangedCount, is(9));
    assertThat(machine.getState().getIds(), contains(TasksHandler.STATE_READY));
    Map<Object, Object> variables = machine.getExtendedState().getVariables();
    assertThat(variables.size(), is(3));
}

From source file:org.springframework.statemachine.recipes.TasksHandlerTests.java

@Test
public void testRunFail() throws InterruptedException {
    TasksHandler handler = TasksHandler.builder().task("1", sleepRunnable()).task("2", sleepRunnable())
            .task("3", failRunnable()).build();

    TestListener listener = new TestListener();
    listener.reset(11, 0, 0);//from  w  ww  . ja v a2 s.  co  m
    StateMachine<String, String> machine = handler.getStateMachine();
    machine.addStateListener(listener);
    machine.start();
    assertThat(listener.stateMachineStartedLatch.await(1, TimeUnit.SECONDS), is(true));

    handler.runTasks();

    assertThat(listener.stateChangedLatch.await(8, TimeUnit.SECONDS), is(true));
    assertThat(listener.stateChangedCount, is(11));
    assertThat(machine.getState().getIds(), contains(TasksHandler.STATE_ERROR, TasksHandler.STATE_MANUAL));
    Map<Object, Object> variables = machine.getExtendedState().getVariables();
    assertThat(variables.size(), is(3));
}

From source file:org.springframework.statemachine.recipes.TasksHandlerTests.java

@Test
public void testRunFailAndFixAndContinue() throws InterruptedException {
    TasksHandler handler = TasksHandler.builder().task("1", sleepRunnable()).task("2", sleepRunnable())
            .task("3", failRunnable()).build();

    TestListener listener = new TestListener();
    listener.reset(11, 0, 0);/*from   w  w w.j a v a2s.  c om*/
    StateMachine<String, String> machine = handler.getStateMachine();
    machine.addStateListener(listener);
    machine.start();
    assertThat(listener.stateMachineStartedLatch.await(1, TimeUnit.SECONDS), is(true));

    handler.runTasks();

    assertThat(listener.stateChangedLatch.await(8, TimeUnit.SECONDS), is(true));
    assertThat(listener.stateChangedCount, is(11));
    assertThat(machine.getState().getIds(), contains(TasksHandler.STATE_ERROR, TasksHandler.STATE_MANUAL));

    listener.reset(0, 0, 0, 0, 1);
    handler.fixCurrentProblems();
    assertThat(listener.extendedStateChangedLatch.await(1, TimeUnit.SECONDS), is(true));

    listener.reset(1, 0, 0);
    handler.continueFromError();
    assertThat(listener.stateChangedLatch.await(1, TimeUnit.SECONDS), is(true));
    assertThat(listener.stateChangedCount, is(1));
    assertThat(machine.getState().getIds(), contains(TasksHandler.STATE_READY));
}

From source file:org.springframework.statemachine.recipes.TasksHandlerTests.java

@Test
public void testRunFailAndAutomaticFix() throws InterruptedException {
    TasksHandler handler = TasksHandler.builder().task("1", sleepRunnable()).task("2", sleepRunnable())
            .task("3", failRunnable()).build();

    TestTasksListener tasksListener = new TestTasksListener();
    tasksListener.fix = true;// www .j  a v a2  s.  co m
    handler.addTasksListener(tasksListener);

    TestListener listener = new TestListener();
    listener.reset(1, 0, 0);
    StateMachine<String, String> machine = handler.getStateMachine();
    machine.addStateListener(listener);
    machine.start();
    assertThat(listener.stateMachineStartedLatch.await(1, TimeUnit.SECONDS), is(true));
    assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
    assertThat(listener.stateChangedCount, is(1));

    listener.reset(10, 0, 0);

    handler.runTasks();
    assertThat(listener.stateChangedLatch.await(4, TimeUnit.SECONDS), is(true));
    assertThat(listener.stateChangedCount, is(10));
    assertThat(machine.getState().getIds(), contains(TasksHandler.STATE_READY));
}

From source file:org.springframework.statemachine.recipes.TasksHandlerTests.java

@Test
public void testDagSingleRoot() throws InterruptedException {
    TasksHandler handler = TasksHandler.builder().task("1", sleepRunnable()).task("1", "12", sleepRunnable())
            .task("1", "13", sleepRunnable()).build();

    TestListener listener = new TestListener();
    listener.reset(9, 0, 0);//from   w w  w .  j  av  a  2  s .c o  m
    StateMachine<String, String> machine = handler.getStateMachine();
    machine.addStateListener(listener);
    machine.start();
    assertThat(listener.stateMachineStartedLatch.await(1, TimeUnit.SECONDS), is(true));

    handler.runTasks();

    assertThat(listener.stateChangedLatch.await(12, TimeUnit.SECONDS), is(true));
    assertThat(listener.stateChangedCount, is(9));
    assertThat(machine.getState().getIds(), contains(TasksHandler.STATE_READY));
    Map<Object, Object> variables = machine.getExtendedState().getVariables();
    assertThat(variables.size(), is(3));
}

From source file:org.springframework.statemachine.recipes.TasksHandlerTests.java

@Test
public void testDagMultiRoot() throws InterruptedException {
    TasksHandler handler = TasksHandler.builder().task("1", sleepRunnable()).task("1", "12", sleepRunnable())
            .task("1", "13", sleepRunnable()).task("2", sleepRunnable()).task("2", "22", sleepRunnable())
            .task("2", "23", sleepRunnable()).task("3", sleepRunnable()).task("3", "32", sleepRunnable())
            .task("3", "33", sleepRunnable()).build();

    TestListener listener = new TestListener();
    StateMachine<String, String> machine = handler.getStateMachine();

    machine.addStateListener(listener);
    listener.reset(1, 0, 0);/*from   w w w  . j  a  va  2s.  c o m*/
    machine.start();
    assertThat(listener.stateMachineStartedLatch.await(1, TimeUnit.SECONDS), is(true));
    assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
    assertThat(listener.stateChangedCount, is(1));

    listener.reset(20, 0, 0);
    handler.runTasks();

    assertThat(listener.stateChangedLatch.await(10, TimeUnit.SECONDS), is(true));
    assertThat(listener.stateChangedCount, is(20));
    assertThat(machine.getState().getIds(), contains(TasksHandler.STATE_READY));
    Map<Object, Object> variables = machine.getExtendedState().getVariables();
    assertThat(variables.size(), is(9));
}

From source file:org.springframework.statemachine.recipes.TasksHandlerTests.java

@Test
public void testEvents1() throws InterruptedException {
    TestTasksListener tasksListener = new TestTasksListener();
    TasksHandler handler = TasksHandler.builder().task("1", sleepRunnable()).task("2", sleepRunnable())
            .task("3", sleepRunnable()).listener(tasksListener).build();

    TestListener listener = new TestListener();
    listener.reset(9, 0, 0);//from  w  ww  . j a  v a 2s.c  o  m
    StateMachine<String, String> machine = handler.getStateMachine();
    machine.addStateListener(listener);
    machine.start();
    assertThat(listener.stateMachineStartedLatch.await(1, TimeUnit.SECONDS), is(true));

    tasksListener.reset(1, 0, 3, 3, 0, 3, 1, 0);
    handler.runTasks();

    assertThat(listener.stateChangedLatch.await(8, TimeUnit.SECONDS), is(true));
    assertThat(listener.stateChangedCount, is(9));
    assertThat(machine.getState().getIds(), contains(TasksHandler.STATE_READY));

    assertThat(tasksListener.onTasksStartedLatch.await(1, TimeUnit.SECONDS), is(true));
    assertThat(tasksListener.onTasksStarted, is(1));
    assertThat(tasksListener.onTaskPreExecuteLatch.await(3, TimeUnit.SECONDS), is(true));
    assertThat(tasksListener.onTaskPreExecute, is(3));
    assertThat(tasksListener.onTaskPostExecuteLatch.await(3, TimeUnit.SECONDS), is(true));
    assertThat(tasksListener.onTaskPostExecute, is(3));
    assertThat(tasksListener.onTaskFailed, is(0));
    assertThat(tasksListener.onTaskSuccessLatch.await(3, TimeUnit.SECONDS), is(true));
    assertThat(tasksListener.onTaskSuccess, is(3));
    assertThat(tasksListener.onTasksSuccessLatch.await(1, TimeUnit.SECONDS), is(true));
    assertThat(tasksListener.onTasksSuccess, is(1));
}