Change StateMachineFunction to Consumer

- Remove StateMachineFunction class
- Replace StateMachineFunction with Consumer
- Fixes #767
This commit is contained in:
Ming Deng
2019-05-16 18:22:52 +08:00
committed by Janne Valkealahti
parent 10f986ce06
commit f816a88e7e
15 changed files with 501 additions and 820 deletions

View File

@@ -16,14 +16,15 @@
package org.springframework.statemachine.access;
import java.util.List;
import java.util.function.Consumer;
import org.springframework.statemachine.StateMachine;
/**
* Functional interface for {@link StateMachine} to allow more programmatic
* access to underlying functionality. Functions prefixed "doWith" will expose
* {@link StateMachineAccess} via {@link StateMachineFunction} for better functional
* access with jdk7. Functions prefixed "with" is better suitable for lambdas.
* {@link StateMachineAccess} via {@link Consumer} for better functional
* access with jdk8. Functions prefixed "with" is better suitable for lambdas.
*
* @author Janne Valkealahti
*
@@ -33,11 +34,11 @@ import org.springframework.statemachine.StateMachine;
public interface StateMachineAccessor<S, E> {
/**
* Execute given {@link StateMachineFunction} with all recursive regions.
* Execute given function with all recursive regions.
*
* @param stateMachineAccess the state machine access
*/
void doWithAllRegions(StateMachineFunction<StateMachineAccess<S, E>> stateMachineAccess);
void doWithAllRegions(Consumer<StateMachineAccess<S, E>> stateMachineAccess);
/**
* Gets all regions.
@@ -47,11 +48,11 @@ public interface StateMachineAccessor<S, E> {
List<StateMachineAccess<S, E>> withAllRegions();
/**
* Execute given {@link StateMachineFunction} with a region.
* Execute given function with a region.
*
* @param stateMachineAccess the state machine access
*/
void doWithRegion(StateMachineFunction<StateMachineAccess<S, E>> stateMachineAccess);
void doWithRegion(Consumer<StateMachineAccess<S, E>> stateMachineAccess);
/**
* Get a region.

View File

@@ -1,36 +0,0 @@
/*
* 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
*
* https://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.access;
/**
* Strategic function interface for applying arbitrary function
* or feature.
*
* @author Janne Valkealahti
*
* @param <I> the function type
* @see StateMachineAccessor
*/
public interface StateMachineFunction<I> {
/**
* Apply a function.
*
* @param function the function
*/
void apply(I function);
}

View File

@@ -40,8 +40,6 @@ import org.springframework.scheduling.TaskScheduler;
import org.springframework.statemachine.ExtendedState;
import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.access.StateMachineAccess;
import org.springframework.statemachine.access.StateMachineFunction;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.action.Actions;
import org.springframework.statemachine.config.model.ChoiceData;
@@ -284,27 +282,17 @@ public abstract class AbstractStateMachineFactory<S, E> extends LifecycleObjectS
// 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);
}
});
fmachine.getStateMachineAccessor().doWithAllRegions(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);
}
fmachine.getStateMachineAccessor().doWithRegion(function -> {
if (defaultStateMachineMonitor != null) {
function.addStateMachineMonitor(defaultStateMachineMonitor);
}
if (stateMachineMonitor != null) {
function.addStateMachineMonitor(stateMachineMonitor);
}
});
}
@@ -323,13 +311,7 @@ public abstract class AbstractStateMachineFactory<S, E> extends LifecycleObjectS
m = machineMap.get(sParent);
}
final StateMachine<S, E> mm = m;
mme.getValue().getStateMachineAccessor().doWithRegion(new StateMachineFunction<StateMachineAccess<S ,E>>(){
@Override
public void apply(StateMachineAccess<S, E> function) {
function.setParentMachine(mm);
}
});
mme.getValue().getStateMachineAccessor().doWithRegion(function -> function.setParentMachine(mm));
}
// init built machines
@@ -345,13 +327,8 @@ public abstract class AbstractStateMachineFactory<S, E> extends LifecycleObjectS
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);
}
});
fmachine.getStateMachineAccessor()
.doWithAllRegions(function -> function.addStateMachineInterceptor(securityInterceptor));
}
// setup distributed state machine if needed.
@@ -371,15 +348,11 @@ public abstract class AbstractStateMachineFactory<S, E> extends LifecycleObjectS
List<StateMachineInterceptor<S,E>> interceptors = stateMachineModel.getConfigurationData().getStateMachineInterceptors();
if (interceptors != null) {
for (final StateMachineInterceptor<S, E> interceptor : interceptors) {
// add persisting interceptor hooks to all regions
RegionPersistingInterceptorAdapter<S, E> adapter = new RegionPersistingInterceptorAdapter<>(interceptor, machine);
machine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<S,E>>() {
@Override
public void apply(StateMachineAccess<S, E> function) {
function.addStateMachineInterceptor(adapter);
}
});
machine.getStateMachineAccessor().doWithAllRegions(function -> function.addStateMachineInterceptor(adapter));
}
}

View File

@@ -29,9 +29,7 @@ import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.StateMachineContext;
import org.springframework.statemachine.StateMachineEventResult;
import org.springframework.statemachine.StateMachineSystemConstants;
import org.springframework.statemachine.access.StateMachineAccess;
import org.springframework.statemachine.access.StateMachineAccessor;
import org.springframework.statemachine.access.StateMachineFunction;
import org.springframework.statemachine.listener.StateMachineListener;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.support.DefaultStateMachineContext;
@@ -82,13 +80,7 @@ public class DistributedStateMachine<S, E> extends LifecycleObjectSupport implem
@Override
protected void onInit() throws Exception {
// TODO: should we register with all, not just top one?
delegate.getStateMachineAccessor().doWithRegion(new StateMachineFunction<StateMachineAccess<S, E>>() {
@Override
public void apply(StateMachineAccess<S, E> function) {
function.addStateMachineInterceptor(interceptor);
}
});
delegate.getStateMachineAccessor().doWithRegion(function -> function.addStateMachineInterceptor(interceptor));
}
@@ -307,14 +299,7 @@ public class DistributedStateMachine<S, E> extends LifecycleObjectSupport implem
log.debug("Joining with context " + context);
}
delegate.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<S, E>>() {
@Override
public void apply(StateMachineAccess<S, E> function) {
function.resetStateMachine(context);
}
});
delegate.getStateMachineAccessor().doWithAllRegions(function -> function.resetStateMachine(context));
}
log.info("Requesting to start delegating state machine " + delegate);
log.info("Delegating machine id " + delegate.getUuid());

View File

@@ -24,8 +24,6 @@ import org.springframework.statemachine.ExtendedState;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.StateMachineContext;
import org.springframework.statemachine.StateMachinePersist;
import org.springframework.statemachine.access.StateMachineAccess;
import org.springframework.statemachine.access.StateMachineFunction;
import org.springframework.statemachine.region.Region;
import org.springframework.statemachine.state.AbstractState;
import org.springframework.statemachine.state.HistoryPseudoState;
@@ -69,13 +67,7 @@ public abstract class AbstractStateMachinePersister<S, E, T> implements StateMac
public final StateMachine<S, E> restore(StateMachine<S, E> stateMachine, T contextObj) throws Exception {
final StateMachineContext<S, E> context = stateMachinePersist.read(contextObj);
stateMachine.stopReactively().block();
stateMachine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<S, E>>() {
@Override
public void apply(StateMachineAccess<S, E> function) {
function.resetStateMachine(context);
}
});
stateMachine.getStateMachineAccessor().doWithAllRegions(function -> function.resetStateMachine(context));
stateMachine.startReactively().block();
return stateMachine;
}

