Add redis/mongo for machine persistence
- Add similar implementations as done for JPA which uses redis and mongo. - Relates #428
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.data.mongodb;
|
||||
|
||||
import org.springframework.statemachine.StateMachineContext;
|
||||
import org.springframework.statemachine.data.mongodb.MongoDbRepositoryStateMachinePersist;
|
||||
import org.springframework.statemachine.data.mongodb.MongoDbStateMachineRepository;
|
||||
import org.springframework.statemachine.persist.AbstractPersistingStateMachineInterceptor;
|
||||
import org.springframework.statemachine.persist.StateMachineRuntimePersister;
|
||||
import org.springframework.statemachine.support.StateMachineInterceptor;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@code MongoDb} implementation of a {@link AbstractPersistingStateMachineInterceptor}.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
* @param <S> the type of state
|
||||
* @param <E> the type of event
|
||||
* @param <T> the type of persister context object
|
||||
*/
|
||||
public class MongoDbPersistingStateMachineInterceptor<S, E, T> extends AbstractPersistingStateMachineInterceptor<S, E, T>
|
||||
implements StateMachineRuntimePersister<S, E, T> {
|
||||
|
||||
private final MongoDbRepositoryStateMachinePersist<S, E> persist;
|
||||
|
||||
/**
|
||||
* Instantiates a new mongodb persisting state machine interceptor.
|
||||
*
|
||||
* @param mongodbStateMachineRepository the mongodb state machine repository
|
||||
*/
|
||||
public MongoDbPersistingStateMachineInterceptor(MongoDbStateMachineRepository mongodbStateMachineRepository) {
|
||||
Assert.notNull(mongodbStateMachineRepository, "'mongodbStateMachineRepository' must be set");
|
||||
this.persist = new MongoDbRepositoryStateMachinePersist<S, E>(mongodbStateMachineRepository);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new mongodb persisting state machine interceptor.
|
||||
*
|
||||
* @param persist the persist
|
||||
*/
|
||||
public MongoDbPersistingStateMachineInterceptor(MongoDbRepositoryStateMachinePersist<S, E> persist) {
|
||||
Assert.notNull(persist, "'persist' must be set");
|
||||
this.persist = persist;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateMachineInterceptor<S, E> getInterceptor() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(StateMachineContext<S, E> context, T contextObj) throws Exception {
|
||||
persist.write(context, contextObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateMachineContext<S, E> read(Object contextObj) throws Exception {
|
||||
return persist.read(contextObj);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.data.mongodb;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.statemachine.data.RepositoryStateMachine;
|
||||
|
||||
/**
|
||||
* A {@link RepositoryStateMachine} interface for Redis used for states machines.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
*/
|
||||
@Document(collection = "MongoDbRepositoryStateMachine")
|
||||
public class MongoDbRepositoryStateMachine extends RepositoryStateMachine {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
private String machineId;
|
||||
private String state;
|
||||
private byte[] stateMachineContext;
|
||||
|
||||
@Override
|
||||
public String getMachineId() {
|
||||
return machineId;
|
||||
}
|
||||
|
||||
public void setMachineId(String machineId) {
|
||||
this.machineId = machineId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getStateMachineContext() {
|
||||
return stateMachineContext;
|
||||
}
|
||||
|
||||
public void setStateMachineContext(byte[] stateMachineContext) {
|
||||
this.stateMachineContext = stateMachineContext;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.data.mongodb;
|
||||
|
||||
import org.springframework.statemachine.StateMachineContext;
|
||||
import org.springframework.statemachine.data.RepositoryStateMachinePersist;
|
||||
import org.springframework.statemachine.data.StateMachineRepository;
|
||||
import org.springframework.statemachine.service.StateMachineSerialisationService;
|
||||
|
||||
/**
|
||||
* {@code MongoDb} based implementation of a {@link RepositoryStateMachinePersist}.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
* @param <S> the type of state
|
||||
* @param <E> the type of event
|
||||
*/
|
||||
public class MongoDbRepositoryStateMachinePersist<S, E> extends RepositoryStateMachinePersist<MongoDbRepositoryStateMachine, S, E> {
|
||||
|
||||
private final MongoDbStateMachineRepository mongodbStateMachineRepository;
|
||||
|
||||
/**
|
||||
* Instantiates a new mongodb repository state machine persist.
|
||||
*
|
||||
* @param mongodbStateMachineRepository the mongodb state machine repository
|
||||
*/
|
||||
public MongoDbRepositoryStateMachinePersist(MongoDbStateMachineRepository mongodbStateMachineRepository) {
|
||||
super();
|
||||
this.mongodbStateMachineRepository = mongodbStateMachineRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new mongodb repository state machine persist.
|
||||
*
|
||||
* @param mongodbStateMachineRepository the mongodb state machine repository
|
||||
* @param serialisationService the serialisation service
|
||||
*/
|
||||
public MongoDbRepositoryStateMachinePersist(MongoDbStateMachineRepository mongodbStateMachineRepository,
|
||||
StateMachineSerialisationService<S, E> serialisationService) {
|
||||
super(serialisationService);
|
||||
this.mongodbStateMachineRepository = mongodbStateMachineRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StateMachineRepository<MongoDbRepositoryStateMachine> getRepository() {
|
||||
return mongodbStateMachineRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MongoDbRepositoryStateMachine build(StateMachineContext<S, E> context, byte[] serialisedContext) {
|
||||
MongoDbRepositoryStateMachine mongodbRepositoryStateMachine = new MongoDbRepositoryStateMachine();
|
||||
mongodbRepositoryStateMachine.setMachineId(context.getId());
|
||||
mongodbRepositoryStateMachine.setState(context.getState().toString());
|
||||
mongodbRepositoryStateMachine.setStateMachineContext(serialisedContext);
|
||||
return mongodbRepositoryStateMachine;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.data.mongodb;
|
||||
|
||||
import org.springframework.statemachine.data.StateMachineRepository;
|
||||
|
||||
/**
|
||||
* A {@link StateMachineRepository} interface for MongoDb used for states machines.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
*/
|
||||
public interface MongoDbStateMachineRepository extends StateMachineRepository<MongoDbRepositoryStateMachine>{
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
* Copyright 2016-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.
|
||||
@@ -24,11 +24,22 @@ import java.util.List;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
//import org.springframework.data.keyvalue.core.KeyValueTemplate;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.config.EnableStateMachine;
|
||||
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
|
||||
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
|
||||
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
|
||||
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
|
||||
import org.springframework.statemachine.data.AbstractRepositoryTests;
|
||||
import org.springframework.statemachine.data.mongodb.MongoDbPersistingStateMachineInterceptor;
|
||||
import org.springframework.statemachine.data.mongodb.MongoDbStateMachineRepository;
|
||||
import org.springframework.statemachine.persist.StateMachineRuntimePersister;
|
||||
import org.springframework.statemachine.transition.TransitionKind;
|
||||
|
||||
/**
|
||||
@@ -109,6 +120,36 @@ public class MongoDbRepositoryTests extends AbstractRepositoryTests {
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testStateMachinePersistWithStrings() {
|
||||
context.register(TestConfig.class, ConfigWithStrings.class);
|
||||
context.refresh();
|
||||
|
||||
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
|
||||
stateMachine.start();
|
||||
assertThat(stateMachine.getState().getId(), is("S1"));
|
||||
stateMachine.sendEvent("E1");
|
||||
assertThat(stateMachine.getState().getId(), is("S2"));
|
||||
stateMachine.sendEvent("E2");
|
||||
assertThat(stateMachine.getState().getId(), is("S1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testStateMachinePersistWithEnums() {
|
||||
context.register(TestConfig.class, ConfigWithEnums.class);
|
||||
context.refresh();
|
||||
|
||||
StateMachine<PersistTestStates, PersistTestEvents> stateMachine = context.getBean(StateMachine.class);
|
||||
stateMachine.start();
|
||||
assertThat(stateMachine.getState().getId(), is(PersistTestStates.S1));
|
||||
stateMachine.sendEvent(PersistTestEvents.E1);
|
||||
assertThat(stateMachine.getState().getId(), is(PersistTestStates.S2));
|
||||
stateMachine.sendEvent(PersistTestEvents.E2);
|
||||
assertThat(stateMachine.getState().getId(), is(PersistTestStates.S1));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getRegisteredClasses() {
|
||||
return new Class<?>[] { TestConfig.class };
|
||||
@@ -122,4 +163,102 @@ public class MongoDbRepositoryTests extends AbstractRepositoryTests {
|
||||
@EnableAutoConfiguration
|
||||
static class TestConfig {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
public static class ConfigWithStrings extends StateMachineConfigurerAdapter<String, String> {
|
||||
|
||||
@Autowired
|
||||
private MongoDbStateMachineRepository mongodbStateMachineRepository;
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineConfigurationConfigurer<String, String> config) throws Exception {
|
||||
config
|
||||
.withConfiguration()
|
||||
.machineId("xxx1")
|
||||
.and()
|
||||
.withPersistence()
|
||||
.runtimePersister(stateMachineRuntimePersister());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineStateConfigurer<String, String> states) throws Exception {
|
||||
states
|
||||
.withStates()
|
||||
.initial("S1")
|
||||
.state("S2");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineTransitionConfigurer<String, String> transitions) throws Exception {
|
||||
transitions
|
||||
.withExternal()
|
||||
.source("S1")
|
||||
.target("S2")
|
||||
.event("E1")
|
||||
.and()
|
||||
.withExternal()
|
||||
.source("S2")
|
||||
.target("S1")
|
||||
.event("E2");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StateMachineRuntimePersister<String, String, String> stateMachineRuntimePersister() {
|
||||
return new MongoDbPersistingStateMachineInterceptor<>(mongodbStateMachineRepository);
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
public static class ConfigWithEnums extends StateMachineConfigurerAdapter<PersistTestStates, PersistTestEvents> {
|
||||
|
||||
@Autowired
|
||||
private MongoDbStateMachineRepository mongodbStateMachineRepository;
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineConfigurationConfigurer<PersistTestStates, PersistTestEvents> config) throws Exception {
|
||||
config
|
||||
.withConfiguration()
|
||||
.machineId("xxx2")
|
||||
.and()
|
||||
.withPersistence()
|
||||
.runtimePersister(stateMachineRuntimePersister());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineStateConfigurer<PersistTestStates, PersistTestEvents> states) throws Exception {
|
||||
states
|
||||
.withStates()
|
||||
.initial(PersistTestStates.S1)
|
||||
.state(PersistTestStates.S2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineTransitionConfigurer<PersistTestStates, PersistTestEvents> transitions) throws Exception {
|
||||
transitions
|
||||
.withExternal()
|
||||
.source(PersistTestStates.S1)
|
||||
.target(PersistTestStates.S2)
|
||||
.event(PersistTestEvents.E1)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(PersistTestStates.S2)
|
||||
.target(PersistTestStates.S1)
|
||||
.event(PersistTestEvents.E2);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StateMachineRuntimePersister<PersistTestStates, PersistTestEvents, String> stateMachineRuntimePersister() {
|
||||
return new MongoDbPersistingStateMachineInterceptor<>(mongodbStateMachineRepository);
|
||||
}
|
||||
}
|
||||
|
||||
public enum PersistTestStates {
|
||||
S1, S2;
|
||||
}
|
||||
|
||||
public enum PersistTestEvents {
|
||||
E1, E2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.data.redis;
|
||||
|
||||
import org.springframework.statemachine.StateMachineContext;
|
||||
import org.springframework.statemachine.data.redis.RedisRepositoryStateMachinePersist;
|
||||
import org.springframework.statemachine.data.redis.RedisStateMachineRepository;
|
||||
import org.springframework.statemachine.persist.AbstractPersistingStateMachineInterceptor;
|
||||
import org.springframework.statemachine.persist.StateMachineRuntimePersister;
|
||||
import org.springframework.statemachine.support.StateMachineInterceptor;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@code JPA} implementation of a {@link AbstractPersistingStateMachineInterceptor}.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
* @param <S> the type of state
|
||||
* @param <E> the type of event
|
||||
* @param <T> the type of persister context object
|
||||
*/
|
||||
public class RedisPersistingStateMachineInterceptor<S, E, T> extends AbstractPersistingStateMachineInterceptor<S, E, T>
|
||||
implements StateMachineRuntimePersister<S, E, T> {
|
||||
|
||||
private final RedisRepositoryStateMachinePersist<S, E> persist;
|
||||
|
||||
/**
|
||||
* Instantiates a new redis persisting state machine interceptor.
|
||||
*
|
||||
* @param redisStateMachineRepository the redis state machine repository
|
||||
*/
|
||||
public RedisPersistingStateMachineInterceptor(RedisStateMachineRepository redisStateMachineRepository) {
|
||||
Assert.notNull(redisStateMachineRepository, "'redisStateMachineRepository' must be set");
|
||||
this.persist = new RedisRepositoryStateMachinePersist<S, E>(redisStateMachineRepository);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new redis persisting state machine interceptor.
|
||||
*
|
||||
* @param persist the persist
|
||||
*/
|
||||
public RedisPersistingStateMachineInterceptor(RedisRepositoryStateMachinePersist<S, E> persist) {
|
||||
Assert.notNull(persist, "'persist' must be set");
|
||||
this.persist = persist;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateMachineInterceptor<S, E> getInterceptor() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(StateMachineContext<S, E> context, T contextObj) throws Exception {
|
||||
persist.write(context, contextObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateMachineContext<S, E> read(Object contextObj) throws Exception {
|
||||
return persist.read(contextObj);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.data.redis;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.redis.core.RedisHash;
|
||||
import org.springframework.statemachine.data.RepositoryStateMachine;
|
||||
|
||||
/**
|
||||
* A {@link RepositoryStateMachine} interface for Redis used for states machines.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
*/
|
||||
@RedisHash("RedisRepositoryStateMachine")
|
||||
public class RedisRepositoryStateMachine extends RepositoryStateMachine {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
private String machineId;
|
||||
private String state;
|
||||
private byte[] stateMachineContext;
|
||||
|
||||
@Override
|
||||
public String getMachineId() {
|
||||
return machineId;
|
||||
}
|
||||
|
||||
public void setMachineId(String machineId) {
|
||||
this.machineId = machineId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getStateMachineContext() {
|
||||
return stateMachineContext;
|
||||
}
|
||||
|
||||
public void setStateMachineContext(byte[] stateMachineContext) {
|
||||
this.stateMachineContext = stateMachineContext;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.data.redis;
|
||||
|
||||
import org.springframework.statemachine.StateMachineContext;
|
||||
import org.springframework.statemachine.data.RepositoryStateMachinePersist;
|
||||
import org.springframework.statemachine.data.StateMachineRepository;
|
||||
import org.springframework.statemachine.service.StateMachineSerialisationService;
|
||||
|
||||
/**
|
||||
* {@code Redis} based implementation of a {@link RepositoryStateMachinePersist}.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
* @param <S> the type of state
|
||||
* @param <E> the type of event
|
||||
*/
|
||||
public class RedisRepositoryStateMachinePersist<S, E> extends RepositoryStateMachinePersist<RedisRepositoryStateMachine, S, E> {
|
||||
|
||||
private final RedisStateMachineRepository redisStateMachineRepository;
|
||||
|
||||
/**
|
||||
* Instantiates a new redis repository state machine persist.
|
||||
*
|
||||
* @param redisStateMachineRepository the redis state machine repository
|
||||
*/
|
||||
public RedisRepositoryStateMachinePersist(RedisStateMachineRepository redisStateMachineRepository) {
|
||||
super();
|
||||
this.redisStateMachineRepository = redisStateMachineRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new redis repository state machine persist.
|
||||
*
|
||||
* @param redisStateMachineRepository the redis state machine repository
|
||||
* @param serialisationService the serialisation service
|
||||
*/
|
||||
public RedisRepositoryStateMachinePersist(RedisStateMachineRepository redisStateMachineRepository,
|
||||
StateMachineSerialisationService<S, E> serialisationService) {
|
||||
super(serialisationService);
|
||||
this.redisStateMachineRepository = redisStateMachineRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StateMachineRepository<RedisRepositoryStateMachine> getRepository() {
|
||||
return redisStateMachineRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RedisRepositoryStateMachine build(StateMachineContext<S, E> context, byte[] serialisedContext) {
|
||||
RedisRepositoryStateMachine redisRepositoryStateMachine = new RedisRepositoryStateMachine();
|
||||
redisRepositoryStateMachine.setMachineId(context.getId());
|
||||
redisRepositoryStateMachine.setState(context.getState().toString());
|
||||
redisRepositoryStateMachine.setStateMachineContext(serialisedContext);
|
||||
return redisRepositoryStateMachine;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.data.redis;
|
||||
|
||||
import org.springframework.statemachine.data.StateMachineRepository;
|
||||
|
||||
/**
|
||||
* A {@link StateMachineRepository} interface for Redis used for states machines.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
*/
|
||||
public interface RedisStateMachineRepository extends StateMachineRepository<RedisRepositoryStateMachine>{
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
* Copyright 2016-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.
|
||||
@@ -24,10 +24,20 @@ import java.util.List;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.keyvalue.core.KeyValueTemplate;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.config.EnableStateMachine;
|
||||
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
|
||||
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
|
||||
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
|
||||
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
|
||||
import org.springframework.statemachine.data.AbstractRepositoryTests;
|
||||
import org.springframework.statemachine.persist.StateMachineRuntimePersister;
|
||||
import org.springframework.statemachine.transition.TransitionKind;
|
||||
|
||||
/**
|
||||
@@ -108,6 +118,36 @@ public class RedisRepositoryTests extends AbstractRepositoryTests {
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testStateMachinePersistWithStrings() {
|
||||
context.register(TestConfig.class, ConfigWithStrings.class);
|
||||
context.refresh();
|
||||
|
||||
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
|
||||
stateMachine.start();
|
||||
assertThat(stateMachine.getState().getId(), is("S1"));
|
||||
stateMachine.sendEvent("E1");
|
||||
assertThat(stateMachine.getState().getId(), is("S2"));
|
||||
stateMachine.sendEvent("E2");
|
||||
assertThat(stateMachine.getState().getId(), is("S1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testStateMachinePersistWithEnums() {
|
||||
context.register(TestConfig.class, ConfigWithEnums.class);
|
||||
context.refresh();
|
||||
|
||||
StateMachine<PersistTestStates, PersistTestEvents> stateMachine = context.getBean(StateMachine.class);
|
||||
stateMachine.start();
|
||||
assertThat(stateMachine.getState().getId(), is(PersistTestStates.S1));
|
||||
stateMachine.sendEvent(PersistTestEvents.E1);
|
||||
assertThat(stateMachine.getState().getId(), is(PersistTestStates.S2));
|
||||
stateMachine.sendEvent(PersistTestEvents.E2);
|
||||
assertThat(stateMachine.getState().getId(), is(PersistTestStates.S1));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getRegisteredClasses() {
|
||||
return new Class<?>[] { TestConfig.class };
|
||||
@@ -121,4 +161,102 @@ public class RedisRepositoryTests extends AbstractRepositoryTests {
|
||||
@EnableAutoConfiguration
|
||||
static class TestConfig {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
public static class ConfigWithStrings extends StateMachineConfigurerAdapter<String, String> {
|
||||
|
||||
@Autowired
|
||||
private RedisStateMachineRepository redisStateMachineRepository;
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineConfigurationConfigurer<String, String> config) throws Exception {
|
||||
config
|
||||
.withConfiguration()
|
||||
.machineId("xxx1")
|
||||
.and()
|
||||
.withPersistence()
|
||||
.runtimePersister(stateMachineRuntimePersister());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineStateConfigurer<String, String> states) throws Exception {
|
||||
states
|
||||
.withStates()
|
||||
.initial("S1")
|
||||
.state("S2");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineTransitionConfigurer<String, String> transitions) throws Exception {
|
||||
transitions
|
||||
.withExternal()
|
||||
.source("S1")
|
||||
.target("S2")
|
||||
.event("E1")
|
||||
.and()
|
||||
.withExternal()
|
||||
.source("S2")
|
||||
.target("S1")
|
||||
.event("E2");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StateMachineRuntimePersister<String, String, String> stateMachineRuntimePersister() {
|
||||
return new RedisPersistingStateMachineInterceptor<>(redisStateMachineRepository);
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
public static class ConfigWithEnums extends StateMachineConfigurerAdapter<PersistTestStates, PersistTestEvents> {
|
||||
|
||||
@Autowired
|
||||
private RedisStateMachineRepository redisStateMachineRepository;
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineConfigurationConfigurer<PersistTestStates, PersistTestEvents> config) throws Exception {
|
||||
config
|
||||
.withConfiguration()
|
||||
.machineId("xxx2")
|
||||
.and()
|
||||
.withPersistence()
|
||||
.runtimePersister(stateMachineRuntimePersister());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineStateConfigurer<PersistTestStates, PersistTestEvents> states) throws Exception {
|
||||
states
|
||||
.withStates()
|
||||
.initial(PersistTestStates.S1)
|
||||
.state(PersistTestStates.S2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineTransitionConfigurer<PersistTestStates, PersistTestEvents> transitions) throws Exception {
|
||||
transitions
|
||||
.withExternal()
|
||||
.source(PersistTestStates.S1)
|
||||
.target(PersistTestStates.S2)
|
||||
.event(PersistTestEvents.E1)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(PersistTestStates.S2)
|
||||
.target(PersistTestStates.S1)
|
||||
.event(PersistTestEvents.E2);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StateMachineRuntimePersister<PersistTestStates, PersistTestEvents, String> stateMachineRuntimePersister() {
|
||||
return new RedisPersistingStateMachineInterceptor<>(redisStateMachineRepository);
|
||||
}
|
||||
}
|
||||
|
||||
public enum PersistTestStates {
|
||||
S1, S2;
|
||||
}
|
||||
|
||||
public enum PersistTestEvents {
|
||||
E1, E2;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user