Fix Redis/Mongo entity states

- Fix RedisRepositoryState and MongoDbStateRepository not to use
  null for machineid in any case as contract is that empty machineid
  is always empty not null.
- This issue was found when adding initial tck config tests, thus
  this commit also adds initial tck tests.
- Fixes #279
- Relates to #278
This commit is contained in:
Janne Valkealahti
2016-11-19 17:51:15 +00:00
parent b3fbdeb17c
commit 55c6faf225
20 changed files with 1284 additions and 2 deletions

View File

@@ -305,6 +305,13 @@ project('spring-statemachine-build-tests') {
dependencies {
testCompile project(":spring-statemachine-uml")
testCompile project(":spring-statemachine-test")
testCompile project(":spring-statemachine-data-common:spring-statemachine-data-jpa")
testCompile project(":spring-statemachine-data-common:spring-statemachine-data-redis")
testCompile project(":spring-statemachine-data-common:spring-statemachine-data-mongodb")
testRuntime "org.springframework.boot:spring-boot-starter-data-redis:$springBootVersion"
testCompile "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion"
testCompile "com.h2database:h2:$h2Version"
testCompile "org.springframework.boot:spring-boot-starter:$springBootVersion"
testCompile "org.springframework:spring-test:$springVersion"
testCompile "org.hamcrest:hamcrest-core:$hamcrestVersion"
testCompile "org.hamcrest:hamcrest-library:$hamcrestVersion"

View File

@@ -0,0 +1,89 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.statemachine.buildtests.tck;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.config.StateMachineFactory;
import org.springframework.statemachine.test.StateMachineTestPlan;
import org.springframework.statemachine.test.StateMachineTestPlanBuilder;
/**
* Base tck test class for defining various machine tests
* which different config implementations can implement to
* test that same machine behaviour.
*
* @author Janne Valkealahti
*
*/
public abstract class AbstractTckTests {
protected AnnotationConfigApplicationContext context;
@Before
public void setup() {
cleanInternal();
context = buildContext();
}
@After
public void clean() {
if (context != null) {
context.close();
}
context = null;
}
@SuppressWarnings("unchecked")
protected StateMachine<String, String> getStateMachineFromContext() {
return context.getBean(StateMachine.class);
}
@SuppressWarnings("unchecked")
protected StateMachineFactory<String, String> getStateMachineFactoryFromContext() {
return context.getBean(StateMachineFactory.class);
}
protected void cleanInternal() {
}
protected AnnotationConfigApplicationContext buildContext() {
return null;
}
@Test
public void testSimpleMachine() throws Exception {
StateMachine<String,String> stateMachine = getSimpleMachine();
StateMachineTestPlan<String, String> plan =
StateMachineTestPlanBuilder.<String, String>builder()
.stateMachine(stateMachine)
.step().expectStates("S1").and()
.step().sendEvent("E1").expectStates("S2").and()
.step().sendEvent("E2").expectStates("S3").and()
.build();
plan.test();
}
/**
* Return state machine for {@link #testSimpleMachine()}.
*
* @return StateMachine for SimpleMachine
*/
protected abstract StateMachine<String, String> getSimpleMachine();
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.statemachine.buildtests.tck.javaconfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.buildtests.tck.AbstractTckTests;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
/**
* Tck tests for annotation based javaconfig.
*
* @author Janne Valkealahti
*
*/
public class AnnotationTckTests extends AbstractTckTests {
@Override
protected AnnotationConfigApplicationContext buildContext() {
return new AnnotationConfigApplicationContext();
}
@Override
protected StateMachine<String, String> getSimpleMachine() {
context.register(SimpleMachineConfig.class);
context.refresh();
return getStateMachineFromContext();
}
@Configuration
@EnableStateMachine
static class SimpleMachineConfig extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineStateConfigurer<String, String> states) throws Exception {
states
.withStates()
.initial("S1")
.state("S2")
.state("S3");
}
@Override
public void configure(StateMachineTransitionConfigurer<String, String> transitions) throws Exception {
transitions
.withExternal()
.source("S1").target("S2")
.event("E1")
.and()
.withExternal()
.source("S2").target("S3")
.event("E2");
}
}
}

View File

@@ -0,0 +1,100 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.statemachine.buildtests.tck.jpa;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.buildtests.tck.AbstractTckTests;
import org.springframework.statemachine.config.EnableStateMachineFactory;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
import org.springframework.statemachine.config.model.StateMachineModelFactory;
import org.springframework.statemachine.data.RepositoryState;
import org.springframework.statemachine.data.RepositoryStateMachineModelFactory;
import org.springframework.statemachine.data.RepositoryTransition;
import org.springframework.statemachine.data.StateRepository;
import org.springframework.statemachine.data.TransitionRepository;
import org.springframework.statemachine.data.support.StateMachineJackson2RepositoryPopulatorFactoryBean;
/**
* Tck tests for machine configs imported from json entity definitions.
*
* @author Janne Valkealahti
*
*/
public class JpaJsonTckTests extends AbstractTckTests {
@Override
protected AnnotationConfigApplicationContext buildContext() {
return new AnnotationConfigApplicationContext();
}
@Override
protected StateMachine<String, String> getSimpleMachine() {
context.register(TestConfig.class, SimpleMachineConfig.class, StateMachineFactoryConfig.class);
context.refresh();
return getStateMachineFactoryFromContext().getStateMachine();
}
@Configuration
public static class SimpleMachineConfig {
@Bean
public StateMachineJackson2RepositoryPopulatorFactoryBean jackson2RepositoryPopulatorFactoryBean() {
StateMachineJackson2RepositoryPopulatorFactoryBean factoryBean = new StateMachineJackson2RepositoryPopulatorFactoryBean();
factoryBean.setResources(new Resource[]{new ClassPathResource("org/springframework/statemachine/buildtests/tck/jpa/SimpleMachine.json")});
return factoryBean;
}
}
@Configuration
@EnableStateMachineFactory
public static class StateMachineFactoryConfig extends StateMachineConfigurerAdapter<String, String> {
@Autowired
private StateRepository<? extends RepositoryState> stateRepository;
@Autowired
private TransitionRepository<? extends RepositoryTransition> transitionRepository;
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new RepositoryStateMachineModelFactory(stateRepository, transitionRepository);
}
}
@EnableAutoConfiguration
@EntityScan(basePackages = {"org.springframework.statemachine.data.jpa"})
@EnableJpaRepositories(basePackages = {"org.springframework.statemachine.data.jpa"})
static class TestConfig {
}
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.statemachine.buildtests.tck.jpa;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.buildtests.tck.AbstractTckTests;
import org.springframework.statemachine.config.EnableStateMachineFactory;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
import org.springframework.statemachine.config.model.StateMachineModelFactory;
import org.springframework.statemachine.data.RepositoryState;
import org.springframework.statemachine.data.RepositoryStateMachineModelFactory;
import org.springframework.statemachine.data.RepositoryTransition;
import org.springframework.statemachine.data.StateRepository;
import org.springframework.statemachine.data.TransitionRepository;
import org.springframework.statemachine.data.jpa.JpaRepositoryState;
import org.springframework.statemachine.data.jpa.JpaRepositoryTransition;
import org.springframework.statemachine.data.jpa.JpaStateRepository;
import org.springframework.statemachine.data.jpa.JpaTransitionRepository;
/**
* Tck tests for machine configs build manually agains repository interfaces.
*
* @author Janne Valkealahti
*
*/
public class JpaManualTckTests extends AbstractTckTests {
@Override
protected AnnotationConfigApplicationContext buildContext() {
return new AnnotationConfigApplicationContext();
}
@Override
protected StateMachine<String, String> getSimpleMachine() {
context.register(TestConfig.class, StateMachineFactoryConfig.class);
context.refresh();
JpaStateRepository stateRepository = context.getBean(JpaStateRepository.class);
JpaTransitionRepository transitionRepository = context.getBean(JpaTransitionRepository.class);
JpaRepositoryState stateS1 = new JpaRepositoryState("S1", true);
JpaRepositoryState stateS2 = new JpaRepositoryState("S2");
JpaRepositoryState stateS3 = new JpaRepositoryState("S3");
stateRepository.save(stateS1);
stateRepository.save(stateS2);
stateRepository.save(stateS3);
JpaRepositoryTransition transitionS1ToS2 = new JpaRepositoryTransition(stateS1, stateS2, "E1");
JpaRepositoryTransition transitionS2ToS3 = new JpaRepositoryTransition(stateS2, stateS3, "E2");
transitionRepository.save(transitionS1ToS2);
transitionRepository.save(transitionS2ToS3);
return getStateMachineFactoryFromContext().getStateMachine();
}
@Configuration
@EnableStateMachineFactory
public static class StateMachineFactoryConfig extends StateMachineConfigurerAdapter<String, String> {
@Autowired
private StateRepository<? extends RepositoryState> stateRepository;
@Autowired
private TransitionRepository<? extends RepositoryTransition> transitionRepository;
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new RepositoryStateMachineModelFactory(stateRepository, transitionRepository);
}
}
@EnableAutoConfiguration
@EntityScan(basePackages = {"org.springframework.statemachine.data.jpa"})
@EnableJpaRepositories(basePackages = {"org.springframework.statemachine.data.jpa"})
static class TestConfig {
}
}

