parent
ff038be773
commit
15cd343737
@ -1,65 +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 com.github.benmanes.caffeine.cache.Caffeine;
|
||||
|
||||
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.ConditionalOnNotWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.cache.caffeine.CaffeineCacheManager;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.context.annotation.ScopedProxyMode;
|
||||
import org.springframework.data.neo4j.bookmark.BeanFactoryBookmarkOperationAdvisor;
|
||||
import org.springframework.data.neo4j.bookmark.BookmarkInterceptor;
|
||||
import org.springframework.data.neo4j.bookmark.BookmarkManager;
|
||||
import org.springframework.data.neo4j.bookmark.CaffeineBookmarkManager;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
/**
|
||||
* Provides a {@link BookmarkManager} for Neo4j's bookmark support based on Caffeine if
|
||||
* available. Depending on the application's type (web or not) the bookmark manager will
|
||||
* be bound to the application or the request, as recommend by Spring Data Neo4j.
|
||||
*
|
||||
* @author Michael Simons
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ Caffeine.class, CaffeineCacheManager.class })
|
||||
@ConditionalOnMissingBean(BookmarkManager.class)
|
||||
@ConditionalOnBean({ BeanFactoryBookmarkOperationAdvisor.class, BookmarkInterceptor.class })
|
||||
class Neo4jBookmarkManagementConfiguration {
|
||||
|
||||
private static final String BOOKMARK_MANAGER_BEAN_NAME = "bookmarkManager";
|
||||
|
||||
@Bean(BOOKMARK_MANAGER_BEAN_NAME)
|
||||
@ConditionalOnWebApplication
|
||||
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.INTERFACES)
|
||||
BookmarkManager requestScopedBookmarkManager() {
|
||||
return new CaffeineBookmarkManager();
|
||||
}
|
||||
|
||||
@Bean(BOOKMARK_MANAGER_BEAN_NAME)
|
||||
@ConditionalOnNotWebApplication
|
||||
BookmarkManager singletonScopedBookmarkManager() {
|
||||
return new CaffeineBookmarkManager();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.context.properties.ConfigurationProperties;
|
||||
import org.springframework.data.neo4j.core.DatabaseSelectionProvider;
|
||||
|
||||
/**
|
||||
* Configuration properties for Spring Data Neo4j.
|
||||
*
|
||||
* @author Michael J. Simons
|
||||
* @since 2.4.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.data.neo4j")
|
||||
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.
|
||||
*/
|
||||
private String database;
|
||||
|
||||
public String getDatabase() {
|
||||
return this.database;
|
||||
}
|
||||
|
||||
public void setDatabase(String database) {
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
}
|
@ -1,177 +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.ogm.config.AutoIndexMode;
|
||||
import org.neo4j.ogm.config.Configuration;
|
||||
import org.neo4j.ogm.config.Configuration.Builder;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Configuration properties for Neo4j.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Michael Hunger
|
||||
* @author Vince Bickers
|
||||
* @author Aurélien Leboulanger
|
||||
* @author Michael Simons
|
||||
* @since 1.4.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.data.neo4j")
|
||||
public class Neo4jProperties implements ApplicationContextAware {
|
||||
|
||||
static final String EMBEDDED_DRIVER = "org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver";
|
||||
|
||||
static final String HTTP_DRIVER = "org.neo4j.ogm.drivers.http.driver.HttpDriver";
|
||||
|
||||
static final String DEFAULT_BOLT_URI = "bolt://localhost:7687";
|
||||
|
||||
static final String BOLT_DRIVER = "org.neo4j.ogm.drivers.bolt.driver.BoltDriver";
|
||||
|
||||
/**
|
||||
* URI used by the driver. Auto-detected by default.
|
||||
*/
|
||||
private String uri;
|
||||
|
||||
/**
|
||||
* Login user of the server.
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* Login password of the server.
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* Auto index mode.
|
||||
*/
|
||||
private AutoIndexMode autoIndex = AutoIndexMode.NONE;
|
||||
|
||||
/**
|
||||
* Whether to use Neo4j native types wherever possible.
|
||||
*/
|
||||
private boolean useNativeTypes = false;
|
||||
|
||||
private final Embedded embedded = new Embedded();
|
||||
|
||||
private ClassLoader classLoader = Neo4jProperties.class.getClassLoader();
|
||||
|
||||
public String getUri() {
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
public void setUri(String uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public AutoIndexMode getAutoIndex() {
|
||||
return this.autoIndex;
|
||||
}
|
||||
|
||||
public void setAutoIndex(AutoIndexMode autoIndex) {
|
||||
this.autoIndex = autoIndex;
|
||||
}
|
||||
|
||||
public boolean isUseNativeTypes() {
|
||||
return this.useNativeTypes;
|
||||
}
|
||||
|
||||
public void setUseNativeTypes(boolean useNativeTypes) {
|
||||
this.useNativeTypes = useNativeTypes;
|
||||
}
|
||||
|
||||
public Embedded getEmbedded() {
|
||||
return this.embedded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
|
||||
this.classLoader = ctx.getClassLoader();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link Configuration} based on the state of this instance.
|
||||
* @return a configuration
|
||||
*/
|
||||
public Configuration createConfiguration() {
|
||||
Builder builder = new Builder();
|
||||
configure(builder);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private void configure(Builder builder) {
|
||||
if (this.uri != null) {
|
||||
builder.uri(this.uri);
|
||||
}
|
||||
else {
|
||||
configureUriWithDefaults(builder);
|
||||
}
|
||||
if (this.username != null && this.password != null) {
|
||||
builder.credentials(this.username, this.password);
|
||||
}
|
||||
builder.autoIndex(getAutoIndex().getName());
|
||||
if (this.useNativeTypes) {
|
||||
builder.useNativeTypes();
|
||||
}
|
||||
}
|
||||
|
||||
private void configureUriWithDefaults(Builder builder) {
|
||||
if (!getEmbedded().isEnabled() || !ClassUtils.isPresent(EMBEDDED_DRIVER, this.classLoader)) {
|
||||
builder.uri(DEFAULT_BOLT_URI);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Embedded {
|
||||
|
||||
/**
|
||||
* Whether to enable embedded mode if the embedded driver is available.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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 reactor.core.publisher.Flux;
|
||||
|
||||
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.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;
|
||||
import org.springframework.data.neo4j.core.ReactiveNeo4jOperations;
|
||||
import org.springframework.data.neo4j.core.ReactiveNeo4jTemplate;
|
||||
import org.springframework.data.neo4j.core.mapping.Neo4jMappingContext;
|
||||
import org.springframework.data.neo4j.core.transaction.ReactiveNeo4jTransactionManager;
|
||||
import org.springframework.data.neo4j.repository.config.ReactiveNeo4jRepositoryConfigurationExtension;
|
||||
import org.springframework.transaction.ReactiveTransactionManager;
|
||||
|
||||
/**
|
||||
* Internal configuration for the reactive Neo4j client.
|
||||
*
|
||||
* @author Michael J. Simons
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ ReactiveNeo4jTransactionManager.class, ReactiveTransactionManager.class, Flux.class })
|
||||
@ConditionalOnRepositoryType(store = "neo4j", type = RepositoryType.REACTIVE)
|
||||
@AutoConfigureAfter(Neo4jAutoConfiguration.class)
|
||||
@AutoConfigureBefore(Neo4jReactiveRepositoriesConfiguration.class)
|
||||
@Import(Neo4jDefaultReactiveCallbacksRegistrar.class)
|
||||
class Neo4jReactiveDataConfiguration {
|
||||
|
||||
@Bean("reactiveDatabaseSelectionProvider")
|
||||
@ConditionalOnProperty(prefix = "spring.data.neo4j", name = "database")
|
||||
@ConditionalOnMissingBean
|
||||
@Order(-30)
|
||||
ReactiveDatabaseSelectionProvider staticDatabaseSelectionProvider(Neo4jDataProperties dataProperties) {
|
||||
return ReactiveDatabaseSelectionProvider.createStaticDatabaseSelectionProvider(dataProperties.getDatabase());
|
||||
}
|
||||
|
||||
@Bean("reactiveDatabaseSelectionProvider")
|
||||
@ConditionalOnMissingBean
|
||||
@Order(-20)
|
||||
ReactiveDatabaseSelectionProvider defaultSelectionProvider() {
|
||||
return ReactiveDatabaseSelectionProvider.getDefaultSelectionProvider();
|
||||
}
|
||||
|
||||
@Bean(ReactiveNeo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_CLIENT_BEAN_NAME)
|
||||
@ConditionalOnMissingBean
|
||||
ReactiveNeo4jClient neo4jClient(Driver driver) {
|
||||
return ReactiveNeo4jClient.create(driver);
|
||||
}
|
||||
|
||||
@Bean(ReactiveNeo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_TEMPLATE_BEAN_NAME)
|
||||
@ConditionalOnMissingBean(ReactiveNeo4jOperations.class)
|
||||
ReactiveNeo4jTemplate neo4jTemplate(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,
|
||||
ReactiveDatabaseSelectionProvider databaseNameProvider) {
|
||||
return new ReactiveNeo4jTransactionManager(driver, databaseNameProvider);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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 reactor.core.publisher.Flux;
|
||||
|
||||
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.ReactiveNeo4jRepository;
|
||||
import org.springframework.data.neo4j.repository.config.ReactiveNeo4jRepositoryConfigurationExtension;
|
||||
import org.springframework.data.neo4j.repository.support.ReactiveNeo4jRepositoryFactoryBean;
|
||||
|
||||
/**
|
||||
* Imports the registrar for reactive Neo4j repositories.
|
||||
*
|
||||
* @author Michael J. Simons
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ Flux.class, ReactiveNeo4jRepository.class })
|
||||
@ConditionalOnMissingBean({ ReactiveNeo4jRepositoryFactoryBean.class,
|
||||
ReactiveNeo4jRepositoryConfigurationExtension.class })
|
||||
@ConditionalOnRepositoryType(store = "neo4j", type = RepositoryType.REACTIVE)
|
||||
@Import(Neo4jReactiveRepositoriesConfigureRegistrar.class)
|
||||
final class Neo4jReactiveRepositoriesConfiguration {
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 java.lang.annotation.Annotation;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport;
|
||||
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
|
||||
* Repositories.
|
||||
*
|
||||
* @author Michael J. Simons
|
||||
*/
|
||||
final class Neo4jReactiveRepositoriesConfigureRegistrar extends AbstractRepositoryConfigurationSourceSupport {
|
||||
|
||||
@Override
|
||||
protected Class<? extends Annotation> getAnnotation() {
|
||||
return EnableReactiveNeo4jRepositories.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> getConfiguration() {
|
||||
return SpringDataNeo4jConfiguration.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() {
|
||||
return new ReactiveNeo4jRepositoryConfigurationExtension();
|
||||
}
|
||||
|
||||
@EnableReactiveNeo4jRepositories
|
||||
private static class SpringDataNeo4jConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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,49 @@
|
||||
/*
|
||||
* 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 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 static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Driver configuration mocked to avoid instantiation of a real driver with connection
|
||||
* creation.
|
||||
*
|
||||
* @author Michael J. Simons
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
class MockedDriverConfiguration {
|
||||
|
||||
@Bean
|
||||
Driver driver() {
|
||||
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);
|
||||
return driver;
|
||||
}
|
||||
|
||||
}
|
@ -1,191 +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 java.util.Base64;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.neo4j.ogm.config.AutoIndexMode;
|
||||
import org.neo4j.ogm.config.Configuration;
|
||||
import org.neo4j.ogm.config.Credentials;
|
||||
import org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver;
|
||||
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link Neo4jProperties}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Michael Simons
|
||||
*/
|
||||
class Neo4jPropertiesTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@AfterEach
|
||||
void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultUseEmbeddedInMemoryIfAvailable() {
|
||||
Neo4jProperties properties = load(true);
|
||||
Configuration configuration = properties.createConfiguration();
|
||||
assertDriver(configuration, Neo4jProperties.EMBEDDED_DRIVER, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultUseBoltDriverIfEmbeddedDriverIsNotAvailable() {
|
||||
Neo4jProperties properties = load(false);
|
||||
Configuration configuration = properties.createConfiguration();
|
||||
assertDriver(configuration, Neo4jProperties.BOLT_DRIVER, Neo4jProperties.DEFAULT_BOLT_URI);
|
||||
}
|
||||
|
||||
@Test
|
||||
void httpUriUseHttpDriver() {
|
||||
Neo4jProperties properties = load(true, "spring.data.neo4j.uri=http://localhost:7474");
|
||||
Configuration configuration = properties.createConfiguration();
|
||||
assertDriver(configuration, Neo4jProperties.HTTP_DRIVER, "http://localhost:7474");
|
||||
}
|
||||
|
||||
@Test
|
||||
void httpsUriUseHttpDriver() {
|
||||
Neo4jProperties properties = load(true, "spring.data.neo4j.uri=https://localhost:7474");
|
||||
Configuration configuration = properties.createConfiguration();
|
||||
assertDriver(configuration, Neo4jProperties.HTTP_DRIVER, "https://localhost:7474");
|
||||
}
|
||||
|
||||
@Test
|
||||
void boltUriUseBoltDriver() {
|
||||
Neo4jProperties properties = load(true, "spring.data.neo4j.uri=bolt://localhost:7687");
|
||||
Configuration configuration = properties.createConfiguration();
|
||||
assertDriver(configuration, Neo4jProperties.BOLT_DRIVER, "bolt://localhost:7687");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fileUriUseEmbeddedServer() {
|
||||
Neo4jProperties properties = load(true, "spring.data.neo4j.uri=file://var/tmp/graph.db");
|
||||
Configuration configuration = properties.createConfiguration();
|
||||
assertDriver(configuration, Neo4jProperties.EMBEDDED_DRIVER, "file://var/tmp/graph.db");
|
||||
}
|
||||
|
||||
@Test
|
||||
void credentialsAreSet() {
|
||||
Neo4jProperties properties = load(true, "spring.data.neo4j.uri=http://localhost:7474",
|
||||
"spring.data.neo4j.username=user", "spring.data.neo4j.password=secret");
|
||||
Configuration configuration = properties.createConfiguration();
|
||||
assertDriver(configuration, Neo4jProperties.HTTP_DRIVER, "http://localhost:7474");
|
||||
assertCredentials(configuration, "user", "secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
void credentialsAreSetFromUri() {
|
||||
Neo4jProperties properties = load(true, "spring.data.neo4j.uri=https://user:secret@my-server:7474");
|
||||
Configuration configuration = properties.createConfiguration();
|
||||
assertDriver(configuration, Neo4jProperties.HTTP_DRIVER, "https://my-server:7474");
|
||||
assertCredentials(configuration, "user", "secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoIndexNoneByDefault() {
|
||||
Neo4jProperties properties = load(true);
|
||||
Configuration configuration = properties.createConfiguration();
|
||||
assertThat(configuration.getAutoIndex()).isEqualTo(AutoIndexMode.NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoIndexCanBeConfigured() {
|
||||
Neo4jProperties properties = load(true, "spring.data.neo4j.auto-index=validate");
|
||||
Configuration configuration = properties.createConfiguration();
|
||||
assertThat(configuration.getAutoIndex()).isEqualTo(AutoIndexMode.VALIDATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void embeddedModeDisabledUseBoltUri() {
|
||||
Neo4jProperties properties = load(true, "spring.data.neo4j.embedded.enabled=false");
|
||||
Configuration configuration = properties.createConfiguration();
|
||||
assertDriver(configuration, Neo4jProperties.BOLT_DRIVER, Neo4jProperties.DEFAULT_BOLT_URI);
|
||||
}
|
||||
|
||||
@Test
|
||||
void embeddedModeWithRelativeLocation() {
|
||||
Neo4jProperties properties = load(true, "spring.data.neo4j.uri=file:relative/path/to/my.db");
|
||||
Configuration configuration = properties.createConfiguration();
|
||||
assertDriver(configuration, Neo4jProperties.EMBEDDED_DRIVER, "file:relative/path/to/my.db");
|
||||
}
|
||||
|
||||
@Test
|
||||
void nativeTypesAreSetToFalseByDefault() {
|
||||
Neo4jProperties properties = load(true);
|
||||
Configuration configuration = properties.createConfiguration();
|
||||
assertThat(configuration.getUseNativeTypes()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void nativeTypesCanBeConfigured() {
|
||||
Neo4jProperties properties = load(true, "spring.data.neo4j.use-native-types=true");
|
||||
Configuration configuration = properties.createConfiguration();
|
||||
assertThat(configuration.getUseNativeTypes()).isTrue();
|
||||
}
|
||||
|
||||
private static void assertDriver(Configuration actual, String driver, String uri) {
|
||||
assertThat(actual).isNotNull();
|
||||
assertThat(actual.getDriverClassName()).isEqualTo(driver);
|
||||
assertThat(actual.getURI()).isEqualTo(uri);
|
||||
}
|
||||
|
||||
private static void assertCredentials(Configuration actual, String username, String password) {
|
||||
Credentials<?> credentials = actual.getCredentials();
|
||||
if (username == null && password == null) {
|
||||
assertThat(credentials).isNull();
|
||||
}
|
||||
else {
|
||||
assertThat(credentials).isNotNull();
|
||||
Object content = credentials.credentials();
|
||||
assertThat(content).isInstanceOf(String.class);
|
||||
String[] auth = new String(Base64.getDecoder().decode((String) content)).split(":");
|
||||
assertThat(auth).containsExactly(username, password);
|
||||
}
|
||||
}
|
||||
|
||||
Neo4jProperties load(boolean embeddedAvailable, String... environment) {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
if (!embeddedAvailable) {
|
||||
ctx.setClassLoader(new FilteredClassLoader(EmbeddedDriver.class));
|
||||
}
|
||||
TestPropertyValues.of(environment).applyTo(ctx);
|
||||
ctx.register(TestConfiguration.class);
|
||||
ctx.refresh();
|
||||
this.context = ctx;
|
||||
return this.context.getBean(Neo4jProperties.class);
|
||||
}
|
||||
|
||||
@org.springframework.context.annotation.Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties(Neo4jProperties.class)
|
||||
static class TestConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.neo4j.country.CountryRepository;
|
||||
import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Test to ensure that the properties get read and applied during the auto-configuration.
|
||||
*
|
||||
* @author Michael J. Simons
|
||||
*/
|
||||
@SpringBootTest(properties = "spring.data.neo4j.repositories.type=imperative")
|
||||
@Testcontainers(disabledWithoutDocker = true)
|
||||
public class Neo4jRepositoriesAutoConfigurationIntegrationTests {
|
||||
|
||||
@Container
|
||||
private static 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;
|
||||
}
|
||||
|
||||
@Test
|
||||
void ensureRepositoryIsReady() {
|
||||
|
||||
assertThat(countryRepository.count()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableNeo4jRepositories(basePackageClasses = CountryRepository.class)
|
||||
@ImportAutoConfiguration({ Neo4jAutoConfiguration.class, Neo4jDataAutoConfiguration.class,
|
||||
Neo4jRepositoriesAutoConfiguration.class })
|
||||
static class TestConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* 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"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.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<City, Long> {
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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.country;
|
||||
|
||||
import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository;
|
||||
|
||||
public interface ReactiveCountryRepository extends ReactiveNeo4jRepository<Country, Long> {
|
||||
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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,100 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.data.neo4j;
|
||||
|
||||
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.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;
|
||||
|
||||
/**
|
||||
* Integration tests for the reactive SDN/RX Neo4j test slice.
|
||||
*
|
||||
* @author Michael J. Simons
|
||||
* @since 2.4.0
|
||||
*/
|
||||
@DataNeo4jTest
|
||||
@Testcontainers(disabledWithoutDocker = true)
|
||||
class ReactiveDataNeo4jIntegrationTests {
|
||||
|
||||
@Container
|
||||
static final Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:4.0").withoutAuthentication()
|
||||
.withStartupTimeout(Duration.ofMinutes(10));
|
||||
|
||||
@DynamicPropertySource
|
||||
static void neo4jProperties(DynamicPropertyRegistry registry) {
|
||||
registry.add("spring.neo4j.uri", neo4j::getBoltUrl);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private Driver driver;
|
||||
|
||||
@Autowired
|
||||
private ReactiveNeo4jTemplate neo4jTemplate;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Test
|
||||
void testTemplate() {
|
||||
|
||||
Mono.just(new ExampleGraph("Look, new @DataNeo4jTest with reactive!")).flatMap(neo4jTemplate::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);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void didNotInjectExampleService() {
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
||||
.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));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue