Merge branch 'gh-22647'
This upgrades to Spring Data 2020.0.0 snapshots which required some changes in Spring Data REST and Spring Data Elasticsearch before upgrading to Spring Data Neo4j 6. Closes gh-22299
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,7 +32,6 @@ import org.springframework.boot.actuate.web.mappings.HandlerMethodDescription;
|
||||
import org.springframework.boot.actuate.web.mappings.MappingDescriptionProvider;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.rest.webmvc.support.DelegatingHandlerMapping;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
@@ -51,6 +50,7 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMappi
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class DispatcherServletsMappingDescriptionProvider implements MappingDescriptionProvider {
|
||||
|
||||
private static final List<HandlerMappingDescriptionProvider<? extends HandlerMapping>> descriptionProviders;
|
||||
@@ -171,8 +171,8 @@ public class DispatcherServletsMappingDescriptionProvider implements MappingDesc
|
||||
|
||||
}
|
||||
|
||||
private static final class DelegatingHandlerMappingDescriptionProvider
|
||||
implements HandlerMappingDescriptionProvider<DelegatingHandlerMapping> {
|
||||
private static final class DelegatingHandlerMappingDescriptionProvider implements
|
||||
HandlerMappingDescriptionProvider<org.springframework.data.rest.webmvc.support.DelegatingHandlerMapping> {
|
||||
|
||||
private final List<HandlerMappingDescriptionProvider<?>> descriptionProviders;
|
||||
|
||||
@@ -182,12 +182,13 @@ public class DispatcherServletsMappingDescriptionProvider implements MappingDesc
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<DelegatingHandlerMapping> getMappingClass() {
|
||||
return DelegatingHandlerMapping.class;
|
||||
public Class<org.springframework.data.rest.webmvc.support.DelegatingHandlerMapping> getMappingClass() {
|
||||
return org.springframework.data.rest.webmvc.support.DelegatingHandlerMapping.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DispatcherServletMappingDescription> describe(DelegatingHandlerMapping handlerMapping) {
|
||||
public List<DispatcherServletMappingDescription> describe(
|
||||
org.springframework.data.rest.webmvc.support.DelegatingHandlerMapping handlerMapping) {
|
||||
List<DispatcherServletMappingDescription> descriptions = new ArrayList<>();
|
||||
for (HandlerMapping delegate : handlerMapping.getDelegates()) {
|
||||
descriptions.addAll(
|
||||
|
||||
@@ -171,9 +171,6 @@ dependencies {
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter")
|
||||
testImplementation("org.mockito:mockito-core")
|
||||
testImplementation("org.neo4j:neo4j-ogm-bolt-native-types")
|
||||
testImplementation("org.neo4j:neo4j-ogm-http-driver")
|
||||
testImplementation("org.neo4j:neo4j-ogm-embedded-driver")
|
||||
testImplementation("org.springframework:spring-test")
|
||||
testImplementation("org.springframework.kafka:spring-kafka-test")
|
||||
testImplementation("org.springframework.security:spring-security-test")
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,32 +16,37 @@
|
||||
|
||||
package org.springframework.boot.autoconfigure.data.neo4j;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.neo4j.ogm.session.SessionFactory;
|
||||
import org.neo4j.ogm.session.event.EventListener;
|
||||
import org.neo4j.driver.Driver;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScanPackages;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScanner;
|
||||
import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.neo4j.transaction.Neo4jTransactionManager;
|
||||
import org.springframework.data.neo4j.web.support.OpenSessionInViewInterceptor;
|
||||
import org.springframework.data.neo4j.config.Neo4jDefaultCallbacksRegistrar;
|
||||
import org.springframework.data.neo4j.core.DatabaseSelectionProvider;
|
||||
import org.springframework.data.neo4j.core.Neo4jClient;
|
||||
import org.springframework.data.neo4j.core.Neo4jOperations;
|
||||
import org.springframework.data.neo4j.core.Neo4jTemplate;
|
||||
import org.springframework.data.neo4j.core.convert.Neo4jConversions;
|
||||
import org.springframework.data.neo4j.core.mapping.Neo4jMappingContext;
|
||||
import org.springframework.data.neo4j.core.schema.Node;
|
||||
import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager;
|
||||
import org.springframework.data.neo4j.repository.config.Neo4jRepositoryConfigurationExtension;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data Neo4j.
|
||||
@@ -51,76 +56,62 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
* @author Vince Bickers
|
||||
* @author Stephane Nicoll
|
||||
* @author Kazuki Shimizu
|
||||
* @author Michael Simons
|
||||
* @author Michael J. Simons
|
||||
* @since 1.4.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ SessionFactory.class, Neo4jTransactionManager.class, PlatformTransactionManager.class })
|
||||
@EnableConfigurationProperties(Neo4jProperties.class)
|
||||
@Import(Neo4jBookmarkManagementConfiguration.class)
|
||||
@ConditionalOnClass({ Driver.class, Neo4jTransactionManager.class, PlatformTransactionManager.class })
|
||||
@EnableConfigurationProperties(Neo4jDataProperties.class)
|
||||
@ConditionalOnBean(Driver.class)
|
||||
@AutoConfigureBefore(TransactionAutoConfiguration.class)
|
||||
@AutoConfigureAfter(Neo4jAutoConfiguration.class)
|
||||
@Import(Neo4jDefaultCallbacksRegistrar.class)
|
||||
public class Neo4jDataAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public Neo4jConversions neo4jConversions() {
|
||||
return new Neo4jConversions();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public Neo4jMappingContext neo4jMappingContext(ApplicationContext applicationContext,
|
||||
Neo4jConversions neo4jConversions) throws ClassNotFoundException {
|
||||
Set<Class<?>> initialEntityClasses = new EntityScanner(applicationContext).scan(Node.class);
|
||||
Neo4jMappingContext context = new Neo4jMappingContext(neo4jConversions);
|
||||
context.setInitialEntitySet(initialEntityClasses);
|
||||
return context;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public DatabaseSelectionProvider databaseSelectionProvider(Neo4jDataProperties properties) {
|
||||
String database = properties.getDatabase();
|
||||
return (database != null) ? DatabaseSelectionProvider.createStaticDatabaseSelectionProvider(database)
|
||||
: DatabaseSelectionProvider.getDefaultSelectionProvider();
|
||||
}
|
||||
|
||||
@Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_CLIENT_BEAN_NAME)
|
||||
@ConditionalOnMissingBean
|
||||
public Neo4jClient neo4jClient(Driver driver) {
|
||||
return Neo4jClient.create(driver);
|
||||
}
|
||||
|
||||
@Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_TEMPLATE_BEAN_NAME)
|
||||
@ConditionalOnMissingBean(Neo4jOperations.class)
|
||||
public Neo4jTemplate neo4jTemplate(Neo4jClient neo4jClient, Neo4jMappingContext neo4jMappingContext,
|
||||
DatabaseSelectionProvider databaseNameProvider) {
|
||||
return new Neo4jTemplate(neo4jClient, neo4jMappingContext, databaseNameProvider);
|
||||
}
|
||||
|
||||
@Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_TRANSACTION_MANAGER_BEAN_NAME)
|
||||
@ConditionalOnMissingBean(PlatformTransactionManager.class)
|
||||
public Neo4jTransactionManager transactionManager(SessionFactory sessionFactory,
|
||||
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
|
||||
Neo4jTransactionManager transactionManager = new Neo4jTransactionManager(sessionFactory);
|
||||
transactionManagerCustomizers.ifAvailable((customizers) -> customizers.customize(transactionManager));
|
||||
public Neo4jTransactionManager transactionManager(Driver driver, DatabaseSelectionProvider databaseNameProvider,
|
||||
ObjectProvider<TransactionManagerCustomizers> optionalCustomizers) {
|
||||
Neo4jTransactionManager transactionManager = new Neo4jTransactionManager(driver, databaseNameProvider);
|
||||
optionalCustomizers.ifAvailable((customizer) -> customizer.customize(transactionManager));
|
||||
return transactionManager;
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnMissingBean(SessionFactory.class)
|
||||
static class Neo4jOgmSessionFactoryConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
org.neo4j.ogm.config.Configuration configuration(Neo4jProperties properties) {
|
||||
return properties.createConfiguration();
|
||||
}
|
||||
|
||||
@Bean
|
||||
SessionFactory sessionFactory(org.neo4j.ogm.config.Configuration configuration, BeanFactory beanFactory,
|
||||
ObjectProvider<EventListener> eventListeners) {
|
||||
SessionFactory sessionFactory = new SessionFactory(configuration, getPackagesToScan(beanFactory));
|
||||
eventListeners.orderedStream().forEach(sessionFactory::register);
|
||||
return sessionFactory;
|
||||
}
|
||||
|
||||
private String[] getPackagesToScan(BeanFactory beanFactory) {
|
||||
List<String> packages = EntityScanPackages.get(beanFactory).getPackageNames();
|
||||
if (packages.isEmpty() && AutoConfigurationPackages.has(beanFactory)) {
|
||||
packages = AutoConfigurationPackages.get(beanFactory);
|
||||
}
|
||||
return StringUtils.toStringArray(packages);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
@ConditionalOnClass({ WebMvcConfigurer.class, OpenSessionInViewInterceptor.class })
|
||||
@ConditionalOnMissingBean(OpenSessionInViewInterceptor.class)
|
||||
@ConditionalOnProperty(prefix = "spring.data.neo4j", name = "open-in-view", havingValue = "true")
|
||||
static class Neo4jWebConfiguration {
|
||||
|
||||
@Bean
|
||||
OpenSessionInViewInterceptor neo4jOpenSessionInViewInterceptor() {
|
||||
return new OpenSessionInViewInterceptor();
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebMvcConfigurer neo4jOpenSessionInViewInterceptorConfigurer(OpenSessionInViewInterceptor interceptor) {
|
||||
return new WebMvcConfigurer() {
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addWebRequestInterceptor(interceptor);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Configuration properties for Spring Data Neo4j.
|
||||
*
|
||||
* @author Michael J. Simons
|
||||
* @since 2.4.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.data.neo4j")
|
||||
public class Neo4jDataProperties {
|
||||
|
||||
/**
|
||||
* Database name to use. By default, the server decides 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,84 @@
|
||||
/*
|
||||
* 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.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
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;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's reactive Neo4j
|
||||
* support.
|
||||
*
|
||||
* @author Michael J. Simons
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.4.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ Driver.class, ReactiveNeo4jTransactionManager.class, ReactiveTransactionManager.class,
|
||||
Flux.class })
|
||||
@ConditionalOnBean(Driver.class)
|
||||
@AutoConfigureAfter(Neo4jDataAutoConfiguration.class)
|
||||
@Import(Neo4jDefaultReactiveCallbacksRegistrar.class)
|
||||
public class Neo4jReactiveDataAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ReactiveDatabaseSelectionProvider reactiveDatabaseSelectionProvider(Neo4jDataProperties dataProperties) {
|
||||
String database = dataProperties.getDatabase();
|
||||
return (database != null) ? ReactiveDatabaseSelectionProvider.createStaticDatabaseSelectionProvider(database)
|
||||
: ReactiveDatabaseSelectionProvider.getDefaultSelectionProvider();
|
||||
}
|
||||
|
||||
@Bean(ReactiveNeo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_CLIENT_BEAN_NAME)
|
||||
@ConditionalOnMissingBean
|
||||
public ReactiveNeo4jClient reactiveNeo4jClient(Driver driver) {
|
||||
return ReactiveNeo4jClient.create(driver);
|
||||
}
|
||||
|
||||
@Bean(ReactiveNeo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_TEMPLATE_BEAN_NAME)
|
||||
@ConditionalOnMissingBean(ReactiveNeo4jOperations.class)
|
||||
public ReactiveNeo4jTemplate reactiveNeo4jTemplate(ReactiveNeo4jClient neo4jClient,
|
||||
Neo4jMappingContext neo4jMappingContext, ReactiveDatabaseSelectionProvider databaseNameProvider) {
|
||||
return new ReactiveNeo4jTemplate(neo4jClient, neo4jMappingContext, databaseNameProvider);
|
||||
}
|
||||
|
||||
@Bean(ReactiveNeo4jRepositoryConfigurationExtension.DEFAULT_TRANSACTION_MANAGER_BEAN_NAME)
|
||||
@ConditionalOnMissingBean(ReactiveTransactionManager.class)
|
||||
public ReactiveTransactionManager reactiveTransactionManager(Driver driver,
|
||||
ReactiveDatabaseSelectionProvider databaseNameProvider) {
|
||||
return new ReactiveNeo4jTransactionManager(driver, databaseNameProvider);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.data.ConditionalOnRepositoryType;
|
||||
import org.springframework.boot.autoconfigure.data.RepositoryType;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository;
|
||||
import org.springframework.data.neo4j.repository.config.ReactiveNeo4jRepositoryConfigurationExtension;
|
||||
import org.springframework.data.neo4j.repository.support.ReactiveNeo4jRepositoryFactoryBean;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Neo4j Reactive
|
||||
* Repositories.
|
||||
*
|
||||
* @author Michael J. Simons
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.4.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ Driver.class, ReactiveNeo4jRepository.class, Flux.class })
|
||||
@ConditionalOnMissingBean({ ReactiveNeo4jRepositoryFactoryBean.class,
|
||||
ReactiveNeo4jRepositoryConfigurationExtension.class })
|
||||
@ConditionalOnRepositoryType(store = "neo4j", type = RepositoryType.REACTIVE)
|
||||
@Import(Neo4jReactiveRepositoriesRegistrar.class)
|
||||
@AutoConfigureAfter(Neo4jReactiveDataAutoConfiguration.class)
|
||||
public class Neo4jReactiveRepositoriesAutoConfiguration {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.data.neo4j.repository.config.EnableReactiveNeo4jRepositories;
|
||||
import org.springframework.data.neo4j.repository.config.ReactiveNeo4jRepositoryConfigurationExtension;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
|
||||
|
||||
/**
|
||||
* {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data Neo4j reactive
|
||||
* Repositories.
|
||||
*
|
||||
* @author Michael J. Simons
|
||||
*/
|
||||
class Neo4jReactiveRepositoriesRegistrar extends AbstractRepositoryConfigurationSourceSupport {
|
||||
|
||||
@Override
|
||||
protected Class<? extends Annotation> getAnnotation() {
|
||||
return EnableReactiveNeo4jRepositories.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> getConfiguration() {
|
||||
return EnableReactiveNeo4jRepositoriesConfiguration.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() {
|
||||
return new ReactiveNeo4jRepositoryConfigurationExtension();
|
||||
}
|
||||
|
||||
@EnableReactiveNeo4jRepositories
|
||||
private static class EnableReactiveNeo4jRepositoriesConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,13 +16,14 @@
|
||||
|
||||
package org.springframework.boot.autoconfigure.data.neo4j;
|
||||
|
||||
import org.neo4j.ogm.session.Neo4jSession;
|
||||
import org.neo4j.driver.Driver;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
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;
|
||||
@@ -34,10 +35,10 @@ import org.springframework.data.neo4j.repository.support.Neo4jRepositoryFactoryB
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Neo4j
|
||||
* Repositories.
|
||||
* <p>
|
||||
* Activates when there is no bean of type {@link Neo4jRepositoryFactoryBean} configured
|
||||
* in the context, the Spring Data Neo4j {@link Neo4jRepository} type is on the classpath,
|
||||
* the Neo4j client driver API is on the classpath, and there is no other configured
|
||||
* {@link Neo4jRepository}.
|
||||
* Activates when there is no bean of type {@link Neo4jRepositoryFactoryBean} or
|
||||
* {@link Neo4jRepositoryConfigurationExtension} configured in the context, the Spring
|
||||
* Data Neo4j {@link Neo4jRepository} type is on the classpath, the Neo4j client driver
|
||||
* API is on the classpath, and there is no other configured {@link Neo4jRepository}.
|
||||
* <p>
|
||||
* Once in effect, the auto-configuration is the equivalent of enabling Neo4j repositories
|
||||
* using the {@link EnableNeo4jRepositories @EnableNeo4jRepositories} annotation.
|
||||
@@ -45,14 +46,14 @@ import org.springframework.data.neo4j.repository.support.Neo4jRepositoryFactoryB
|
||||
* @author Dave Syer
|
||||
* @author Oliver Gierke
|
||||
* @author Josh Long
|
||||
* @author Michael J. Simons
|
||||
* @since 1.4.0
|
||||
* @see EnableNeo4jRepositories
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ Neo4jSession.class, Neo4jRepository.class })
|
||||
@ConditionalOnClass({ Driver.class, Neo4jRepository.class })
|
||||
@ConditionalOnMissingBean({ Neo4jRepositoryFactoryBean.class, Neo4jRepositoryConfigurationExtension.class })
|
||||
@ConditionalOnProperty(prefix = "spring.data.neo4j.repositories", name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
@ConditionalOnRepositoryType(store = "neo4j", type = RepositoryType.IMPERATIVE)
|
||||
@Import(Neo4jRepositoriesRegistrar.class)
|
||||
@AutoConfigureAfter(Neo4jDataAutoConfiguration.class)
|
||||
public class Neo4jRepositoriesAutoConfiguration {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,6 +23,7 @@ import org.springframework.core.annotation.Order;
|
||||
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
|
||||
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer;
|
||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
|
||||
/**
|
||||
* A {@code RepositoryRestConfigurer} that applies configuration items from the
|
||||
@@ -43,7 +44,13 @@ class SpringBootRepositoryRestConfigurer implements RepositoryRestConfigurer {
|
||||
private RepositoryRestProperties properties;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
|
||||
configureRepositoryRestConfiguration(config, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
|
||||
this.properties.applyTo(config);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,12 +34,11 @@ import org.springframework.core.annotation.AliasFor;
|
||||
* <li>Set the
|
||||
* {@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#setPackagesToScan(String...)
|
||||
* packages scanned} for JPA entities.</li>
|
||||
* <li>Set the packages used with Neo4J's {@link org.neo4j.ogm.session.SessionFactory
|
||||
* SessionFactory}.</li>
|
||||
* <li>Set the
|
||||
* {@link org.springframework.data.mapping.context.AbstractMappingContext#setInitialEntitySet(java.util.Set)
|
||||
* initial entity set} used with Spring Data
|
||||
* {@link org.springframework.data.mongodb.core.mapping.MongoMappingContext MongoDB},
|
||||
* {@link org.springframework.data.neo4j.core.mapping.Neo4jMappingContext Neo4j},
|
||||
* {@link org.springframework.data.cassandra.core.mapping.CassandraMappingContext
|
||||
* Cassandra} and
|
||||
* {@link org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext
|
||||
|
||||
@@ -651,19 +651,81 @@
|
||||
},
|
||||
{
|
||||
"name": "spring.data.neo4j.auto-index",
|
||||
"defaultValue": "none"
|
||||
"description": "Auto index mode.",
|
||||
"defaultValue": "none",
|
||||
"deprecation": {
|
||||
"reason": "Automatic index creation is no longer supported.",
|
||||
"level": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.data.neo4j.embedded.enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "Whether to enable embedded mode if the embedded driver is available.",
|
||||
"deprecation": {
|
||||
"reason": "Embedded mode is no longer supported, please use Testcontainers instead.",
|
||||
"level": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.data.neo4j.open-in-view",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "Register OpenSessionInViewInterceptor that binds a Neo4j Session to the thread for the entire processing of the request.",
|
||||
"defaultValue": false
|
||||
"deprecation": {
|
||||
"level": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.data.neo4j.password",
|
||||
"type": "java.lang.String",
|
||||
"description": "Login password of the server.",
|
||||
"deprecation": {
|
||||
"replacement": "spring.neo4j.authentication.password",
|
||||
"level": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.data.neo4j.repositories.enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "Whether to enable Neo4j repositories.",
|
||||
"defaultValue": true
|
||||
"defaultValue": true,
|
||||
"deprecation": {
|
||||
"replacement": "spring.data.neo4j.repositories.type",
|
||||
"level": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.data.neo4j.repositories.type",
|
||||
"type": "org.springframework.boot.autoconfigure.data.RepositoryType",
|
||||
"description": "Type of Neo4j repositories to enable.",
|
||||
"defaultValue": "auto"
|
||||
},
|
||||
{
|
||||
"name": "spring.data.neo4j.uri",
|
||||
"type": "java.lang.String",
|
||||
"description": "URI used by the driver. Auto-detected by default.",
|
||||
"deprecation": {
|
||||
"replacement": "spring.neo4j.uri",
|
||||
"level": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.data.neo4j.use-native-types",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "Whether to use Neo4j native types wherever possible.",
|
||||
"deprecation": {
|
||||
"reason": "Native type support is now built-in.",
|
||||
"level": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.data.neo4j.username",
|
||||
"type": "java.lang.String",
|
||||
"description": "Login user of the server.",
|
||||
"deprecation": {
|
||||
"replacement": "spring.neo4j.authentication.password",
|
||||
"level": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.data.r2dbc.repositories.enabled",
|
||||
|
||||
@@ -51,6 +51,8 @@ org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfigura
|
||||
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveDataAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,7 +19,10 @@ package org.springframework.boot.autoconfigure.data.neo4j;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver;
|
||||
import org.neo4j.driver.Config;
|
||||
import org.neo4j.driver.Driver;
|
||||
import org.neo4j.driver.GraphDatabase;
|
||||
import org.neo4j.driver.internal.logging.Slf4jLogging;
|
||||
|
||||
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
|
||||
import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration;
|
||||
@@ -31,11 +34,12 @@ import org.springframework.boot.autoconfigure.data.neo4j.empty.EmptyMarker;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.data.neo4j.config.AbstractNeo4jConfig;
|
||||
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -48,6 +52,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Michael Hunger
|
||||
* @author Vince Bickers
|
||||
* @author Stephane Nicoll
|
||||
* @author Michael J. Simons
|
||||
*/
|
||||
class MixedNeo4jRepositoriesAutoConfigurationTests {
|
||||
|
||||
@@ -94,12 +99,12 @@ class MixedNeo4jRepositoriesAutoConfigurationTests {
|
||||
|
||||
private void load(Class<?> config, String... environment) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.setClassLoader(new FilteredClassLoader(EmbeddedDriver.class));
|
||||
TestPropertyValues.of(environment).and("spring.datasource.initialization-mode=never").applyTo(context);
|
||||
context.register(config);
|
||||
context.register(DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
|
||||
JpaRepositoriesAutoConfiguration.class, Neo4jDataAutoConfiguration.class,
|
||||
Neo4jRepositoriesAutoConfiguration.class);
|
||||
Neo4jReactiveDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class,
|
||||
Neo4jReactiveRepositoriesAutoConfiguration.class);
|
||||
context.refresh();
|
||||
this.context = context;
|
||||
}
|
||||
@@ -108,7 +113,14 @@ class MixedNeo4jRepositoriesAutoConfigurationTests {
|
||||
@TestAutoConfigurationPackage(EmptyMarker.class)
|
||||
// Not this package or its parent
|
||||
@EnableNeo4jRepositories(basePackageClasses = Country.class)
|
||||
static class TestConfiguration {
|
||||
static class TestConfiguration extends AbstractNeo4jConfig {
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public Driver driver() {
|
||||
return GraphDatabase.driver("bolt://neo4j.test:7687",
|
||||
Config.builder().withLogging(new Slf4jLogging()).build());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -117,7 +129,14 @@ class MixedNeo4jRepositoriesAutoConfigurationTests {
|
||||
@EnableNeo4jRepositories(basePackageClasses = Country.class)
|
||||
@EntityScan(basePackageClasses = City.class)
|
||||
@EnableJpaRepositories(basePackageClasses = CityRepository.class)
|
||||
static class MixedConfiguration {
|
||||
static class MixedConfiguration extends AbstractNeo4jConfig {
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public Driver driver() {
|
||||
return GraphDatabase.driver("bolt://neo4j.test:7687",
|
||||
Config.builder().withLogging(new Slf4jLogging()).build());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.mockito.Mockito;
|
||||
import org.neo4j.driver.Driver;
|
||||
import org.neo4j.driver.Session;
|
||||
import org.neo4j.driver.SessionConfig;
|
||||
import org.neo4j.driver.types.TypeSystem;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
given(driver.defaultTypeSystem()).willReturn(typeSystem);
|
||||
given(driver.session(Mockito.any(SessionConfig.class))).willReturn(session);
|
||||
return driver;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,257 +16,124 @@
|
||||
|
||||
package org.springframework.boot.autoconfigure.data.neo4j;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.neo4j.ogm.driver.NativeTypesNotAvailableException;
|
||||
import org.neo4j.ogm.driver.NativeTypesNotSupportedException;
|
||||
import org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver;
|
||||
import org.neo4j.ogm.session.Session;
|
||||
import org.neo4j.ogm.session.SessionFactory;
|
||||
import org.neo4j.ogm.session.event.Event;
|
||||
import org.neo4j.ogm.session.event.EventListener;
|
||||
import org.neo4j.ogm.session.event.PersistenceEvent;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.data.neo4j.city.City;
|
||||
import org.springframework.boot.autoconfigure.data.neo4j.country.Country;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.neo4j.annotation.EnableBookmarkManagement;
|
||||
import org.springframework.data.neo4j.bookmark.BookmarkManager;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jMappingContext;
|
||||
import org.springframework.data.neo4j.transaction.Neo4jTransactionManager;
|
||||
import org.springframework.data.neo4j.web.support.OpenSessionInViewInterceptor;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.data.neo4j.core.DatabaseSelection;
|
||||
import org.springframework.data.neo4j.core.DatabaseSelectionProvider;
|
||||
import org.springframework.data.neo4j.core.Neo4jClient;
|
||||
import org.springframework.data.neo4j.core.Neo4jOperations;
|
||||
import org.springframework.data.neo4j.core.Neo4jTemplate;
|
||||
import org.springframework.data.neo4j.core.convert.Neo4jConversions;
|
||||
import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link Neo4jDataAutoConfiguration}. Tests should not use the embedded driver
|
||||
* as it requires the complete Neo4j-Kernel and server to function properly.
|
||||
* Tests for {@link Neo4jDataAutoConfiguration}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Michael Hunger
|
||||
* @author Vince Bickers
|
||||
* @author Andy Wilkinson
|
||||
* @author Kazuki Shimizu
|
||||
* @author Michael Simons
|
||||
* @author Michael J. Simons
|
||||
*/
|
||||
class Neo4jDataAutoConfigurationTests {
|
||||
|
||||
private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
|
||||
.withClassLoader(new FilteredClassLoader(EmbeddedDriver.class))
|
||||
.withUserConfiguration(TestConfiguration.class).withConfiguration(
|
||||
AutoConfigurations.of(Neo4jDataAutoConfiguration.class, TransactionAutoConfiguration.class));
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(MockedDriverConfiguration.class)
|
||||
.withConfiguration(AutoConfigurations.of(Neo4jAutoConfiguration.class, Neo4jDataAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void defaultConfiguration() {
|
||||
this.contextRunner.withPropertyValues("spring.data.neo4j.uri=http://localhost:8989").run((context) -> {
|
||||
assertThat(context).hasSingleBean(org.neo4j.ogm.config.Configuration.class);
|
||||
assertThat(context).hasSingleBean(SessionFactory.class);
|
||||
void shouldProvideConversions() {
|
||||
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(Neo4jConversions.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldProvideDefaultDatabaseNameProvider() {
|
||||
this.contextRunner.run((context) -> {
|
||||
assertThat(context).hasSingleBean(DatabaseSelectionProvider.class);
|
||||
assertThat(context.getBean(DatabaseSelectionProvider.class))
|
||||
.isSameAs(DatabaseSelectionProvider.getDefaultSelectionProvider());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldUseDatabaseNameIfSet() {
|
||||
this.contextRunner.withPropertyValues("spring.data.neo4j.database=test").run((context) -> {
|
||||
assertThat(context).hasSingleBean(DatabaseSelectionProvider.class);
|
||||
assertThat(context.getBean(DatabaseSelectionProvider.class).getDatabaseSelection())
|
||||
.isEqualTo(DatabaseSelection.byName("test"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReuseExistingDatabaseNameProvider() {
|
||||
this.contextRunner.withPropertyValues("spring.data.neo4j.database=ignored")
|
||||
.withUserConfiguration(CustomDatabaseSelectionProviderConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(DatabaseSelectionProvider.class);
|
||||
assertThat(context.getBean(DatabaseSelectionProvider.class).getDatabaseSelection())
|
||||
.isEqualTo(DatabaseSelection.byName("custom"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldProvideNeo4jClient() {
|
||||
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(Neo4jClient.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReuseExistingNeo4jClient() {
|
||||
this.contextRunner.withBean("myCustomClient", Neo4jClient.class, () -> mock(Neo4jClient.class))
|
||||
.run((context) -> assertThat(context).hasSingleBean(Neo4jClient.class).hasBean("myCustomClient"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldProvideNeo4jTemplate() {
|
||||
this.contextRunner.withUserConfiguration(CustomDatabaseSelectionProviderConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(Neo4jTemplate.class);
|
||||
assertThat(context.getBean(Neo4jTemplate.class)).extracting("databaseSelectionProvider")
|
||||
.isSameAs(context.getBean(DatabaseSelectionProvider.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReuseExistingNeo4jTemplate() {
|
||||
this.contextRunner.withBean("myCustomOperations", Neo4jOperations.class, () -> mock(Neo4jOperations.class)).run(
|
||||
(context) -> assertThat(context).hasSingleBean(Neo4jOperations.class).hasBean("myCustomOperations"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldProvideTransactionManager() {
|
||||
this.contextRunner.withUserConfiguration(CustomDatabaseSelectionProviderConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(Neo4jTransactionManager.class);
|
||||
assertThat(context).doesNotHaveBean(OpenSessionInViewInterceptor.class);
|
||||
assertThat(context).doesNotHaveBean(BookmarkManager.class);
|
||||
assertThat(context.getBean(Neo4jTransactionManager.class)).extracting("databaseSelectionProvider")
|
||||
.isSameAs(context.getBean(DatabaseSelectionProvider.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void customNeo4jTransactionManagerUsingProperties() {
|
||||
this.contextRunner.withPropertyValues("spring.transaction.default-timeout=30",
|
||||
"spring.transaction.rollback-on-commit-failure:true").run((context) -> {
|
||||
Neo4jTransactionManager transactionManager = context.getBean(Neo4jTransactionManager.class);
|
||||
assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30);
|
||||
assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void customSessionFactory() {
|
||||
this.contextRunner.withUserConfiguration(CustomSessionFactory.class).run((context) -> {
|
||||
assertThat(context).doesNotHaveBean(org.neo4j.ogm.config.Configuration.class);
|
||||
assertThat(context).hasSingleBean(SessionFactory.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void customSessionFactoryShouldNotDisableOtherDefaults() {
|
||||
this.contextRunner.withUserConfiguration(CustomSessionFactory.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(SessionFactory.class);
|
||||
assertThat(context.getBean(SessionFactory.class)).isSameAs(context.getBean("customSessionFactory"));
|
||||
assertThat(context).hasSingleBean(Neo4jTransactionManager.class);
|
||||
assertThat(context).doesNotHaveBean(OpenSessionInViewInterceptor.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void customConfiguration() {
|
||||
this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> {
|
||||
assertThat(context.getBean(org.neo4j.ogm.config.Configuration.class))
|
||||
.isSameAs(context.getBean("myConfiguration"));
|
||||
assertThat(context).hasSingleBean(SessionFactory.class);
|
||||
assertThat(context).hasSingleBean(org.neo4j.ogm.config.Configuration.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void usesAutoConfigurationPackageToPickUpDomainTypes() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.setClassLoader(new FilteredClassLoader(EmbeddedDriver.class));
|
||||
String cityPackage = City.class.getPackage().getName();
|
||||
AutoConfigurationPackages.register(context, cityPackage);
|
||||
context.register(Neo4jDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class);
|
||||
try {
|
||||
context.refresh();
|
||||
assertDomainTypesDiscovered(context.getBean(Neo4jMappingContext.class), City.class);
|
||||
}
|
||||
finally {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void openSessionInViewInterceptorCanBeEnabled() {
|
||||
this.contextRunner.withPropertyValues("spring.data.neo4j.open-in-view:true")
|
||||
.run((context) -> assertThat(context).hasSingleBean(OpenSessionInViewInterceptor.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBeAbleToUseNativeTypesWithBolt() {
|
||||
void shouldReuseExistingTransactionManager() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.data.neo4j.uri=bolt://localhost:7687",
|
||||
"spring.data.neo4j.use-native-types:true")
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(Neo4jDataAutoConfiguration.class, TransactionAutoConfiguration.class))
|
||||
.run((context) -> assertThat(context).getBean(org.neo4j.ogm.config.Configuration.class)
|
||||
.hasFieldOrPropertyWithValue("useNativeTypes", true));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFailWhenNativeTypesAreNotAvailable() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("org.neo4j.ogm.drivers.bolt.types"))
|
||||
.withPropertyValues("spring.data.neo4j.uri=bolt://localhost:7687",
|
||||
"spring.data.neo4j.use-native-types:true")
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(Neo4jDataAutoConfiguration.class, TransactionAutoConfiguration.class))
|
||||
.run((context) -> {
|
||||
assertThat(context).hasFailed();
|
||||
assertThat(context.getStartupFailure())
|
||||
.hasRootCauseInstanceOf(NativeTypesNotAvailableException.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFailWhenNativeTypesAreNotSupported() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.data.neo4j.uri=http://localhost:7474",
|
||||
"spring.data.neo4j.use-native-types:true")
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(Neo4jDataAutoConfiguration.class, TransactionAutoConfiguration.class))
|
||||
.run((context) -> {
|
||||
assertThat(context).hasFailed();
|
||||
assertThat(context.getStartupFailure())
|
||||
.hasRootCauseInstanceOf(NativeTypesNotSupportedException.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void eventListenersAreAutoRegistered() {
|
||||
this.contextRunner.withUserConfiguration(EventListenerConfiguration.class).run((context) -> {
|
||||
Session session = context.getBean(SessionFactory.class).openSession();
|
||||
session.notifyListeners(new PersistenceEvent(null, Event.TYPE.PRE_SAVE));
|
||||
verify(context.getBean("eventListenerOne", EventListener.class)).onPreSave(any(Event.class));
|
||||
verify(context.getBean("eventListenerTwo", EventListener.class)).onPreSave(any(Event.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void providesARequestScopedBookmarkManagerIfNecessaryAndPossible() {
|
||||
this.contextRunner.withUserConfiguration(BookmarkManagementEnabledConfiguration.class).run((context) -> {
|
||||
BeanDefinition bookmarkManagerBean = context.getBeanFactory()
|
||||
.getBeanDefinition("scopedTarget.bookmarkManager");
|
||||
assertThat(bookmarkManagerBean.getScope()).isEqualTo(WebApplicationContext.SCOPE_REQUEST);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void providesASingletonScopedBookmarkManagerIfNecessaryAndPossible() {
|
||||
new ApplicationContextRunner().withClassLoader(new FilteredClassLoader(EmbeddedDriver.class))
|
||||
.withUserConfiguration(TestConfiguration.class, BookmarkManagementEnabledConfiguration.class)
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(Neo4jDataAutoConfiguration.class, TransactionAutoConfiguration.class))
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(BookmarkManager.class);
|
||||
assertThat(context.getBeanDefinitionNames()).doesNotContain("scopedTarget.bookmarkManager");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void doesNotProvideABookmarkManagerIfNotPossible() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader(Caffeine.class, EmbeddedDriver.class))
|
||||
.withUserConfiguration(BookmarkManagementEnabledConfiguration.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(BookmarkManager.class));
|
||||
}
|
||||
|
||||
private static void assertDomainTypesDiscovered(Neo4jMappingContext mappingContext, Class<?>... types) {
|
||||
for (Class<?> type : types) {
|
||||
assertThat(mappingContext.getPersistentEntity(type)).isNotNull();
|
||||
}
|
||||
.withBean("myCustomTransactionManager", PlatformTransactionManager.class,
|
||||
() -> mock(PlatformTransactionManager.class))
|
||||
.run((context) -> assertThat(context).hasSingleBean(PlatformTransactionManager.class)
|
||||
.hasBean("myCustomTransactionManager"));
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EntityScan(basePackageClasses = Country.class)
|
||||
static class TestConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomSessionFactory {
|
||||
static class CustomDatabaseSelectionProviderConfiguration {
|
||||
|
||||
@Bean
|
||||
SessionFactory customSessionFactory() {
|
||||
return mock(SessionFactory.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomConfiguration {
|
||||
|
||||
@Bean
|
||||
org.neo4j.ogm.config.Configuration myConfiguration() {
|
||||
return new org.neo4j.ogm.config.Configuration.Builder().uri("http://localhost:12345").build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableBookmarkManagement
|
||||
static class BookmarkManagementEnabledConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class EventListenerConfiguration {
|
||||
|
||||
@Bean
|
||||
EventListener eventListenerOne() {
|
||||
return mock(EventListener.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
EventListener eventListenerTwo() {
|
||||
return mock(EventListener.class);
|
||||
DatabaseSelectionProvider databaseSelectionProvider() {
|
||||
return () -> DatabaseSelection.byName("custom");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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,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 {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.testcontainers.containers.Neo4jContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.neo4j.country.CountryRepository;
|
||||
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 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
|
||||
@Testcontainers(disabledWithoutDocker = true)
|
||||
public class Neo4jRepositoriesAutoConfigurationIntegrationTests {
|
||||
|
||||
@Container
|
||||
private static final Neo4jContainer<?> neo4jServer = new Neo4jContainer<>("neo4j:4.0");
|
||||
|
||||
@DynamicPropertySource
|
||||
static void neo4jProperties(DynamicPropertyRegistry registry) {
|
||||
registry.add("spring.neo4j.uri", neo4jServer::getBoltUrl);
|
||||
registry.add("spring.neo4j.authentication.username", () -> "neo4j");
|
||||
registry.add("spring.neo4j.authentication.password", neo4jServer::getAdminPassword);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private CountryRepository countryRepository;
|
||||
|
||||
@Test
|
||||
void ensureRepositoryIsReady() {
|
||||
assertThat(this.countryRepository.count()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableNeo4jRepositories(basePackageClasses = CountryRepository.class)
|
||||
@ImportAutoConfiguration({ Neo4jAutoConfiguration.class, Neo4jDataAutoConfiguration.class,
|
||||
Neo4jRepositoriesAutoConfiguration.class })
|
||||
static class TestConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,25 +16,26 @@
|
||||
|
||||
package org.springframework.boot.autoconfigure.data.neo4j;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.neo4j.ogm.session.SessionFactory;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.alt.neo4j.CityNeo4jRepository;
|
||||
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.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
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.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jMappingContext;
|
||||
import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager;
|
||||
import org.springframework.data.neo4j.repository.Neo4jRepository;
|
||||
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
|
||||
import org.springframework.data.neo4j.repository.support.ReactiveNeo4jRepositoryFactoryBean;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Tests for {@link Neo4jRepositoriesAutoConfiguration}.
|
||||
@@ -44,50 +45,62 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
* @author Michael Hunger
|
||||
* @author Vince Bickers
|
||||
* @author Stephane Nicoll
|
||||
* @author Michael J. Simons
|
||||
*/
|
||||
class Neo4jRepositoriesAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(MockedDriverConfiguration.class).withConfiguration(
|
||||
AutoConfigurations.of(Neo4jDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class));
|
||||
|
||||
@AfterEach
|
||||
void close() {
|
||||
this.context.close();
|
||||
@Test
|
||||
void configurationWithDefaultRepositories() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(CityRepository.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultRepositoryConfiguration() {
|
||||
prepareApplicationContext(TestConfiguration.class);
|
||||
assertThat(this.context.getBean(CityRepository.class)).isNotNull();
|
||||
Neo4jMappingContext mappingContext = this.context.getBean(Neo4jMappingContext.class);
|
||||
assertThat(mappingContext.getPersistentEntity(City.class)).isNotNull();
|
||||
void configurationWithNoRepositories() {
|
||||
this.contextRunner.withUserConfiguration(EmptyConfiguration.class).run((context) -> assertThat(context)
|
||||
.hasSingleBean(Neo4jTransactionManager.class).doesNotHaveBean(Neo4jRepository.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNoRepositoryConfiguration() {
|
||||
prepareApplicationContext(EmptyConfiguration.class);
|
||||
assertThat(this.context.getBean(SessionFactory.class)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void doesNotTriggerDefaultRepositoryDetectionIfCustomized() {
|
||||
prepareApplicationContext(CustomizedConfiguration.class);
|
||||
assertThat(this.context.getBean(CityNeo4jRepository.class)).isNotNull();
|
||||
void configurationWithDisabledRepositories() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.data.neo4j.repositories.type=none")
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(Neo4jRepository.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoConfigurationShouldNotKickInEvenIfManualConfigDidNotCreateAnyRepositories() {
|
||||
prepareApplicationContext(SortOfInvalidCustomConfiguration.class);
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
||||
.isThrownBy(() -> this.context.getBean(CityRepository.class));
|
||||
this.contextRunner.withUserConfiguration(SortOfInvalidCustomConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(Neo4jTransactionManager.class)
|
||||
.doesNotHaveBean(Neo4jRepository.class));
|
||||
}
|
||||
|
||||
private void prepareApplicationContext(Class<?>... configurationClasses) {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
TestPropertyValues.of("spring.data.neo4j.uri=http://localhost:9797").applyTo(this.context);
|
||||
this.context.register(configurationClasses);
|
||||
this.context.register(Neo4jDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
@Test
|
||||
void shouldRespectAtEnableNeo4jRepositories() {
|
||||
this.contextRunner.withUserConfiguration(SortOfInvalidCustomConfiguration.class, WithCustomRepositoryScan.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(CityRepository.class)
|
||||
.doesNotHaveBean(ReactiveCityRepository.class).hasSingleBean(CountryRepository.class)
|
||||
.doesNotHaveBean(ReactiveCountryRepository.class));
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableNeo4jRepositories(basePackageClasses = CountryRepository.class)
|
||||
static class WithCustomRepositoryScan {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class WithFakeEnabledReactiveNeo4jRepositories {
|
||||
|
||||
@Bean
|
||||
ReactiveNeo4jRepositoryFactoryBean<?, ?, ?> reactiveNeo4jRepositoryFactoryBean() {
|
||||
return Mockito.mock(ReactiveNeo4jRepositoryFactoryBean.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@@ -103,14 +116,6 @@ class Neo4jRepositoriesAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@TestAutoConfigurationPackage(Neo4jRepositoriesAutoConfigurationTests.class)
|
||||
@EnableNeo4jRepositories(basePackageClasses = CityNeo4jRepository.class)
|
||||
static class CustomizedConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
// To not find any repositories
|
||||
@EnableNeo4jRepositories("foo.bar")
|
||||
@TestAutoConfigurationPackage(Neo4jRepositoriesAutoConfigurationTests.class)
|
||||
static class SortOfInvalidCustomConfiguration {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,13 +18,12 @@ package org.springframework.boot.autoconfigure.data.neo4j.city;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.neo4j.ogm.annotation.GeneratedValue;
|
||||
import org.neo4j.ogm.annotation.Id;
|
||||
import org.neo4j.ogm.annotation.NodeEntity;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.neo4j.country.Country;
|
||||
import org.springframework.data.neo4j.core.schema.GeneratedValue;
|
||||
import org.springframework.data.neo4j.core.schema.Id;
|
||||
import org.springframework.data.neo4j.core.schema.Node;
|
||||
|
||||
@NodeEntity
|
||||
@Node
|
||||
public class City implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@@ -41,9 +40,6 @@ public class City implements Serializable {
|
||||
|
||||
private String map;
|
||||
|
||||
public City() {
|
||||
}
|
||||
|
||||
public City(String name, Country country) {
|
||||
this.name = name;
|
||||
this.country = country;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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.city;
|
||||
|
||||
import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository;
|
||||
|
||||
public interface ReactiveCityRepository extends ReactiveNeo4jRepository<City, Long> {
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,11 +18,11 @@ package org.springframework.boot.autoconfigure.data.neo4j.country;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.neo4j.ogm.annotation.GeneratedValue;
|
||||
import org.neo4j.ogm.annotation.Id;
|
||||
import org.neo4j.ogm.annotation.NodeEntity;
|
||||
import org.springframework.data.neo4j.core.schema.GeneratedValue;
|
||||
import org.springframework.data.neo4j.core.schema.Id;
|
||||
import org.springframework.data.neo4j.core.schema.Node;
|
||||
|
||||
@NodeEntity
|
||||
@Node
|
||||
public class Country implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@@ -33,9 +33,6 @@ public class Country implements Serializable {
|
||||
|
||||
private String name;
|
||||
|
||||
public Country() {
|
||||
}
|
||||
|
||||
public Country(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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.country;
|
||||
|
||||
import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository;
|
||||
|
||||
public interface ReactiveCountryRepository extends ReactiveNeo4jRepository<Country, Long> {
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -42,6 +42,7 @@ import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguratio
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -76,7 +77,7 @@ class RepositoryRestMvcAutoConfigurationTests {
|
||||
assertThat(this.context.getBean(RepositoryRestMvcConfiguration.class)).isNotNull();
|
||||
RepositoryRestConfiguration bean = this.context.getBean(RepositoryRestConfiguration.class);
|
||||
URI expectedUri = URI.create("/foo");
|
||||
assertThat(bean.getBaseUri()).as("Custom basePath not set").isEqualTo(expectedUri);
|
||||
assertThat(bean.getBasePath()).as("Custom basePath not set").isEqualTo(expectedUri);
|
||||
BaseUri baseUri = this.context.getBean(BaseUri.class);
|
||||
assertThat(expectedUri).as("Custom basePath has not been applied to BaseUri bean").isEqualTo(baseUri.getUri());
|
||||
}
|
||||
@@ -119,7 +120,7 @@ class RepositoryRestMvcAutoConfigurationTests {
|
||||
load(TestConfigurationWithRestMvcConfig.class, "spring.data.rest.base-path:foo");
|
||||
assertThat(this.context.getBean(RepositoryRestMvcConfiguration.class)).isNotNull();
|
||||
RepositoryRestConfiguration bean = this.context.getBean(RepositoryRestConfiguration.class);
|
||||
assertThat(bean.getBaseUri()).isEqualTo(URI.create(""));
|
||||
assertThat(bean.getBasePath()).isEqualTo(URI.create(""));
|
||||
}
|
||||
|
||||
private void load(Class<?> config, String... environment) {
|
||||
@@ -174,7 +175,7 @@ class RepositoryRestMvcAutoConfigurationTests {
|
||||
static class TestRepositoryRestConfigurer implements RepositoryRestConfigurer {
|
||||
|
||||
@Override
|
||||
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
|
||||
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
|
||||
config.setRepositoryDetectionStrategy(RepositoryDetectionStrategies.ALL);
|
||||
config.setDefaultMediaType(MediaType.parseMediaType("application/my-custom-json"));
|
||||
config.setMaxPageSize(78);
|
||||
|
||||
@@ -271,7 +271,7 @@ bom {
|
||||
]
|
||||
}
|
||||
}
|
||||
library("Elasticsearch", "7.7.1") {
|
||||
library("Elasticsearch", "7.8.1") {
|
||||
group("org.elasticsearch") {
|
||||
modules = [
|
||||
"elasticsearch"
|
||||
@@ -1177,19 +1177,6 @@ bom {
|
||||
]
|
||||
}
|
||||
}
|
||||
library("Neo4j OGM", "3.2.12") {
|
||||
group("org.neo4j") {
|
||||
modules = [
|
||||
"neo4j-ogm-api",
|
||||
"neo4j-ogm-bolt-driver",
|
||||
"neo4j-ogm-bolt-native-types",
|
||||
"neo4j-ogm-core",
|
||||
"neo4j-ogm-embedded-driver",
|
||||
"neo4j-ogm-embedded-native-types",
|
||||
"neo4j-ogm-http-driver"
|
||||
]
|
||||
}
|
||||
}
|
||||
library("Netty", "4.1.50.Final") {
|
||||
group("io.netty") {
|
||||
imports = [
|
||||
@@ -1563,7 +1550,7 @@ bom {
|
||||
]
|
||||
}
|
||||
}
|
||||
library("Spring Data Bom", "2020.0.0-M1") {
|
||||
library("Spring Data Bom", "2020.0.0-SNAPSHOT") {
|
||||
group("org.springframework.data") {
|
||||
imports = [
|
||||
"spring-data-bom"
|
||||
|
||||
@@ -2978,7 +2978,7 @@ class ExampleIntegrationTests {
|
||||
|
||||
@DynamicPropertySource
|
||||
static void neo4jProperties(DynamicPropertyRegistry registry) {
|
||||
registry.add("spring.data.neo4j.uri", neo4j::getBoltUrl);
|
||||
registry.add("spring.neo4j.uri", neo4j::getBoltUrl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4532,47 +4532,6 @@ Each will be called in order with the `ConfigBuilder` that is used to build the
|
||||
|
||||
|
||||
|
||||
[[boot-features-connecting-to-neo4j-embedded]]
|
||||
==== Using the Embedded Mode
|
||||
If you add `org.neo4j:neo4j-ogm-embedded-driver` to the dependencies of your application, Spring Boot automatically configures an in-process embedded instance of Neo4j that does not persist any data when your application shuts down.
|
||||
|
||||
NOTE: As the embedded Neo4j OGM driver does not provide the Neo4j kernel itself, you have to declare `org.neo4j:neo4j` as dependency yourself.
|
||||
Refer to https://neo4j.com/docs/ogm-manual/current/reference/#reference:getting-started[the Neo4j OGM documentation] for a list of compatible versions.
|
||||
|
||||
The embedded driver takes precedence over the other drivers when there are multiple drivers on the classpath.
|
||||
You can explicitly disable the embedded mode by setting `spring.data.neo4j.embedded.enabled=false`.
|
||||
|
||||
<<boot-features-testing-spring-boot-applications-testing-autoconfigured-neo4j-test,Data Neo4j Tests>> automatically make use of an embedded Neo4j instance if the embedded driver and Neo4j kernel are on the classpath as described above.
|
||||
|
||||
NOTE: You can enable persistence for the embedded mode by providing a path to a database file in your configuration, e.g. `spring.data.neo4j.uri=file://var/tmp/graph.db`.
|
||||
|
||||
|
||||
|
||||
[[boot-features-neo4j-ogm-native-types]]
|
||||
==== Using Native Types
|
||||
Neo4j-OGM can map some types, like those in `java.time.*`, to `String`-based properties or to one of the native types that Neo4j provides.
|
||||
For backwards compatibility reasons the default for Neo4j-OGM is to use a `String`-based representation.
|
||||
To use native types, add a dependency on either `org.neo4j:neo4j-ogm-bolt-native-types` or `org.neo4j:neo4j-ogm-embedded-native-types`, and configure the configprop:spring.data.neo4j.use-native-types[] property as shown in the following example:
|
||||
|
||||
[source,properties,indent=0,configprops]
|
||||
----
|
||||
spring.data.neo4j.use-native-types=true
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[boot-features-neo4j-ogm-session]]
|
||||
==== Neo4jSession
|
||||
By default, if you are running a web application, the session is bound to the thread for the entire processing of the request (that is, it uses the "Open Session in View" pattern).
|
||||
If you do not want this behavior, add the following line to your `application.properties` file:
|
||||
|
||||
[source,properties,indent=0,configprops]
|
||||
----
|
||||
spring.data.neo4j.open-in-view=false
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[boot-features-spring-data-neo4j-repositories]]
|
||||
==== Spring Data Neo4j Repositories
|
||||
Spring Data includes repository support for Neo4j.
|
||||
|
||||
@@ -42,7 +42,10 @@ org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration
|
||||
|
||||
# AutoConfigureDataNeo4j auto-configuration imports
|
||||
org.springframework.boot.test.autoconfigure.data.neo4j.AutoConfigureDataNeo4j=\
|
||||
org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveDataAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ package org.springframework.boot.test.autoconfigure.data.neo4j;
|
||||
import java.time.Duration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.neo4j.ogm.session.Session;
|
||||
import org.testcontainers.containers.Neo4jContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
@@ -27,6 +26,7 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.neo4j.core.Neo4jTemplate;
|
||||
import org.springframework.test.context.DynamicPropertyRegistry;
|
||||
import org.springframework.test.context.DynamicPropertySource;
|
||||
|
||||
@@ -48,8 +48,13 @@ class DataNeo4jTestIntegrationTests {
|
||||
static final Neo4jContainer<?> neo4j = new Neo4jContainer<>().withoutAuthentication()
|
||||
.withStartupTimeout(Duration.ofMinutes(10));
|
||||
|
||||
@DynamicPropertySource
|
||||
static void neo4jProperties(DynamicPropertyRegistry registry) {
|
||||
registry.add("spring.neo4j.uri", neo4j::getBoltUrl);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private Session session;
|
||||
private Neo4jTemplate neo4jTemplate;
|
||||
|
||||
@Autowired
|
||||
private ExampleRepository exampleRepository;
|
||||
@@ -57,19 +62,13 @@ class DataNeo4jTestIntegrationTests {
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@DynamicPropertySource
|
||||
static void neo4jProperties(DynamicPropertyRegistry registry) {
|
||||
registry.add("spring.data.neo4j.uri", neo4j::getBoltUrl);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRepository() {
|
||||
ExampleGraph exampleGraph = new ExampleGraph();
|
||||
exampleGraph.setDescription("Look, new @DataNeo4jTest!");
|
||||
ExampleGraph exampleGraph = new ExampleGraph("Look, new @DataNeo4jTest!");
|
||||
assertThat(exampleGraph.getId()).isNull();
|
||||
ExampleGraph savedGraph = this.exampleRepository.save(exampleGraph);
|
||||
assertThat(savedGraph.getId()).isNotNull();
|
||||
assertThat(this.session.countEntitiesOfType(ExampleGraph.class)).isEqualTo(1);
|
||||
assertThat(this.neo4jTemplate.count(ExampleGraph.class)).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -44,14 +44,14 @@ class DataNeo4jTestPropertiesIntegrationTests {
|
||||
static final Neo4jContainer<?> neo4j = new Neo4jContainer<>().withoutAuthentication()
|
||||
.withStartupTimeout(Duration.ofMinutes(10));
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
@DynamicPropertySource
|
||||
static void neo4jProperties(DynamicPropertyRegistry registry) {
|
||||
registry.add("spring.data.neo4j.uri", neo4j::getBoltUrl);
|
||||
registry.add("spring.neo4j.uri", neo4j::getBoltUrl);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
@Test
|
||||
void environmentWithNewProfile() {
|
||||
assertThat(this.environment.getActiveProfiles()).containsExactly("test");
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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 java.time.Duration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
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 org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.neo4j.core.ReactiveNeo4jTemplate;
|
||||
import org.springframework.test.context.DynamicPropertyRegistry;
|
||||
import org.springframework.test.context.DynamicPropertySource;
|
||||
|
||||
import 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 DataNeo4jTestReactiveIntegrationTests {
|
||||
|
||||
@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 ReactiveNeo4jTemplate neo4jTemplate;
|
||||
|
||||
@Autowired
|
||||
private ExampleReactiveRepository exampleRepository;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Test
|
||||
void testRepository() {
|
||||
Mono.just(new ExampleGraph("Look, new @DataNeo4jTest with reactive!")).flatMap(this.exampleRepository::save)
|
||||
.as(StepVerifier::create).expectNextCount(1).verifyComplete();
|
||||
StepVerifier.create(this.neo4jTemplate.count(ExampleGraph.class)).expectNext(1L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void didNotInjectExampleService() {
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
||||
.isThrownBy(() -> this.applicationContext.getBean(ExampleService.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -45,14 +45,14 @@ class DataNeo4jTestWithIncludeFilterIntegrationTests {
|
||||
static final Neo4jContainer<?> neo4j = new Neo4jContainer<>().withoutAuthentication()
|
||||
.withStartupTimeout(Duration.ofMinutes(10));
|
||||
|
||||
@Autowired
|
||||
private ExampleService service;
|
||||
|
||||
@DynamicPropertySource
|
||||
static void neo4jProperties(DynamicPropertyRegistry registry) {
|
||||
registry.add("spring.data.neo4j.uri", neo4j::getBoltUrl);
|
||||
registry.add("spring.neo4j.uri", neo4j::getBoltUrl);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private ExampleService service;
|
||||
|
||||
@Test
|
||||
void testService() {
|
||||
assertThat(this.service.hasNode(ExampleGraph.class)).isFalse();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,17 +16,17 @@
|
||||
|
||||
package org.springframework.boot.test.autoconfigure.data.neo4j;
|
||||
|
||||
import org.neo4j.ogm.annotation.GeneratedValue;
|
||||
import org.neo4j.ogm.annotation.Id;
|
||||
import org.neo4j.ogm.annotation.NodeEntity;
|
||||
import org.neo4j.ogm.annotation.Property;
|
||||
import org.springframework.data.neo4j.core.schema.GeneratedValue;
|
||||
import org.springframework.data.neo4j.core.schema.Id;
|
||||
import org.springframework.data.neo4j.core.schema.Node;
|
||||
import org.springframework.data.neo4j.core.schema.Property;
|
||||
|
||||
/**
|
||||
* Example graph used with {@link DataNeo4jTest @DataNeo4jTest} tests.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
@NodeEntity
|
||||
@Node
|
||||
public class ExampleGraph {
|
||||
|
||||
@Id
|
||||
@@ -36,6 +36,10 @@ public class ExampleGraph {
|
||||
@Property
|
||||
private String description;
|
||||
|
||||
public ExampleGraph(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@@ -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> {
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,26 +16,26 @@
|
||||
|
||||
package org.springframework.boot.test.autoconfigure.data.neo4j;
|
||||
|
||||
import org.neo4j.ogm.session.Session;
|
||||
|
||||
import org.springframework.data.neo4j.core.Neo4jTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* Example service used with {@link DataNeo4jTest @DataNeo4jTest} tests.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @author Michael J. Simons
|
||||
*/
|
||||
@Service
|
||||
public class ExampleService {
|
||||
|
||||
private final Session session;
|
||||
private final Neo4jTemplate neo4jTemplate;
|
||||
|
||||
public ExampleService(Session session) {
|
||||
this.session = session;
|
||||
public ExampleService(Neo4jTemplate neo4jTemplate) {
|
||||
this.neo4jTemplate = neo4jTemplate;
|
||||
}
|
||||
|
||||
public boolean hasNode(Class<?> clazz) {
|
||||
return this.session.countEntitiesOfType(clazz) == 1;
|
||||
return this.neo4jTemplate.count(clazz) == 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ dependencies {
|
||||
compileOnly("org.junit.jupiter:junit-jupiter")
|
||||
compileOnly("org.junit.platform:junit-platform-engine")
|
||||
compileOnly("org.mockito:mockito-core")
|
||||
compileOnly("org.neo4j:neo4j-ogm-core")
|
||||
compileOnly("org.springframework:spring-context")
|
||||
compileOnly("org.springframework.data:spring-data-redis")
|
||||
compileOnly("org.testcontainers:testcontainers")
|
||||
|
||||
@@ -56,7 +56,6 @@ dependencies {
|
||||
optional("org.hibernate.validator:hibernate-validator")
|
||||
optional("org.jboss:jboss-transaction-spi")
|
||||
optional("org.liquibase:liquibase-core")
|
||||
optional("org.neo4j:neo4j-ogm-core")
|
||||
optional("org.slf4j:jul-to-slf4j")
|
||||
optional("org.slf4j:slf4j-api")
|
||||
optional("org.springframework:spring-messaging")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
package smoketest.data.neo4j;
|
||||
|
||||
import org.neo4j.ogm.annotation.GeneratedValue;
|
||||
import org.neo4j.ogm.annotation.Id;
|
||||
import org.neo4j.ogm.annotation.NodeEntity;
|
||||
import org.springframework.data.neo4j.core.schema.GeneratedValue;
|
||||
import org.springframework.data.neo4j.core.schema.Id;
|
||||
import org.springframework.data.neo4j.core.schema.Node;
|
||||
|
||||
@NodeEntity
|
||||
@Node
|
||||
public class Customer {
|
||||
|
||||
@Id
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
# spring.data.neo4j.open-in-view=true
|
||||
|
||||
Reference in New Issue
Block a user