View File

@@ -0,0 +1,121 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.statemachine.buildtests.tck.mongodb;
import org.junit.Rule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.buildtests.tck.AbstractTckTests;
import org.springframework.statemachine.config.EnableStateMachineFactory;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
import org.springframework.statemachine.config.model.StateMachineModelFactory;
import org.springframework.statemachine.data.RepositoryState;
import org.springframework.statemachine.data.RepositoryStateMachineModelFactory;
import org.springframework.statemachine.data.RepositoryTransition;
import org.springframework.statemachine.data.StateRepository;
import org.springframework.statemachine.data.TransitionRepository;
import org.springframework.statemachine.data.mongodb.MongoDbRepositoryAction;
import org.springframework.statemachine.data.mongodb.MongoDbRepositoryGuard;
import org.springframework.statemachine.data.mongodb.MongoDbRepositoryState;
import org.springframework.statemachine.data.mongodb.MongoDbRepositoryTransition;
import org.springframework.statemachine.data.support.StateMachineJackson2RepositoryPopulatorFactoryBean;
/**
* Tck tests for machine configs imported from json entity definitions.
*
* @author Janne Valkealahti
*
*/
public class MongoDbJsonTckTests extends AbstractTckTests {
@Rule
public MongoDbRule MongoDbAvailableRule = new MongoDbRule();
@Override
protected void cleanInternal() {
AnnotationConfigApplicationContext c = new AnnotationConfigApplicationContext();
c.register(TestConfig.class);
c.refresh();
MongoTemplate template = c.getBean(MongoTemplate.class);
template.dropCollection(MongoDbRepositoryAction.class);
template.dropCollection(MongoDbRepositoryGuard.class);
template.dropCollection(MongoDbRepositoryState.class);
template.dropCollection(MongoDbRepositoryTransition.class);
c.close();
}
@Override
protected AnnotationConfigApplicationContext buildContext() {
return new AnnotationConfigApplicationContext();
}
@Override
protected StateMachine<String, String> getSimpleMachine() {
context.register(TestConfig.class, SimpleMachineConfig.class, StateMachineFactoryConfig.class);
context.refresh();
return getStateMachineFactoryFromContext().getStateMachine();
}
@Configuration
public static class SimpleMachineConfig {
@Bean
public StateMachineJackson2RepositoryPopulatorFactoryBean jackson2RepositoryPopulatorFactoryBean() {
StateMachineJackson2RepositoryPopulatorFactoryBean factoryBean = new StateMachineJackson2RepositoryPopulatorFactoryBean();
factoryBean.setResources(new Resource[]{new ClassPathResource("org/springframework/statemachine/buildtests/tck/mongodb/SimpleMachine.json")});
return factoryBean;
}
}
@Configuration
@EnableStateMachineFactory
public static class StateMachineFactoryConfig extends StateMachineConfigurerAdapter<String, String> {
@Autowired
private StateRepository<? extends RepositoryState> stateRepository;
@Autowired
private TransitionRepository<? extends RepositoryTransition> transitionRepository;
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new RepositoryStateMachineModelFactory(stateRepository, transitionRepository);
}
}
@EnableAutoConfiguration
@EntityScan(basePackages = {"org.springframework.statemachine.data.mongodb"})
@EnableMongoRepositories(basePackages = {"org.springframework.statemachine.data.mongodb"})
static class TestConfig {
}
}

