diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/StateMachineContext.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/StateMachineContext.java index 256474b9..4c4a958b 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/StateMachineContext.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/StateMachineContext.java @@ -28,6 +28,13 @@ import java.util.Map; */ public interface StateMachineContext { + /** + * Gets the machine id. + * + * @return the machine id + */ + String getId(); + /** * Gets the child contexts if any. * diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/AbstractStateMachineFactory.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/AbstractStateMachineFactory.java index 4c12b6f8..117dfb13 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/AbstractStateMachineFactory.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/AbstractStateMachineFactory.java @@ -112,9 +112,14 @@ public abstract class AbstractStateMachineFactory extends LifecycleObjectS this.beanName = name; } - @SuppressWarnings("unchecked") @Override public StateMachine getStateMachine() { + return getStateMachine(null); + } + + @SuppressWarnings("unchecked") + @Override + public StateMachine getStateMachine(String machineId) { if (stateMachineModel.getConfigurationData().isVerifierEnabled()) { StateMachineModelVerifier verifier = stateMachineModel.getConfigurationData().getVerifier(); if (verifier == null) { @@ -173,7 +178,7 @@ public abstract class AbstractStateMachineFactory extends LifecycleObjectS for (Collection> regionStateDatas : regionsStateDatas) { machine = buildMachine(machineMap, stateMap, regionStateDatas, transitionsData, resolveBeanFactory(), contextEvents, defaultExtendedState, stateMachineModel.getTransitionsData(), resolveTaskExecutor(), - resolveTaskScheduler()); + resolveTaskScheduler(), machineId); regionStack.push(new MachineStackItem(machine)); } @@ -192,14 +197,16 @@ public abstract class AbstractStateMachineFactory extends LifecycleObjectS Collection> states = new ArrayList>(); states.add(rstate); Transition initialTransition = new InitialTransition(rstate); - StateMachine m = buildStateMachineInternal(states, new ArrayList>(), rstate, - initialTransition, null, defaultExtendedState, null, contextEvents, resolveBeanFactory(), - resolveTaskExecutor(), resolveTaskScheduler(), beanName); + StateMachine m = buildStateMachineInternal(states, new ArrayList>(), rstate, initialTransition, + null, defaultExtendedState, null, contextEvents, resolveBeanFactory(), resolveTaskExecutor(), + resolveTaskScheduler(), beanName, + machineId != null ? machineId : stateMachineModel.getConfigurationData().getMachineId()); machine = m; } } else { - machine = buildMachine(machineMap, stateMap, stateDatas, transitionsData, resolveBeanFactory(), - contextEvents, defaultExtendedState, stateMachineModel.getTransitionsData(), resolveTaskExecutor(), resolveTaskScheduler()); + machine = buildMachine(machineMap, stateMap, stateDatas, transitionsData, resolveBeanFactory(), contextEvents, + defaultExtendedState, stateMachineModel.getTransitionsData(), resolveTaskExecutor(), resolveTaskScheduler(), + machineId); if (peek.isInitial() || (!peek.isInitial() && !machineMap.containsKey(peek.getParent()))) { machineMap.put(peek.getParent(), machine); } @@ -395,7 +402,7 @@ public abstract class AbstractStateMachineFactory extends LifecycleObjectS Collection> stateDatas, Collection> transitionsData, BeanFactory beanFactory, Boolean contextEvents, DefaultExtendedState defaultExtendedState, TransitionsData stateMachineTransitions, TaskExecutor taskExecutor, - TaskScheduler taskScheduler) { + TaskScheduler taskScheduler, String machineId) { State state = null; State initialState = null; PseudoState historyState = null; @@ -579,7 +586,7 @@ public abstract class AbstractStateMachineFactory extends LifecycleObjectS Transition initialTransition = new InitialTransition(initialState, initialAction); StateMachine machine = buildStateMachineInternal(states, transitions, initialState, initialTransition, null, defaultExtendedState, historyState, contextEvents, beanFactory, taskExecutor, taskScheduler, - beanName); + beanName, machineId != null ? machineId : stateMachineModel.getConfigurationData().getMachineId()); return machine; } @@ -587,7 +594,7 @@ public abstract class AbstractStateMachineFactory extends LifecycleObjectS Collection> transitions, State initialState, Transition initialTransition, Message initialEvent, ExtendedState extendedState, PseudoState historyState, Boolean contextEventsEnabled, BeanFactory beanFactory, TaskExecutor taskExecutor, - TaskScheduler taskScheduler, String beanName); + TaskScheduler taskScheduler, String beanName, String machineId); protected abstract State buildStateInternal(S id, Collection deferred, Collection> entryActions, Collection> exitActions, PseudoState pseudoState); diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/ObjectStateMachineFactory.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/ObjectStateMachineFactory.java index 4edab967..4054da75 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/ObjectStateMachineFactory.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/ObjectStateMachineFactory.java @@ -59,9 +59,10 @@ public class ObjectStateMachineFactory extends AbstractStateMachineFactory Collection> transitions, State initialState, Transition initialTransition, Message initialEvent, ExtendedState extendedState, PseudoState historyState, Boolean contextEventsEnabled, BeanFactory beanFactory, TaskExecutor taskExecutor, - TaskScheduler taskScheduler, String beanName) { + TaskScheduler taskScheduler, String beanName, String machineId) { ObjectStateMachine machine = new ObjectStateMachine(states, transitions, initialState, initialTransition, initialEvent, extendedState); + machine.setId(machineId); machine.setHistoryState(historyState); if (contextEventsEnabled != null) { machine.setContextEventsEnabled(contextEventsEnabled); @@ -73,7 +74,7 @@ public class ObjectStateMachineFactory extends AbstractStateMachineFactory machine.setTaskExecutor(taskExecutor); } if (taskScheduler != null) { - machine.setTaskScheduler(taskScheduler);; + machine.setTaskScheduler(taskScheduler); } if (machine instanceof BeanNameAware) { ((BeanNameAware)machine).setBeanName(beanName); diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/StateMachineFactory.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/StateMachineFactory.java index e890f498..32f30b8c 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/StateMachineFactory.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/StateMachineFactory.java @@ -19,7 +19,7 @@ import org.springframework.statemachine.StateMachine; /** * {@code StateMachineFactory} is a strategy interface building {@link StateMachine}s. - * + * * @author Janne Valkealahti * * @param the type of state @@ -29,9 +29,17 @@ public interface StateMachineFactory { /** * Build a new {@link StateMachine} instance. - * + * * @return a new state machine instance. */ StateMachine getStateMachine(); + /** + * Build a new {@link StateMachine} instance + * with a given machine id. + * + * @param machineId the machine id + * @return a new state machine instance. + */ + StateMachine getStateMachine(String machineId); } diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/builders/StateMachineConfigurationBuilder.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/builders/StateMachineConfigurationBuilder.java index 626058b0..fb6fa115 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/builders/StateMachineConfigurationBuilder.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/builders/StateMachineConfigurationBuilder.java @@ -52,6 +52,7 @@ public class StateMachineConfigurationBuilder extends AbstractConfiguredAnnotationBuilder, StateMachineConfigurationConfigurer, StateMachineConfigurationBuilder> implements StateMachineConfigurationConfigurer { + private String machineId; private BeanFactory beanFactory; private TaskExecutor taskExecutor; private TaskScheduler taskScheculer; @@ -117,7 +118,16 @@ public class StateMachineConfigurationBuilder protected ConfigurationData performBuild() throws Exception { return new ConfigurationData(beanFactory, taskExecutor, taskScheculer, autoStart, ensemble, listeners, securityEnabled, transitionSecurityAccessDecisionManager, eventSecurityAccessDecisionManager, eventSecurityRule, - transitionSecurityRule, verifierEnabled, verifier); + transitionSecurityRule, verifierEnabled, verifier, machineId); + } + + /** + * Sets the machine id. + * + * @param machineId the new machine id + */ + public void setMachineId(String machineId) { + this.machineId = machineId; } /** diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/configurers/ConfigurationConfigurer.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/configurers/ConfigurationConfigurer.java index 2f1ac309..2ad2205c 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/configurers/ConfigurationConfigurer.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/configurers/ConfigurationConfigurer.java @@ -18,6 +18,7 @@ package org.springframework.statemachine.config.configurers; import org.springframework.beans.factory.BeanFactory; import org.springframework.core.task.TaskExecutor; import org.springframework.scheduling.TaskScheduler; +import org.springframework.statemachine.StateMachine; import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer; import org.springframework.statemachine.config.common.annotation.AnnotationConfigurerBuilder; import org.springframework.statemachine.listener.StateMachineListener; @@ -33,6 +34,15 @@ import org.springframework.statemachine.listener.StateMachineListener; public interface ConfigurationConfigurer extends AnnotationConfigurerBuilder> { + /** + * Specify a machine identifier. + * + * @param id the machine identifier + * @return configurer for chaining + * @see StateMachine#getId() + */ + ConfigurationConfigurer machineId(String id); + /** * Specify a {@link BeanFactory}. * diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/configurers/DefaultConfigurationConfigurer.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/configurers/DefaultConfigurationConfigurer.java index dcad9753..da5e21e4 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/configurers/DefaultConfigurationConfigurer.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/configurers/DefaultConfigurationConfigurer.java @@ -39,6 +39,7 @@ public class DefaultConfigurationConfigurer extends AnnotationConfigurerAdapter, StateMachineConfigurationConfigurer, StateMachineConfigurationBuilder> implements ConfigurationConfigurer { + private String machineId; private BeanFactory beanFactory; private TaskExecutor taskExecutor; private TaskScheduler taskScheculer; @@ -47,6 +48,7 @@ public class DefaultConfigurationConfigurer @Override public void configure(StateMachineConfigurationBuilder builder) throws Exception { + builder.setMachineId(machineId); builder.setBeanFactory(beanFactory); builder.setTaskExecutor(taskExecutor); builder.setTaskScheculer(taskScheculer); @@ -54,6 +56,12 @@ public class DefaultConfigurationConfigurer builder.setStateMachineListeners(listeners); } + @Override + public ConfigurationConfigurer machineId(String id) { + this.machineId = id; + return this; + } + @Override public ConfigurationConfigurer beanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/model/ConfigurationData.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/model/ConfigurationData.java index e1382239..96f41b0b 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/model/ConfigurationData.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/model/ConfigurationData.java @@ -41,6 +41,7 @@ import org.springframework.statemachine.security.SecurityRule; */ public class ConfigurationData { + private final String machineId; private final BeanFactory beanFactory; private final TaskExecutor taskExecutor; private final TaskScheduler taskScheduler; @@ -60,7 +61,7 @@ public class ConfigurationData { */ public ConfigurationData() { this(null, new SyncTaskExecutor(), new ConcurrentTaskScheduler(), false, null, new ArrayList>(), false, - null, null, null, null, true, new DefaultStateMachineModelVerifier()); + null, null, null, null, true, new DefaultStateMachineModelVerifier(), null); } /** @@ -79,13 +80,14 @@ public class ConfigurationData { * @param transitionSecurityRule the transition security rule * @param verifierEnabled the verifier enabled flag * @param verifier the state machine model verifier + * @param machineId the machine id */ public ConfigurationData(BeanFactory beanFactory, TaskExecutor taskExecutor, TaskScheduler taskScheduler, boolean autoStart, StateMachineEnsemble ensemble, List> listeners, boolean securityEnabled, AccessDecisionManager transitionSecurityAccessDecisionManager, AccessDecisionManager eventSecurityAccessDecisionManager, SecurityRule eventSecurityRule, SecurityRule transitionSecurityRule, boolean verifierEnabled, - StateMachineModelVerifier verifier) { + StateMachineModelVerifier verifier, String machineId) { this.beanFactory = beanFactory; this.taskExecutor = taskExecutor; this.taskScheduler = taskScheduler; @@ -99,6 +101,11 @@ public class ConfigurationData { this.transitionSecurityRule = transitionSecurityRule; this.verifierEnabled = verifierEnabled; this.verifier = verifier; + this.machineId = machineId; + } + + public String getMachineId() { + return machineId; } /** diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/ensemble/DistributedStateMachine.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/ensemble/DistributedStateMachine.java index 203c87d6..e583891b 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/ensemble/DistributedStateMachine.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/ensemble/DistributedStateMachine.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2016 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. @@ -16,6 +16,7 @@ package org.springframework.statemachine.ensemble; import java.util.Collection; +import java.util.UUID; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -105,7 +106,7 @@ public class DistributedStateMachine extends LifecycleObjectSupport implem // adding state machine id to the message so that // listeners can know from where a state change originates return delegate.sendEvent(MessageBuilder.fromMessage(event) - .setHeader(StateMachineSystemConstants.STATEMACHINE_IDENTIFIER, delegate.getId()).build()); + .setHeader(StateMachineSystemConstants.STATEMACHINE_IDENTIFIER, delegate.getUuid()).build()); } @Override @@ -168,6 +169,11 @@ public class DistributedStateMachine extends LifecycleObjectSupport implem return delegate.getStateMachineAccessor(); } + @Override + public UUID getUuid() { + return delegate.getUuid(); + } + @Override public String getId() { return delegate.getId(); @@ -198,7 +204,7 @@ public class DistributedStateMachine extends LifecycleObjectSupport implem } // only handle if state change originates from this dist machine if (message != null - && ObjectUtils.nullSafeEquals(delegate.getId(), + && ObjectUtils.nullSafeEquals(delegate.getUuid(), message.getHeaders().get(StateMachineSystemConstants.STATEMACHINE_IDENTIFIER))) { ensemble.setState(new DefaultStateMachineContext(transition.getTarget().getId(), message .getPayload(), message.getHeaders(), stateMachine.getExtendedState())); @@ -220,7 +226,7 @@ public class DistributedStateMachine extends LifecycleObjectSupport implem // only handle if state change originates from this dist machine if (stateContext.getTransition() != null && stateContext.getTransition().getKind() == TransitionKind.INTERNAL - && ObjectUtils.nullSafeEquals(delegate.getId(), + && ObjectUtils.nullSafeEquals(delegate.getUuid(), stateContext.getMessageHeader(StateMachineSystemConstants.STATEMACHINE_IDENTIFIER))) { StateMachineContext current = ensemble.getState(); if (current != null) { @@ -276,7 +282,7 @@ public class DistributedStateMachine extends LifecycleObjectSupport implem }); } log.info("Requesting to start delegating state machine " + delegate); - log.info("Delegating machine id " + delegate.getId()); + log.info("Delegating machine id " + delegate.getUuid()); delegate.start(); } } @@ -292,7 +298,7 @@ public class DistributedStateMachine extends LifecycleObjectSupport implem @Override public void stateChanged(StateMachineContext context) { // do not pass if state change was originated from this dist machine - if (!ObjectUtils.nullSafeEquals(delegate.getId(), + if (!ObjectUtils.nullSafeEquals(delegate.getUuid(), context.getEventHeaders().get(StateMachineSystemConstants.STATEMACHINE_IDENTIFIER))) { delegate.sendEvent(MessageBuilder.withPayload(context.getEvent()) .copyHeaders(context.getEventHeaders()).build()); diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/persist/AbstractStateMachinePersister.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/persist/AbstractStateMachinePersister.java index a9a6dd57..d4224c12 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/persist/AbstractStateMachinePersister.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/persist/AbstractStateMachinePersister.java @@ -129,6 +129,6 @@ public abstract class AbstractStateMachinePersister implements StateMac } } } - return new DefaultStateMachineContext(childs, id, null, null, extendedState, historyStates); + return new DefaultStateMachineContext(childs, id, null, null, extendedState, historyStates, stateMachine.getId()); } } diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/region/Region.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/region/Region.java index b475d2b1..159e344a 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/region/Region.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/region/Region.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2016 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. @@ -16,6 +16,7 @@ package org.springframework.statemachine.region; import java.util.Collection; +import java.util.UUID; import org.springframework.messaging.Message; import org.springframework.statemachine.listener.StateMachineListener; @@ -38,6 +39,15 @@ public interface Region { * * @return the region and state machine unique id */ + UUID getUuid(); + + /** + * Gets the region and state machine id. This identifier + * is provided for users disposal and can be set from + * a various ways to build a machines. + * + * @return the region and state machine id + */ String getId(); /** diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/support/AbstractStateMachine.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/support/AbstractStateMachine.java index edc0e360..572d49ff 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/support/AbstractStateMachine.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/support/AbstractStateMachine.java @@ -100,7 +100,9 @@ public abstract class AbstractStateMachine extends StateMachineObjectSuppo private Boolean initialEnabled = null; - private String id = UUID.randomUUID().toString(); + private UUID uuid = UUID.randomUUID(); + + private String id; private volatile Message forwardedInitialEvent; @@ -490,6 +492,8 @@ public abstract class AbstractStateMachine extends StateMachineObjectSuppo if (currentState != null) { buf.append(StringUtils.collectionToCommaDelimitedString(currentState.getIds())); } + buf.append(" / uuid="); + buf.append(uuid); buf.append(" / id="); buf.append(id); return buf.toString(); @@ -507,6 +511,7 @@ public abstract class AbstractStateMachine extends StateMachineObjectSuppo if (log.isDebugEnabled()) { log.debug("Request to reset state machine: stateMachine=[" + this + "] stateMachineContext=[" + stateMachineContext + "]"); } + setId(stateMachineContext.getId()); S state = stateMachineContext.getState(); boolean stateSet = false; // handle state reset @@ -622,11 +627,25 @@ public abstract class AbstractStateMachine extends StateMachineObjectSuppo stateMachineExecutor.addStateMachineInterceptor(interceptor); } + @Override + public UUID getUuid() { + return uuid; + } + @Override public String getId() { return id; } + /** + * Sets the machine id. + * + * @param id the new machine id + */ + public void setId(String id) { + this.id = id; + } + protected synchronized boolean acceptEvent(Message message) { if ((currentState != null && currentState.shouldDefer(message))) { log.info("Current state " + currentState + " deferred event " + message); diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/support/DefaultStateMachineContext.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/support/DefaultStateMachineContext.java index 2a1427f3..fbc812fc 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/support/DefaultStateMachineContext.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/support/DefaultStateMachineContext.java @@ -33,6 +33,7 @@ import org.springframework.statemachine.StateMachineContext; */ public class DefaultStateMachineContext implements StateMachineContext { + private final String id; private final List> childs; private final S state; private final Map historyStates; @@ -66,6 +67,21 @@ public class DefaultStateMachineContext implements StateMachineContext>(), state, event, eventHeaders, extendedState, historyStates); } + /** + * Instantiates a new default state machine context. + * + * @param state the state + * @param event the event + * @param eventHeaders the event headers + * @param extendedState the extended state + * @param historyStates the history state mappings + * @param id the machine id + */ + public DefaultStateMachineContext(S state, E event, Map eventHeaders, ExtendedState extendedState, + Map historyStates, String id) { + this(new ArrayList>(), state, event, eventHeaders, extendedState, historyStates, id); + } + /** * Instantiates a new default state machine context. * @@ -92,12 +108,34 @@ public class DefaultStateMachineContext implements StateMachineContext> childs, S state, E event, Map eventHeaders, ExtendedState extendedState, Map historyStates) { + this(childs, state, event, eventHeaders, extendedState, historyStates, null); + } + + /** + * Instantiates a new default state machine context. + * + * @param childs the child state machine contexts + * @param state the state + * @param event the event + * @param eventHeaders the event headers + * @param extendedState the extended state + * @param historyStates the history state mappings + * @param id the machine id + */ + public DefaultStateMachineContext(List> childs, S state, E event, + Map eventHeaders, ExtendedState extendedState, Map historyStates, String id) { this.childs = childs; this.state = state; this.event = event; this.eventHeaders = eventHeaders; this.extendedState = extendedState; this.historyStates = historyStates != null ? historyStates : new HashMap(); + this.id = id; + } + + @Override + public String getId() { + return id; } @Override @@ -132,7 +170,7 @@ public class DefaultStateMachineContext implements StateMachineContext extends LifecycleObjectSupport im if (!map.containsKey(StateMachineSystemConstants.STATEMACHINE_IDENTIFIER)) { // don't set sm id if it's already present because // we want to keep the originating sm id - map.put(StateMachineSystemConstants.STATEMACHINE_IDENTIFIER, stateMachine.getId()); + map.put(StateMachineSystemConstants.STATEMACHINE_IDENTIFIER, stateMachine.getUuid()); } return new DefaultStateContext(Stage.TRANSITION, message, new MessageHeaders(map), stateMachine.getExtendedState(), transition, stateMachine, null, null, null); } diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/access/StateMachineAccessTests.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/access/StateMachineAccessTests.java index 89aa914b..b7ae2370 100644 --- a/spring-statemachine-core/src/test/java/org/springframework/statemachine/access/StateMachineAccessTests.java +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/access/StateMachineAccessTests.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertThat; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.UUID; import org.junit.Test; import org.springframework.messaging.Message; @@ -173,6 +174,11 @@ public class StateMachineAccessTests { public void setInitialEnabled(boolean enabled) { } + @Override + public UUID getUuid() { + return null; + } + @Override public String getId() { return null; diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/config/ConfigurationTests.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/config/ConfigurationTests.java index c7445b24..373d5c14 100644 --- a/spring-statemachine-core/src/test/java/org/springframework/statemachine/config/ConfigurationTests.java +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/config/ConfigurationTests.java @@ -242,6 +242,31 @@ public class ConfigurationTests extends AbstractStateMachineTests { assertThat(bfFromMachine, sameInstance(Config16.beanFactory)); } + @Test + public void testMachineIdFlat() { + context.register(Config17.class); + context.refresh(); + @SuppressWarnings("unchecked") + StateMachine stateMachine = context.getBean(StateMachine.class); + assertThat(stateMachine, notNullValue()); + assertThat(stateMachine.getId(), is("testid1")); + } + + @Test + public void testMachineIdViaFactory() { + context.register(Config18.class); + context.refresh(); + @SuppressWarnings("unchecked") + StateMachineFactory stateMachineFactory = context.getBean(StateMachineFactory.class); + StateMachine stateMachine = stateMachineFactory.getStateMachine(); + assertThat(stateMachine, notNullValue()); + assertThat(stateMachine.getId(), is("testid1")); + + stateMachine = stateMachineFactory.getStateMachine("testid2"); + assertThat(stateMachine, notNullValue()); + assertThat(stateMachine.getId(), is("testid2")); + } + @Configuration @EnableStateMachine public static class Config1 extends EnumStateMachineConfigurerAdapter { @@ -731,4 +756,62 @@ public class ConfigurationTests extends AbstractStateMachineTests { } + @Configuration + public static class Config17 { + + public static BeanFactory beanFactory = new DefaultListableBeanFactory(); + + @Bean + StateMachine stateMachine() throws Exception { + Builder builder = StateMachineBuilder.builder(); + builder.configureConfiguration() + .withConfiguration() + .machineId("testid1") + .autoStartup(false) + .beanFactory(beanFactory); + builder.configureStates() + .withStates() + .initial("S1").state("S2"); + builder.configureTransitions() + .withExternal() + .source("S1").target("S2").event("E1") + .and() + .withExternal() + .source("S2").target("S1").event("E2"); + StateMachine stateMachine = builder.build(); + return stateMachine; + } + + } + + @Configuration + @EnableStateMachineFactory + public static class Config18 extends StateMachineConfigurerAdapter { + + @Override + public void configure(StateMachineConfigurationConfigurer config) throws Exception { + config + .withConfiguration() + .machineId("testid1") + .autoStartup(true); + } + + @Override + public void configure(StateMachineStateConfigurer states) throws Exception { + states + .withStates() + .initial("S1") + .state("S2"); + } + + @Override + public void configure(StateMachineTransitionConfigurer transitions) throws Exception { + transitions + .withExternal() + .source("S1") + .target("S2") + .event("E1"); + } + } + } diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/config/model/StateMachineModelTests.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/config/model/StateMachineModelTests.java index 0bc3fdaf..a4cf81c1 100644 --- a/spring-statemachine-core/src/test/java/org/springframework/statemachine/config/model/StateMachineModelTests.java +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/config/model/StateMachineModelTests.java @@ -59,7 +59,7 @@ public class StateMachineModelTests { ConfigurationData configurationData = new ConfigurationData<>(beanFactory, taskExecutor, taskScheduler, autoStart, ensemble, listeners, securityEnabled, transitionSecurityAccessDecisionManager, eventSecurityAccessDecisionManager, - eventSecurityRule, transitionSecurityRule, verifierEnabled, verifier); + eventSecurityRule, transitionSecurityRule, verifierEnabled, verifier, null); Collection> stateData = new ArrayList<>(); StateData stateData1 = new StateData(null, null, "S1", null, null, null); diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/persist/StateMachinePersistTests3.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/persist/StateMachinePersistTests3.java new file mode 100644 index 00000000..0b54d563 --- /dev/null +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/persist/StateMachinePersistTests3.java @@ -0,0 +1,112 @@ +/* + * Copyright 2016 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.persist; + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; + +import java.util.HashMap; + +import org.junit.Test; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.statemachine.AbstractStateMachineTests; +import org.springframework.statemachine.StateMachine; +import org.springframework.statemachine.StateMachineContext; +import org.springframework.statemachine.StateMachinePersist; +import org.springframework.statemachine.config.EnableStateMachineFactory; +import org.springframework.statemachine.config.StateMachineConfigurerAdapter; +import org.springframework.statemachine.config.StateMachineFactory; +import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer; +import org.springframework.statemachine.config.builders.StateMachineStateConfigurer; +import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer; + +public class StateMachinePersistTests3 extends AbstractStateMachineTests { + + @Override + protected AnnotationConfigApplicationContext buildContext() { + return new AnnotationConfigApplicationContext(); + } + + @Test + public void testPersistMachineId() throws Exception { + context.register(Config1.class); + context.refresh(); + InMemoryStateMachinePersist1 stateMachinePersist = new InMemoryStateMachinePersist1(); + StateMachinePersister persister = new DefaultStateMachinePersister<>(stateMachinePersist); + @SuppressWarnings("unchecked") + StateMachineFactory stateMachineFactory = context.getBean(StateMachineFactory.class); + + StateMachine stateMachine = stateMachineFactory.getStateMachine("testid2"); + assertThat(stateMachine, notNullValue()); + assertThat(stateMachine.getId(), is("testid2")); + + persister.persist(stateMachine, "xxx"); + + stateMachine = stateMachineFactory.getStateMachine(); + assertThat(stateMachine, notNullValue()); + assertThat(stateMachine.getId(), nullValue()); + + stateMachine = persister.restore(stateMachine, "xxx"); + assertThat(stateMachine.getId(), is("testid2")); + } + + @Configuration + @EnableStateMachineFactory + public static class Config1 extends StateMachineConfigurerAdapter { + + @Override + public void configure(StateMachineConfigurationConfigurer config) throws Exception { + config + .withConfiguration() + .autoStartup(true); + } + + @Override + public void configure(StateMachineStateConfigurer states) throws Exception { + states + .withStates() + .initial("S1") + .state("S2"); + } + + @Override + public void configure(StateMachineTransitionConfigurer transitions) throws Exception { + transitions + .withExternal() + .source("S1") + .target("S2") + .event("E1"); + } + } + + static class InMemoryStateMachinePersist1 implements StateMachinePersist { + + private final HashMap> contexts = new HashMap<>(); + + @Override + public void write(StateMachineContext context, String contextOjb) throws Exception { + contexts.put(contextOjb, context); + } + + @Override + public StateMachineContext read(String contextOjb) throws Exception { + return contexts.get(contextOjb); + } + } +} diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/support/StateContextExpressionMethodsTests.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/support/StateContextExpressionMethodsTests.java index f0f1b0ae..4ef4c4a6 100644 --- a/spring-statemachine-core/src/test/java/org/springframework/statemachine/support/StateContextExpressionMethodsTests.java +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/support/StateContextExpressionMethodsTests.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.UUID; import org.junit.Test; import org.springframework.expression.ExpressionParser; @@ -209,6 +210,11 @@ public class StateContextExpressionMethodsTests { return null; } + @Override + public UUID getUuid() { + return null; + } + @Override public String getId() { return null; diff --git a/spring-statemachine-zookeeper/src/test/java/org/springframework/statemachine/zookeeper/ZookeeperStateMachineEnsembleTests.java b/spring-statemachine-zookeeper/src/test/java/org/springframework/statemachine/zookeeper/ZookeeperStateMachineEnsembleTests.java index 095d5bc0..7a48571f 100644 --- a/spring-statemachine-zookeeper/src/test/java/org/springframework/statemachine/zookeeper/ZookeeperStateMachineEnsembleTests.java +++ b/spring-statemachine-zookeeper/src/test/java/org/springframework/statemachine/zookeeper/ZookeeperStateMachineEnsembleTests.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; +import java.util.UUID; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -756,6 +757,11 @@ public class ZookeeperStateMachineEnsembleTests extends AbstractZookeeperTests { return null; } + @Override + public UUID getUuid() { + return null; + } + @Override public String getId() { return null;