Add base DefaultStateMachineService implementation

- First take on new interface StateMachineService with
  its default impl.
- Modify datajpapersist sample to use it.
- Relates to #432
This commit is contained in:
Janne Valkealahti
2017-11-21 10:46:49 +00:00
parent c0e5a9d305
commit 3d538f7600
4 changed files with 195 additions and 41 deletions

View File

@@ -0,0 +1,120 @@
/*
* Copyright 2017 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.service;
import java.util.HashMap;
import java.util.Map;
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.util.Assert;
/**
* Default implementation of a {@link StateMachineService}.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public class DefaultStateMachineService<S, E> implements StateMachineService<S, E> {
private final StateMachineFactory<S, E> stateMachineFactory;
private final Map<String, StateMachine<S, E>> machines = new HashMap<String, StateMachine<S, E>>();
private StateMachinePersist<S, E, String> stateMachinePersist;
/**
* Instantiates a new default state machine service.
*
* @param stateMachineFactory the state machine factory
*/
public DefaultStateMachineService(StateMachineFactory<S, E> stateMachineFactory) {
this(stateMachineFactory, null);
}
/**
* Instantiates a new default state machine service.
*
* @param stateMachineFactory the state machine factory
* @param stateMachinePersist the state machine persist
*/
public DefaultStateMachineService(StateMachineFactory<S, E> stateMachineFactory,
StateMachinePersist<S, E, String> stateMachinePersist) {
Assert.notNull(stateMachineFactory, "'stateMachineFactory' must be set");
this.stateMachineFactory = stateMachineFactory;
this.stateMachinePersist = stateMachinePersist;
}
@Override
public StateMachine<S, E> acquireStateMachine(String machineId) {
synchronized (machines) {
StateMachine<S,E> stateMachine = machines.get(machineId);
if (stateMachine == null) {
stateMachine = stateMachineFactory.getStateMachine(machineId);
machines.put(machineId, stateMachine);
}
if (stateMachinePersist != null) {
try {
StateMachineContext<S, E> stateMachineContext = stateMachinePersist.read(machineId);
return restoreStateMachine(stateMachine, stateMachineContext);
} catch (Exception e) {
throw new StateMachineException("Unable to read context from store", e);
}
} else {
return stateMachine;
}
}
}
@Override
public void releaseStateMachine(String machineId) {
synchronized (machines) {
StateMachine<S, E> stateMachine = machines.remove(machineId);
if (stateMachine != null) {
stateMachine.stop();
}
}
}
/**
* Sets the state machine persist.
*
* @param stateMachinePersist the state machine persist
*/
public void setStateMachinePersist(StateMachinePersist<S, E, String> stateMachinePersist) {
this.stateMachinePersist = stateMachinePersist;
}
protected StateMachine<S, E> restoreStateMachine(StateMachine<S, E> stateMachine, final StateMachineContext<S, E> stateMachineContext) {
if (stateMachineContext == null) {
return stateMachine;
}
stateMachine.stop();
stateMachine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<S, E>>() {
@Override
public void apply(StateMachineAccess<S, E> function) {
function.resetStateMachine(stateMachineContext);
}
});
return stateMachine;
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2017 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.service;
import org.springframework.statemachine.StateMachine;
/**
* Service class helping to persist and restore {@link StateMachine}s
* in a runtime environment.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public interface StateMachineService<S, E> {
/**
* Acquires the state machine.
*
* @param machineId the machine id
* @return the state machine
*/
StateMachine<S, E> acquireStateMachine(String machineId);
/**
* Release the state machine.
*
* @param machineId the machine id
*/
void releaseStateMachine(String machineId);
}