View File

@@ -0,0 +1,127 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.statemachine.buildtests.tck.mongodb;
import org.junit.Rule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
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.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.buildtests.tck.AbstractTckTests;
import org.springframework.statemachine.config.EnableStateMachineFactory;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
import org.springframework.statemachine.config.model.StateMachineModelFactory;
import org.springframework.statemachine.data.RepositoryState;
import org.springframework.statemachine.data.RepositoryStateMachineModelFactory;
import org.springframework.statemachine.data.RepositoryTransition;
import org.springframework.statemachine.data.StateRepository;
import org.springframework.statemachine.data.TransitionRepository;
import org.springframework.statemachine.data.mongodb.MongoDbRepositoryAction;
import org.springframework.statemachine.data.mongodb.MongoDbRepositoryGuard;
import org.springframework.statemachine.data.mongodb.MongoDbRepositoryState;
import org.springframework.statemachine.data.mongodb.MongoDbRepositoryTransition;
import org.springframework.statemachine.data.mongodb.MongoDbStateRepository;
import org.springframework.statemachine.data.mongodb.MongoDbTransitionRepository;
/**
* Tck tests for machine configs build manually agains repository interfaces.
*
* @author Janne Valkealahti
*
*/
public class MongoDbManualTckTests extends AbstractTckTests {
@Rule
public MongoDbRule MongoDbAvailableRule = new MongoDbRule();
@Override
protected void cleanInternal() {
AnnotationConfigApplicationContext c = new AnnotationConfigApplicationContext();
c.register(TestConfig.class);
c.refresh();
MongoTemplate template = c.getBean(MongoTemplate.class);
template.dropCollection(MongoDbRepositoryAction.class);
template.dropCollection(MongoDbRepositoryGuard.class);
template.dropCollection(MongoDbRepositoryState.class);
template.dropCollection(MongoDbRepositoryTransition.class);
c.close();
}
@Override
protected AnnotationConfigApplicationContext buildContext() {
return new AnnotationConfigApplicationContext();
}
@Override
protected StateMachine<String, String> getSimpleMachine() {
context.register(TestConfig.class, StateMachineFactoryConfig.class);
context.refresh();
MongoDbStateRepository stateRepository = context.getBean(MongoDbStateRepository.class);
MongoDbTransitionRepository transitionRepository = context.getBean(MongoDbTransitionRepository.class);
MongoDbRepositoryState stateS1 = new MongoDbRepositoryState("S1", true);
MongoDbRepositoryState stateS2 = new MongoDbRepositoryState("S2");
MongoDbRepositoryState stateS3 = new MongoDbRepositoryState("S3");
stateRepository.save(stateS1);
stateRepository.save(stateS2);
stateRepository.save(stateS3);
MongoDbRepositoryTransition transitionS1ToS2 = new MongoDbRepositoryTransition(stateS1, stateS2, "E1");
MongoDbRepositoryTransition transitionS2ToS3 = new MongoDbRepositoryTransition(stateS2, stateS3, "E2");
transitionRepository.save(transitionS1ToS2);
transitionRepository.save(transitionS2ToS3);
return getStateMachineFactoryFromContext().getStateMachine();
}
@Configuration
@EnableStateMachineFactory
public static class StateMachineFactoryConfig extends StateMachineConfigurerAdapter<String, String> {
@Autowired
private StateRepository<? extends RepositoryState> stateRepository;
@Autowired
private TransitionRepository<? extends RepositoryTransition> transitionRepository;
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new RepositoryStateMachineModelFactory(stateRepository, transitionRepository);
}
}
@EnableAutoConfiguration
@EntityScan(basePackages = {"org.springframework.statemachine.data.mongodb"})
@EnableMongoRepositories(basePackages = {"org.springframework.statemachine.data.mongodb"})
static class TestConfig {
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.statemachine.buildtests.tck.mongodb;
import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.ServerAddress;
/**
* Rule skipping tests if MongoDb is not available from localhost with default settings.
*
* @author Janne Valkealahti
*
*/
public class MongoDbRule extends TestWatcher implements TestRule {
@Override
public Statement apply(Statement base, Description description) {
MongoClient client = null;
try {
client = new MongoClient(new ServerAddress(), MongoClientOptions.builder().connectTimeout(50).build());
client.getAddress();
} catch (Exception e) {
return super.apply(new Statement() {
@Override
public void evaluate() throws Throwable {
}
}, Description.EMPTY);
} finally {
if (client != null) {
client.close();
}
}
return super.apply(base, description);
}
}

View File

@@ -0,0 +1,121 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.statemachine.buildtests.tck.redis;
import org.junit.Rule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.data.keyvalue.core.KeyValueTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.buildtests.tck.AbstractTckTests;
import org.springframework.statemachine.config.EnableStateMachineFactory;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
import org.springframework.statemachine.config.model.StateMachineModelFactory;
import org.springframework.statemachine.data.RepositoryState;
import org.springframework.statemachine.data.RepositoryStateMachineModelFactory;
import org.springframework.statemachine.data.RepositoryTransition;
import org.springframework.statemachine.data.StateRepository;
import org.springframework.statemachine.data.TransitionRepository;
import org.springframework.statemachine.data.redis.RedisRepositoryAction;
import org.springframework.statemachine.data.redis.RedisRepositoryGuard;
import org.springframework.statemachine.data.redis.RedisRepositoryState;
import org.springframework.statemachine.data.redis.RedisRepositoryTransition;
import org.springframework.statemachine.data.support.StateMachineJackson2RepositoryPopulatorFactoryBean;
/**
* Tck tests for machine configs imported from json entity definitions.
*
* @author Janne Valkealahti
*
*/
public class RedisJsonTckTests extends AbstractTckTests {
@Rule
public RedisRule redisAvailableRule = new RedisRule();
@Override
protected AnnotationConfigApplicationContext buildContext() {
return new AnnotationConfigApplicationContext();
}
@Override
protected void cleanInternal() {
AnnotationConfigApplicationContext c = new AnnotationConfigApplicationContext();
c.register(TestConfig.class);
c.refresh();
KeyValueTemplate kvTemplate = c.getBean(KeyValueTemplate.class);
kvTemplate.delete(RedisRepositoryAction.class);
kvTemplate.delete(RedisRepositoryGuard.class);
kvTemplate.delete(RedisRepositoryState.class);
kvTemplate.delete(RedisRepositoryTransition.class);
c.close();
}
@Override
protected StateMachine<String, String> getSimpleMachine() {
context.register(TestConfig.class, SimpleMachineConfig.class, StateMachineFactoryConfig.class);
context.refresh();
return getStateMachineFactoryFromContext().getStateMachine();
}
@Configuration
public static class SimpleMachineConfig {
@Bean
public StateMachineJackson2RepositoryPopulatorFactoryBean jackson2RepositoryPopulatorFactoryBean() {
StateMachineJackson2RepositoryPopulatorFactoryBean factoryBean = new StateMachineJackson2RepositoryPopulatorFactoryBean();
factoryBean.setResources(new Resource[]{new ClassPathResource("org/springframework/statemachine/buildtests/tck/redis/SimpleMachine.json")});
return factoryBean;
}
}
@Configuration
@EnableStateMachineFactory
public static class StateMachineFactoryConfig extends StateMachineConfigurerAdapter<String, String> {
@Autowired
private StateRepository<? extends RepositoryState> stateRepository;
@Autowired
private TransitionRepository<? extends RepositoryTransition> transitionRepository;
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new RepositoryStateMachineModelFactory(stateRepository, transitionRepository);
}
}
@EnableAutoConfiguration
@EntityScan(basePackages = {"org.springframework.statemachine.data.redis"})
@EnableRedisRepositories(basePackages = {"org.springframework.statemachine.data.redis"})
static class TestConfig {
}
}