View File

@@ -28,8 +28,6 @@ import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.StateMachineContext;
import org.springframework.statemachine.StateMachineException;
import org.springframework.statemachine.StateMachinePersist;
import org.springframework.statemachine.access.StateMachineAccess;
import org.springframework.statemachine.access.StateMachineFunction;
import org.springframework.statemachine.config.StateMachineFactory;
import org.springframework.statemachine.listener.StateMachineListenerAdapter;
import org.springframework.util.Assert;
@@ -165,13 +163,7 @@ public class DefaultStateMachineService<S, E> implements StateMachineService<S,
}
stateMachine.stopReactively().block();
// only go via top region
stateMachine.getStateMachineAccessor().doWithRegion(new StateMachineFunction<StateMachineAccess<S, E>>() {
@Override
public void apply(StateMachineAccess<S, E> function) {
function.resetStateMachine(stateMachineContext);
}
});
stateMachine.getStateMachineAccessor().doWithRegion(function -> function.resetStateMachine(stateMachineContext));
return stateMachine;
}

View File

@@ -24,8 +24,6 @@ import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.StateMachineEventResult;
import org.springframework.statemachine.access.StateMachineAccess;
import org.springframework.statemachine.access.StateMachineFunction;
import org.springframework.statemachine.support.StateMachineUtils;
import org.springframework.statemachine.transition.Transition;
import org.springframework.statemachine.transition.TransitionKind;
@@ -181,69 +179,33 @@ public class StateMachineState<S, E> extends AbstractState<S, E> {
if (context.getEvent() != null) {
getSubmachine().getStateMachineAccessor()
.doWithRegion(new StateMachineFunction<StateMachineAccess<S, E>>() {
@Override
public void apply(StateMachineAccess<S, E> function) {
function.setForwardedInitialEvent(MessageBuilder.withPayload(context.getEvent())
.copyHeaders(context.getMessageHeaders()).build());
}
});
.doWithRegion(function -> function.setForwardedInitialEvent(MessageBuilder.withPayload(context.getEvent())
.copyHeaders(context.getMessageHeaders()).build()));
}
// disable initial state where needed
if (immediateDeepParent != null && immediateDeepParent.isSubmachineState() && (!isInitial(target))) {
((StateMachineState<S, E>) immediateDeepParent).getSubmachine().getStateMachineAccessor()
.doWithRegion(new StateMachineFunction<StateMachineAccess<S, E>>() {
@Override
public void apply(StateMachineAccess<S, E> function) {
function.setInitialEnabled(false);
}
});
.doWithRegion(function -> function.setInitialEnabled(false));
}
if (immediateDeepParent != null && !isInitial(immediateDeepParent)) {
getSubmachine().getStateMachineAccessor()
.doWithRegion(new StateMachineFunction<StateMachineAccess<S, E>>() {
@Override
public void apply(StateMachineAccess<S, E> function) {
function.setInitialEnabled(false);
}
});
.doWithRegion(function -> function.setInitialEnabled(false));
} else if (immediateDeepParent != null && isInitial(immediateDeepParent) && isInitial(target)) {
((StateMachineState<S, E>) immediateDeepParent).getSubmachine().getStateMachineAccessor()
.doWithRegion(new StateMachineFunction<StateMachineAccess<S, E>>() {
@Override
public void apply(StateMachineAccess<S, E> function) {
function.setInitialEnabled(false);
}
});
.doWithRegion(function -> function.setInitialEnabled(false));
}
if (immediateDeepParent == null && getSubmachine().getStates().contains(target) && !isInitial(target)
&& StateMachineUtils.isSubstate(context.getTransition().getSource(),
context.getTransition().getTarget())) {
getSubmachine().getStateMachineAccessor()
.doWithRegion(new StateMachineFunction<StateMachineAccess<S, E>>() {
@Override
public void apply(StateMachineAccess<S, E> function) {
function.setInitialEnabled(false);
}
});
.doWithRegion(function -> function.setInitialEnabled(false));
}
if (immediateDeepParent == null && getSubmachine().getStates().contains(target) && isEntry(target)) {
getSubmachine().getStateMachineAccessor()
.doWithRegion(new StateMachineFunction<StateMachineAccess<S, E>>() {
@Override
public void apply(StateMachineAccess<S, E> function) {
function.setInitialEnabled(false);
}
});
.doWithRegion(function -> function.setInitialEnabled(false));
}
}
}));

View File

