diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java index f50ecd55a01..cd5f3a917b0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java @@ -20,42 +20,52 @@ import java.util.Set; import org.neo4j.driver.Driver; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.domain.EntityScanner; import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration; import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; +import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.data.neo4j.config.Neo4jDefaultCallbacksRegistrar; +import org.springframework.data.neo4j.core.DatabaseSelectionProvider; +import org.springframework.data.neo4j.core.Neo4jClient; +import org.springframework.data.neo4j.core.Neo4jOperations; +import org.springframework.data.neo4j.core.Neo4jTemplate; import org.springframework.data.neo4j.core.convert.Neo4jConversions; import org.springframework.data.neo4j.core.mapping.Neo4jMappingContext; import org.springframework.data.neo4j.core.schema.Node; +import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager; +import org.springframework.data.neo4j.repository.config.Neo4jRepositoryConfigurationExtension; +import org.springframework.transaction.PlatformTransactionManager; /** - * {@link EnableAutoConfiguration Auto-configuration} for Spring Data Neo4j. Automatic - * configuration of base infrastructure that imports configuration for both imperative and - * reactive Neo4j repositories. + * {@link EnableAutoConfiguration Auto-configuration} for Spring Data Neo4j. * * @author Michael Hunger * @author Josh Long * @author Vince Bickers * @author Stephane Nicoll * @author Kazuki Shimizu - * @author Michael J Simons + * @author Michael J. Simons * @since 1.4.0 */ @Configuration(proxyBeanMethods = false) -@ConditionalOnBean(Driver.class) +@ConditionalOnClass({ Driver.class, Neo4jTransactionManager.class, PlatformTransactionManager.class }) @EnableConfigurationProperties(Neo4jDataProperties.class) -@AutoConfigureAfter(Neo4jAutoConfiguration.class) +@ConditionalOnBean(Driver.class) @AutoConfigureBefore(TransactionAutoConfiguration.class) -@Import({ Neo4jDataConfiguration.class, Neo4jReactiveDataConfiguration.class }) +@AutoConfigureAfter(Neo4jAutoConfiguration.class) +@Import(Neo4jDefaultCallbacksRegistrar.class) public class Neo4jDataAutoConfiguration { @Bean @@ -74,4 +84,34 @@ public class Neo4jDataAutoConfiguration { return context; } + @Bean + @ConditionalOnMissingBean + public DatabaseSelectionProvider databaseSelectionProvider(Neo4jDataProperties properties) { + String database = properties.getDatabase(); + return (database != null) ? DatabaseSelectionProvider.createStaticDatabaseSelectionProvider(database) + : DatabaseSelectionProvider.getDefaultSelectionProvider(); + } + + @Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_CLIENT_BEAN_NAME) + @ConditionalOnMissingBean + public Neo4jClient neo4jClient(Driver driver) { + return Neo4jClient.create(driver); + } + + @Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_TEMPLATE_BEAN_NAME) + @ConditionalOnMissingBean(Neo4jOperations.class) + public Neo4jTemplate neo4jTemplate(Neo4jClient neo4jClient, Neo4jMappingContext neo4jMappingContext, + DatabaseSelectionProvider databaseNameProvider) { + return new Neo4jTemplate(neo4jClient, neo4jMappingContext, databaseNameProvider); + } + + @Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_TRANSACTION_MANAGER_BEAN_NAME) + @ConditionalOnMissingBean(PlatformTransactionManager.class) + public Neo4jTransactionManager transactionManager(Driver driver, DatabaseSelectionProvider databaseNameProvider, + ObjectProvider optionalCustomizers) { + Neo4jTransactionManager transactionManager = new Neo4jTransactionManager(driver, databaseNameProvider); + optionalCustomizers.ifAvailable((customizer) -> customizer.customize(transactionManager)); + return transactionManager; + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataConfiguration.java deleted file mode 100644 index 070ab1471cf..00000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataConfiguration.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2012-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.neo4j; - -import org.neo4j.driver.Driver; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.data.ConditionalOnRepositoryType; -import org.springframework.boot.autoconfigure.data.RepositoryType; -import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.env.Environment; -import org.springframework.data.neo4j.config.Neo4jDefaultCallbacksRegistrar; -import org.springframework.data.neo4j.core.DatabaseSelectionProvider; -import org.springframework.data.neo4j.core.Neo4jClient; -import org.springframework.data.neo4j.core.Neo4jOperations; -import org.springframework.data.neo4j.core.Neo4jTemplate; -import org.springframework.data.neo4j.core.mapping.Neo4jMappingContext; -import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager; -import org.springframework.data.neo4j.repository.config.Neo4jRepositoryConfigurationExtension; -import org.springframework.transaction.PlatformTransactionManager; - -/** - * Internal configuration of Neo4j client and transaction manager. - * - * @author Michael J. Simons - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ Neo4jTransactionManager.class, PlatformTransactionManager.class }) -@ConditionalOnRepositoryType(store = "neo4j", type = RepositoryType.IMPERATIVE) -@AutoConfigureAfter(Neo4jAutoConfiguration.class) -@AutoConfigureBefore(Neo4jRepositoriesConfiguration.class) -@Import(Neo4jDefaultCallbacksRegistrar.class) -class Neo4jDataConfiguration { - - @Bean("databaseSelectionProvider") - @ConditionalOnMissingBean - DatabaseSelectionProvider defaultSelectionProvider(Environment environment) { - String database = environment.getProperty("spring.data.neo4j.database"); - if (database != null) { - return DatabaseSelectionProvider.createStaticDatabaseSelectionProvider(database); - } - return DatabaseSelectionProvider.getDefaultSelectionProvider(); - } - - @Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_CLIENT_BEAN_NAME) - @ConditionalOnMissingBean - Neo4jClient neo4jClient(Driver driver) { - return Neo4jClient.create(driver); - } - - @Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_TEMPLATE_BEAN_NAME) - @ConditionalOnMissingBean(Neo4jOperations.class) - Neo4jTemplate neo4jTemplate(Neo4jClient neo4jClient, Neo4jMappingContext neo4jMappingContext, - DatabaseSelectionProvider databaseNameProvider) { - return new Neo4jTemplate(neo4jClient, neo4jMappingContext, databaseNameProvider); - } - - @Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_TRANSACTION_MANAGER_BEAN_NAME) - @ConditionalOnMissingBean(PlatformTransactionManager.class) - Neo4jTransactionManager transactionManager(Driver driver, DatabaseSelectionProvider databaseNameProvider, - ObjectProvider optionalCustomizers) { - Neo4jTransactionManager transactionManager = new Neo4jTransactionManager(driver, databaseNameProvider); - optionalCustomizers.ifAvailable((customizer) -> customizer.customize(transactionManager)); - return transactionManager; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataProperties.java index dad06eca713..ea1c1905247 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataProperties.java @@ -17,7 +17,6 @@ package org.springframework.boot.autoconfigure.data.neo4j; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.data.neo4j.core.DatabaseSelectionProvider; /** * Configuration properties for Spring Data Neo4j. @@ -29,10 +28,7 @@ import org.springframework.data.neo4j.core.DatabaseSelectionProvider; public class Neo4jDataProperties { /** - * A statically configured database. This property is only applicable when connecting - * against a 4.0 cluster or server and will lead to errors if used with a prior - * version of Neo4j. Leave this null (the default) to indicate that you like the - * server to decide the default database to use. + * Database name to use. By default, the server decides the default database to use. */ private String database; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfiguration.java similarity index 63% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataConfiguration.java rename to spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfiguration.java index c43fb455ebb..58bcb406d28 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfiguration.java @@ -20,17 +20,13 @@ import org.neo4j.driver.Driver; import reactor.core.publisher.Flux; import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.data.ConditionalOnRepositoryType; -import org.springframework.boot.autoconfigure.data.RepositoryType; -import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.core.annotation.Order; import org.springframework.data.neo4j.config.Neo4jDefaultReactiveCallbacksRegistrar; import org.springframework.data.neo4j.core.ReactiveDatabaseSelectionProvider; import org.springframework.data.neo4j.core.ReactiveNeo4jClient; @@ -42,49 +38,45 @@ import org.springframework.data.neo4j.repository.config.ReactiveNeo4jRepositoryC import org.springframework.transaction.ReactiveTransactionManager; /** - * Internal configuration for the reactive Neo4j client. + * {@link EnableAutoConfiguration Auto-configuration} for Spring Data's reactive Neo4j + * support. * * @author Michael J. Simons + * @author Stephane Nicoll + * @since 2.4.0 */ @Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ ReactiveNeo4jTransactionManager.class, ReactiveTransactionManager.class, Flux.class }) -@ConditionalOnRepositoryType(store = "neo4j", type = RepositoryType.REACTIVE) -@AutoConfigureAfter(Neo4jAutoConfiguration.class) -@AutoConfigureBefore(Neo4jReactiveRepositoriesConfiguration.class) +@ConditionalOnClass({ Driver.class, ReactiveNeo4jTransactionManager.class, ReactiveTransactionManager.class, + Flux.class }) +@ConditionalOnBean(Driver.class) +@AutoConfigureAfter(Neo4jDataAutoConfiguration.class) @Import(Neo4jDefaultReactiveCallbacksRegistrar.class) -class Neo4jReactiveDataConfiguration { +public class Neo4jReactiveDataAutoConfiguration { - @Bean("reactiveDatabaseSelectionProvider") - @ConditionalOnProperty(prefix = "spring.data.neo4j", name = "database") + @Bean @ConditionalOnMissingBean - @Order(-30) - ReactiveDatabaseSelectionProvider staticDatabaseSelectionProvider(Neo4jDataProperties dataProperties) { - return ReactiveDatabaseSelectionProvider.createStaticDatabaseSelectionProvider(dataProperties.getDatabase()); - } - - @Bean("reactiveDatabaseSelectionProvider") - @ConditionalOnMissingBean - @Order(-20) - ReactiveDatabaseSelectionProvider defaultSelectionProvider() { - return ReactiveDatabaseSelectionProvider.getDefaultSelectionProvider(); + public ReactiveDatabaseSelectionProvider reactiveDatabaseSelectionProvider(Neo4jDataProperties dataProperties) { + String database = dataProperties.getDatabase(); + return (database != null) ? ReactiveDatabaseSelectionProvider.createStaticDatabaseSelectionProvider(database) + : ReactiveDatabaseSelectionProvider.getDefaultSelectionProvider(); } @Bean(ReactiveNeo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_CLIENT_BEAN_NAME) @ConditionalOnMissingBean - ReactiveNeo4jClient neo4jClient(Driver driver) { + public ReactiveNeo4jClient reactiveNeo4jClient(Driver driver) { return ReactiveNeo4jClient.create(driver); } @Bean(ReactiveNeo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_TEMPLATE_BEAN_NAME) @ConditionalOnMissingBean(ReactiveNeo4jOperations.class) - ReactiveNeo4jTemplate neo4jTemplate(ReactiveNeo4jClient neo4jClient, Neo4jMappingContext neo4jMappingContext, - ReactiveDatabaseSelectionProvider databaseNameProvider) { + public ReactiveNeo4jTemplate reactiveNeo4jTemplate(ReactiveNeo4jClient neo4jClient, + Neo4jMappingContext neo4jMappingContext, ReactiveDatabaseSelectionProvider databaseNameProvider) { return new ReactiveNeo4jTemplate(neo4jClient, neo4jMappingContext, databaseNameProvider); } @Bean(ReactiveNeo4jRepositoryConfigurationExtension.DEFAULT_TRANSACTION_MANAGER_BEAN_NAME) @ConditionalOnMissingBean(ReactiveTransactionManager.class) - ReactiveTransactionManager transactionManager(Driver driver, + public ReactiveTransactionManager reactiveTransactionManager(Driver driver, ReactiveDatabaseSelectionProvider databaseNameProvider) { return new ReactiveNeo4jTransactionManager(driver, databaseNameProvider); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesAutoConfiguration.java similarity index 74% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesConfiguration.java rename to spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesAutoConfiguration.java index 281ba5ce4e9..27cb2ee2009 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesAutoConfiguration.java @@ -16,8 +16,11 @@ package org.springframework.boot.autoconfigure.data.neo4j; +import org.neo4j.driver.Driver; import reactor.core.publisher.Flux; +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.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.data.ConditionalOnRepositoryType; @@ -29,16 +32,20 @@ import org.springframework.data.neo4j.repository.config.ReactiveNeo4jRepositoryC import org.springframework.data.neo4j.repository.support.ReactiveNeo4jRepositoryFactoryBean; /** - * Imports the registrar for reactive Neo4j repositories. + * {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Neo4j Reactive + * Repositories. * * @author Michael J. Simons + * @author Stephane Nicoll + * @since 2.4.0 */ @Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ Flux.class, ReactiveNeo4jRepository.class }) +@ConditionalOnClass({ Driver.class, ReactiveNeo4jRepository.class, Flux.class }) @ConditionalOnMissingBean({ ReactiveNeo4jRepositoryFactoryBean.class, ReactiveNeo4jRepositoryConfigurationExtension.class }) @ConditionalOnRepositoryType(store = "neo4j", type = RepositoryType.REACTIVE) -@Import(Neo4jReactiveRepositoriesConfigureRegistrar.class) -final class Neo4jReactiveRepositoriesConfiguration { +@Import(Neo4jReactiveRepositoriesRegistrar.class) +@AutoConfigureAfter(Neo4jReactiveDataAutoConfiguration.class) +public class Neo4jReactiveRepositoriesAutoConfiguration { } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesConfigureRegistrar.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesRegistrar.java similarity index 82% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesConfigureRegistrar.java rename to spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesRegistrar.java index 5561bc9e44a..e52749df557 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesConfigureRegistrar.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesRegistrar.java @@ -19,17 +19,18 @@ package org.springframework.boot.autoconfigure.data.neo4j; import java.lang.annotation.Annotation; import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport; +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.data.neo4j.repository.config.EnableReactiveNeo4jRepositories; import org.springframework.data.neo4j.repository.config.ReactiveNeo4jRepositoryConfigurationExtension; import org.springframework.data.repository.config.RepositoryConfigurationExtension; /** - * {@link ImportBeanDefinitionRegistrar} used to auto-configure reactive Spring Data Neo4j + * {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data Neo4j reactive * Repositories. * * @author Michael J. Simons */ -final class Neo4jReactiveRepositoriesConfigureRegistrar extends AbstractRepositoryConfigurationSourceSupport { +class Neo4jReactiveRepositoriesRegistrar extends AbstractRepositoryConfigurationSourceSupport { @Override protected Class getAnnotation() { @@ -38,7 +39,7 @@ final class Neo4jReactiveRepositoriesConfigureRegistrar extends AbstractReposito @Override protected Class getConfiguration() { - return SpringDataNeo4jConfiguration.class; + return EnableReactiveNeo4jRepositoriesConfiguration.class; } @Override @@ -47,7 +48,7 @@ final class Neo4jReactiveRepositoriesConfigureRegistrar extends AbstractReposito } @EnableReactiveNeo4jRepositories - private static class SpringDataNeo4jConfiguration { + private static class EnableReactiveNeo4jRepositoriesConfiguration { } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfiguration.java index c611ad42c52..76977f3e7c1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfiguration.java @@ -19,26 +19,43 @@ package org.springframework.boot.autoconfigure.data.neo4j; import org.neo4j.driver.Driver; 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.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.data.ConditionalOnRepositoryType; +import org.springframework.boot.autoconfigure.data.RepositoryType; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.data.neo4j.repository.Neo4jRepository; import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; +import org.springframework.data.neo4j.repository.config.Neo4jRepositoryConfigurationExtension; +import org.springframework.data.neo4j.repository.support.Neo4jRepositoryFactoryBean; /** - * Shared entry point for the configuration of Spring Data Neo4j repositories in their - * imperative and reactive forms. + * {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Neo4j + * Repositories. + *

+ * Activates when there is no bean of type {@link Neo4jRepositoryFactoryBean} or + * {@link Neo4jRepositoryConfigurationExtension} configured in the context, the Spring + * Data Neo4j {@link Neo4jRepository} type is on the classpath, the Neo4j client driver + * API is on the classpath, and there is no other configured {@link Neo4jRepository}. + *

+ * Once in effect, the auto-configuration is the equivalent of enabling Neo4j repositories + * using the {@link EnableNeo4jRepositories @EnableNeo4jRepositories} annotation. * * @author Dave Syer * @author Oliver Gierke * @author Josh Long * @author Michael J. Simons - * @see EnableNeo4jRepositories * @since 1.4.0 + * @see EnableNeo4jRepositories */ @Configuration(proxyBeanMethods = false) -@ConditionalOnClass(Driver.class) +@ConditionalOnClass({ Driver.class, Neo4jRepository.class }) +@ConditionalOnMissingBean({ Neo4jRepositoryFactoryBean.class, Neo4jRepositoryConfigurationExtension.class }) +@ConditionalOnRepositoryType(store = "neo4j", type = RepositoryType.IMPERATIVE) +@Import(Neo4jRepositoriesRegistrar.class) @AutoConfigureAfter(Neo4jDataAutoConfiguration.class) -@Import({ Neo4jRepositoriesConfiguration.class, Neo4jReactiveRepositoriesConfiguration.class }) public class Neo4jRepositoriesAutoConfiguration { } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesConfiguration.java deleted file mode 100644 index 7a190c68228..00000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesConfiguration.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2012-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.neo4j; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.data.ConditionalOnRepositoryType; -import org.springframework.boot.autoconfigure.data.RepositoryType; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.data.neo4j.repository.Neo4jRepository; -import org.springframework.data.neo4j.repository.config.Neo4jRepositoryConfigurationExtension; -import org.springframework.data.neo4j.repository.support.Neo4jRepositoryFactoryBean; - -/** - * Imports the registrar for imperative Neo4j repositories. - * - * @author Michael J. Simons - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(Neo4jRepository.class) -@ConditionalOnMissingBean({ Neo4jRepositoryFactoryBean.class, Neo4jRepositoryConfigurationExtension.class }) -@ConditionalOnRepositoryType(store = "neo4j", type = RepositoryType.IMPERATIVE) -@Import(Neo4jRepositoriesConfigureRegistrar.class) -class Neo4jRepositoriesConfiguration { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesConfigureRegistrar.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesRegistrar.java similarity index 81% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesConfigureRegistrar.java rename to spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesRegistrar.java index 268dff593ba..976581095e3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesConfigureRegistrar.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2019 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. @@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.data.neo4j; import java.lang.annotation.Annotation; import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport; +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; import org.springframework.data.neo4j.repository.config.Neo4jRepositoryConfigurationExtension; import org.springframework.data.repository.config.RepositoryConfigurationExtension; @@ -28,9 +29,8 @@ import org.springframework.data.repository.config.RepositoryConfigurationExtensi * Repositories. * * @author Michael Hunger - * @author Michael J. Simons */ -class Neo4jRepositoriesConfigureRegistrar extends AbstractRepositoryConfigurationSourceSupport { +class Neo4jRepositoriesRegistrar extends AbstractRepositoryConfigurationSourceSupport { @Override protected Class getAnnotation() { @@ -39,7 +39,7 @@ class Neo4jRepositoriesConfigureRegistrar extends AbstractRepositoryConfiguratio @Override protected Class getConfiguration() { - return SpringDataNeo4jConfiguration.class; + return EnableNeo4jRepositoriesConfiguration.class; } @Override @@ -48,7 +48,7 @@ class Neo4jRepositoriesConfigureRegistrar extends AbstractRepositoryConfiguratio } @EnableNeo4jRepositories - private static class SpringDataNeo4jConfiguration { + private static class EnableNeo4jRepositoriesConfiguration { } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/domain/EntityScan.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/domain/EntityScan.java index fd1b388ae8c..5b9b47c3b5c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/domain/EntityScan.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/domain/EntityScan.java @@ -51,7 +51,6 @@ import org.springframework.core.annotation.AliasFor; * annotation. * * @author Phillip Webb - * @author Michael J. Simons * @since 1.4.0 * @see EntityScanPackages */ diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 194db53153a..acd3527413a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -651,19 +651,81 @@ }, { "name": "spring.data.neo4j.auto-index", - "defaultValue": "none" + "description": "Auto index mode.", + "defaultValue": "none", + "deprecation": { + "reason": "Automatic index creation is no longer supported.", + "level": "error" + } + }, + { + "name": "spring.data.neo4j.embedded.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable embedded mode if the embedded driver is available.", + "deprecation": { + "reason": "Embedded mode is no longer supported, please use Testcontainers instead.", + "level": "error" + } }, { "name": "spring.data.neo4j.open-in-view", "type": "java.lang.Boolean", "description": "Register OpenSessionInViewInterceptor that binds a Neo4j Session to the thread for the entire processing of the request.", - "defaultValue": false + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.data.neo4j.password", + "type": "java.lang.String", + "description": "Login password of the server.", + "deprecation": { + "replacement": "spring.neo4j.authentication.password", + "level": "error" + } }, { "name": "spring.data.neo4j.repositories.enabled", "type": "java.lang.Boolean", "description": "Whether to enable Neo4j repositories.", - "defaultValue": true + "defaultValue": true, + "deprecation": { + "replacement": "spring.data.neo4j.repositories.type", + "level": "error" + } + }, + { + "name": "spring.data.neo4j.repositories.type", + "type": "org.springframework.boot.autoconfigure.data.RepositoryType", + "description": "Type of Neo4j repositories to enable.", + "defaultValue": "auto" + }, + { + "name": "spring.data.neo4j.uri", + "type": "java.lang.String", + "description": "URI used by the driver. Auto-detected by default.", + "deprecation": { + "replacement": "spring.neo4j.uri", + "level": "error" + } + }, + { + "name": "spring.data.neo4j.use-native-types", + "type": "java.lang.Boolean", + "description": "Whether to use Neo4j native types wherever possible.", + "deprecation": { + "reason": "Native type support is now built-in.", + "level": "error" + } + }, + { + "name": "spring.data.neo4j.username", + "type": "java.lang.String", + "description": "Login user of the server.", + "deprecation": { + "replacement": "spring.neo4j.authentication.password", + "level": "error" + } }, { "name": "spring.data.r2dbc.repositories.enabled", diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index 144b482523e..fdd60832eb8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -51,6 +51,8 @@ org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfigura org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\ +org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveDataAutoConfiguration,\ +org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\ diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/MixedNeo4jRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/MixedNeo4jRepositoriesAutoConfigurationTests.java index e9d160029fb..eb949d32fdb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/MixedNeo4jRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/MixedNeo4jRepositoriesAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -19,6 +19,11 @@ package org.springframework.boot.autoconfigure.data.neo4j; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import org.neo4j.driver.Config; +import org.neo4j.driver.Driver; +import org.neo4j.driver.GraphDatabase; +import org.neo4j.driver.internal.logging.Slf4jLogging; + import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration; import org.springframework.boot.autoconfigure.data.jpa.city.City; @@ -37,11 +42,6 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.data.neo4j.config.AbstractNeo4jConfig; import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; -import org.neo4j.driver.Config; -import org.neo4j.driver.Driver; -import org.neo4j.driver.GraphDatabase; -import org.neo4j.driver.internal.logging.Slf4jLogging; - import static org.assertj.core.api.Assertions.assertThat; /** @@ -103,7 +103,8 @@ class MixedNeo4jRepositoriesAutoConfigurationTests { context.register(config); context.register(DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class, JpaRepositoriesAutoConfiguration.class, Neo4jDataAutoConfiguration.class, - Neo4jRepositoriesAutoConfiguration.class); + Neo4jReactiveDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class, + Neo4jReactiveRepositoriesAutoConfiguration.class); context.refresh(); this.context = context; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/MockedDriverConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/MockedDriverConfiguration.java index 8c2a3a42779..4740cf67dcc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/MockedDriverConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/MockedDriverConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -16,16 +16,16 @@ package org.springframework.boot.autoconfigure.data.neo4j; import org.mockito.Mockito; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - import org.neo4j.driver.Driver; import org.neo4j.driver.Session; import org.neo4j.driver.SessionConfig; import org.neo4j.driver.types.TypeSystem; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; /** * Driver configuration mocked to avoid instantiation of a real driver with connection @@ -41,8 +41,8 @@ class MockedDriverConfiguration { Driver driver = mock(Driver.class); TypeSystem typeSystem = mock(TypeSystem.class); Session session = mock(Session.class); - when(driver.defaultTypeSystem()).thenReturn(typeSystem); - when(driver.session(Mockito.any(SessionConfig.class))).thenReturn(session); + given(driver.defaultTypeSystem()).willReturn(typeSystem); + given(driver.session(Mockito.any(SessionConfig.class))).willReturn(session); return driver; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java index d678521498b..686ade7e252 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -16,14 +16,10 @@ package org.springframework.boot.autoconfigure.data.neo4j; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; - import org.junit.jupiter.api.Test; -import org.neo4j.driver.Driver; + import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration; -import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -34,150 +30,110 @@ import org.springframework.data.neo4j.core.Neo4jOperations; import org.springframework.data.neo4j.core.Neo4jTemplate; import org.springframework.data.neo4j.core.convert.Neo4jConversions; import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager; -import org.springframework.test.util.ReflectionTestUtils; import org.springframework.transaction.PlatformTransactionManager; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + /** + * Tests for {@link Neo4jDataAutoConfiguration}. + * + * @author Stephane Nicoll + * @author Michael Hunger + * @author Vince Bickers + * @author Andy Wilkinson + * @author Kazuki Shimizu * @author Michael J. Simons */ class Neo4jDataAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withPropertyValues("spring.data.neo4j.repositories.type=imperative") .withUserConfiguration(MockedDriverConfiguration.class) .withConfiguration(AutoConfigurations.of(Neo4jAutoConfiguration.class, Neo4jDataAutoConfiguration.class)); @Test void shouldProvideConversions() { - contextRunner.run(ctx -> assertThat(ctx).hasSingleBean(Neo4jConversions.class)); + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(Neo4jConversions.class)); } @Test void shouldProvideDefaultDatabaseNameProvider() { - contextRunner.run(ctx -> { - assertThat(ctx).hasSingleBean(DatabaseSelectionProvider.class); - DatabaseSelectionProvider databaseNameProvider = ctx.getBean(DatabaseSelectionProvider.class); - assertThat(databaseNameProvider).isSameAs(DatabaseSelectionProvider.getDefaultSelectionProvider()); + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(DatabaseSelectionProvider.class); + assertThat(context.getBean(DatabaseSelectionProvider.class)) + .isSameAs(DatabaseSelectionProvider.getDefaultSelectionProvider()); }); } @Test - void shouldProvideStaticDatabaseNameProviderIfConfigured() { - contextRunner.withPropertyValues("spring.data.neo4j.database=foobar").run(ctx -> { - assertThat(ctx).hasSingleBean(DatabaseSelectionProvider.class); - DatabaseSelectionProvider databaseNameProvider = ctx.getBean(DatabaseSelectionProvider.class); - assertThat(databaseNameProvider.getDatabaseSelection()).isEqualTo(DatabaseSelection.byName("foobar")); + void shouldUseDatabaseNameIfSet() { + this.contextRunner.withPropertyValues("spring.data.neo4j.database=test").run((context) -> { + assertThat(context).hasSingleBean(DatabaseSelectionProvider.class); + assertThat(context.getBean(DatabaseSelectionProvider.class).getDatabaseSelection()) + .isEqualTo(DatabaseSelection.byName("test")); }); } @Test - void shouldRespectExistingDatabaseNameProvider() { - contextRunner.withPropertyValues("spring.data.neo4j.database=foobar") - .withUserConfiguration(ConfigurationWithExistingDatabaseSelectionProvider.class).run(ctx -> { - assertThat(ctx).hasSingleBean(DatabaseSelectionProvider.class); - DatabaseSelectionProvider databaseNameProvider = ctx.getBean(DatabaseSelectionProvider.class); - assertThat(databaseNameProvider.getDatabaseSelection()) - .isEqualTo(DatabaseSelection.byName("whatever")); + void shouldReuseExistingDatabaseNameProvider() { + this.contextRunner.withPropertyValues("spring.data.neo4j.database=ignored") + .withUserConfiguration(CustomDatabaseSelectionProviderConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(DatabaseSelectionProvider.class); + assertThat(context.getBean(DatabaseSelectionProvider.class).getDatabaseSelection()) + .isEqualTo(DatabaseSelection.byName("custom")); }); } @Test - void shouldRequireAllNeededClasses() { - contextRunner - .withClassLoader( - new FilteredClassLoader(Neo4jTransactionManager.class, PlatformTransactionManager.class)) - .run(ctx -> assertThat(ctx).doesNotHaveBean(Neo4jClient.class).doesNotHaveBean(Neo4jTemplate.class) - .doesNotHaveBean(Neo4jTransactionManager.class)); + void shouldProvideNeo4jClient() { + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(Neo4jClient.class)); } @Test - void shouldCreateNewNeo4jClient() { - contextRunner.run(ctx -> assertThat(ctx).hasSingleBean(Neo4jClient.class)); + void shouldReuseExistingNeo4jClient() { + this.contextRunner.withBean("myCustomClient", Neo4jClient.class, () -> mock(Neo4jClient.class)) + .run((context) -> assertThat(context).hasSingleBean(Neo4jClient.class).hasBean("myCustomClient")); } @Test - void shouldNotReplaceExistingNeo4jClient() { - contextRunner.withUserConfiguration(ConfigurationWithExistingClient.class) - .run(ctx -> assertThat(ctx).hasSingleBean(Neo4jClient.class).hasBean("myCustomClient")); - } - - @Test - void shouldCreateNewNeo4jTemplate() { - contextRunner.withUserConfiguration(ConfigurationWithExistingDatabaseSelectionProvider.class).run(ctx -> { - assertThat(ctx).hasSingleBean(Neo4jTemplate.class); - - // Verify that the template uses the provided database name - // provider - Neo4jTemplate template = ctx.getBean(Neo4jTemplate.class); - DatabaseSelectionProvider provider = (DatabaseSelectionProvider) ReflectionTestUtils.getField(template, - "databaseSelectionProvider"); - assertThat(provider).isSameAs(ctx.getBean(DatabaseSelectionProvider.class)); + void shouldProvideNeo4jTemplate() { + this.contextRunner.withUserConfiguration(CustomDatabaseSelectionProviderConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(Neo4jTemplate.class); + assertThat(context.getBean(Neo4jTemplate.class)).extracting("databaseSelectionProvider") + .isSameAs(context.getBean(DatabaseSelectionProvider.class)); }); } @Test - void shouldNotReplaceExistingNeo4jTemplate() { - contextRunner.withUserConfiguration(ConfigurationWithExistingTemplate.class) - .run(ctx -> assertThat(ctx).hasSingleBean(Neo4jOperations.class).hasBean("myCustomOperations")); + void shouldReuseExistingNeo4jTemplate() { + this.contextRunner.withBean("myCustomOperations", Neo4jOperations.class, () -> mock(Neo4jOperations.class)).run( + (context) -> assertThat(context).hasSingleBean(Neo4jOperations.class).hasBean("myCustomOperations")); } @Test - void shouldCreateNewTransactionManager() { - contextRunner.withUserConfiguration(ConfigurationWithExistingDatabaseSelectionProvider.class).run(ctx -> { - assertThat(ctx).hasSingleBean(Neo4jTransactionManager.class); - - // Verify that the transaction manager uses the provided - // database name provider - Neo4jTransactionManager transactionManager = ctx.getBean(Neo4jTransactionManager.class); - DatabaseSelectionProvider provider = (DatabaseSelectionProvider) ReflectionTestUtils - .getField(transactionManager, "databaseSelectionProvider"); - assertThat(provider).isSameAs(ctx.getBean(DatabaseSelectionProvider.class)); + void shouldProvideTransactionManager() { + this.contextRunner.withUserConfiguration(CustomDatabaseSelectionProviderConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(Neo4jTransactionManager.class); + assertThat(context.getBean(Neo4jTransactionManager.class)).extracting("databaseSelectionProvider") + .isSameAs(context.getBean(DatabaseSelectionProvider.class)); }); } @Test - void shouldHonourExistingTransactionManager() { - contextRunner.withUserConfiguration(ConfigurationWithExistingTransactionManager.class) - .run(ctx -> assertThat(ctx).hasSingleBean(PlatformTransactionManager.class) + void shouldReuseExistingTransactionManager() { + this.contextRunner + .withBean("myCustomTransactionManager", PlatformTransactionManager.class, + () -> mock(PlatformTransactionManager.class)) + .run((context) -> assertThat(context).hasSingleBean(PlatformTransactionManager.class) .hasBean("myCustomTransactionManager")); } - @Configuration - static class ConfigurationWithExistingClient { - - @Bean("myCustomClient") - Neo4jClient neo4jClient(Driver driver) { - return Neo4jClient.create(driver); - } - - } - - @Configuration - static class ConfigurationWithExistingTemplate { - - @Bean("myCustomOperations") - Neo4jOperations neo4jOperations() { - return mock(Neo4jOperations.class); - } - - } - - @Configuration - static class ConfigurationWithExistingTransactionManager { - - @Bean("myCustomTransactionManager") - PlatformTransactionManager transactionManager() { - return mock(PlatformTransactionManager.class); - } - - } - - @Configuration - static class ConfigurationWithExistingDatabaseSelectionProvider { + @Configuration(proxyBeanMethods = false) + static class CustomDatabaseSelectionProviderConfiguration { @Bean DatabaseSelectionProvider databaseSelectionProvider() { - return () -> DatabaseSelection.byName("whatever"); + return () -> DatabaseSelection.byName("custom"); } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfigurationTests.java new file mode 100644 index 00000000000..b4e7c5ac04e --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfigurationTests.java @@ -0,0 +1,145 @@ +/* + * Copyright 2012-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.data.neo4j; + +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.neo4j.core.DatabaseSelection; +import org.springframework.data.neo4j.core.ReactiveDatabaseSelectionProvider; +import org.springframework.data.neo4j.core.ReactiveNeo4jClient; +import org.springframework.data.neo4j.core.ReactiveNeo4jOperations; +import org.springframework.data.neo4j.core.ReactiveNeo4jTemplate; +import org.springframework.data.neo4j.core.transaction.ReactiveNeo4jTransactionManager; +import org.springframework.transaction.ReactiveTransactionManager; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link Neo4jReactiveDataAutoConfiguration}. + * + * @author Michael J. Simons + * @author Stephane Nicoll + */ +class Neo4jReactiveDataAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withUserConfiguration(MockedDriverConfiguration.class) + .withConfiguration(AutoConfigurations.of(Neo4jAutoConfiguration.class, Neo4jDataAutoConfiguration.class, + Neo4jReactiveDataAutoConfiguration.class)); + + @Test + void shouldProvideDefaultDatabaseNameProvider() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(ReactiveDatabaseSelectionProvider.class); + assertThat(context.getBean(ReactiveDatabaseSelectionProvider.class)) + .isSameAs(ReactiveDatabaseSelectionProvider.getDefaultSelectionProvider()); + }); + } + + @Test + void shouldUseDatabaseNameIfSet() { + this.contextRunner.withPropertyValues("spring.data.neo4j.database=test").run((context) -> { + assertThat(context).hasSingleBean(ReactiveDatabaseSelectionProvider.class); + StepVerifier.create(context.getBean(ReactiveDatabaseSelectionProvider.class).getDatabaseSelection()) + .consumeNextWith((databaseSelection) -> assertThat(databaseSelection.getValue()).isEqualTo("test")) + .expectComplete(); + }); + } + + @Test + void shouldReuseExistingDatabaseNameProvider() { + this.contextRunner.withPropertyValues("spring.data.neo4j.database=ignored") + .withUserConfiguration(CustomReactiveDatabaseSelectionProviderConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(ReactiveDatabaseSelectionProvider.class); + StepVerifier.create(context.getBean(ReactiveDatabaseSelectionProvider.class).getDatabaseSelection()) + .consumeNextWith( + (databaseSelection) -> assertThat(databaseSelection.getValue()).isEqualTo("custom")) + .expectComplete(); + }); + } + + @Test + void shouldProvideReactiveNeo4jClient() { + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ReactiveNeo4jClient.class)); + } + + @Test + void shouldReuseExistingReactiveNeo4jClient() { + this.contextRunner + .withBean("myCustomReactiveClient", ReactiveNeo4jClient.class, () -> mock(ReactiveNeo4jClient.class)) + .run((context) -> assertThat(context).hasSingleBean(ReactiveNeo4jClient.class) + .hasBean("myCustomReactiveClient")); + } + + @Test + void shouldProvideReactiveNeo4jTemplate() { + this.contextRunner.withUserConfiguration(CustomReactiveDatabaseSelectionProviderConfiguration.class) + .run((context) -> { + assertThat(context).hasSingleBean(ReactiveNeo4jTemplate.class); + assertThat(context.getBean(ReactiveNeo4jTemplate.class)).extracting("databaseSelectionProvider") + .isSameAs(context.getBean(ReactiveDatabaseSelectionProvider.class)); + }); + } + + @Test + void shouldReuseExistingReactiveNeo4jTemplate() { + this.contextRunner + .withBean("myCustomReactiveOperations", ReactiveNeo4jOperations.class, + () -> mock(ReactiveNeo4jOperations.class)) + .run((context) -> assertThat(context).hasSingleBean(ReactiveNeo4jOperations.class) + .hasBean("myCustomReactiveOperations")); + } + + @Test + void shouldProvideReactiveTransactionManager() { + this.contextRunner.withUserConfiguration(CustomReactiveDatabaseSelectionProviderConfiguration.class) + .run((context) -> { + assertThat(context).hasSingleBean(ReactiveNeo4jTransactionManager.class); + assertThat(context.getBean(ReactiveNeo4jTransactionManager.class)) + .extracting("databaseSelectionProvider") + .isSameAs(context.getBean(ReactiveDatabaseSelectionProvider.class)); + }); + } + + @Test + void shouldReuseExistingReactiveTransactionManager() { + this.contextRunner + .withBean("myCustomReactiveTransactionManager", ReactiveTransactionManager.class, + () -> mock(ReactiveTransactionManager.class)) + .run((context) -> assertThat(context).hasSingleBean(ReactiveTransactionManager.class) + .hasBean("myCustomReactiveTransactionManager")); + } + + @Configuration(proxyBeanMethods = false) + static class CustomReactiveDatabaseSelectionProviderConfiguration { + + @Bean + ReactiveDatabaseSelectionProvider databaseNameProvider() { + return () -> Mono.just(DatabaseSelection.byName("custom")); + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesAutoConfigurationTests.java new file mode 100644 index 00000000000..05584cfc7dc --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesAutoConfigurationTests.java @@ -0,0 +1,112 @@ +/* + * Copyright 2012-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.data.neo4j; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; +import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage; +import org.springframework.boot.autoconfigure.data.neo4j.city.City; +import org.springframework.boot.autoconfigure.data.neo4j.city.CityRepository; +import org.springframework.boot.autoconfigure.data.neo4j.city.ReactiveCityRepository; +import org.springframework.boot.autoconfigure.data.neo4j.country.CountryRepository; +import org.springframework.boot.autoconfigure.data.neo4j.country.ReactiveCountryRepository; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.neo4j.core.transaction.ReactiveNeo4jTransactionManager; +import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository; +import org.springframework.data.neo4j.repository.config.EnableReactiveNeo4jRepositories; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link Neo4jReactiveRepositoriesAutoConfiguration}. + * + * @author Stephane Nicoll + * @author Michael J. Simons + */ +public class Neo4jReactiveRepositoriesAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withUserConfiguration(MockedDriverConfiguration.class) + .withConfiguration(AutoConfigurations.of(Neo4jDataAutoConfiguration.class, + Neo4jReactiveDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class, + Neo4jReactiveRepositoriesAutoConfiguration.class)); + + @Test + void configurationWithDefaultRepositories() { + this.contextRunner.withUserConfiguration(TestConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(ReactiveCityRepository.class)); + } + + @Test + void configurationWithNoRepositories() { + this.contextRunner.withUserConfiguration(EmptyConfiguration.class).run((context) -> assertThat(context) + .hasSingleBean(ReactiveNeo4jTransactionManager.class).doesNotHaveBean(ReactiveNeo4jRepository.class)); + } + + @Test + void configurationWithDisabledRepositories() { + this.contextRunner.withUserConfiguration(TestConfiguration.class) + .withPropertyValues("spring.data.neo4j.repositories.type=none") + .run((context) -> assertThat(context).doesNotHaveBean(ReactiveNeo4jRepository.class)); + } + + @Test + void autoConfigurationShouldNotKickInEvenIfManualConfigDidNotCreateAnyRepositories() { + this.contextRunner.withUserConfiguration(SortOfInvalidCustomConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(ReactiveNeo4jTransactionManager.class) + .doesNotHaveBean(ReactiveNeo4jRepository.class)); + } + + @Test + void shouldRespectAtEnableReactiveNeo4jRepositories() { + this.contextRunner + .withUserConfiguration(SortOfInvalidCustomConfiguration.class, WithCustomReactiveRepositoryScan.class) + .withPropertyValues("spring.data.neo4j.repositories.type=reactive") + .run((context) -> assertThat(context).doesNotHaveBean(CityRepository.class) + .doesNotHaveBean(ReactiveCityRepository.class).doesNotHaveBean(CountryRepository.class) + .hasSingleBean(ReactiveCountryRepository.class)); + } + + @Configuration(proxyBeanMethods = false) + @TestAutoConfigurationPackage(City.class) + static class TestConfiguration { + + } + + @Configuration(proxyBeanMethods = false) + @TestAutoConfigurationPackage(EmptyDataPackage.class) + static class EmptyConfiguration { + + } + + @Configuration(proxyBeanMethods = false) + @EnableReactiveNeo4jRepositories("foo.bar") + @TestAutoConfigurationPackage(Neo4jReactiveRepositoriesAutoConfigurationTests.class) + static class SortOfInvalidCustomConfiguration { + + } + + @Configuration(proxyBeanMethods = false) + @EnableReactiveNeo4jRepositories(basePackageClasses = ReactiveCountryRepository.class) + static class WithCustomReactiveRepositoryScan { + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationIntegrationTests.java index f6a8592c158..c5f3a9cb536 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationIntegrationTests.java @@ -17,6 +17,10 @@ package org.springframework.boot.autoconfigure.data.neo4j; import org.junit.jupiter.api.Test; +import org.testcontainers.containers.Neo4jContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.data.neo4j.country.CountryRepository; @@ -26,9 +30,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; -import org.testcontainers.containers.Neo4jContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import static org.assertj.core.api.Assertions.assertThat; @@ -37,32 +38,26 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Michael J. Simons */ -@SpringBootTest(properties = "spring.data.neo4j.repositories.type=imperative") +@SpringBootTest @Testcontainers(disabledWithoutDocker = true) public class Neo4jRepositoriesAutoConfigurationIntegrationTests { @Container - private static Neo4jContainer neo4jServer = new Neo4jContainer<>("neo4j:4.0"); + private static final Neo4jContainer neo4jServer = new Neo4jContainer<>("neo4j:4.0"); @DynamicPropertySource static void neo4jProperties(DynamicPropertyRegistry registry) { - registry.add("spring.neo4j.uri", neo4jServer::getBoltUrl); registry.add("spring.neo4j.authentication.username", () -> "neo4j"); registry.add("spring.neo4j.authentication.password", neo4jServer::getAdminPassword); } - private final CountryRepository countryRepository; - @Autowired - Neo4jRepositoriesAutoConfigurationIntegrationTests(CountryRepository countryRepository) { - this.countryRepository = countryRepository; - } + private CountryRepository countryRepository; @Test void ensureRepositoryIsReady() { - - assertThat(countryRepository.count()).isEqualTo(0); + assertThat(this.countryRepository.count()).isEqualTo(0); } @Configuration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationTests.java index c8e0ac302d1..708b4372bea 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.data.neo4j; import org.junit.jupiter.api.Test; import org.mockito.Mockito; + import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage; @@ -26,19 +27,13 @@ import org.springframework.boot.autoconfigure.data.neo4j.city.CityRepository; import org.springframework.boot.autoconfigure.data.neo4j.city.ReactiveCityRepository; import org.springframework.boot.autoconfigure.data.neo4j.country.CountryRepository; import org.springframework.boot.autoconfigure.data.neo4j.country.ReactiveCountryRepository; -import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.data.neo4j.core.Neo4jClient; -import org.springframework.data.neo4j.core.ReactiveNeo4jClient; import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager; import org.springframework.data.neo4j.repository.Neo4jRepository; -import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository; import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; -import org.springframework.data.neo4j.repository.config.EnableReactiveNeo4jRepositories; import org.springframework.data.neo4j.repository.support.ReactiveNeo4jRepositoryFactoryBean; -import reactor.core.publisher.Flux; import static org.assertj.core.api.Assertions.assertThat; @@ -55,75 +50,49 @@ import static org.assertj.core.api.Assertions.assertThat; class Neo4jRepositoriesAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withUserConfiguration(MockedDriverConfiguration.class) - .withConfiguration(AutoConfigurations.of(Neo4jRepositoriesAutoConfigurationTests.class, - Neo4jDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class)); + .withUserConfiguration(MockedDriverConfiguration.class).withConfiguration( + AutoConfigurations.of(Neo4jDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class)); @Test - void defaultRepositoryConfigurationShouldWork() { + void configurationWithDefaultRepositories() { this.contextRunner.withUserConfiguration(TestConfiguration.class) - .withPropertyValues("spring.data.neo4j.repositories.type=imperative") - .run(ctx -> assertThat(ctx).hasSingleBean(CityRepository.class)); + .run((context) -> assertThat(context).hasSingleBean(CityRepository.class)); } @Test - void repositoryConfigurationShouldNotCreateArbitraryRepos() { - this.contextRunner.withUserConfiguration(EmptyConfiguration.class) - .withPropertyValues("spring.data.neo4j.repositories.type=imperative").run(ctx -> assertThat(ctx) - .hasSingleBean(Neo4jTransactionManager.class).doesNotHaveBean(Neo4jRepository.class)); + void configurationWithNoRepositories() { + this.contextRunner.withUserConfiguration(EmptyConfiguration.class).run((context) -> assertThat(context) + .hasSingleBean(Neo4jTransactionManager.class).doesNotHaveBean(Neo4jRepository.class)); } @Test - void configurationOfRepositoryTypeShouldWork() { - this.contextRunner.withPropertyValues("spring.data.neo4j.repositories.type=none") - .withUserConfiguration(TestConfiguration.class).withClassLoader(new FilteredClassLoader(Flux.class)) - .run(ctx -> assertThat(ctx).doesNotHaveBean(Neo4jTransactionManager.class) - .doesNotHaveBean(ReactiveNeo4jClient.class).doesNotHaveBean(Neo4jRepository.class)); - - this.contextRunner.withPropertyValues("spring.data.neo4j.repositories.type=imperative") - .withUserConfiguration(TestConfiguration.class) - .run(ctx -> assertThat(ctx).hasSingleBean(Neo4jTransactionManager.class) - .hasSingleBean(Neo4jClient.class).doesNotHaveBean(ReactiveNeo4jRepository.class)); + void configurationWithDisabledRepositories() { + this.contextRunner.withUserConfiguration(TestConfiguration.class) + .withPropertyValues("spring.data.neo4j.repositories.type=none") + .run((context) -> assertThat(context).doesNotHaveBean(Neo4jRepository.class)); } @Test void autoConfigurationShouldNotKickInEvenIfManualConfigDidNotCreateAnyRepositories() { this.contextRunner.withUserConfiguration(SortOfInvalidCustomConfiguration.class) - .withPropertyValues("spring.data.neo4j.repositories.type=imperative").run(ctx -> assertThat(ctx) - .hasSingleBean(Neo4jTransactionManager.class).doesNotHaveBean(Neo4jRepository.class)); + .run((context) -> assertThat(context).hasSingleBean(Neo4jTransactionManager.class) + .doesNotHaveBean(Neo4jRepository.class)); } @Test void shouldRespectAtEnableNeo4jRepositories() { this.contextRunner.withUserConfiguration(SortOfInvalidCustomConfiguration.class, WithCustomRepositoryScan.class) - .withPropertyValues("spring.data.neo4j.repositories.type=imperative") - .run(ctx -> assertThat(ctx).doesNotHaveBean(CityRepository.class) + .run((context) -> assertThat(context).doesNotHaveBean(CityRepository.class) .doesNotHaveBean(ReactiveCityRepository.class).hasSingleBean(CountryRepository.class) .doesNotHaveBean(ReactiveCountryRepository.class)); } - @Test - void shouldRespectAtEnableReactiveNeo4jRepositories() { - this.contextRunner - .withUserConfiguration(SortOfInvalidCustomConfiguration.class, WithCustomReactiveRepositoryScan.class) - .withPropertyValues("spring.data.neo4j.repositories.type=reactive") - .run(ctx -> assertThat(ctx).doesNotHaveBean(CityRepository.class) - .doesNotHaveBean(ReactiveCityRepository.class).doesNotHaveBean(CountryRepository.class) - .hasSingleBean(ReactiveCountryRepository.class)); - } - @Configuration(proxyBeanMethods = false) @EnableNeo4jRepositories(basePackageClasses = CountryRepository.class) static class WithCustomRepositoryScan { } - @Configuration(proxyBeanMethods = false) - @EnableReactiveNeo4jRepositories(basePackageClasses = ReactiveCountryRepository.class) - static class WithCustomReactiveRepositoryScan { - - } - @Configuration(proxyBeanMethods = false) static class WithFakeEnabledReactiveNeo4jRepositories { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/ReactiveNeo4jDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/ReactiveNeo4jDataAutoConfigurationTests.java deleted file mode 100644 index dfdf47bd70b..00000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/ReactiveNeo4jDataAutoConfigurationTests.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2012-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.neo4j; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import org.junit.jupiter.api.Test; -import org.neo4j.driver.Driver; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.neo4j.core.DatabaseSelection; -import org.springframework.data.neo4j.core.ReactiveDatabaseSelectionProvider; -import org.springframework.data.neo4j.core.ReactiveNeo4jClient; -import org.springframework.data.neo4j.core.ReactiveNeo4jOperations; -import org.springframework.data.neo4j.core.ReactiveNeo4jTemplate; -import org.springframework.data.neo4j.core.convert.Neo4jConversions; -import org.springframework.data.neo4j.core.transaction.ReactiveNeo4jTransactionManager; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.transaction.ReactiveTransactionManager; - -/** - * @author Michael J. Simons - */ -class ReactiveNeo4jDataAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withPropertyValues("spring.data.neo4j.repositories.type=reactive") - .withUserConfiguration(MockedDriverConfiguration.class) - .withConfiguration(AutoConfigurations.of(Neo4jAutoConfiguration.class, Neo4jDataAutoConfiguration.class)); - - @Test - void shouldProvideConversions() { - contextRunner.run(ctx -> assertThat(ctx).hasSingleBean(Neo4jConversions.class)); - } - - @Test - void shouldProvideDefaultDatabaseNameProvider() { - contextRunner.run(ctx -> { - assertThat(ctx).hasSingleBean(ReactiveDatabaseSelectionProvider.class); - ReactiveDatabaseSelectionProvider databaseNameProvider = ctx - .getBean(ReactiveDatabaseSelectionProvider.class); - assertThat(databaseNameProvider).isSameAs(ReactiveDatabaseSelectionProvider.getDefaultSelectionProvider()); - }); - } - - @Test - void shouldProvideStaticDatabaseNameProviderIfConfigured() { - contextRunner.withPropertyValues("spring.data.neo4j.database=foobar").run(ctx -> { - assertThat(ctx).hasSingleBean(ReactiveDatabaseSelectionProvider.class); - ReactiveDatabaseSelectionProvider databaseNameProvider = ctx - .getBean(ReactiveDatabaseSelectionProvider.class); - StepVerifier.create(databaseNameProvider.getDatabaseSelection().map(DatabaseSelection::getValue)) - .expectNext("foobar").expectComplete(); - }); - } - - @Test - void shouldRespectExistingDatabaseNameProvider() { - contextRunner.withPropertyValues("spring.data.neo4j.database=foobar") - .withUserConfiguration(ConfigurationWithExistingReactiveDatabaseSelectionProvider.class).run(ctx -> { - assertThat(ctx).hasSingleBean(ReactiveDatabaseSelectionProvider.class); - ReactiveDatabaseSelectionProvider databaseNameProvider = ctx - .getBean(ReactiveDatabaseSelectionProvider.class); - StepVerifier.create(databaseNameProvider.getDatabaseSelection().map(DatabaseSelection::getValue)) - .expectNext("whatever").expectComplete(); - }); - } - - @Test - void shouldRequireAllNeededClasses() { - contextRunner - .withClassLoader(new FilteredClassLoader(ReactiveNeo4jTransactionManager.class, - ReactiveTransactionManager.class, Flux.class)) - .run(ctx -> assertThat(ctx).doesNotHaveBean(ReactiveNeo4jClient.class) - .doesNotHaveBean(ReactiveNeo4jTemplate.class) - .doesNotHaveBean(ReactiveNeo4jTransactionManager.class)); - } - - @Test - void shouldCreateNewReactiveNeo4jClient() { - contextRunner.run(ctx -> assertThat(ctx).hasSingleBean(ReactiveNeo4jClient.class)); - } - - @Test - void shouldNotReplaceExistingReactiveNeo4jClient() { - contextRunner.withUserConfiguration(ConfigurationWithExistingReactiveClient.class) - .run(ctx -> assertThat(ctx).hasSingleBean(ReactiveNeo4jClient.class).hasBean("myCustomReactiveClient")); - } - - @Test - void shouldCreateNewNeo4jTemplate() { - contextRunner.withUserConfiguration(ConfigurationWithExistingReactiveDatabaseSelectionProvider.class) - .run(ctx -> { - assertThat(ctx).hasSingleBean(ReactiveNeo4jTemplate.class); - - // Verify that the template uses the provided database name - // provider - ReactiveNeo4jTemplate template = ctx.getBean(ReactiveNeo4jTemplate.class); - ReactiveDatabaseSelectionProvider provider = (ReactiveDatabaseSelectionProvider) ReflectionTestUtils - .getField(template, "databaseSelectionProvider"); - assertThat(provider).isSameAs(ctx.getBean(ReactiveDatabaseSelectionProvider.class)); - }); - } - - @Test - void shouldNotReplaceExistingNeo4jTemplate() { - contextRunner.withUserConfiguration(ConfigurationWithExistingReactiveTemplate.class).run(ctx -> assertThat(ctx) - .hasSingleBean(ReactiveNeo4jOperations.class).hasBean("myCustomReactiveOperations")); - } - - @Test - void shouldCreateNewTransactionManager() { - contextRunner.withUserConfiguration(ConfigurationWithExistingReactiveDatabaseSelectionProvider.class) - .run(ctx -> { - assertThat(ctx).hasSingleBean(ReactiveNeo4jTransactionManager.class); - - // Verify that the transaction manager uses the provided - // database name provider - ReactiveNeo4jTransactionManager transactionManager = ctx - .getBean(ReactiveNeo4jTransactionManager.class); - ReactiveDatabaseSelectionProvider provider = (ReactiveDatabaseSelectionProvider) ReflectionTestUtils - .getField(transactionManager, "databaseSelectionProvider"); - assertThat(provider).isSameAs(ctx.getBean(ReactiveDatabaseSelectionProvider.class)); - }); - } - - @Test - void shouldHonourExistingTransactionManager() { - contextRunner.withUserConfiguration(ConfigurationWithExistingReactiveTransactionManager.class) - .run(ctx -> assertThat(ctx).hasSingleBean(ReactiveTransactionManager.class) - .hasBean("myCustomReactiveTransactionManager")); - } - - @Configuration - static class ConfigurationWithExistingReactiveClient { - - @Bean("myCustomReactiveClient") - ReactiveNeo4jClient neo4jClient(Driver driver) { - return ReactiveNeo4jClient.create(driver); - } - - } - - @Configuration - static class ConfigurationWithExistingReactiveTemplate { - - @Bean("myCustomReactiveOperations") - ReactiveNeo4jOperations neo4jOperations() { - return mock(ReactiveNeo4jOperations.class); - } - - } - - @Configuration - static class ConfigurationWithExistingReactiveTransactionManager { - - @Bean("myCustomReactiveTransactionManager") - ReactiveTransactionManager transactionManager() { - return mock(ReactiveTransactionManager.class); - } - - } - - @Configuration - static class ConfigurationWithExistingReactiveDatabaseSelectionProvider { - - @Bean - ReactiveDatabaseSelectionProvider databaseNameProvider() { - return () -> Mono.just(DatabaseSelection.byName("whatever")); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/City.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/City.java index 27f1db193fc..29e84bdca3b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/City.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/City.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/ReactiveCityRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/ReactiveCityRepository.java index 215d9f1716a..8b88301d5a4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/ReactiveCityRepository.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/ReactiveCityRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -16,9 +16,6 @@ package org.springframework.boot.autoconfigure.data.neo4j.city; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.neo4j.repository.Neo4jRepository; import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository; public interface ReactiveCityRepository extends ReactiveNeo4jRepository { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/Country.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/Country.java index 34c504c098b..2ab5a426717 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/Country.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/Country.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -16,12 +16,12 @@ package org.springframework.boot.autoconfigure.data.neo4j.country; +import java.io.Serializable; + import org.springframework.data.neo4j.core.schema.GeneratedValue; import org.springframework.data.neo4j.core.schema.Id; import org.springframework.data.neo4j.core.schema.Node; -import java.io.Serializable; - @Node public class Country implements Serializable { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/ReactiveCountryRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/ReactiveCountryRepository.java index 790aa84d94d..c97759cadc6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/ReactiveCountryRepository.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/ReactiveCountryRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto.adoc index 415e09ade84..12d189b8682 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto.adoc @@ -2978,7 +2978,7 @@ class ExampleIntegrationTests { @DynamicPropertySource static void neo4jProperties(DynamicPropertyRegistry registry) { - registry.add("spring.data.neo4j.uri", neo4j::getBoltUrl); + registry.add("spring.neo4j.uri", neo4j::getBoltUrl); } } diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc index 0d34edd13aa..4c2e987eae4 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc @@ -4532,47 +4532,6 @@ Each will be called in order with the `ConfigBuilder` that is used to build the -[[boot-features-connecting-to-neo4j-embedded]] -==== Using the Embedded Mode -If you add `org.neo4j:neo4j-ogm-embedded-driver` to the dependencies of your application, Spring Boot automatically configures an in-process embedded instance of Neo4j that does not persist any data when your application shuts down. - -NOTE: As the embedded Neo4j OGM driver does not provide the Neo4j kernel itself, you have to declare `org.neo4j:neo4j` as dependency yourself. -Refer to https://neo4j.com/docs/ogm-manual/current/reference/#reference:getting-started[the Neo4j OGM documentation] for a list of compatible versions. - -The embedded driver takes precedence over the other drivers when there are multiple drivers on the classpath. -You can explicitly disable the embedded mode by setting `spring.data.neo4j.embedded.enabled=false`. - -<> automatically make use of an embedded Neo4j instance if the embedded driver and Neo4j kernel are on the classpath as described above. - -NOTE: You can enable persistence for the embedded mode by providing a path to a database file in your configuration, e.g. `spring.data.neo4j.uri=file://var/tmp/graph.db`. - - - -[[boot-features-neo4j-ogm-native-types]] -==== Using Native Types -Neo4j-OGM can map some types, like those in `java.time.*`, to `String`-based properties or to one of the native types that Neo4j provides. -For backwards compatibility reasons the default for Neo4j-OGM is to use a `String`-based representation. -To use native types, add a dependency on either `org.neo4j:neo4j-ogm-bolt-native-types` or `org.neo4j:neo4j-ogm-embedded-native-types`, and configure the configprop:spring.data.neo4j.use-native-types[] property as shown in the following example: - -[source,properties,indent=0,configprops] ----- - spring.data.neo4j.use-native-types=true ----- - - - -[[boot-features-neo4j-ogm-session]] -==== Neo4jSession -By default, if you are running a web application, the session is bound to the thread for the entire processing of the request (that is, it uses the "Open Session in View" pattern). -If you do not want this behavior, add the following line to your `application.properties` file: - -[source,properties,indent=0,configprops] ----- - spring.data.neo4j.open-in-view=false ----- - - - [[boot-features-spring-data-neo4j-repositories]] ==== Spring Data Neo4j Repositories Spring Data includes repository support for Neo4j. diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories index b8e2f1e6466..9034663f251 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories @@ -42,7 +42,10 @@ org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration # AutoConfigureDataNeo4j auto-configuration imports org.springframework.boot.test.autoconfigure.data.neo4j.AutoConfigureDataNeo4j=\ +org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration,\ org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\ +org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveDataAutoConfiguration,\ +org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java index c10b33a03c4..b806684d187 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java @@ -19,8 +19,6 @@ package org.springframework.boot.test.autoconfigure.data.neo4j; import java.time.Duration; import org.junit.jupiter.api.Test; - -import org.springframework.data.neo4j.core.Neo4jTemplate; import org.testcontainers.containers.Neo4jContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -28,6 +26,7 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; +import org.springframework.data.neo4j.core.Neo4jTemplate; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; @@ -49,6 +48,11 @@ class DataNeo4jTestIntegrationTests { static final Neo4jContainer neo4j = new Neo4jContainer<>().withoutAuthentication() .withStartupTimeout(Duration.ofMinutes(10)); + @DynamicPropertySource + static void neo4jProperties(DynamicPropertyRegistry registry) { + registry.add("spring.neo4j.uri", neo4j::getBoltUrl); + } + @Autowired private Neo4jTemplate neo4jTemplate; @@ -58,11 +62,6 @@ class DataNeo4jTestIntegrationTests { @Autowired private ApplicationContext applicationContext; - @DynamicPropertySource - static void neo4jProperties(DynamicPropertyRegistry registry) { - registry.add("spring.neo4j.uri", neo4j::getBoltUrl); - } - @Test void testRepository() { ExampleGraph exampleGraph = new ExampleGraph("Look, new @DataNeo4jTest!"); diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestPropertiesIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestPropertiesIntegrationTests.java index b4efc9eac0c..f7f73685006 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestPropertiesIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestPropertiesIntegrationTests.java @@ -44,14 +44,14 @@ class DataNeo4jTestPropertiesIntegrationTests { static final Neo4jContainer neo4j = new Neo4jContainer<>().withoutAuthentication() .withStartupTimeout(Duration.ofMinutes(10)); - @Autowired - private Environment environment; - @DynamicPropertySource static void neo4jProperties(DynamicPropertyRegistry registry) { registry.add("spring.neo4j.uri", neo4j::getBoltUrl); } + @Autowired + private Environment environment; + @Test void environmentWithNewProfile() { assertThat(this.environment.getActiveProfiles()).containsExactly("test"); diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ReactiveDataNeo4jIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestReactiveIntegrationTests.java similarity index 67% rename from spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ReactiveDataNeo4jIntegrationTests.java rename to spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestReactiveIntegrationTests.java index c85a900c4bf..570f4849174 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ReactiveDataNeo4jIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestReactiveIntegrationTests.java @@ -16,30 +16,22 @@ package org.springframework.boot.test.autoconfigure.data.neo4j; +import java.time.Duration; + import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.data.neo4j.core.ReactiveNeo4jTemplate; -import org.springframework.data.neo4j.core.transaction.ReactiveNeo4jTransactionManager; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.ReactiveTransactionManager; import org.testcontainers.containers.Neo4jContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import java.time.Duration; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.data.neo4j.core.ReactiveNeo4jTemplate; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; -import org.neo4j.driver.AccessMode; -import org.neo4j.driver.Driver; -import org.neo4j.driver.Session; -import org.neo4j.driver.SessionConfig; - -import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; /** @@ -50,7 +42,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; */ @DataNeo4jTest @Testcontainers(disabledWithoutDocker = true) -class ReactiveDataNeo4jIntegrationTests { +class DataNeo4jTestReactiveIntegrationTests { @Container static final Neo4jContainer neo4j = new Neo4jContainer<>("neo4j:4.0").withoutAuthentication() @@ -62,24 +54,19 @@ class ReactiveDataNeo4jIntegrationTests { } @Autowired - private Driver driver; + private ReactiveNeo4jTemplate neo4jTemplate; @Autowired - private ReactiveNeo4jTemplate neo4jTemplate; + private ExampleReactiveRepository exampleRepository; @Autowired private ApplicationContext applicationContext; @Test - void testTemplate() { - - Mono.just(new ExampleGraph("Look, new @DataNeo4jTest with reactive!")).flatMap(neo4jTemplate::save) + void testRepository() { + Mono.just(new ExampleGraph("Look, new @DataNeo4jTest with reactive!")).flatMap(this.exampleRepository::save) .as(StepVerifier::create).expectNextCount(1).verifyComplete(); - - try (Session session = driver.session(SessionConfig.builder().withDefaultAccessMode(AccessMode.READ).build())) { - long cnt = session.run("MATCH (n:ExampleGraph) RETURN count(n) as cnt").single().get("cnt").asLong(); - assertThat(cnt).isEqualTo(1L); - } + StepVerifier.create(this.neo4jTemplate.count(ExampleGraph.class)).expectNext(1L).verifyComplete(); } @Test @@ -88,13 +75,4 @@ class ReactiveDataNeo4jIntegrationTests { .isThrownBy(() -> this.applicationContext.getBean(ExampleService.class)); } - @Test - void didProvideOnlyReactiveTransactionManager() { - - assertThat(this.applicationContext.getBean(ReactiveTransactionManager.class)) - .isInstanceOf(ReactiveNeo4jTransactionManager.class); - assertThatExceptionOfType(NoSuchBeanDefinitionException.class) - .isThrownBy(() -> this.applicationContext.getBean(PlatformTransactionManager.class)); - } - } diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java index a8812f06cf8..f4f56b8ba57 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java @@ -45,14 +45,14 @@ class DataNeo4jTestWithIncludeFilterIntegrationTests { static final Neo4jContainer neo4j = new Neo4jContainer<>().withoutAuthentication() .withStartupTimeout(Duration.ofMinutes(10)); - @Autowired - private ExampleService service; - @DynamicPropertySource static void neo4jProperties(DynamicPropertyRegistry registry) { registry.add("spring.neo4j.uri", neo4j::getBoltUrl); } + @Autowired + private ExampleService service; + @Test void testService() { assertThat(this.service.hasNode(ExampleGraph.class)).isFalse(); diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTypeExcludeFilterTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTypeExcludeFilterTests.java deleted file mode 100644 index dda71f1dd44..00000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTypeExcludeFilterTests.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2019-2020 "Neo4j," - * Neo4j Sweden AB [https://neo4j.com] - * - * This file is part of Neo4j. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.boot.test.autoconfigure.data.neo4j; - -import org.junit.jupiter.api.Test; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.FilterType; -import org.springframework.core.type.classreading.MetadataReader; -import org.springframework.core.type.classreading.MetadataReaderFactory; -import org.springframework.core.type.classreading.SimpleMetadataReaderFactory; - -import java.io.IOException; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Michael J. Simons - */ -class DataNeo4jTypeExcludeFilterTests { - - private MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory(); - - @Test - void matchWithExcludeFilter() throws Exception { - DataNeo4jTypeExcludeFilter filter = new DataNeo4jTypeExcludeFilter(WithExcludeFilter.class); - assertThat(excludes(filter, ExampleService.class)).isTrue(); - assertThat(excludes(filter, ExampleRepository.class)).isTrue(); - } - - @Test - void matchWithoutExcludeFilter() throws Exception { - DataNeo4jTypeExcludeFilter filter = new DataNeo4jTypeExcludeFilter(WithoutExcludeFilter.class); - assertThat(excludes(filter, ExampleService.class)).isTrue(); - assertThat(excludes(filter, ExampleRepository.class)).isFalse(); - } - - @DataNeo4jTest( - excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ExampleRepository.class)) - static class WithExcludeFilter { - - } - - @DataNeo4jTest - static class WithoutExcludeFilter { - - } - - private boolean excludes(DataNeo4jTypeExcludeFilter filter, Class type) throws IOException { - MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(type.getName()); - return filter.match(metadataReader, this.metadataReaderFactory); - } - -} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleGraph.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleGraph.java index 4c3736a2d40..70124981305 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleGraph.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleGraph.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -25,7 +25,6 @@ import org.springframework.data.neo4j.core.schema.Property; * Example graph used with {@link DataNeo4jTest @DataNeo4jTest} tests. * * @author EddĂș MelĂ©ndez - * @author Michael J. Simons */ @Node public class ExampleGraph { diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleReactiveRepository.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleReactiveRepository.java new file mode 100644 index 00000000000..8fd588fdb4e --- /dev/null +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ExampleReactiveRepository.java @@ -0,0 +1,28 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.test.autoconfigure.data.neo4j; + +import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository; + +/** + * Example reactive repository used with {@link DataNeo4jTest @DataNeo4jTest} tests. + * + * @author Stephane Nicoll + */ +interface ExampleReactiveRepository extends ReactiveNeo4jRepository { + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-neo4j/src/main/resources/application.properties b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-neo4j/src/main/resources/application.properties index 6dabd65d3ed..e69de29bb2d 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-neo4j/src/main/resources/application.properties +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-neo4j/src/main/resources/application.properties @@ -1 +0,0 @@ -# spring.data.neo4j.open-in-view=true