diff --git a/pom.xml b/pom.xml index c76f81a8..74be18bc 100644 --- a/pom.xml +++ b/pom.xml @@ -105,6 +105,13 @@ true + + io.reactivex.rxjava2 + rxjava + ${rxjava2} + true + + javax.validation @@ -121,7 +128,7 @@ 1.0.1 test - + javax.interceptor javax.interceptor-api diff --git a/src/main/java/org/springframework/data/couchbase/repository/config/CouchbaseRepositoryConfigurationExtension.java b/src/main/java/org/springframework/data/couchbase/repository/config/CouchbaseRepositoryConfigurationExtension.java index 5a84c3a4..9d47bc11 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/config/CouchbaseRepositoryConfigurationExtension.java +++ b/src/main/java/org/springframework/data/couchbase/repository/config/CouchbaseRepositoryConfigurationExtension.java @@ -35,6 +35,7 @@ import org.w3c.dom.Element; * @author Michael Nitschinger * @author Mark Paluch * @author Oliver Gierke + * @author Alexander Derkach */ public class CouchbaseRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport { @@ -44,30 +45,32 @@ public class CouchbaseRepositoryConfigurationExtension extends RepositoryConfigu /** The reference property to use in xml configuration to specify the index manager bean to use with a repository. */ private static final String COUCHBASE_INDEX_MANAGER_REF = "couchbase-index-manager-ref"; + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getModuleName() + */ + @Override + public String getModuleName() { + return "Couchbase"; +} + + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getModulePrefix() + */ @Override protected String getModulePrefix() { return "couchbase"; } + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtension#getRepositoryFactoryBeanClassName() + */ public String getRepositoryFactoryBeanClassName() { return CouchbaseRepositoryFactoryBean.class.getName(); } - @Override - public void postProcess(final BeanDefinitionBuilder builder, final XmlRepositoryConfigurationSource config) { - Element element = config.getElement(); - ParsingUtils.setPropertyReference(builder, element, COUCHBASE_TEMPLATE_REF, "couchbaseOperations"); - ParsingUtils.setPropertyReference(builder, element, COUCHBASE_INDEX_MANAGER_REF, "indexManager"); - } - - @Override - public void postProcess(final BeanDefinitionBuilder builder, final AnnotationRepositoryConfigurationSource config) { - builder.addDependsOn(BeanNames.COUCHBASE_OPERATIONS_MAPPING); - builder.addDependsOn(BeanNames.COUCHBASE_INDEX_MANAGER); - builder.addPropertyReference("couchbaseOperationsMapping", BeanNames.COUCHBASE_OPERATIONS_MAPPING); - builder.addPropertyReference("indexManager", BeanNames.COUCHBASE_INDEX_MANAGER); - } - /* * (non-Javadoc) * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getIdentifyingAnnotations() @@ -86,6 +89,36 @@ public class CouchbaseRepositoryConfigurationExtension extends RepositoryConfigu return Collections.singleton(CouchbaseRepository.class); } + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#postProcess(org.springframework.beans.factory.support.BeanDefinitionBuilder, org.springframework.data.repository.config.XmlRepositoryConfigurationSource) + */ + @Override + public void postProcess(BeanDefinitionBuilder builder, XmlRepositoryConfigurationSource config) { + + Element element = config.getElement(); + + ParsingUtils.setPropertyReference(builder, element, COUCHBASE_TEMPLATE_REF, "couchbaseOperations"); + ParsingUtils.setPropertyReference(builder, element, COUCHBASE_INDEX_MANAGER_REF, "indexManager"); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#postProcess(org.springframework.beans.factory.support.BeanDefinitionBuilder, org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource) + */ + @Override + public void postProcess(BeanDefinitionBuilder builder, AnnotationRepositoryConfigurationSource config) { + + builder.addDependsOn(BeanNames.COUCHBASE_OPERATIONS_MAPPING); + builder.addDependsOn(BeanNames.COUCHBASE_INDEX_MANAGER); + builder.addPropertyReference("couchbaseOperationsMapping", BeanNames.COUCHBASE_OPERATIONS_MAPPING); + builder.addPropertyReference("indexManager", BeanNames.COUCHBASE_INDEX_MANAGER); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#useRepositoryConfiguration(org.springframework.data.repository.core.RepositoryMetadata) + */ protected boolean useRepositoryConfiguration(RepositoryMetadata metadata) { return !metadata.isReactiveRepository(); } diff --git a/src/main/java/org/springframework/data/couchbase/repository/config/ReactiveCouchbaseRepositoryConfigurationExtension.java b/src/main/java/org/springframework/data/couchbase/repository/config/ReactiveCouchbaseRepositoryConfigurationExtension.java index 07dd130b..bba47bf4 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/config/ReactiveCouchbaseRepositoryConfigurationExtension.java +++ b/src/main/java/org/springframework/data/couchbase/repository/config/ReactiveCouchbaseRepositoryConfigurationExtension.java @@ -19,22 +19,22 @@ import java.lang.annotation.Annotation; import java.util.Collection; import java.util.Collections; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.data.config.ParsingUtils; +import org.springframework.data.couchbase.config.BeanNames; import org.springframework.data.couchbase.core.mapping.Document; import org.springframework.data.couchbase.repository.ReactiveCouchbaseRepository; import org.springframework.data.couchbase.repository.support.ReactiveCouchbaseRepositoryFactoryBean; +import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource; import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport; import org.springframework.data.repository.config.XmlRepositoryConfigurationSource; import org.springframework.data.repository.core.RepositoryMetadata; import org.w3c.dom.Element; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.data.config.ParsingUtils; -import org.springframework.data.couchbase.config.BeanNames; -import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource; - /** * @author Subhashni Balakrishnan * @author Mark Paluch + * @author Alexander Derkach * @since 3.0 */ public class ReactiveCouchbaseRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport { @@ -45,48 +45,80 @@ public class ReactiveCouchbaseRepositoryConfigurationExtension extends Repositor /** The reference property to use in xml configuration to specify the index manager bean to use with a repository. */ private static final String COUCHBASE_INDEX_MANAGER_REF = "couchbase-index-manager-ref"; + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getModuleName() + */ @Override - protected String getModulePrefix() { - return "reactive-couchbase"; - } - - public String getRepositoryFactoryBeanClassName() { - return ReactiveCouchbaseRepositoryFactoryBean.class.getName(); - } - - @Override - public void postProcess(final BeanDefinitionBuilder builder, final XmlRepositoryConfigurationSource config) { - Element element = config.getElement(); - ParsingUtils.setPropertyReference(builder, element, REACTIVE_COUCHBASE_TEMPLATE_REF, "reactiveCouchbaseOperations"); - ParsingUtils.setPropertyReference(builder, element, COUCHBASE_INDEX_MANAGER_REF, "indexManager"); - } - - @Override - public void postProcess(final BeanDefinitionBuilder builder, final AnnotationRepositoryConfigurationSource config) { - builder.addDependsOn(BeanNames.REACTIVE_COUCHBASE_OPERATIONS_MAPPING); - builder.addDependsOn(BeanNames.COUCHBASE_INDEX_MANAGER); - builder.addPropertyReference("couchbaseOperationsMapping", BeanNames.REACTIVE_COUCHBASE_OPERATIONS_MAPPING); - builder.addPropertyReference("indexManager", BeanNames.COUCHBASE_INDEX_MANAGER); + public String getModuleName() { + return "Couchbase"; } /* * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getIdentifyingAnnotations() + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getModulePrefix() */ @Override + protected String getModulePrefix() { + return "couchbase"; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtension#getRepositoryFactoryBeanClassName() + */ + public String getRepositoryFactoryBeanClassName() { + return ReactiveCouchbaseRepositoryFactoryBean.class.getName(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getIdentifyingAnnotations() + */ + @Override protected Collection> getIdentifyingAnnotations() { return Collections.singleton(Document.class); } /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getIdentifyingTypes() - */ + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getIdentifyingTypes() + */ @Override protected Collection> getIdentifyingTypes() { return Collections.singleton(ReactiveCouchbaseRepository.class); } + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#postProcess(org.springframework.beans.factory.support.BeanDefinitionBuilder, org.springframework.data.repository.config.XmlRepositoryConfigurationSource) + */ + @Override + public void postProcess(BeanDefinitionBuilder builder, XmlRepositoryConfigurationSource config) { + + Element element = config.getElement(); + ParsingUtils.setPropertyReference(builder, element, REACTIVE_COUCHBASE_TEMPLATE_REF, "reactiveCouchbaseOperations"); + ParsingUtils.setPropertyReference(builder, element, COUCHBASE_INDEX_MANAGER_REF, "indexManager"); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#postProcess(org.springframework.beans.factory.support.BeanDefinitionBuilder, org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource) + */ + @Override + public void postProcess(BeanDefinitionBuilder builder, AnnotationRepositoryConfigurationSource config) { + + builder.addDependsOn(BeanNames.REACTIVE_COUCHBASE_OPERATIONS_MAPPING); + builder.addDependsOn(BeanNames.COUCHBASE_INDEX_MANAGER); + builder.addPropertyReference("couchbaseOperationsMapping", BeanNames.REACTIVE_COUCHBASE_OPERATIONS_MAPPING); + builder.addPropertyReference("indexManager", BeanNames.COUCHBASE_INDEX_MANAGER); + } + + + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#useRepositoryConfiguration(org.springframework.data.repository.core.RepositoryMetadata) + */ protected boolean useRepositoryConfiguration(RepositoryMetadata metadata) { return metadata.isReactiveRepository(); } diff --git a/src/test/java/org/springframework/data/couchbase/repository/config/ReactiveCouchbaseRepositoryConfigurationExtensionUnitTests.java b/src/test/java/org/springframework/data/couchbase/repository/config/ReactiveCouchbaseRepositoryConfigurationExtensionUnitTests.java new file mode 100644 index 00000000..561f592b --- /dev/null +++ b/src/test/java/org/springframework/data/couchbase/repository/config/ReactiveCouchbaseRepositoryConfigurationExtensionUnitTests.java @@ -0,0 +1,113 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.couchbase.repository.config; + +import static org.junit.Assert.*; + +import java.util.Collection; + +import org.junit.Test; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.core.env.Environment; +import org.springframework.core.env.StandardEnvironment; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.type.StandardAnnotationMetadata; +import org.springframework.data.couchbase.core.mapping.Document; +import org.springframework.data.couchbase.repository.ReactiveCouchbaseRepository; +import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource; +import org.springframework.data.repository.config.RepositoryConfiguration; +import org.springframework.data.repository.config.RepositoryConfigurationSource; +import org.springframework.data.repository.reactive.ReactiveCrudRepository; +import org.springframework.data.repository.reactive.RxJava2CrudRepository; + +/** + * Unit tests for {@link ReactiveCouchbaseRepositoryConfigurationExtension}. + * + * @author Mark Paluch + */ +public class ReactiveCouchbaseRepositoryConfigurationExtensionUnitTests { + + StandardAnnotationMetadata metadata = new StandardAnnotationMetadata(Config.class, true); + ResourceLoader loader = new PathMatchingResourcePatternResolver(); + Environment environment = new StandardEnvironment(); + BeanDefinitionRegistry registry = new DefaultListableBeanFactory(); + + RepositoryConfigurationSource configurationSource = new AnnotationRepositoryConfigurationSource(metadata, + EnableReactiveCouchbaseRepositories.class, loader, environment, registry); + + @Test // DATACOUCH-350 + public void isStrictMatchIfDomainTypeIsAnnotatedWithDocument() { + + ReactiveCouchbaseRepositoryConfigurationExtension extension = new ReactiveCouchbaseRepositoryConfigurationExtension(); + assertHasRepo(SampleRepository.class, extension.getRepositoryConfigurations(configurationSource, loader, true)); + } + + @Test // DATACOUCH-350 + public void isStrictMatchIfRepositoryExtendsStoreSpecificBase() { + + ReactiveCouchbaseRepositoryConfigurationExtension extension = new ReactiveCouchbaseRepositoryConfigurationExtension(); + assertHasRepo(StoreRepository.class, extension.getRepositoryConfigurations(configurationSource, loader, true)); + } + + @Test // DATACOUCH-350 + public void isNotStrictMatchIfDomainTypeIsNotAnnotatedWithDocument() { + + ReactiveCouchbaseRepositoryConfigurationExtension extension = new ReactiveCouchbaseRepositoryConfigurationExtension(); + assertDoesNotHaveRepo(UnannotatedRepository.class, + extension.getRepositoryConfigurations(configurationSource, loader, true)); + } + + private static void assertHasRepo(Class repositoryInterface, + Collection> configs) { + + for (RepositoryConfiguration config : configs) { + if (config.getRepositoryInterface().equals(repositoryInterface.getName())) { + return; + } + } + + fail("Expected to find config for repository interface ".concat(repositoryInterface.getName()).concat(" but got ") + .concat(configs.toString())); + } + + private static void assertDoesNotHaveRepo(Class repositoryInterface, + Collection> configs) { + + for (RepositoryConfiguration config : configs) { + if (config.getRepositoryInterface().equals(repositoryInterface.getName())) { + fail("Expected not to find config for repository interface ".concat(repositoryInterface.getName())); + } + } + } + + @EnableReactiveCouchbaseRepositories(considerNestedRepositories = true) + static class Config { + + } + + @Document + static class Sample {} + + static class Store {} + + interface SampleRepository extends ReactiveCrudRepository {} + + interface UnannotatedRepository extends RxJava2CrudRepository {} + + interface StoreRepository extends ReactiveCouchbaseRepository {} +}