@@ -45,7 +45,6 @@ import org.springframework.statemachine.StateMachineEventResult;
import org.springframework.statemachine.StateMachineEventResult.ResultType;
import org.springframework.statemachine.access.StateMachineAccess;
import org.springframework.statemachine.access.StateMachineAccessor;
import org.springframework.statemachine.access.StateMachineFunction;
import org.springframework.statemachine.action.ActionListener;
import org.springframework.statemachine.listener.StateMachineListener;
import org.springframework.statemachine.monitor.StateMachineMonitor;
@@ -551,8 +550,8 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
return new StateMachineAccessor<S, E>() {
@Override
public void doWithAllRegions(StateMachineFunction<StateMachineAccess<S, E>> stateMachineAccess) {
stateMachineAccess.apply(AbstractStateMachine.this);
public void doWithAllRegions(Consumer<StateMachineAccess<S, E>> stateMachineAccess) {
stateMachineAccess.accept(AbstractStateMachine.this);
for (State<S, E> state : states) {
if (state.isSubmachineState()) {
StateMachine<S, E> submachine = ((AbstractState<S, E>) state).getSubmachine();
@@ -587,8 +586,8 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
}
@Override
public void doWithRegion(StateMachineFunction<StateMachineAccess<S, E>> stateMachineAccess) {
stateMachineAccess.apply(AbstractStateMachine.this);
public void doWithRegion(Consumer<StateMachineAccess<S, E>> stateMachineAccess) {
stateMachineAccess.accept(AbstractStateMachine.this);
}
@Override
@@ -733,26 +732,17 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
// needed if we only transit to super state or reset regions
if (s.isSubmachineState()) {
StateMachine<S, E> submachine = ((AbstractState<S, E>)s).getSubmachine();
for (final StateMachineContext<S, E> child : stateMachineContext.getChilds()) {
submachine.getStateMachineAccessor().doWithRegion(new StateMachineFunction<StateMachineAccess<S,E>>() {
@Override
public void apply(StateMachineAccess<S, E> function) {
function.resetStateMachine(child);
}
});
}
stateMachineContext.getChilds()
.forEach(child -> submachine.getStateMachineAccessor()
.doWithRegion(function -> function.resetStateMachine(child)));
} else if (s.isOrthogonal() && stateMachineContext.getChilds() != null) {
Collection<Region<S, E>> regions = ((AbstractState<S, E>)s).getRegions();
for (Region<S, E> region : regions) {
for (final StateMachineContext<S, E> child : stateMachineContext.getChilds()) {
((StateMachine<S, E>)region).getStateMachineAccessor().doWithRegion(new StateMachineFunction<StateMachineAccess<S,E>>() {
@Override
public void apply(StateMachineAccess<S, E> function) {
function.resetStateMachine(child);
}
});
((StateMachine<S, E>)region).getStateMachineAccessor()
.doWithRegion(function -> function.resetStateMachine(child));
}
}
}
@@ -771,13 +761,8 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
for (final StateMachineContext<S, E> child : stateMachineContext.getChilds()) {
// only call if reqion id matches with context id
if (ObjectUtils.nullSafeEquals(region.getId(), child.getId())) {
((StateMachine<S, E>)region).getStateMachineAccessor().doWithRegion(new StateMachineFunction<StateMachineAccess<S,E>>() {
@Override
public void apply(StateMachineAccess<S, E> function) {
function.resetStateMachine(child);
}
});
((StateMachine<S, E>)region).getStateMachineAccessor()
.doWithRegion(function -> function.resetStateMachine(child));
}
}
}

View File

@@ -28,8 +28,6 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.Message;
import org.springframework.statemachine.access.StateMachineAccess;
import org.springframework.statemachine.access.StateMachineFunction;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
@@ -50,430 +48,425 @@ import org.springframework.statemachine.transition.Transition;
*/
public class StateMachineErrorTests extends AbstractStateMachineTests {
@Override
protected AnnotationConfigApplicationContext buildContext() {
return new AnnotationConfigApplicationContext();
}
@Test
public void testEvents() throws Exception {
context.register(EventListenerConfig1.class, Config1.class);
context.refresh();
TestApplicationEventListener1 listener1 = context.getBean(TestApplicationEventListener1.class);
TestApplicationEventListener2 listener3 = context.getBean(TestApplicationEventListener2.class);
@SuppressWarnings("unchecked")
ObjectStateMachine<TestStates,TestEvents> machine =
context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class);
assertThat(machine.hasStateMachineError(), is(false));
TestStateMachineListener listener2 = new TestStateMachineListener();
machine.addStateListener(listener2);
machine.start();
machine.setStateMachineError(new RuntimeException("myerror"));
assertThat(listener1.latch.await(1, TimeUnit.SECONDS), is(true));
assertThat(listener1.count, is(1));
assertThat(listener3.latch.await(1, TimeUnit.SECONDS), is(true));
assertThat(listener3.count, is(1));
assertThat(listener2.latch.await(1, TimeUnit.SECONDS), is(true));
assertThat(listener2.count, is(1));
assertThat(machine.hasStateMachineError(), is(true));
}
@Test
public void testInterceptHandlesError() throws Exception {
context.register(EventListenerConfig1.class, Config1.class);
context.refresh();
TestApplicationEventListener1 listener1 = context.getBean(TestApplicationEventListener1.class);
@SuppressWarnings("unchecked")
ObjectStateMachine<TestStates,TestEvents> machine =
context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class);
assertThat(machine.hasStateMachineError(), is(false));
machine.getStateMachineAccessor().doWithRegion(new StateMachineFunction<StateMachineAccess<TestStates,TestEvents>>() {
@Override
public void apply(StateMachineAccess<TestStates, TestEvents> function) {
function.addStateMachineInterceptor(new StateMachineInterceptorAdapter<TestStates,TestEvents>() {
@Override
public Exception stateMachineError(StateMachine<TestStates, TestEvents> stateMachine,
Exception exception) {
return null;
}
});
}
});
TestStateMachineListener listener2 = new TestStateMachineListener();
machine.addStateListener(listener2);
machine.start();
machine.setStateMachineError(new RuntimeException("myerror"));
assertThat(listener1.latch.await(1, TimeUnit.SECONDS), is(false));
assertThat(listener1.count, is(0));
assertThat(listener2.latch.await(1, TimeUnit.SECONDS), is(false));
assertThat(listener2.count, is(0));
assertThat(machine.hasStateMachineError(), is(false));
}
@Test
public void testErrorActive() throws Exception {
context.register(Config1.class);
context.refresh();
@SuppressWarnings("unchecked")
ObjectStateMachine<TestStates,TestEvents> machine =
context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class);
assertThat(machine.hasStateMachineError(), is(false));
machine.start();
machine.setStateMachineError(new RuntimeException("myerror"));
assertThat(machine.hasStateMachineError(), is(true));
assertThat(machine.getState().getIds(), containsInAnyOrder(TestStates.S1));
machine.sendEvent(TestEvents.E1);
assertThat(machine.getState().getIds(), containsInAnyOrder(TestStates.S1));
}
@Test
public void testListenerErrorsCauseNoMalfunction() throws Exception {
context.register(EventListenerConfig2.class, Config1.class);
context.refresh();
@SuppressWarnings("unchecked")
ObjectStateMachine<TestStates,TestEvents> machine =
context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class);
StartedStateMachineListener listener1 = new StartedStateMachineListener();
ErroringStateMachineListener listener2 = new ErroringStateMachineListener();
StateChangedStateMachineListener listener3 = new StateChangedStateMachineListener();
machine.addStateListener(listener1);
machine.addStateListener(listener2);
machine.start();
assertThat(listener1.latch.await(2, TimeUnit.SECONDS), is(true));
machine.addStateListener(listener3);
machine.sendEvent(TestEvents.E1);
assertThat(listener3.latch.await(2, TimeUnit.SECONDS), is(true));
assertThat(machine.getState().getIds(), containsInAnyOrder(TestStates.S2));
}
@Test
public void testListenerErrorsCauseNoMalfunction2() throws Exception {
context.register(EventListenerConfig2.class, Config1.class);
context.refresh();
@SuppressWarnings("unchecked")
ObjectStateMachine<TestStates,TestEvents> machine =
context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class);
StartedStateMachineListener listener1 = new StartedStateMachineListener();
ErroringStateMachineListener2 listener2 = new ErroringStateMachineListener2();
StateChangedStateMachineListener listener3 = new StateChangedStateMachineListener();
machine.addStateListener(listener1);
machine.addStateListener(listener2);
machine.start();
assertThat(listener1.latch.await(2, TimeUnit.SECONDS), is(true));
machine.addStateListener(listener3);
machine.sendEvent(TestEvents.E1);
assertThat(listener3.latch.await(2, TimeUnit.SECONDS), is(true));
assertThat(machine.getState().getIds(), containsInAnyOrder(TestStates.S2));
}
@Configuration
@EnableStateMachine
static class Config1 extends EnumStateMachineConfigurerAdapter<TestStates, TestEvents> {
@Override
public void configure(StateMachineStateConfigurer<TestStates, TestEvents> states) throws Exception {
states
.withStates()
.initial(TestStates.S1)
.state(TestStates.S2)
.state(TestStates.S3)
.state(TestStates.S4);
}
@Override
public void configure(StateMachineTransitionConfigurer<TestStates, TestEvents> transitions) throws Exception {
transitions
.withExternal()
.source(TestStates.S1)
.target(TestStates.S2)
.event(TestEvents.E1)
.and()
.withExternal()
.source(TestStates.S2)
.target(TestStates.S3)
.event(TestEvents.E2)
.and()
.withExternal()
.source(TestStates.S3)
.target(TestStates.S4)
.event(TestEvents.E3)
.and()
.withExternal()
.source(TestStates.S4)
.target(TestStates.S3)
.event(TestEvents.E4);
}
}
@Configuration
@EnableStateMachine
static class Config2 extends EnumStateMachineConfigurerAdapter<TestStates, TestEvents> {
@Override
public void configure(StateMachineStateConfigurer<TestStates, TestEvents> states) throws Exception {
states
.withStates()
.initial(TestStates.S1)
.state(TestStates.S2)
.state(TestStates.S3);
}
@Override
public void configure(StateMachineTransitionConfigurer<TestStates, TestEvents> transitions) throws Exception {
transitions
.withExternal()
.source(TestStates.S1)
.target(TestStates.S2)
.event(TestEvents.E1)
.and()
.withExternal()
.source(TestStates.S2)
.target(TestStates.S3)
.event(TestEvents.E2);
}
}
@Configuration
static class EventListenerConfig1 {
@Bean
public TestApplicationEventListener1 testApplicationEventListener1() {
return new TestApplicationEventListener1();
}
@Bean
public TestApplicationEventListener2 testApplicationEventListener2() {
return new TestApplicationEventListener2();
}
}
@Configuration
static class EventListenerConfig2 {
@Bean
public ErroringApplicationEventListener1 erroringApplicationEventListener1() {
return new ErroringApplicationEventListener1();
}
}
static class TestStateMachineListener extends StateMachineListenerAdapter<TestStates, TestEvents> {
CountDownLatch latch = new CountDownLatch(1);
int count = 0;
@Override
public void stateMachineError(StateMachine<TestStates, TestEvents> stateMachine, Exception exception) {
count++;
latch.countDown();
}
}
static class TestApplicationEventListener1 implements ApplicationListener<StateMachineEvent> {
CountDownLatch latch = new CountDownLatch(1);
int count = 0;
@Override
public void onApplicationEvent(StateMachineEvent event) {
if (event instanceof OnStateMachineError) {
count++;
latch.countDown();
}
}
}
static class TestApplicationEventListener2 implements ApplicationListener<OnStateMachineError> {
CountDownLatch latch = new CountDownLatch(1);
int count = 0;
@Override
public void onApplicationEvent(OnStateMachineError event) {
count++;
latch.countDown();
}
}
static class ErroringApplicationEventListener1 implements ApplicationListener<StateMachineEvent> {
@Override
public void onApplicationEvent(StateMachineEvent event) {
throw new RuntimeException();
}
}
static class StateChangedStateMachineListener extends StateMachineListenerAdapter<TestStates, TestEvents> {
CountDownLatch latch = new CountDownLatch(1);
@Override
public void stateChanged(State<TestStates, TestEvents> from, State<TestStates, TestEvents> to) {
latch.countDown();
}
void reset(int a) {
latch = new CountDownLatch(a);
}
}
static class StartedStateMachineListener extends StateMachineListenerAdapter<TestStates, TestEvents> {
CountDownLatch latch = new CountDownLatch(1);
@Override
public void stateMachineStarted(StateMachine<TestStates, TestEvents> stateMachine) {
latch.countDown();
}
}
static class ErroringStateMachineListener implements StateMachineListener<TestStates, TestEvents> {
@Override
public void stateChanged(State<TestStates, TestEvents> from, State<TestStates, TestEvents> to) {
throw new RuntimeException();
}
@Override
public void stateEntered(State<TestStates, TestEvents> state) {
throw new RuntimeException();
}
@Override
public void stateExited(State<TestStates, TestEvents> state) {
throw new RuntimeException();
}
@Override
public void eventNotAccepted(Message<TestEvents> event) {
throw new RuntimeException();
}
@Override
public void transition(Transition<TestStates, TestEvents> transition) {
throw new RuntimeException();
}
@Override
public void transitionStarted(Transition<TestStates, TestEvents> transition) {
throw new RuntimeException();
}
@Override
public void transitionEnded(Transition<TestStates, TestEvents> transition) {
throw new RuntimeException();
}
@Override
public void stateMachineStarted(StateMachine<TestStates, TestEvents> stateMachine) {
throw new RuntimeException();
}
@Override
public void stateMachineStopped(StateMachine<TestStates, TestEvents> stateMachine) {
throw new RuntimeException();
}
@Override
public void stateMachineError(StateMachine<TestStates, TestEvents> stateMachine, Exception exception) {
throw new RuntimeException();
}
@Override
public void extendedStateChanged(Object key, Object value) {
throw new RuntimeException();
}
@Override
public void stateContext(StateContext<TestStates, TestEvents> stateContext) {
throw new RuntimeException();
}
}
static class ErroringStateMachineListener2 implements StateMachineListener<TestStates, TestEvents> {
@Override
public void stateChanged(State<TestStates, TestEvents> from, State<TestStates, TestEvents> to) {
throw new Error();
}
@Override
public void stateEntered(State<TestStates, TestEvents> state) {
throw new Error();
}
@Override
public void stateExited(State<TestStates, TestEvents> state) {
throw new Error();
}
@Override
public void eventNotAccepted(Message<TestEvents> event) {
throw new Error();
}
@Override
public void transition(Transition<TestStates, TestEvents> transition) {
throw new Error();
}
@Override
public void transitionStarted(Transition<TestStates, TestEvents> transition) {
throw new Error();
}
@Override
public void transitionEnded(Transition<TestStates, TestEvents> transition) {
throw new Error();
}
@Override
public void stateMachineStarted(StateMachine<TestStates, TestEvents> stateMachine) {
throw new Error();
}
@Override
public void stateMachineStopped(StateMachine<TestStates, TestEvents> stateMachine) {
throw new Error();
}
@Override
public void stateMachineError(StateMachine<TestStates, TestEvents> stateMachine, Exception exception) {
throw new Error();
}
@Override
public void extendedStateChanged(Object key, Object value) {
throw new Error();
}
@Override
public void stateContext(StateContext<TestStates, TestEvents> stateContext) {
throw new Error();
}
}
@Override
protected AnnotationConfigApplicationContext buildContext() {
return new AnnotationConfigApplicationContext();
}
@Test
public void testEvents() throws Exception {
context.register(EventListenerConfig1.class, Config1.class);
context.refresh();
TestApplicationEventListener1 listener1 = context.getBean(TestApplicationEventListener1.class);
TestApplicationEventListener2 listener3 = context.getBean(TestApplicationEventListener2.class);
@SuppressWarnings("unchecked")
ObjectStateMachine<TestStates,TestEvents> machine =
context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class);
assertThat(machine.hasStateMachineError(), is(false));
TestStateMachineListener listener2 = new TestStateMachineListener();
machine.addStateListener(listener2);
machine.start();
machine.setStateMachineError(new RuntimeException("myerror"));
assertThat(listener1.latch.await(1, TimeUnit.SECONDS), is(true));
assertThat(listener1.count, is(1));
assertThat(listener3.latch.await(1, TimeUnit.SECONDS), is(true));
assertThat(listener3.count, is(1));
assertThat(listener2.latch.await(1, TimeUnit.SECONDS), is(true));
assertThat(listener2.count, is(1));
assertThat(machine.hasStateMachineError(), is(true));
}
@Test
public void testInterceptHandlesError() throws Exception {
context.register(EventListenerConfig1.class, Config1.class);
context.refresh();
TestApplicationEventListener1 listener1 = context.getBean(TestApplicationEventListener1.class);
@SuppressWarnings("unchecked")
ObjectStateMachine<TestStates,TestEvents> machine =
context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class);
assertThat(machine.hasStateMachineError(), is(false));
machine.getStateMachineAccessor().doWithRegion(
function -> function.addStateMachineInterceptor(new StateMachineInterceptorAdapter<TestStates,TestEvents>() {
@Override
public Exception stateMachineError(StateMachine<TestStates, TestEvents> stateMachine,
Exception exception) {
return null;
}
}));
TestStateMachineListener listener2 = new TestStateMachineListener();
machine.addStateListener(listener2);
machine.start();
machine.setStateMachineError(new RuntimeException("myerror"));
assertThat(listener1.latch.await(1, TimeUnit.SECONDS), is(false));
assertThat(listener1.count, is(0));
assertThat(listener2.latch.await(1, TimeUnit.SECONDS), is(false));
assertThat(listener2.count, is(0));
assertThat(machine.hasStateMachineError(), is(false));
}
@Test
public void testErrorActive() throws Exception {
context.register(Config1.class);
context.refresh();
@SuppressWarnings("unchecked")
ObjectStateMachine<TestStates,TestEvents> machine =
context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class);
assertThat(machine.hasStateMachineError(), is(false));
machine.start();
machine.setStateMachineError(new RuntimeException("myerror"));
assertThat(machine.hasStateMachineError(), is(true));
assertThat(machine.getState().getIds(), containsInAnyOrder(TestStates.S1));
machine.sendEvent(TestEvents.E1);
assertThat(machine.getState().getIds(), containsInAnyOrder(TestStates.S1));
}
@Test
public void testListenerErrorsCauseNoMalfunction() throws Exception {
context.register(EventListenerConfig2.class, Config1.class);
context.refresh();
@SuppressWarnings("unchecked")
ObjectStateMachine<TestStates,TestEvents> machine =
context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class);
StartedStateMachineListener listener1 = new StartedStateMachineListener();
ErroringStateMachineListener listener2 = new ErroringStateMachineListener();
StateChangedStateMachineListener listener3 = new StateChangedStateMachineListener();
machine.addStateListener(listener1);
machine.addStateListener(listener2);
machine.start();
assertThat(listener1.latch.await(2, TimeUnit.SECONDS), is(true));
machine.addStateListener(listener3);
machine.sendEvent(TestEvents.E1);
assertThat(listener3.latch.await(2, TimeUnit.SECONDS), is(true));
assertThat(machine.getState().getIds(), containsInAnyOrder(TestStates.S2));
}
@Test
public void testListenerErrorsCauseNoMalfunction2() throws Exception {
context.register(EventListenerConfig2.class, Config1.class);
context.refresh();
@SuppressWarnings("unchecked")
ObjectStateMachine<TestStates,TestEvents> machine =
context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class);
StartedStateMachineListener listener1 = new StartedStateMachineListener();
ErroringStateMachineListener2 listener2 = new ErroringStateMachineListener2();
StateChangedStateMachineListener listener3 = new StateChangedStateMachineListener();
machine.addStateListener(listener1);
machine.addStateListener(listener2);
machine.start();
assertThat(listener1.latch.await(2, TimeUnit.SECONDS), is(true));
machine.addStateListener(listener3);
machine.sendEvent(TestEvents.E1);
assertThat(listener3.latch.await(2, TimeUnit.SECONDS), is(true));
assertThat(machine.getState().getIds(), containsInAnyOrder(TestStates.S2));
}
@Configuration
@EnableStateMachine
static class Config1 extends EnumStateMachineConfigurerAdapter<TestStates, TestEvents> {
@Override
public void configure(StateMachineStateConfigurer<TestStates, TestEvents> states) throws Exception {
states
.withStates()
.initial(TestStates.S1)
.state(TestStates.S2)
.state(TestStates.S3)
.state(TestStates.S4);
}
@Override
public void configure(StateMachineTransitionConfigurer<TestStates, TestEvents> transitions) throws Exception {
transitions
.withExternal()
.source(TestStates.S1)
.target(TestStates.S2)
.event(TestEvents.E1)
.and()
.withExternal()
.source(TestStates.S2)
.target(TestStates.S3)
.event(TestEvents.E2)
.and()
.withExternal()
.source(TestStates.S3)
.target(TestStates.S4)
.event(TestEvents.E3)
.and()
.withExternal()
.source(TestStates.S4)
.target(TestStates.S3)
.event(TestEvents.E4);
}
}
@Configuration
@EnableStateMachine
static class Config2 extends EnumStateMachineConfigurerAdapter<TestStates, TestEvents> {
@Override
public void configure(StateMachineStateConfigurer<TestStates, TestEvents> states) throws Exception {
states
.withStates()
.initial(TestStates.S1)
.state(TestStates.S2)
.state(TestStates.S3);
}
@Override
public void configure(StateMachineTransitionConfigurer<TestStates, TestEvents> transitions) throws Exception {
transitions
.withExternal()
.source(TestStates.S1)
.target(TestStates.S2)
.event(TestEvents.E1)
.and()
.withExternal()
.source(TestStates.S2)
.target(TestStates.S3)
.event(TestEvents.E2);
}
}
@Configuration
static class EventListenerConfig1 {
@Bean
public TestApplicationEventListener1 testApplicationEventListener1() {
return new TestApplicationEventListener1();
}
@Bean
public TestApplicationEventListener2 testApplicationEventListener2() {
return new TestApplicationEventListener2();
}
}
@Configuration
static class EventListenerConfig2 {
@Bean
public ErroringApplicationEventListener1 erroringApplicationEventListener1() {
return new ErroringApplicationEventListener1();
}
}
static class TestStateMachineListener extends StateMachineListenerAdapter<TestStates, TestEvents> {
CountDownLatch latch = new CountDownLatch(1);
int count = 0;
@Override
public void stateMachineError(StateMachine<TestStates, TestEvents> stateMachine, Exception exception) {
count++;
latch.countDown();
}
}
static class TestApplicationEventListener1 implements ApplicationListener<StateMachineEvent> {
CountDownLatch latch = new CountDownLatch(1);
int count = 0;
@Override
public void onApplicationEvent(StateMachineEvent event) {
if (event instanceof OnStateMachineError) {
count++;
latch.countDown();
}
}
}
static class TestApplicationEventListener2 implements ApplicationListener<OnStateMachineError> {
CountDownLatch latch = new CountDownLatch(1);
int count = 0;
@Override
public void onApplicationEvent(OnStateMachineError event) {
count++;
latch.countDown();
}
}
static class ErroringApplicationEventListener1 implements ApplicationListener<StateMachineEvent> {
@Override
public void onApplicationEvent(StateMachineEvent event) {
throw new RuntimeException();
}
}
static class StateChangedStateMachineListener extends StateMachineListenerAdapter<TestStates, TestEvents> {
CountDownLatch latch = new CountDownLatch(1);
@Override
public void stateChanged(State<TestStates, TestEvents> from, State<TestStates, TestEvents> to) {
latch.countDown();
}
void reset(int a) {
latch = new CountDownLatch(a);
}
}
static class StartedStateMachineListener extends StateMachineListenerAdapter<TestStates, TestEvents> {
CountDownLatch latch = new CountDownLatch(1);
@Override
public void stateMachineStarted(StateMachine<TestStates, TestEvents> stateMachine) {
latch.countDown();
}
}
static class ErroringStateMachineListener implements StateMachineListener<TestStates, TestEvents> {
@Override
public void stateChanged(State<TestStates, TestEvents> from, State<TestStates, TestEvents> to) {
throw new RuntimeException();
}
@Override
public void stateEntered(State<TestStates, TestEvents> state) {
throw new RuntimeException();
}
@Override
public void stateExited(State<TestStates, TestEvents> state) {
throw new RuntimeException();
}
@Override
public void eventNotAccepted(Message<TestEvents> event) {
throw new RuntimeException();
}
@Override
public void transition(Transition<TestStates, TestEvents> transition) {
throw new RuntimeException();
}
@Override
public void transitionStarted(Transition<TestStates, TestEvents> transition) {
throw new RuntimeException();
}
@Override
public void transitionEnded(Transition<TestStates, TestEvents> transition) {
throw new RuntimeException();
}
@Override
public void stateMachineStarted(StateMachine<TestStates, TestEvents> stateMachine) {
throw new RuntimeException();
}
@Override
public void stateMachineStopped(StateMachine<TestStates, TestEvents> stateMachine) {
throw new RuntimeException();
}
@Override
public void stateMachineError(StateMachine<TestStates, TestEvents> stateMachine, Exception exception) {
throw new RuntimeException();
}
@Override
public void extendedStateChanged(Object key, Object value) {
throw new RuntimeException();
}
@Override
public void stateContext(StateContext<TestStates, TestEvents> stateContext) {
throw new RuntimeException();
}
}
static class ErroringStateMachineListener2 implements StateMachineListener<TestStates, TestEvents> {
@Override
public void stateChanged(State<TestStates, TestEvents> from, State<TestStates, TestEvents> to) {
throw new Error();
}
@Override
public void stateEntered(State<TestStates, TestEvents> state) {
throw new Error();
}
@Override
public void stateExited(State<TestStates, TestEvents> state) {
throw new Error();
}
@Override
public void eventNotAccepted(Message<TestEvents> event) {
throw new Error();
}
@Override
public void transition(Transition<TestStates, TestEvents> transition) {
throw new Error();
}
@Override
public void transitionStarted(Transition<TestStates, TestEvents> transition) {
throw new Error();
}
@Override
public void transitionEnded(Transition<TestStates, TestEvents> transition) {
throw new Error();
}
@Override
public void stateMachineStarted(StateMachine<TestStates, TestEvents> stateMachine) {
throw new Error();
}
@Override
public void stateMachineStopped(StateMachine<TestStates, TestEvents> stateMachine) {
throw new Error();
}
@Override
public void stateMachineError(StateMachine<TestStates, TestEvents> stateMachine, Exception exception) {
throw new Error();
}
@Override
public void extendedStateChanged(Object key, Object value) {
throw new Error();
}
@Override
public void stateContext(StateContext<TestStates, TestEvents> stateContext) {
throw new Error();
}
}
}

