35 changed files with 593 additions and 732 deletions
@ -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<TransactionManagerCustomizers> optionalCustomizers) { |
|
||||||
Neo4jTransactionManager transactionManager = new Neo4jTransactionManager(driver, databaseNameProvider); |
|
||||||
optionalCustomizers.ifAvailable((customizer) -> customizer.customize(transactionManager)); |
|
||||||
return transactionManager; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
48
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataConfiguration.java → spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfiguration.java
48
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataConfiguration.java → spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfiguration.java
15
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesConfiguration.java → spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesAutoConfiguration.java
15
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesConfiguration.java → spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesAutoConfiguration.java
9
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesConfigureRegistrar.java → spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesRegistrar.java
9
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesConfigureRegistrar.java → spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesRegistrar.java
@ -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 { |
|
||||||
|
|
||||||
} |
|
||||||
@ -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")); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -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 { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -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")); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
50
spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ReactiveDataNeo4jIntegrationTests.java → spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestReactiveIntegrationTests.java
50
spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/ReactiveDataNeo4jIntegrationTests.java → spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestReactiveIntegrationTests.java
@ -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); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -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<ExampleGraph, Long> { |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue