diff --git a/build.gradle b/build.gradle index 17386fdc..3f70d3b2 100644 --- a/build.gradle +++ b/build.gradle @@ -147,6 +147,14 @@ project('spring-statemachine-boot') { compile project(":spring-statemachine-core") compile "org.springframework.boot:spring-boot-autoconfigure:$springBootVersion" compile "org.springframework.boot:spring-boot-actuator:$springBootVersion" + optional project(":spring-statemachine-data-common:spring-statemachine-data-jpa") + optional project(":spring-statemachine-data-common:spring-statemachine-data-redis") + optional project(":spring-statemachine-data-common:spring-statemachine-data-mongodb") + optional "org.eclipse.persistence:javax.persistence:$eclipsePersistenceVersion" + optional "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion" + optional "org.springframework.boot:spring-boot-starter-data-redis:$springBootVersion" + optional "org.springframework.boot:spring-boot-starter-data-mongodb:$springBootVersion" + testRuntime "com.h2database:h2:$h2Version" testCompile "org.springframework.boot:spring-boot-test:$springBootVersion" testCompile "org.springframework:spring-test:$springVersion" testCompile "org.hamcrest:hamcrest-core:$hamcrestVersion" diff --git a/spring-statemachine-boot/src/main/java/org/springframework/statemachine/boot/StateMachineJpaRepositoriesAutoConfiguration.java b/spring-statemachine-boot/src/main/java/org/springframework/statemachine/boot/StateMachineJpaRepositoriesAutoConfiguration.java new file mode 100644 index 00000000..25de08ba --- /dev/null +++ b/spring-statemachine-boot/src/main/java/org/springframework/statemachine/boot/StateMachineJpaRepositoriesAutoConfiguration.java @@ -0,0 +1,41 @@ +/* + * 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.boot; + +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.statemachine.data.jpa.JpaRepositoryState; +import org.springframework.statemachine.data.jpa.JpaStateRepository; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for JPA repositories + * and Entity classes. + */ +@Configuration +@ConditionalOnClass(JpaStateRepository.class) +@ConditionalOnProperty(prefix = "spring.statemachine.data.jpa.repositories", name = "enabled", havingValue = "true", matchIfMissing = true) +@AutoConfigureAfter(JpaRepositoriesAutoConfiguration.class) +@EntityScan(basePackageClasses = { JpaRepositoryState.class }) +@EnableJpaRepositories(basePackageClasses = { JpaStateRepository.class }) +public class StateMachineJpaRepositoriesAutoConfiguration { + +} diff --git a/spring-statemachine-boot/src/main/java/org/springframework/statemachine/boot/StateMachineMongoDbRepositoriesAutoConfiguration.java b/spring-statemachine-boot/src/main/java/org/springframework/statemachine/boot/StateMachineMongoDbRepositoriesAutoConfiguration.java new file mode 100644 index 00000000..33bed483 --- /dev/null +++ b/spring-statemachine-boot/src/main/java/org/springframework/statemachine/boot/StateMachineMongoDbRepositoriesAutoConfiguration.java @@ -0,0 +1,41 @@ +/* + * 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.boot; + +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; +import org.springframework.statemachine.data.mongodb.MongoDbRepositoryState; +import org.springframework.statemachine.data.mongodb.MongoDbStateRepository; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for MongoDb repositories + * and Entity classes. + */ +@Configuration +@ConditionalOnClass(MongoDbStateRepository.class) +@ConditionalOnProperty(prefix = "spring.statemachine.data.mongo.repositories", name = "enabled", havingValue = "true", matchIfMissing = true) +@AutoConfigureAfter(MongoRepositoriesAutoConfiguration.class) +@EntityScan(basePackageClasses = { MongoDbRepositoryState.class }) +@EnableMongoRepositories(basePackageClasses = { MongoDbStateRepository.class }) +public class StateMachineMongoDbRepositoriesAutoConfiguration { + +} diff --git a/spring-statemachine-boot/src/main/java/org/springframework/statemachine/boot/StateMachineRedisRepositoriesAutoConfiguration.java b/spring-statemachine-boot/src/main/java/org/springframework/statemachine/boot/StateMachineRedisRepositoriesAutoConfiguration.java new file mode 100644 index 00000000..bfd27f8a --- /dev/null +++ b/spring-statemachine-boot/src/main/java/org/springframework/statemachine/boot/StateMachineRedisRepositoriesAutoConfiguration.java @@ -0,0 +1,41 @@ +/* + * 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.boot; + +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; +import org.springframework.statemachine.data.redis.RedisRepositoryState; +import org.springframework.statemachine.data.redis.RedisStateRepository; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Redis repositories + * and Entity classes. + */ +@Configuration +@ConditionalOnClass(RedisStateRepository.class) +@ConditionalOnProperty(prefix = "spring.statemachine.data.redis.repositories", name = "enabled", havingValue = "true", matchIfMissing = true) +@AutoConfigureAfter(RedisRepositoriesAutoConfiguration.class) +@EntityScan(basePackageClasses = { RedisRepositoryState.class }) +@EnableRedisRepositories(basePackageClasses = { RedisStateRepository.class }) +public class StateMachineRedisRepositoriesAutoConfiguration { + +} diff --git a/spring-statemachine-boot/src/main/resources/META-INF/spring.factories b/spring-statemachine-boot/src/main/resources/META-INF/spring.factories index d5293ae7..beea946a 100644 --- a/spring-statemachine-boot/src/main/resources/META-INF/spring.factories +++ b/spring-statemachine-boot/src/main/resources/META-INF/spring.factories @@ -1,3 +1,7 @@ # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.statemachine.boot.StateMachineAutoConfiguration +org.springframework.statemachine.boot.StateMachineAutoConfiguration,\ +org.springframework.statemachine.boot.StateMachineJpaRepositoriesAutoConfiguration,\ +org.springframework.statemachine.boot.StateMachineRedisRepositoriesAutoConfiguration,\ +org.springframework.statemachine.boot.StateMachineMongoDbRepositoriesAutoConfiguration + diff --git a/spring-statemachine-boot/src/test/java/org/springframework/statemachine/boot/StateMachineJpaRepositoriesAutoConfigurationTests.java b/spring-statemachine-boot/src/test/java/org/springframework/statemachine/boot/StateMachineJpaRepositoriesAutoConfigurationTests.java new file mode 100644 index 00000000..2617500f --- /dev/null +++ b/spring-statemachine-boot/src/test/java/org/springframework/statemachine/boot/StateMachineJpaRepositoriesAutoConfigurationTests.java @@ -0,0 +1,70 @@ +/* + * 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.boot; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import org.junit.After; +import org.junit.Test; +import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; +import org.springframework.boot.test.util.EnvironmentTestUtils; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.statemachine.data.jpa.JpaRepositoryState; + +public class StateMachineJpaRepositoriesAutoConfigurationTests { + + private AnnotationConfigApplicationContext context; + + @After + public void close() { + if (context != null) { + context.close(); + } + context = null; + } + + @Test + public void testJpaEnabled() throws Exception { + context = new AnnotationConfigApplicationContext(); + context.register(TestConfiguration.class); + context.register( + EmbeddedDataSourceConfiguration.class, + HibernateJpaAutoConfiguration.class, + JpaRepositoriesAutoConfiguration.class, + StateMachineJpaRepositoriesAutoConfiguration.class); + + context.refresh(); + assertThat(context.containsBean("jpaStateRepository"), is(true)); + } + + @Test + public void testJpaDisabled() throws Exception { + context = new AnnotationConfigApplicationContext(); + EnvironmentTestUtils.addEnvironment(context, "spring.statemachine.data.jpa.repositories.enabled:false"); + context.register(StateMachineJpaRepositoriesAutoConfiguration.class); + context.refresh(); + assertThat(context.containsBean("jpaStateRepository"), is(false)); + } + + @Configuration + @TestAutoConfigurationPackage(JpaRepositoryState.class) + protected static class TestConfiguration { + } +} diff --git a/spring-statemachine-boot/src/test/java/org/springframework/statemachine/boot/StateMachineMongoDbRepositoriesAutoConfigurationTests.java b/spring-statemachine-boot/src/test/java/org/springframework/statemachine/boot/StateMachineMongoDbRepositoriesAutoConfigurationTests.java new file mode 100644 index 00000000..1fb9094c --- /dev/null +++ b/spring-statemachine-boot/src/test/java/org/springframework/statemachine/boot/StateMachineMongoDbRepositoriesAutoConfigurationTests.java @@ -0,0 +1,70 @@ +/* + * 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.boot; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import org.junit.After; +import org.junit.Test; +import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; +import org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.boot.test.util.EnvironmentTestUtils; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.statemachine.data.mongodb.MongoDbRepositoryState; + +public class StateMachineMongoDbRepositoriesAutoConfigurationTests { + + private AnnotationConfigApplicationContext context; + + @After + public void close() { + if (context != null) { + context.close(); + } + context = null; + } + + @Test + public void testMongoEnabled() throws Exception { + context = new AnnotationConfigApplicationContext(); + context.register(TestConfiguration.class); + context.register( + MongoAutoConfiguration.class, + MongoDataAutoConfiguration.class, + MongoRepositoriesAutoConfiguration.class, + StateMachineMongoDbRepositoriesAutoConfiguration.class); + + context.refresh(); + assertThat(context.containsBean("mongoDbStateRepository"), is(true)); + } + + @Test + public void testMongoDisabled() throws Exception { + context = new AnnotationConfigApplicationContext(); + EnvironmentTestUtils.addEnvironment(context, "spring.statemachine.data.redis.repositories.enabled:false"); + context.register(StateMachineRedisRepositoriesAutoConfiguration.class); + context.refresh(); + assertThat(context.containsBean("mongoDbStateRepository"), is(false)); + } + + @Configuration + @TestAutoConfigurationPackage(MongoDbRepositoryState.class) + protected static class TestConfiguration { + } +} diff --git a/spring-statemachine-boot/src/test/java/org/springframework/statemachine/boot/StateMachineRedisRepositoriesAutoConfigurationTests.java b/spring-statemachine-boot/src/test/java/org/springframework/statemachine/boot/StateMachineRedisRepositoriesAutoConfigurationTests.java new file mode 100644 index 00000000..7814dd10 --- /dev/null +++ b/spring-statemachine-boot/src/test/java/org/springframework/statemachine/boot/StateMachineRedisRepositoriesAutoConfigurationTests.java @@ -0,0 +1,68 @@ +/* + * 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.boot; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import org.junit.After; +import org.junit.Test; +import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; +import org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration; +import org.springframework.boot.test.util.EnvironmentTestUtils; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.statemachine.data.redis.RedisRepositoryState; + +public class StateMachineRedisRepositoriesAutoConfigurationTests { + + private AnnotationConfigApplicationContext context; + + @After + public void close() { + if (context != null) { + context.close(); + } + context = null; + } + + @Test + public void testRedisEnabled() throws Exception { + context = new AnnotationConfigApplicationContext(); + context.register(TestConfiguration.class); + context.register( + RedisAutoConfiguration.class, + RedisRepositoriesAutoConfiguration.class, + StateMachineRedisRepositoriesAutoConfiguration.class); + + context.refresh(); + assertThat(context.containsBean("redisStateRepository"), is(true)); + } + + @Test + public void testRedisDisabled() throws Exception { + context = new AnnotationConfigApplicationContext(); + EnvironmentTestUtils.addEnvironment(context, "spring.statemachine.data.redis.repositories.enabled:false"); + context.register(StateMachineRedisRepositoriesAutoConfiguration.class); + context.refresh(); + assertThat(context.containsBean("redisStateRepository"), is(false)); + } + + @Configuration + @TestAutoConfigurationPackage(RedisRepositoryState.class) + protected static class TestConfiguration { + } +} diff --git a/spring-statemachine-boot/src/test/java/org/springframework/statemachine/boot/TestAutoConfigurationPackage.java b/spring-statemachine-boot/src/test/java/org/springframework/statemachine/boot/TestAutoConfigurationPackage.java new file mode 100644 index 00000000..01f21eb8 --- /dev/null +++ b/spring-statemachine-boot/src/test/java/org/springframework/statemachine/boot/TestAutoConfigurationPackage.java @@ -0,0 +1,40 @@ +/* + * 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.boot; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.context.annotation.Import; + +/** + * Test annotation to configure the {@link AutoConfigurationPackages} to an arbitrary + * value. + * + * @author Phillip Webb + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Import(TestAutoConfigurationPackageRegistrar.class) +public @interface TestAutoConfigurationPackage { + + Class value(); + +} diff --git a/spring-statemachine-boot/src/test/java/org/springframework/statemachine/boot/TestAutoConfigurationPackageRegistrar.java b/spring-statemachine-boot/src/test/java/org/springframework/statemachine/boot/TestAutoConfigurationPackageRegistrar.java new file mode 100644 index 00000000..e0856468 --- /dev/null +++ b/spring-statemachine-boot/src/test/java/org/springframework/statemachine/boot/TestAutoConfigurationPackageRegistrar.java @@ -0,0 +1,42 @@ +/* + * 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.boot; + +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.boot.autoconfigure.AutoConfigurationPackages; +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.AnnotationAttributes; +import org.springframework.core.annotation.Order; +import org.springframework.core.type.AnnotationMetadata; +import org.springframework.util.ClassUtils; + +/** + * {@link ImportBeanDefinitionRegistrar} to store the base package for tests. + * + * @author Phillip Webb + */ +@Order(Ordered.HIGHEST_PRECEDENCE) +public class TestAutoConfigurationPackageRegistrar implements ImportBeanDefinitionRegistrar { + + @Override + public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { + AnnotationAttributes attributes = AnnotationAttributes + .fromMap(metadata.getAnnotationAttributes(TestAutoConfigurationPackage.class.getName(), true)); + AutoConfigurationPackages.register(registry, ClassUtils.getPackageName(attributes.getString("value"))); + } + +} diff --git a/spring-statemachine-samples/build.gradle b/spring-statemachine-samples/build.gradle index cb13e0c7..766faf2d 100644 --- a/spring-statemachine-samples/build.gradle +++ b/spring-statemachine-samples/build.gradle @@ -112,6 +112,7 @@ project('spring-statemachine-samples-ordershipping') { project('spring-statemachine-samples-datajpa') { description = 'Spring State Machine Data Jpa Sample' dependencies { + compile project(":spring-statemachine-boot") compile project(":spring-statemachine-data-common:spring-statemachine-data-jpa") compile("org.springframework.boot:spring-boot-starter-thymeleaf:$springBootVersion") compile("org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion") diff --git a/spring-statemachine-samples/datajpa/src/main/java/demo/datajpa/Application.java b/spring-statemachine-samples/datajpa/src/main/java/demo/datajpa/Application.java index 9e2b49db..d194f6fb 100644 --- a/spring-statemachine-samples/datajpa/src/main/java/demo/datajpa/Application.java +++ b/spring-statemachine-samples/datajpa/src/main/java/demo/datajpa/Application.java @@ -17,13 +17,9 @@ package demo.datajpa; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; //tag::snippetA[] @SpringBootApplication -@EntityScan(basePackages = {"org.springframework.statemachine.data.jpa"}) -@EnableJpaRepositories(basePackages = {"org.springframework.statemachine.data.jpa"}) public class Application { public static void main(String[] args) {