/* * Copyright 2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.statemachine.recipes; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.junit.Test; import org.springframework.core.task.SyncTaskExecutor; import org.springframework.messaging.Message; import org.springframework.messaging.support.MessageBuilder; import org.springframework.statemachine.StateMachine; import org.springframework.statemachine.config.StateMachineBuilder; import org.springframework.statemachine.recipes.persist.PersistStateMachineHandler; import org.springframework.statemachine.recipes.persist.PersistStateMachineHandler.PersistStateChangeListener; import org.springframework.statemachine.state.State; import org.springframework.statemachine.transition.Transition; public class PersistStateMachineHandlerTests { @Test public void testAcceptedStateChangeViaPersist() throws Exception { StateMachine<String,String> stateMachine = buildTestStateMachine(); PersistStateMachineHandler handler = new PersistStateMachineHandler(stateMachine); handler.afterPropertiesSet(); handler.start(); TestPersistStateChangeListener listener = new TestPersistStateChangeListener(); handler.addPersistStateChangeListener(listener); Message<String> event = MessageBuilder.withPayload("E2").build(); boolean accepted = handler.handleEventWithState(event, "S1"); assertThat(accepted, is(true)); assertThat(listener.latch.await(1, TimeUnit.SECONDS), is(true)); assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2")); } @Test public void testNotAcceptedStateChangeViaPersist() throws Exception { StateMachine<String,String> stateMachine = buildTestStateMachine(); PersistStateMachineHandler handler = new PersistStateMachineHandler(stateMachine); handler.afterPropertiesSet(); handler.start(); TestPersistStateChangeListener listener = new TestPersistStateChangeListener(); handler.addPersistStateChangeListener(listener); Message<String> event = MessageBuilder.withPayload("E1").build(); boolean accepted = handler.handleEventWithState(event, "S1"); assertThat(accepted, is(false)); assertThat(listener.latch.await(1, TimeUnit.SECONDS), is(false)); assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1")); } @Test public void testChoice() throws Exception { StateMachine<String,String> stateMachine = buildTestStateMachine2(); PersistStateMachineHandler handler = new PersistStateMachineHandler(stateMachine); handler.afterPropertiesSet(); handler.start(); TestPersistStateChangeListener listener = new TestPersistStateChangeListener(); handler.addPersistStateChangeListener(listener); Message<String> event = MessageBuilder.withPayload("E1").build(); boolean accepted = handler.handleEventWithState(event, "SI"); assertThat(accepted, is(true)); assertThat(listener.latch.await(1, TimeUnit.SECONDS), is(true)); assertThat(listener.states.size(), is(1)); assertThat(listener.states.get(0).getId(), is("S2")); assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2")); } private static class TestPersistStateChangeListener implements PersistStateChangeListener { CountDownLatch latch = new CountDownLatch(1); List<State<String, String>> states = new ArrayList<>(); @Override public void onPersist(State<String, String> state, Message<String> message, Transition<String, String> transition, StateMachine<String, String> stateMachine) { states.add(state); latch.countDown(); } } private static StateMachine<String, String> buildTestStateMachine() throws Exception { StateMachineBuilder.Builder<String, String> builder = StateMachineBuilder.builder(); builder.configureConfiguration() .withConfiguration() .taskExecutor(new SyncTaskExecutor()) .autoStartup(true); builder.configureStates() .withStates() .initial("SI") .state("S1") .state("S2"); builder.configureTransitions() .withExternal() .source("SI").target("S1").event("E1") .and() .withExternal() .source("S1").target("S2").event("E2"); return builder.build(); } private static StateMachine<String, String> buildTestStateMachine2() throws Exception { StateMachineBuilder.Builder<String, String> builder = StateMachineBuilder.builder(); builder.configureConfiguration() .withConfiguration() .taskExecutor(new SyncTaskExecutor()) .autoStartup(true); builder.configureStates() .withStates() .initial("SI") .choice("S1") .state("S2") .state("S3"); builder.configureTransitions() .withExternal() .source("SI").target("S1").event("E1") .and() .withChoice() .source("S1") .last("S2"); return builder.build(); } }