diff --git a/src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java b/src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java index 983af273..6af72f6f 100644 --- a/src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java +++ b/src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java @@ -38,6 +38,7 @@ import org.springframework.data.couchbase.core.convert.translation.JacksonTransl import org.springframework.data.couchbase.core.convert.translation.TranslationService; import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext; import org.springframework.data.couchbase.core.mapping.Document; +import org.springframework.data.couchbase.repository.config.ReactiveRepositoryOperationsMapping; import org.springframework.data.couchbase.repository.config.RepositoryOperationsMapping; import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy; import org.springframework.data.mapping.model.FieldNamingStrategy; @@ -116,7 +117,7 @@ public abstract class AbstractCouchbaseConfiguration { return new ReactiveCouchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter); } - @Bean + @Bean(name = BeanNames.COUCHBASE_OPERATIONS_MAPPING) public RepositoryOperationsMapping couchbaseRepositoryOperationsMapping(CouchbaseTemplate couchbaseTemplate) { // create a base mapping that associates all repositories to the default template RepositoryOperationsMapping baseMapping = new RepositoryOperationsMapping(couchbaseTemplate); @@ -135,6 +136,25 @@ public abstract class AbstractCouchbaseConfiguration { // NO_OP } + @Bean(name = BeanNames.REACTIVE_COUCHBASE_OPERATIONS_MAPPING) + public ReactiveRepositoryOperationsMapping reactiveCouchbaseRepositoryOperationsMapping(ReactiveCouchbaseTemplate reactiveCouchbaseTemplate) { + // create a base mapping that associates all repositories to the default template + ReactiveRepositoryOperationsMapping baseMapping = new ReactiveRepositoryOperationsMapping(reactiveCouchbaseTemplate); + // let the user tune it + configureReactiveRepositoryOperationsMapping(baseMapping); + return baseMapping; + } + + /** + * In order to customize the mapping between repositories/entity types to couchbase templates, use the provided + * mapping's api (eg. in order to have different buckets backing different repositories). + * + * @param mapping the default mapping (will associate all repositories to the default template). + */ + protected void configureReactiveRepositoryOperationsMapping(ReactiveRepositoryOperationsMapping mapping) { + // NO_OP + } + /** * Scans the mapping base package for classes annotated with {@link Document}. * diff --git a/src/main/java/org/springframework/data/couchbase/repository/config/EnableReactiveCouchbaseRepositories.java b/src/main/java/org/springframework/data/couchbase/repository/config/EnableReactiveCouchbaseRepositories.java index aeaab0fd..76a1e8cc 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/config/EnableReactiveCouchbaseRepositories.java +++ b/src/main/java/org/springframework/data/couchbase/repository/config/EnableReactiveCouchbaseRepositories.java @@ -47,8 +47,8 @@ public @interface EnableReactiveCouchbaseRepositories { /** * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation declarations e.g.: - * {@code @EnableCouchbaseRepositories("org.my.pkg")} instead of - * {@code @EnableCouchbaseRepositories(basePackages="org.my.pkg")}. + * {@code @EnableReactiveCouchbaseRepositories("org.my.pkg")} instead of + * {@code @EnableReactiveCouchbaseRepositories(basePackages="org.my.pkg")}. */ String[] value() default {}; @@ -119,6 +119,6 @@ public @interface EnableReactiveCouchbaseRepositories { * * @return */ - String couchbaseTemplateRef() default BeanNames.COUCHBASE_TEMPLATE; + String couchbaseTemplateRef() default BeanNames.REACTIVE_COUCHBASE_TEMPLATE; } 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 42ececcc..14940e90 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 @@ -109,7 +109,7 @@ public class ReactiveCouchbaseRepositoryConfigurationExtension extends Repositor public void postProcess(BeanDefinitionBuilder builder, AnnotationRepositoryConfigurationSource config) { builder.addDependsOn(BeanNames.REACTIVE_COUCHBASE_OPERATIONS_MAPPING); - builder.addPropertyReference("couchbaseOperationsMapping", BeanNames.REACTIVE_COUCHBASE_OPERATIONS_MAPPING); + builder.addPropertyReference("reactiveCouchbaseOperationsMapping", BeanNames.REACTIVE_COUCHBASE_OPERATIONS_MAPPING); } /* diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveCouchbaseRepositoryQuery.java b/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveCouchbaseRepositoryQuery.java new file mode 100644 index 00000000..39a44306 --- /dev/null +++ b/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveCouchbaseRepositoryQuery.java @@ -0,0 +1,27 @@ +package org.springframework.data.couchbase.repository.query; + +import org.springframework.data.couchbase.core.ReactiveCouchbaseOperations; +import org.springframework.data.repository.query.QueryMethod; +import org.springframework.data.repository.query.RepositoryQuery; + +public class ReactiveCouchbaseRepositoryQuery implements RepositoryQuery { + + private final ReactiveCouchbaseOperations operations; + private final QueryMethod queryMethod; + + public ReactiveCouchbaseRepositoryQuery(final ReactiveCouchbaseOperations operations, final QueryMethod queryMethod) { + this.operations = operations; + this.queryMethod = queryMethod; + } + + @Override + public Object execute(final Object[] parameters) { + return new ReactiveN1qlRepositoryQueryExecutor(operations, queryMethod).execute(parameters); + } + + @Override + public QueryMethod getQueryMethod() { + return queryMethod; + } + +} diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveN1qlRepositoryQueryExecutor.java b/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveN1qlRepositoryQueryExecutor.java new file mode 100644 index 00000000..fd1629dd --- /dev/null +++ b/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveN1qlRepositoryQueryExecutor.java @@ -0,0 +1,34 @@ +package org.springframework.data.couchbase.repository.query; + +import java.util.List; + +import org.springframework.data.couchbase.core.CouchbaseOperations; +import org.springframework.data.couchbase.core.ReactiveCouchbaseOperations; +import org.springframework.data.couchbase.core.query.Query; +import org.springframework.data.repository.query.ParameterAccessor; +import org.springframework.data.repository.query.ParametersParameterAccessor; +import org.springframework.data.repository.query.QueryMethod; +import org.springframework.data.repository.query.parser.PartTree; +import reactor.core.publisher.Flux; + +public class ReactiveN1qlRepositoryQueryExecutor { + + private final ReactiveCouchbaseOperations operations; + private final QueryMethod queryMethod; + + public ReactiveN1qlRepositoryQueryExecutor(final ReactiveCouchbaseOperations operations, final QueryMethod queryMethod) { + this.operations = operations; + this.queryMethod = queryMethod; + } + + public Object execute(final Object[] parameters) { + final Class domainClass = queryMethod.getResultProcessor().getReturnedType().getDomainType(); + final ParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters); + + final PartTree tree = new PartTree(queryMethod.getName(), domainClass); + Query query = new N1qlQueryCreator(tree, accessor, operations.getConverter().getMappingContext()).createQuery(); + + Flux all = operations.findByQuery(domainClass).matching(query).all(); + return all; + } +} diff --git a/src/main/java/org/springframework/data/couchbase/repository/support/ReactiveCouchbaseRepositoryFactory.java b/src/main/java/org/springframework/data/couchbase/repository/support/ReactiveCouchbaseRepositoryFactory.java index c0df9138..810d7b47 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/support/ReactiveCouchbaseRepositoryFactory.java +++ b/src/main/java/org/springframework/data/couchbase/repository/support/ReactiveCouchbaseRepositoryFactory.java @@ -19,12 +19,15 @@ import java.io.Serializable; import java.lang.reflect.Method; import java.util.Optional; +import org.springframework.data.couchbase.core.CouchbaseOperations; import org.springframework.data.couchbase.core.ReactiveCouchbaseOperations; import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity; import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty; import org.springframework.data.couchbase.repository.config.ReactiveRepositoryOperationsMapping; import org.springframework.data.couchbase.repository.query.CouchbaseEntityInformation; import org.springframework.data.couchbase.repository.query.CouchbaseQueryMethod; +import org.springframework.data.couchbase.repository.query.CouchbaseRepositoryQuery; +import org.springframework.data.couchbase.repository.query.ReactiveCouchbaseRepositoryQuery; import org.springframework.data.couchbase.repository.query.ReactivePartTreeN1qlBasedQuery; import org.springframework.data.couchbase.repository.query.ReactiveStringN1qlBasedQuery; import org.springframework.data.mapping.context.MappingContext; @@ -34,6 +37,7 @@ import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.support.ReactiveRepositoryFactorySupport; import org.springframework.data.repository.query.QueryLookupStrategy; +import org.springframework.data.repository.query.QueryMethod; import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.expression.spel.standard.SpelExpressionParser; @@ -57,6 +61,8 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor */ private final MappingContext, CouchbasePersistentProperty> mappingContext; + private final CrudMethodMetadataPostProcessor crudMethodMetadataPostProcessor; + /** * Create a new factory. * @@ -66,8 +72,16 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor Assert.notNull(couchbaseOperationsMapping); this.couchbaseOperationsMapping = couchbaseOperationsMapping; + this.crudMethodMetadataPostProcessor = new CrudMethodMetadataPostProcessor(); mappingContext = this.couchbaseOperationsMapping.getMappingContext(); + addRepositoryProxyPostProcessor(crudMethodMetadataPostProcessor); + } + + @Override + public void setBeanClassLoader(ClassLoader classLoader) { + super.setBeanClassLoader(classLoader); + this.crudMethodMetadataPostProcessor.setBeanClassLoader(classLoader); } /** @@ -80,9 +94,9 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor */ @Override public CouchbaseEntityInformation getEntityInformation(Class domainClass) { - CouchbasePersistentEntity entity = mappingContext.getRequiredPersistentEntity(domainClass); - - return new MappingCouchbaseEntityInformation<>((CouchbasePersistentEntity) entity); + CouchbasePersistentEntity entity = (CouchbasePersistentEntity) mappingContext + .getRequiredPersistentEntity(domainClass); + return new MappingCouchbaseEntityInformation<>(entity); } /** @@ -97,15 +111,12 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor @Override protected final Object getTargetRepository(final RepositoryInformation metadata) { ReactiveCouchbaseOperations couchbaseOperations = couchbaseOperationsMapping.resolve(metadata.getRepositoryInterface(), - metadata.getDomainType()); - // boolean isN1qlAvailable = - // couchbaseOperations.getCouchbaseClusterConfig().clusterCapabilities().containsKey(ServiceType.QUERY); - + metadata.getDomainType()); CouchbaseEntityInformation entityInformation = getEntityInformation(metadata.getDomainType()); - SimpleReactiveCouchbaseRepository repo = getTargetRepositoryViaReflection(metadata, entityInformation, - couchbaseOperations); - // repo.setViewMetadataProvider(viewPostProcessor.getViewMetadataProvider()); - return repo; + SimpleReactiveCouchbaseRepository repository = getTargetRepositoryViaReflection(metadata, entityInformation, + couchbaseOperations); + repository.setRepositoryMethodMetadata(crudMethodMetadataPostProcessor.getCrudMethodMetadata()); + return repository; } /** @@ -119,8 +130,6 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor */ @Override protected final Class getRepositoryBaseClass(final RepositoryMetadata repositoryMetadata) { - // Since we always need n1ql (we eliminated use of views for findAll, etc...), lets just - // always return the n1ql repo return SimpleReactiveCouchbaseRepository.class; } @@ -144,7 +153,12 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor @Override public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, ProjectionFactory factory, NamedQueries namedQueries) { - ReactiveCouchbaseOperations couchbaseOperations = couchbaseOperationsMapping.resolve(metadata.getRepositoryInterface(), + final ReactiveCouchbaseOperations couchbaseOperations = couchbaseOperationsMapping + .resolve(metadata.getRepositoryInterface(), metadata.getDomainType()); + + return new ReactiveCouchbaseRepositoryQuery(couchbaseOperations, new QueryMethod(method, metadata, factory)); + + /*ReactiveCouchbaseOperations couchbaseOperations = couchbaseOperationsMapping.resolve(metadata.getRepositoryInterface(), metadata.getDomainType()); CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method, metadata, factory, mappingContext); @@ -160,7 +174,7 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor evaluationContextProvider); } // otherwise will do default, queryDerivation } - return new ReactivePartTreeN1qlBasedQuery(queryMethod, couchbaseOperations); + return new ReactivePartTreeN1qlBasedQuery(queryMethod, couchbaseOperations);*/ } } diff --git a/src/main/java/org/springframework/data/couchbase/repository/support/ReactiveCouchbaseRepositoryFactoryBean.java b/src/main/java/org/springframework/data/couchbase/repository/support/ReactiveCouchbaseRepositoryFactoryBean.java index 20a849c7..bafa69ca 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/support/ReactiveCouchbaseRepositoryFactoryBean.java +++ b/src/main/java/org/springframework/data/couchbase/repository/support/ReactiveCouchbaseRepositoryFactoryBean.java @@ -51,10 +51,10 @@ public class ReactiveCouchbaseRepositoryFactoryBean, * @param reactiveCouchbaseOperations the reference to the operations template. */ public void setCouchbaseOperations(final ReactiveCouchbaseOperations reactiveCouchbaseOperations) { - setCouchbaseOperationsMapping(new ReactiveRepositoryOperationsMapping(reactiveCouchbaseOperations)); + setReactiveCouchbaseOperationsMapping(new ReactiveRepositoryOperationsMapping(reactiveCouchbaseOperations)); } - public void setCouchbaseOperationsMapping(final ReactiveRepositoryOperationsMapping couchbaseOperationsMapping) { + public void setReactiveCouchbaseOperationsMapping(final ReactiveRepositoryOperationsMapping couchbaseOperationsMapping) { this.couchbaseOperationsMapping = couchbaseOperationsMapping; setMappingContext(couchbaseOperationsMapping.getMappingContext()); } diff --git a/src/main/java/org/springframework/data/couchbase/repository/support/SimpleReactiveCouchbaseRepository.java b/src/main/java/org/springframework/data/couchbase/repository/support/SimpleReactiveCouchbaseRepository.java index 52a9cab5..69db2c62 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/support/SimpleReactiveCouchbaseRepository.java +++ b/src/main/java/org/springframework/data/couchbase/repository/support/SimpleReactiveCouchbaseRepository.java @@ -16,6 +16,7 @@ package org.springframework.data.couchbase.repository.support; +import com.couchbase.client.java.query.QueryScanConsistency; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -55,18 +56,20 @@ public class SimpleReactiveCouchbaseRepository implements ReactiveCouchba */ private final CouchbaseEntityInformation entityInformation; + private CrudMethodMetadata crudMethodMetadata; + /** * Create a new Repository. * - * @param metadata the Metadata for the entity. + * @param entityInformation the Metadata for the entity. * @param operations the reference to the reactive template used. */ - public SimpleReactiveCouchbaseRepository(final CouchbaseEntityInformation metadata, + public SimpleReactiveCouchbaseRepository(final CouchbaseEntityInformation entityInformation, final ReactiveCouchbaseOperations operations) { - Assert.notNull(operations, "RxJavaCouchbaseOperations must not be null!"); - Assert.notNull(metadata, "CouchbaseEntityInformation must not be null!"); + Assert.notNull(operations, "ReactiveCouchbaseOperations must not be null!"); + Assert.notNull(entityInformation, "CouchbaseEntityInformation must not be null!"); - this.entityInformation = metadata; + this.entityInformation = entityInformation; this.operations = operations; } @@ -201,7 +204,24 @@ public class SimpleReactiveCouchbaseRepository implements ReactiveCouchba } private Flux findAll(final Query query) { - return operations.findByQuery(entityInformation.getJavaType()).matching(query).all(); + return operations.findByQuery(entityInformation.getJavaType()).consistentWith(buildQueryScanConsistency()).matching(query).all(); + } + + private QueryScanConsistency buildQueryScanConsistency() { + QueryScanConsistency scanConsistency = QueryScanConsistency.NOT_BOUNDED; + if (crudMethodMetadata.getScanConsistency() != null) { + scanConsistency = crudMethodMetadata.getScanConsistency().query(); + } + return scanConsistency; + } + + /** + * Setter for the repository metadata, contains annotations on the overidden methods. + * + * @param crudMethodMetadata the injected repository metadata. + */ + void setRepositoryMethodMetadata(final CrudMethodMetadata crudMethodMetadata) { + this.crudMethodMetadata = crudMethodMetadata; } } diff --git a/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateKeyValueIntegrationTests.java b/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateKeyValueIntegrationTests.java index 4f30cab5..9d4116cd 100644 --- a/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateKeyValueIntegrationTests.java +++ b/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateKeyValueIntegrationTests.java @@ -19,6 +19,7 @@ package org.springframework.data.couchbase.core; import static org.junit.jupiter.api.Assertions.*; import java.io.IOException; +import java.time.Duration; import java.util.UUID; import org.junit.jupiter.api.AfterAll; @@ -44,6 +45,7 @@ class CouchbaseTemplateKeyValueIntegrationTests extends ClusterAwareIntegrationT @BeforeAll static void beforeAll() { couchbaseClientFactory = new SimpleCouchbaseClientFactory(connectionString(), authenticator(), bucketName()); + couchbaseClientFactory.getBucket().waitUntilReady(Duration.ofSeconds(10)); } @AfterAll diff --git a/src/test/java/org/springframework/data/couchbase/core/CustomTypeKeyIntegrationTests.java b/src/test/java/org/springframework/data/couchbase/core/CustomTypeKeyIntegrationTests.java index 20890543..0f4037b0 100644 --- a/src/test/java/org/springframework/data/couchbase/core/CustomTypeKeyIntegrationTests.java +++ b/src/test/java/org/springframework/data/couchbase/core/CustomTypeKeyIntegrationTests.java @@ -18,6 +18,7 @@ package org.springframework.data.couchbase.core; import static org.junit.jupiter.api.Assertions.*; +import java.time.Duration; import java.util.UUID; import org.junit.jupiter.api.Test; @@ -44,6 +45,8 @@ public class CustomTypeKeyIntegrationTests extends ClusterAwareIntegrationTests @Test void saveSimpleEntityCorrectlyWithDifferentTypeKey() { + clientFactory.getBucket().waitUntilReady(Duration.ofSeconds(5)); + User user = new User(UUID.randomUUID().toString(), "firstname", "lastname"); User modified = operations.upsertById(User.class).one(user); assertEquals(user, modified); diff --git a/src/test/java/org/springframework/data/couchbase/domain/Hotel.java b/src/test/java/org/springframework/data/couchbase/domain/Hotel.java new file mode 100644 index 00000000..30c0c775 --- /dev/null +++ b/src/test/java/org/springframework/data/couchbase/domain/Hotel.java @@ -0,0 +1,67 @@ +/* + * 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.data.couchbase.domain; + +import java.util.Objects; + +import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.couchbase.core.mapping.Document; + +@Document +public class Hotel { + + @Id private String id; + + private String name; + + @PersistenceConstructor + public Hotel(final String id, final String name) { + this.id = id; + this.name = name; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return "Hotel{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Hotel hotel = (Hotel) o; + return Objects.equals(id, hotel.id) && + Objects.equals(name, hotel.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } +} diff --git a/src/test/java/org/springframework/data/couchbase/domain/ReactiveHotelRepository.java b/src/test/java/org/springframework/data/couchbase/domain/ReactiveHotelRepository.java new file mode 100644 index 00000000..f2bddb46 --- /dev/null +++ b/src/test/java/org/springframework/data/couchbase/domain/ReactiveHotelRepository.java @@ -0,0 +1,28 @@ +/* + * 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.data.couchbase.domain; + +import org.springframework.data.couchbase.repository.ReactiveCouchbaseRepository; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; + +@Repository +public interface ReactiveHotelRepository extends ReactiveCouchbaseRepository { + + Flux findByName(String name); + +} diff --git a/src/test/java/org/springframework/data/couchbase/repository/ReactiveCouchbaseRepositoryKeyValueIntegrationTests.java b/src/test/java/org/springframework/data/couchbase/repository/ReactiveCouchbaseRepositoryKeyValueIntegrationTests.java new file mode 100644 index 00000000..8e6edbd3 --- /dev/null +++ b/src/test/java/org/springframework/data/couchbase/repository/ReactiveCouchbaseRepositoryKeyValueIntegrationTests.java @@ -0,0 +1,80 @@ +/* + * 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.data.couchbase.repository; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.UUID; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration; +import org.springframework.data.couchbase.domain.Hotel; +import org.springframework.data.couchbase.domain.ReactiveHotelRepository; +import org.springframework.data.couchbase.repository.config.EnableReactiveCouchbaseRepositories; +import org.springframework.data.couchbase.util.ClusterAwareIntegrationTests; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +@SpringJUnitConfig(ReactiveCouchbaseRepositoryKeyValueIntegrationTests.Config.class) +public class ReactiveCouchbaseRepositoryKeyValueIntegrationTests extends ClusterAwareIntegrationTests { + + @Autowired + ReactiveHotelRepository reactiveHotelRepository; + + @Test + void saveAndFindById() { + Hotel user = new Hotel(UUID.randomUUID().toString(), "f"); + + assertFalse(reactiveHotelRepository.existsById(user.getId()).block()); + + /*reactiveUserRepository.save(user); + + Optional found = reactiveUserRepository.findById(user.getId()).blockOptional(); + assertTrue(found.isPresent()); + found.ifPresent(u -> assertEquals(user, u)); + + assertTrue(reactiveUserRepository.existsById(user.getId()).block());*/ + } + + @Configuration + @EnableReactiveCouchbaseRepositories("org.springframework.data.couchbase") + static class Config extends AbstractCouchbaseConfiguration { + + @Override + public String getConnectionString() { + return connectionString(); + } + + @Override + public String getUserName() { + return config().adminUsername(); + } + + @Override + public String getPassword() { + return config().adminPassword(); + } + + @Override + public String getBucketName() { + return bucketName(); + } + + } + +}