View File

@@ -0,0 +1,128 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.statemachine.buildtests.tck.redis;
import org.junit.Rule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
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.data.redis.repository.configuration.EnableRedisRepositories;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.buildtests.tck.AbstractTckTests;
import org.springframework.statemachine.config.EnableStateMachineFactory;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
import org.springframework.statemachine.config.model.StateMachineModelFactory;
import org.springframework.statemachine.data.RepositoryState;
import org.springframework.statemachine.data.RepositoryStateMachineModelFactory;
import org.springframework.statemachine.data.RepositoryTransition;
import org.springframework.statemachine.data.StateRepository;
import org.springframework.statemachine.data.TransitionRepository;
import org.springframework.statemachine.data.redis.RedisRepositoryAction;
import org.springframework.statemachine.data.redis.RedisRepositoryGuard;
import org.springframework.statemachine.data.redis.RedisRepositoryState;
import org.springframework.statemachine.data.redis.RedisRepositoryTransition;
import org.springframework.statemachine.data.redis.RedisStateRepository;
import org.springframework.statemachine.data.redis.RedisTransitionRepository;
/**
* Tck tests for machine configs build manually agains repository interfaces.
*
* @author Janne Valkealahti
*
*/
public class RedisManualTckTests extends AbstractTckTests {
@Rule
public RedisRule redisAvailableRule = new RedisRule();
@Override
protected void cleanInternal() {
AnnotationConfigApplicationContext c = new AnnotationConfigApplicationContext();
c.register(TestConfig.class);
c.refresh();
KeyValueTemplate kvTemplate = c.getBean(KeyValueTemplate.class);
kvTemplate.delete(RedisRepositoryAction.class);
kvTemplate.delete(RedisRepositoryGuard.class);
kvTemplate.delete(RedisRepositoryState.class);
kvTemplate.delete(RedisRepositoryTransition.class);
c.close();
}
@Override
protected AnnotationConfigApplicationContext buildContext() {
return new AnnotationConfigApplicationContext();
}
@Override
protected StateMachine<String, String> getSimpleMachine() {
context.register(TestConfig.class, StateMachineFactoryConfig.class);
context.refresh();
RedisStateRepository stateRepository = context.getBean(RedisStateRepository.class);
RedisTransitionRepository transitionRepository = context.getBean(RedisTransitionRepository.class);
RedisRepositoryState stateS1 = new RedisRepositoryState("S1", true);
RedisRepositoryState stateS2 = new RedisRepositoryState("S2");
RedisRepositoryState stateS3 = new RedisRepositoryState("S3");
stateRepository.save(stateS1);
stateRepository.save(stateS2);
stateRepository.save(stateS3);
RedisRepositoryTransition transitionS1ToS2 = new RedisRepositoryTransition(stateS1, stateS2, "E1");
RedisRepositoryTransition transitionS2ToS3 = new RedisRepositoryTransition(stateS2, stateS3, "E2");
transitionRepository.save(transitionS1ToS2);
transitionRepository.save(transitionS2ToS3);
return getStateMachineFactoryFromContext().getStateMachine();
}
@Configuration
@EnableStateMachineFactory
public static class StateMachineFactoryConfig extends StateMachineConfigurerAdapter<String, String> {
@Autowired
private StateRepository<? extends RepositoryState> stateRepository;
@Autowired
private TransitionRepository<? extends RepositoryTransition> transitionRepository;
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new RepositoryStateMachineModelFactory(stateRepository, transitionRepository);
}
}
@EnableAutoConfiguration
@EntityScan(basePackages = {"org.springframework.statemachine.data.redis"})
@EnableRedisRepositories(basePackages = {"org.springframework.statemachine.data.redis"})
static class TestConfig {
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.statemachine.buildtests.tck.redis;
import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
/**
* Rule skipping tests if redis is not available from localhost with default settings.
*
* @author Janne Valkealahti
*
*/
public class RedisRule extends TestWatcher implements TestRule {
@Override
public Statement apply(Statement base, Description description) {
JedisConnectionFactory connectionFactory = null;
try {
connectionFactory = new JedisConnectionFactory();
connectionFactory.afterPropertiesSet();
connectionFactory.getConnection().close();
} catch (Exception e) {
return super.apply(new Statement() {
@Override
public void evaluate() throws Throwable {
}
}, Description.EMPTY);
} finally {
if (connectionFactory != null) {
connectionFactory.destroy();
}
}
return super.apply(base, description);
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.statemachine.buildtests.tck.uml;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.buildtests.tck.AbstractTckTests;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
import org.springframework.statemachine.config.model.StateMachineModelFactory;
import org.springframework.statemachine.uml.UmlStateMachineModelFactory;
/**
* Tck tests for machine configs build from uml.
*
* @author Janne Valkealahti
*
*/
public class UmlTckTests extends AbstractTckTests {
@Override
protected AnnotationConfigApplicationContext buildContext() {
return new AnnotationConfigApplicationContext();
}
@Override
protected StateMachine<String, String> getSimpleMachine() {
context.register(SimpleMachineConfig.class);
context.refresh();
return getStateMachineFromContext();
}
@Configuration
@EnableStateMachine
public static class SimpleMachineConfig extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new UmlStateMachineModelFactory("classpath:org/springframework/statemachine/buildtests/tck/uml/SimpleMachine.uml");
}
}
}

View File

@@ -0,0 +1,32 @@
[
{
"@id": "1",
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState",
"initial": true,
"state": "S1"
},
{
"@id": "2",
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState",
"initial": false,
"state": "S2"
},
{
"@id": "3",
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState",
"initial": false,
"state": "S3"
},
{
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition",
"source": "1",
"target": "2",
"event": "E1"
},
{
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition",
"source": "2",
"target": "3",
"event": "E2"
}
]

View File

@@ -0,0 +1,32 @@
[
{
"@id": "1",
"_class": "org.springframework.statemachine.data.mongodb.MongoDbRepositoryState",
"initial": true,
"state": "S1"
},
{
"@id": "2",
"_class": "org.springframework.statemachine.data.mongodb.MongoDbRepositoryState",
"initial": false,
"state": "S2"
},
{
"@id": "3",
"_class": "org.springframework.statemachine.data.mongodb.MongoDbRepositoryState",
"initial": false,
"state": "S3"
},
{
"_class": "org.springframework.statemachine.data.mongodb.MongoDbRepositoryTransition",
"source": "1",
"target": "2",
"event": "E1"
},
{
"_class": "org.springframework.statemachine.data.mongodb.MongoDbRepositoryTransition",
"source": "2",
"target": "3",
"event": "E2"
}
]

View File

@@ -0,0 +1,32 @@
[
{
"@id": "1",
"_class": "org.springframework.statemachine.data.redis.RedisRepositoryState",
"initial": true,
"state": "S1"
},
{
"@id": "2",
"_class": "org.springframework.statemachine.data.redis.RedisRepositoryState",
"initial": false,
"state": "S2"
},
{
"@id": "3",
"_class": "org.springframework.statemachine.data.redis.RedisRepositoryState",
"initial": false,
"state": "S3"
},
{
"_class": "org.springframework.statemachine.data.redis.RedisRepositoryTransition",
"source": "1",
"target": "2",
"event": "E1"
},
{
"_class": "org.springframework.statemachine.data.redis.RedisRepositoryTransition",
"source": "2",
"target": "3",
"event": "E2"
}
]

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8"?>
<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/viewpoints/policy/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_CvKPUK5kEeasH9qRmhZPUw" type="PapyrusUMLStateMachineDiagram" name="StateMachine Diagram" measurementUnit="Pixel">
<children xmi:type="notation:Shape" xmi:id="_CvKPUa5kEeasH9qRmhZPUw" type="2000">
<children xmi:type="notation:DecorationNode" xmi:id="_CvKPUq5kEeasH9qRmhZPUw" type="2001">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_CvKPU65kEeasH9qRmhZPUw" width="700" height="23"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_CvKPVK5kEeasH9qRmhZPUw" type="2002">
<children xmi:type="notation:Shape" xmi:id="_CvKPVa5kEeasH9qRmhZPUw" type="3000">
<eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_CvKPVq5kEeasH9qRmhZPUw" source="RegionAnnotationKey">
<details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_CvKPV65kEeasH9qRmhZPUw" key="RegionZoneKey" value=""/>
</eAnnotations>
<children xmi:type="notation:DecorationNode" xmi:id="_CvKPWK5kEeasH9qRmhZPUw" type="3002">
<children xmi:type="notation:Shape" xmi:id="_FD55IK5kEeasH9qRmhZPUw" type="6000">
<children xmi:type="notation:DecorationNode" xmi:id="_FD55Iq5kEeasH9qRmhZPUw" type="6001"/>
<children xmi:type="notation:DecorationNode" xmi:id="_FD55I65kEeasH9qRmhZPUw" type="19003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_FD55JK5kEeasH9qRmhZPUw" x="40"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_FD55Ja5kEeasH9qRmhZPUw" type="6002">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_FD55Jq5kEeasH9qRmhZPUw"/>
</children>
<element xmi:type="uml:State" href="SimpleMachine.uml#_FD210K5kEeasH9qRmhZPUw"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_FD55Ia5kEeasH9qRmhZPUw" x="137" y="49"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_GKnpkK5kEeasH9qRmhZPUw" type="6000">
<children xmi:type="notation:DecorationNode" xmi:id="_GKoQoK5kEeasH9qRmhZPUw" type="6001"/>
<children xmi:type="notation:DecorationNode" xmi:id="_GKoQoa5kEeasH9qRmhZPUw" type="19003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_GKoQoq5kEeasH9qRmhZPUw" x="40"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_GKoQo65kEeasH9qRmhZPUw" type="6002">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_GKoQpK5kEeasH9qRmhZPUw"/>
</children>
<element xmi:type="uml:State" href="SimpleMachine.uml#_GKkmQK5kEeasH9qRmhZPUw"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_GKnpka5kEeasH9qRmhZPUw" x="272" y="49"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_G5KxoK5kEeasH9qRmhZPUw" type="6000">
<children xmi:type="notation:DecorationNode" xmi:id="_G5Kxoq5kEeasH9qRmhZPUw" type="6001"/>
<children xmi:type="notation:DecorationNode" xmi:id="_G5Kxo65kEeasH9qRmhZPUw" type="19003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_G5KxpK5kEeasH9qRmhZPUw" x="40"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_G5Kxpa5kEeasH9qRmhZPUw" type="6002">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_G5Kxpq5kEeasH9qRmhZPUw"/>
</children>
<element xmi:type="uml:State" href="SimpleMachine.uml#_G5GgMK5kEeasH9qRmhZPUw"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_G5Kxoa5kEeasH9qRmhZPUw" x="409" y="49"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_KqSS0K5kEeasH9qRmhZPUw" type="8000">
<children xmi:type="notation:DecorationNode" xmi:id="_KqSS0q5kEeasH9qRmhZPUw" type="8001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_KqSS065kEeasH9qRmhZPUw" x="25" y="3"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_KqSS1K5kEeasH9qRmhZPUw" type="8002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_KqSS1a5kEeasH9qRmhZPUw" x="25" y="-10"/>
</children>
<element xmi:type="uml:Pseudostate" href="SimpleMachine.uml#_KqMzQK5kEeasH9qRmhZPUw"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_KqSS0a5kEeasH9qRmhZPUw" x="44" y="61"/>
</children>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_CvKPWa5kEeasH9qRmhZPUw"/>
</children>
<element xmi:type="uml:Region" href="SimpleMachine.uml#_CvJoQK5kEeasH9qRmhZPUw"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_CvKPWq5kEeasH9qRmhZPUw" width="700" height="287"/>
</children>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_CvKPW65kEeasH9qRmhZPUw" y="23" width="700" height="287"/>
</children>
<element xmi:type="uml:StateMachine" href="SimpleMachine.uml#_CvJBMK5kEeasH9qRmhZPUw"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_CvKPXK5kEeasH9qRmhZPUw" x="30" y="30" width="700" height="310"/>
</children>
<styles xmi:type="notation:StringValueStyle" xmi:id="_CvKPXa5kEeasH9qRmhZPUw" name="diagram_compatibility_version" stringValue="1.1.0"/>
<styles xmi:type="notation:DiagramStyle" xmi:id="_CvKPXq5kEeasH9qRmhZPUw"/>
<styles xmi:type="style:PapyrusViewStyle" xmi:id="_CvKPX65kEeasH9qRmhZPUw">
<owner xmi:type="uml:Model" href="SimpleMachine.uml#_CvHMAK5kEeasH9qRmhZPUw"/>
</styles>
<element xmi:type="uml:StateMachine" href="SimpleMachine.uml#_CvJBMK5kEeasH9qRmhZPUw"/>
<edges xmi:type="notation:Connector" xmi:id="_MIHiwK5kEeasH9qRmhZPUw" type="7000" source="_KqSS0K5kEeasH9qRmhZPUw" target="_FD55IK5kEeasH9qRmhZPUw">
<children xmi:type="notation:DecorationNode" xmi:id="_MIHiw65kEeasH9qRmhZPUw" type="7001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_MIHixK5kEeasH9qRmhZPUw"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_MIHixa5kEeasH9qRmhZPUw" type="7002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_MIHixq5kEeasH9qRmhZPUw"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_MIHix65kEeasH9qRmhZPUw" type="7003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_MIHiyK5kEeasH9qRmhZPUw" y="60"/>
</children>
<styles xmi:type="notation:FontStyle" xmi:id="_MIHiwa5kEeasH9qRmhZPUw"/>
<element xmi:type="uml:Transition" href="SimpleMachine.uml#_MICDMK5kEeasH9qRmhZPUw"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_MIHiwq5kEeasH9qRmhZPUw" points="[8, -2, -78, 0]$[83, -3, -3, -1]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_MIWzUK5kEeasH9qRmhZPUw" id="(1.0,0.4)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_MIWzUa5kEeasH9qRmhZPUw" id="(0.0,0.425531914893617)"/>
</edges>
<edges xmi:type="notation:Connector" xmi:id="_NPW3oK5kEeasH9qRmhZPUw" type="7000" source="_FD55IK5kEeasH9qRmhZPUw" target="_GKnpkK5kEeasH9qRmhZPUw">
<children xmi:type="notation:DecorationNode" xmi:id="_NPXesK5kEeasH9qRmhZPUw" type="7001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_NPXesa5kEeasH9qRmhZPUw"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_NPXesq5kEeasH9qRmhZPUw" type="7002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_NPXes65kEeasH9qRmhZPUw" x="-2" y="-11"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_NPXetK5kEeasH9qRmhZPUw" type="7003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_NPXeta5kEeasH9qRmhZPUw" y="60"/>
</children>
<styles xmi:type="notation:FontStyle" xmi:id="_NPW3oa5kEeasH9qRmhZPUw"/>
<element xmi:type="uml:Transition" href="SimpleMachine.uml#_NPQJ8K5kEeasH9qRmhZPUw"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_NPW3oq5kEeasH9qRmhZPUw" points="[8, 0, -99, -2]$[103, 1, -4, -1]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NPn9YK5kEeasH9qRmhZPUw" id="(1.0,0.44680851063829785)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NPn9Ya5kEeasH9qRmhZPUw" id="(0.0,0.46808510638297873)"/>
</edges>
<edges xmi:type="notation:Connector" xmi:id="_Nz4hAK5kEeasH9qRmhZPUw" type="7000" source="_GKnpkK5kEeasH9qRmhZPUw" target="_G5KxoK5kEeasH9qRmhZPUw">
<children xmi:type="notation:DecorationNode" xmi:id="_Nz4hA65kEeasH9qRmhZPUw" type="7001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_Nz4hBK5kEeasH9qRmhZPUw"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_Nz4hBa5kEeasH9qRmhZPUw" type="7002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_Nz4hBq5kEeasH9qRmhZPUw" x="-6" y="-13"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_Nz5IEK5kEeasH9qRmhZPUw" type="7003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_Nz5IEa5kEeasH9qRmhZPUw" y="60"/>
</children>
<styles xmi:type="notation:FontStyle" xmi:id="_Nz4hAa5kEeasH9qRmhZPUw"/>
<element xmi:type="uml:Transition" href="SimpleMachine.uml#_NzwlMK5kEeasH9qRmhZPUw"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_Nz4hAq5kEeasH9qRmhZPUw" points="[7, 0, -97, 22]$[144, 13, 40, 35]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_N0MqEK5kEeasH9qRmhZPUw" id="(1.0,0.46808510638297873)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_N0MqEa5kEeasH9qRmhZPUw" id="(0.0,0.46808510638297873)"/>
</edges>
</notation:Diagram>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_CvHMAK5kEeasH9qRmhZPUw" name="RootElement">
<packagedElement xmi:type="uml:StateMachine" xmi:id="_CvJBMK5kEeasH9qRmhZPUw" name="StateMachine">
<region xmi:type="uml:Region" xmi:id="_CvJoQK5kEeasH9qRmhZPUw" name="Region1">
<transition xmi:type="uml:Transition" xmi:id="_MICDMK5kEeasH9qRmhZPUw" source="_KqMzQK5kEeasH9qRmhZPUw" target="_FD210K5kEeasH9qRmhZPUw"/>
<transition xmi:type="uml:Transition" xmi:id="_NPQJ8K5kEeasH9qRmhZPUw" source="_FD210K5kEeasH9qRmhZPUw" target="_GKkmQK5kEeasH9qRmhZPUw">
<trigger xmi:type="uml:Trigger" xmi:id="_jnN1AK5lEeasH9qRmhZPUw" event="_R_K1sK5kEeasH9qRmhZPUw"/>
</transition>
<transition xmi:type="uml:Transition" xmi:id="_NzwlMK5kEeasH9qRmhZPUw" source="_GKkmQK5kEeasH9qRmhZPUw" target="_G5GgMK5kEeasH9qRmhZPUw">
<trigger xmi:type="uml:Trigger" xmi:id="_ldn9AK5lEeasH9qRmhZPUw" event="_UfT3MK5kEeasH9qRmhZPUw"/>
</transition>
<subvertex xmi:type="uml:State" xmi:id="_FD210K5kEeasH9qRmhZPUw" name="S1"/>
<subvertex xmi:type="uml:State" xmi:id="_GKkmQK5kEeasH9qRmhZPUw" name="S2"/>
<subvertex xmi:type="uml:State" xmi:id="_G5GgMK5kEeasH9qRmhZPUw" name="S3"/>
<subvertex xmi:type="uml:Pseudostate" xmi:id="_KqMzQK5kEeasH9qRmhZPUw" name=""/>
</region>
</packagedElement>
<packagedElement xmi:type="uml:Signal" xmi:id="_O5YwgK5kEeasH9qRmhZPUw" name="E1"/>
<packagedElement xmi:type="uml:Signal" xmi:id="_QgSc4K5kEeasH9qRmhZPUw" name="E2"/>
<packagedElement xmi:type="uml:SignalEvent" xmi:id="_R_K1sK5kEeasH9qRmhZPUw" name="SignalEventE1" signal="_O5YwgK5kEeasH9qRmhZPUw"/>
<packagedElement xmi:type="uml:SignalEvent" xmi:id="_UfT3MK5kEeasH9qRmhZPUw" name="SignalEventE2" signal="_QgSc4K5kEeasH9qRmhZPUw"/>
</uml:Model>

View File

@@ -121,7 +121,7 @@ public class MongoDbRepositoryState extends RepositoryState {
*/
public MongoDbRepositoryState(String machineId, MongoDbRepositoryState parentState, String state, boolean initial, Set<MongoDbRepositoryAction> stateActions,
Set<MongoDbRepositoryAction> entryActions, Set<MongoDbRepositoryAction> exitActions) {
this.machineId = machineId;
this.machineId = machineId == null ? "" : machineId;
this.parentState = parentState;
this.state = state;
this.initial = initial;

View File

@@ -131,7 +131,7 @@ public class RedisRepositoryState extends RepositoryState {
*/
public RedisRepositoryState(String machineId, RedisRepositoryState parentState, String state, boolean initial, Set<RedisRepositoryAction> stateActions,
Set<RedisRepositoryAction> entryActions, Set<RedisRepositoryAction> exitActions) {
this.machineId = machineId;
this.machineId = machineId == null ? "" : machineId;
this.parentState = parentState;
this.state = state;
this.initial = initial;