View File

@@ -37,8 +37,6 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.StateContext.Stage;
import org.springframework.statemachine.access.StateMachineAccess;
import org.springframework.statemachine.access.StateMachineFunction;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.EnableStateMachineFactory;
@@ -78,13 +76,7 @@ public class StateMachineResetTests extends AbstractStateMachineTests {
ExtendedState extendedState = new DefaultExtendedState(variables);
DefaultStateMachineContext<States,Events> stateMachineContext = new DefaultStateMachineContext<States, Events>(States.S12, Events.I, null, extendedState);
machine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<States,Events>>() {
@Override
public void apply(StateMachineAccess<States, Events> function) {
function.resetStateMachine(stateMachineContext);
}
});
machine.getStateMachineAccessor().doWithAllRegions(function -> function.resetStateMachine(stateMachineContext));
doStartAndAssert(machine);
assertThat(machine.getState().getIds(), containsInAnyOrder(States.S0, States.S1, States.S12));
@@ -102,13 +94,7 @@ public class StateMachineResetTests extends AbstractStateMachineTests {
ExtendedState extendedState = new DefaultExtendedState(variables);
DefaultStateMachineContext<States,Events> stateMachineContext = new DefaultStateMachineContext<States, Events>(States.S211, Events.C, null, extendedState);
machine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<States,Events>>() {
@Override
public void apply(StateMachineAccess<States, Events> function) {
function.resetStateMachine(stateMachineContext);
}
});
machine.getStateMachineAccessor().doWithAllRegions(function -> function.resetStateMachine(stateMachineContext));
doStartAndAssert(machine);
assertThat(machine.getState().getIds(), containsInAnyOrder(States.S0, States.S2, States.S21, States.S211));
@@ -126,13 +112,7 @@ public class StateMachineResetTests extends AbstractStateMachineTests {
ExtendedState extendedState = new DefaultExtendedState(variables);
DefaultStateMachineContext<States,Events> stateMachineContext = new DefaultStateMachineContext<States, Events>(States.S2, Events.C, null, extendedState);
machine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<States,Events>>() {
@Override
public void apply(StateMachineAccess<States, Events> function) {
function.resetStateMachine(stateMachineContext);
}
});
machine.getStateMachineAccessor().doWithAllRegions(function -> function.resetStateMachine(stateMachineContext));
doStartAndAssert(machine);
assertThat(machine.getState().getIds(), containsInAnyOrder(States.S0, States.S2, States.S21, States.S211));
@@ -157,13 +137,7 @@ public class StateMachineResetTests extends AbstractStateMachineTests {
DefaultStateMachineContext<TestStates, TestEvents> stateMachineContext =
new DefaultStateMachineContext<TestStates, TestEvents>(childs, TestStates.S2, TestEvents.E1, null, null);
machine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<TestStates, TestEvents>>() {
@Override
public void apply(StateMachineAccess<TestStates, TestEvents> function) {
function.resetStateMachine(stateMachineContext);
}
});
machine.getStateMachineAccessor().doWithAllRegions(function -> function.resetStateMachine(stateMachineContext));
doStartAndAssert(machine);
assertThat(machine.getState().getIds(), containsInAnyOrder(TestStates.S2, TestStates.S21, TestStates.S31));
@@ -187,13 +161,7 @@ public class StateMachineResetTests extends AbstractStateMachineTests {
DefaultStateMachineContext<TestStates, TestEvents> stateMachineContext =
new DefaultStateMachineContext<TestStates, TestEvents>(childs, TestStates.S2, null, null, null);
machine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<TestStates, TestEvents>>() {
@Override
public void apply(StateMachineAccess<TestStates, TestEvents> function) {
function.resetStateMachine(stateMachineContext);
}
});
machine.getStateMachineAccessor().doWithAllRegions(function -> function.resetStateMachine(stateMachineContext));
doStartAndAssert(machine);
assertThat(machine.getState().getIds(), containsInAnyOrder(TestStates.S2, TestStates.S21, TestStates.S31));
@@ -215,13 +183,7 @@ public class StateMachineResetTests extends AbstractStateMachineTests {
ExtendedState extendedState = new DefaultExtendedState(variables);
DefaultStateMachineContext<States,Events> stateMachineContext = new DefaultStateMachineContext<States, Events>(States.S0, null, null, extendedState);
machine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<States,Events>>() {
@Override
public void apply(StateMachineAccess<States, Events> function) {
function.resetStateMachine(stateMachineContext);
}
});
machine.getStateMachineAccessor().doWithAllRegions(function -> function.resetStateMachine(stateMachineContext));
doStartAndAssert(machine);
assertThat((Integer)machine.getExtendedState().getVariables().get("count"), is(1));
@@ -244,13 +206,7 @@ public class StateMachineResetTests extends AbstractStateMachineTests {
assertThat((Integer)machine.getExtendedState().getVariables().get("foo"), is(0));
doStopAndAssert(machine);
machine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<States,Events>>() {
@Override
public void apply(StateMachineAccess<States, Events> function) {
function.resetStateMachine(null);
}
});
machine.getStateMachineAccessor().doWithAllRegions(function -> function.resetStateMachine(null));
doStartAndAssert(machine);
assertThat(machine.getState().getIds(), containsInAnyOrder(States.S0, States.S1, States.S11));
assertThat(machine.getExtendedState().getVariables().size(), is(0));
@@ -272,13 +228,7 @@ public class StateMachineResetTests extends AbstractStateMachineTests {
DefaultStateMachineContext<States, Events> stateMachineContext = new DefaultStateMachineContext<States, Events>(
States.S11, null, null, null);
machine.getStateMachineAccessor()
.doWithAllRegions(new StateMachineFunction<StateMachineAccess<States, Events>>() {
@Override
public void apply(StateMachineAccess<States, Events> function) {
function.resetStateMachine(stateMachineContext);
}
});
.doWithAllRegions(function -> function.resetStateMachine(stateMachineContext));
doStartAndAssert(machine);
assertThat(machine.getState().getIds(), containsInAnyOrder(States.S0, States.S1, States.S11));
@@ -295,13 +245,7 @@ public class StateMachineResetTests extends AbstractStateMachineTests {
DefaultStateMachineContext<States, Events> stateMachineContext = new DefaultStateMachineContext<States, Events>(States.S1, null,
null, null);
machine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<States,Events>>() {
@Override
public void apply(StateMachineAccess<States, Events> function) {
function.resetStateMachine(stateMachineContext);
}
});
machine.getStateMachineAccessor().doWithAllRegions(function -> function.resetStateMachine(stateMachineContext));
doStartAndAssert(machine);
Thread.sleep(1100);
@@ -345,13 +289,7 @@ public class StateMachineResetTests extends AbstractStateMachineTests {
ExtendedState extendedState = new DefaultExtendedState(variables);
DefaultStateMachineContext<States,Events> stateMachineContext = new DefaultStateMachineContext<States, Events>(States.S0, null, null, extendedState);
machine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<States,Events>>() {
@Override
public void apply(StateMachineAccess<States, Events> function) {
function.resetStateMachine(stateMachineContext);
}
});
machine.getStateMachineAccessor().doWithAllRegions(function -> function.resetStateMachine(stateMachineContext));
doStartAndAssert(machine);
assertThat((Integer)machine.getExtendedState().getVariables().get("count1"), is(1));
@@ -382,13 +320,7 @@ public class StateMachineResetTests extends AbstractStateMachineTests {
DefaultStateMachineContext<MyState, MyEvent> stateMachineContext = new DefaultStateMachineContext<MyState, MyEvent>(
SubState.SUB_NEXT, null, null, null);
machine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<MyState, MyEvent>>() {
@Override
public void apply(StateMachineAccess<MyState, MyEvent> function) {
function.resetStateMachine(stateMachineContext);
}
});
machine.getStateMachineAccessor().doWithAllRegions(function -> function.resetStateMachine(stateMachineContext));
doStartAndAssert(machine);
assertThat(machine.getState().getIds(), containsInAnyOrder(SuperState.PARENT, SubState.SUB_NEXT));
@@ -404,13 +336,7 @@ public class StateMachineResetTests extends AbstractStateMachineTests {
DefaultStateMachineContext<MyState, MyEvent> stateMachineContext = new DefaultStateMachineContext<MyState, MyEvent>(
SuperState.INITIAL, null, null, null);
machine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<MyState, MyEvent>>() {
@Override
public void apply(StateMachineAccess<MyState, MyEvent> function) {
function.resetStateMachine(stateMachineContext);
}
});
machine.getStateMachineAccessor().doWithAllRegions(function -> function.resetStateMachine(stateMachineContext));
doStartAndAssert(machine);
assertThat(machine.getState().getIds(), containsInAnyOrder(SuperState.INITIAL));

View File

@@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import java.util.function.Consumer;
import org.junit.Test;
import org.springframework.messaging.Message;
@@ -44,14 +45,7 @@ public class StateMachineAccessTests {
public void testDoWithAllRegionsSetRelay() {
MockStateMachine mock = new MockStateMachine();
final StateMachine<String, String> stateMachine = mock;
stateMachine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<String, String>>() {
@Override
public void apply(StateMachineAccess<String, String> function) {
function.setRelay(stateMachine);
}
});
stateMachine.getStateMachineAccessor().doWithAllRegions(function -> function.setRelay(stateMachine));
assertThat(mock.relay, sameInstance(stateMachine));
}
@@ -60,8 +54,7 @@ public class StateMachineAccessTests {
public void testGetAllRegionsSetRelay() {
MockStateMachine mock = new MockStateMachine();
final StateMachine<String, String> stateMachine = mock;
stateMachine.getStateMachineAccessor().withAllRegions().stream()
.forEach(access -> access.setRelay(stateMachine));
stateMachine.getStateMachineAccessor().withAllRegions().forEach(access -> access.setRelay(stateMachine));
assertThat(mock.relay, sameInstance(stateMachine));
}
@@ -75,8 +68,8 @@ public class StateMachineAccessTests {
return new StateMachineAccessor<String, String>() {
@Override
public void doWithAllRegions(StateMachineFunction<StateMachineAccess<String, String>> stateMachineAccess) {
stateMachineAccess.apply(MockStateMachine.this);
public void doWithAllRegions(Consumer<StateMachineAccess<String, String>> stateMachineAccess) {
stateMachineAccess.accept(MockStateMachine.this);
}
@Override
@@ -87,7 +80,7 @@ public class StateMachineAccessTests {
}
@Override
public void doWithRegion(StateMachineFunction<StateMachineAccess<String, String>> stateMachineAccess) {
public void doWithRegion(Consumer<StateMachineAccess<String, String>> stateMachineAccess) {
}
@Override

View File

@@ -35,7 +35,6 @@ import org.springframework.statemachine.AbstractStateMachineTests;
import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.access.StateMachineAccess;
import org.springframework.statemachine.access.StateMachineFunction;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.action.Actions;
import org.springframework.statemachine.action.SpelExpressionAction;
@@ -1259,13 +1258,7 @@ public class DocsConfigurationSampleTests extends AbstractStateMachineTests {
void s1() {
// tag::snippetZA[]
stateMachine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<String,String>>() {
@Override
public void apply(StateMachineAccess<String, String> function) {
function.setRelay(stateMachine);
}
});
stateMachine.getStateMachineAccessor().doWithAllRegions(function -> function.setRelay(stateMachine));
stateMachine.getStateMachineAccessor()
.doWithAllRegions(access -> access.setRelay(stateMachine));
@@ -1274,13 +1267,7 @@ public class DocsConfigurationSampleTests extends AbstractStateMachineTests {
void s2() {
// tag::snippetZB[]
stateMachine.getStateMachineAccessor().doWithRegion(new StateMachineFunction<StateMachineAccess<String,String>>() {
@Override
public void apply(StateMachineAccess<String, String> function) {
function.setRelay(stateMachine);
}
});
stateMachine.getStateMachineAccessor().doWithRegion(function -> function.setRelay(stateMachine));
stateMachine.getStateMachineAccessor()
.doWithRegion(access -> access.setRelay(stateMachine));
@@ -1372,21 +1359,15 @@ public class DocsConfigurationSampleTests extends AbstractStateMachineTests {
void addInterceptor() {
stateMachine.getStateMachineAccessor()
.doWithRegion(new StateMachineFunction<StateMachineAccess<String, String>>() {
@Override
public void apply(StateMachineAccess<String, String> function) {
function.addStateMachineInterceptor(
new StateMachineInterceptorAdapter<String, String>() {
@Override
public Exception stateMachineError(StateMachine<String, String> stateMachine,
Exception exception) {
// return null indicating handled error
return exception;
}
});
}
});
.doWithRegion(function ->
function.addStateMachineInterceptor(new StateMachineInterceptorAdapter<String, String>() {
@Override
public Exception stateMachineError(StateMachine<String, String> stateMachine,
Exception exception) {
return exception;
}
})
);
}
// end::snippet1[]

View File

@@ -36,8 +36,6 @@ import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.AbstractStateMachineTests;
import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.access.StateMachineAccess;
import org.springframework.statemachine.access.StateMachineFunction;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
@@ -64,13 +62,7 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
machine.addStateListener(listener);
TestStateChangeInterceptor interceptor = new TestStateChangeInterceptor();
machine.getStateMachineAccessor().doWithRegion(new StateMachineFunction<StateMachineAccess<States, Events>>() {
@Override
public void apply(StateMachineAccess<States, Events> function) {
function.addStateMachineInterceptor(interceptor);
}
});
machine.getStateMachineAccessor().doWithRegion(function -> function.addStateMachineInterceptor(interceptor));
doStartAndAssert(machine);
@@ -103,13 +95,7 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
machine.addStateListener(listener);
TestStateChangeInterceptor interceptor = new TestStateChangeInterceptor();
machine.getStateMachineAccessor().doWithRegion(new StateMachineFunction<StateMachineAccess<States, Events>>() {
@Override
public void apply(StateMachineAccess<States, Events> function) {
function.addStateMachineInterceptor(interceptor);
}
});
machine.getStateMachineAccessor().doWithRegion(function -> function.addStateMachineInterceptor(interceptor));
doStartAndAssert(machine);
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
@@ -159,13 +145,7 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
machine.addStateListener(listener);
TestStateChangeInterceptor interceptor = new TestStateChangeInterceptor();
machine.getStateMachineAccessor().doWithRegion(new StateMachineFunction<StateMachineAccess<States, Events>>() {
@Override
public void apply(StateMachineAccess<States, Events> function) {
function.addStateMachineInterceptor(interceptor);
}
});
machine.getStateMachineAccessor().doWithRegion(function -> function.addStateMachineInterceptor(interceptor));
doStartAndAssert(machine);
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
@@ -193,13 +173,7 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
machine.addStateListener(listener);
TestStateChangeInterceptor interceptor = new TestStateChangeInterceptor();
machine.getStateMachineAccessor().doWithRegion(new StateMachineFunction<StateMachineAccess<States, Events>>() {
@Override
public void apply(StateMachineAccess<States, Events> function) {
function.addStateMachineInterceptor(interceptor);
}
});
machine.getStateMachineAccessor().doWithRegion(function -> function.addStateMachineInterceptor(interceptor));
doStartAndAssert(machine);
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
@@ -237,13 +211,7 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
machine.addStateListener(listener);
TestStateChangeInterceptor interceptor = new TestStateChangeInterceptor();
machine.getStateMachineAccessor().doWithRegion(new StateMachineFunction<StateMachineAccess<States, Events>>() {
@Override
public void apply(StateMachineAccess<States, Events> function) {
function.addStateMachineInterceptor(interceptor);
}
});
machine.getStateMachineAccessor().doWithRegion(function -> function.addStateMachineInterceptor(interceptor));
doStartAndAssert(machine);
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
@@ -281,13 +249,7 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
machine.addStateListener(listener);
TestStateChangeInterceptor interceptor = new TestStateChangeInterceptor();
machine.getStateMachineAccessor().doWithRegion(new StateMachineFunction<StateMachineAccess<States, Events>>() {
@Override
public void apply(StateMachineAccess<States, Events> function) {
function.addStateMachineInterceptor(interceptor);
}
});
machine.getStateMachineAccessor().doWithRegion(function -> function.addStateMachineInterceptor(interceptor));
doStartAndAssert(machine);
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
@@ -326,13 +288,7 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
machine.addStateListener(listener);
TestStateChangeInterceptor interceptor = new TestStateChangeInterceptor();
machine.getStateMachineAccessor().doWithRegion(new StateMachineFunction<StateMachineAccess<States, Events>>() {
@Override
public void apply(StateMachineAccess<States, Events> function) {
function.addStateMachineInterceptor(interceptor);
}
});
machine.getStateMachineAccessor().doWithRegion(function -> function.addStateMachineInterceptor(interceptor));
doStartAndAssert(machine);
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));

View File

@@ -21,7 +21,6 @@ import java.util.List;
import org.springframework.messaging.Message;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.access.StateMachineAccess;
import org.springframework.statemachine.access.StateMachineFunction;
import org.springframework.statemachine.listener.AbstractCompositeListener;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.support.DefaultStateMachineContext;
@@ -57,13 +56,7 @@ public class PersistStateMachineHandler extends LifecycleObjectSupport {
@Override
protected void onInit() throws Exception {
stateMachine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<String,String>>() {
@Override
public void apply(StateMachineAccess<String, String> function) {
function.addStateMachineInterceptor(interceptor);
}
});
stateMachine.getStateMachineAccessor().doWithAllRegions(function -> function.addStateMachineInterceptor(interceptor));
}
/**

View File

@@ -33,8 +33,6 @@ import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.StateMachineContext;
import org.springframework.statemachine.StateMachineException;
import org.springframework.statemachine.StateMachinePersist;
import org.springframework.statemachine.access.StateMachineAccess;
import org.springframework.statemachine.access.StateMachineFunction;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.StateMachineBuilder;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
@@ -107,13 +105,7 @@ public class TasksHandler {
if (persist != null) {
final LocalStateMachineInterceptor interceptor = new LocalStateMachineInterceptor(persist);
stateMachine.getStateMachineAccessor()
.doWithAllRegions(new StateMachineFunction<StateMachineAccess<String, String>>() {
@Override
public void apply(StateMachineAccess<String, String> function) {
function.addStateMachineInterceptor(interceptor);
}
});
.doWithAllRegions(function -> function.addStateMachineInterceptor(interceptor));
}
} catch (Exception e) {
throw new StateMachineException("Error building state machine from tasks", e);
@@ -173,14 +165,7 @@ public class TasksHandler {
}
stateMachine.stopReactively().block();
stateMachine.getStateMachineAccessor()
.doWithAllRegions(new StateMachineFunction<StateMachineAccess<String, String>>() {
@Override
public void apply(StateMachineAccess<String, String> function) {
function.resetStateMachine(context);
}
});
stateMachine.getStateMachineAccessor().doWithAllRegions(function -> function.resetStateMachine(context));
stateMachine.startReactively().block();
}