From f78edd35697b82691b71a20cf012c3d554a71fd5 Mon Sep 17 00:00:00 2001
From: Lukasz Rys <>
Date: Sun, 1 Sep 2019 20:15:29 +0200
Subject: [PATCH 1/3] [ BAEL-1869 ]: Couchbase spring reactive article
---
spring-5-data-reactive/README.md | 1 +
spring-5-data-reactive/pom.xml | 15 ++++
.../ReactiveCouchbaseApplication.java | 12 +++
.../configuration/CouchbaseProperties.java | 43 ++++++++++
.../N1QLReactiveCouchbaseConfiguration.java | 15 ++++
.../ReactiveCouchbaseConfiguration.java | 47 +++++++++++
.../ViewReactiveCouchbaseConfiguration.java | 13 +++
.../com/baeldung/couchbase/domain/Person.java | 43 ++++++++++
.../repository/n1ql/N1QLPersonRepository.java | 16 ++++
.../n1ql/N1QLSortingPersonRepository.java | 13 +++
.../repository/view/ViewPersonRepository.java | 20 +++++
.../CouchbaseMockConfiguration.java | 54 +++++++++++++
.../n1ql/N1QLPersonRepositoryLiveTest.java | 55 +++++++++++++
.../N1QLSortingPersonRepositoryLiveTest.java | 60 ++++++++++++++
.../ViewPersonRepositoryIntegrationTest.java | 79 +++++++++++++++++++
15 files changed, 486 insertions(+)
create mode 100644 spring-5-data-reactive/src/main/java/com/baeldung/couchbase/ReactiveCouchbaseApplication.java
create mode 100644 spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/CouchbaseProperties.java
create mode 100644 spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/N1QLReactiveCouchbaseConfiguration.java
create mode 100644 spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/ReactiveCouchbaseConfiguration.java
create mode 100644 spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/ViewReactiveCouchbaseConfiguration.java
create mode 100644 spring-5-data-reactive/src/main/java/com/baeldung/couchbase/domain/Person.java
create mode 100644 spring-5-data-reactive/src/main/java/com/baeldung/couchbase/domain/repository/n1ql/N1QLPersonRepository.java
create mode 100644 spring-5-data-reactive/src/main/java/com/baeldung/couchbase/domain/repository/n1ql/N1QLSortingPersonRepository.java
create mode 100644 spring-5-data-reactive/src/main/java/com/baeldung/couchbase/domain/repository/view/ViewPersonRepository.java
create mode 100644 spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/CouchbaseMockConfiguration.java
create mode 100644 spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/n1ql/N1QLPersonRepositoryLiveTest.java
create mode 100644 spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/n1ql/N1QLSortingPersonRepositoryLiveTest.java
create mode 100644 spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/view/ViewPersonRepositoryIntegrationTest.java
diff --git a/spring-5-data-reactive/README.md b/spring-5-data-reactive/README.md
index 4c2347dc77..4e342532b2 100644
--- a/spring-5-data-reactive/README.md
+++ b/spring-5-data-reactive/README.md
@@ -8,3 +8,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Spring Data Reactive Repositories with MongoDB](http://www.baeldung.com/spring-data-mongodb-reactive)
- [Spring Data MongoDB Tailable Cursors](https://www.baeldung.com/spring-data-mongodb-tailable-cursors)
- [A Quick Look at R2DBC with Spring Data](https://www.baeldung.com/spring-data-r2dbc)
+- [Embedded Redis Server with Spring Boot Test]()
diff --git a/spring-5-data-reactive/pom.xml b/spring-5-data-reactive/pom.xml
index 5372803842..296da87529 100644
--- a/spring-5-data-reactive/pom.xml
+++ b/spring-5-data-reactive/pom.xml
@@ -14,6 +14,14 @@
+
+ io.projectreactor
+ reactor-core
+
+
+ org.springframework.boot
+ spring-boot-starter-data-couchbase-reactive
+
org.springframework.boot
spring-boot-starter-data-mongodb-reactive
@@ -105,6 +113,12 @@
httpclient
${httpclient.version}
+
+ com.couchbase.mock
+ CouchbaseMock
+ ${couchbaseMock.version}
+ test
+
@@ -224,6 +238,7 @@
0.8.0.M8
4.5.2
1.4.199
+ 1.5.23
diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/ReactiveCouchbaseApplication.java b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/ReactiveCouchbaseApplication.java
new file mode 100644
index 0000000000..917bcfdaa8
--- /dev/null
+++ b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/ReactiveCouchbaseApplication.java
@@ -0,0 +1,12 @@
+package com.baeldung.couchbase;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ReactiveCouchbaseApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ReactiveCouchbaseApplication.class, args);
+ }
+}
diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/CouchbaseProperties.java b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/CouchbaseProperties.java
new file mode 100644
index 0000000000..85c6997c6a
--- /dev/null
+++ b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/CouchbaseProperties.java
@@ -0,0 +1,43 @@
+package com.baeldung.couchbase.configuration;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Collections;
+import java.util.List;
+
+@Configuration
+public class CouchbaseProperties {
+
+ private final List bootstrapHosts;
+ private final String bucketName;
+ private final String bucketPassword;
+ private final int port;
+
+ public CouchbaseProperties(
+ @Value("${spring.couchbase.bootstrap-hosts}") final List bootstrapHosts,
+ @Value("${spring.couchbase.bucket.name}") final String bucketName,
+ @Value("${spring.couchbase.bucket.password}") final String bucketPassword,
+ @Value("${spring.couchbase.port}") final int port) {
+ this.bootstrapHosts = Collections.unmodifiableList(bootstrapHosts);
+ this.bucketName = bucketName;
+ this.bucketPassword = bucketPassword;
+ this.port = port;
+ }
+
+ public List getBootstrapHosts() {
+ return bootstrapHosts;
+ }
+
+ public String getBucketName() {
+ return bucketName;
+ }
+
+ public String getBucketPassword() {
+ return bucketPassword;
+ }
+
+ public int getPort() {
+ return port;
+ }
+}
diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/N1QLReactiveCouchbaseConfiguration.java b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/N1QLReactiveCouchbaseConfiguration.java
new file mode 100644
index 0000000000..059bd36cae
--- /dev/null
+++ b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/N1QLReactiveCouchbaseConfiguration.java
@@ -0,0 +1,15 @@
+package com.baeldung.couchbase.configuration;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.couchbase.repository.config.EnableReactiveCouchbaseRepositories;
+
+@Configuration
+@EnableReactiveCouchbaseRepositories("com.baeldung.couchbase.domain.repository.n1ql")
+@Primary
+public class N1QLReactiveCouchbaseConfiguration extends ReactiveCouchbaseConfiguration {
+
+ public N1QLReactiveCouchbaseConfiguration(CouchbaseProperties couchbaseProperties) {
+ super(couchbaseProperties);
+ }
+}
diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/ReactiveCouchbaseConfiguration.java b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/ReactiveCouchbaseConfiguration.java
new file mode 100644
index 0000000000..80c040df9f
--- /dev/null
+++ b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/ReactiveCouchbaseConfiguration.java
@@ -0,0 +1,47 @@
+package com.baeldung.couchbase.configuration;
+
+import com.couchbase.client.java.env.CouchbaseEnvironment;
+import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
+import org.springframework.context.annotation.Bean;
+import org.springframework.data.couchbase.config.AbstractReactiveCouchbaseConfiguration;
+import org.springframework.data.couchbase.config.BeanNames;
+import org.springframework.data.couchbase.repository.support.IndexManager;
+
+import java.util.List;
+
+public abstract class ReactiveCouchbaseConfiguration extends AbstractReactiveCouchbaseConfiguration {
+
+ private CouchbaseProperties couchbaseProperties;
+
+ public ReactiveCouchbaseConfiguration(final CouchbaseProperties couchbaseProperties) {
+ this.couchbaseProperties = couchbaseProperties;
+ }
+
+ @Bean(name = BeanNames.COUCHBASE_INDEX_MANAGER)
+ public IndexManager indexManager() {
+ return new IndexManager(true, true, false);
+ }
+
+ @Override
+ protected List getBootstrapHosts() {
+ return couchbaseProperties.getBootstrapHosts();
+ }
+
+ @Override
+ protected String getBucketName() {
+ return couchbaseProperties.getBucketName();
+ }
+
+ @Override
+ protected String getBucketPassword() {
+ return couchbaseProperties.getBucketPassword();
+ }
+
+ @Override
+ public CouchbaseEnvironment couchbaseEnvironment() {
+ return DefaultCouchbaseEnvironment
+ .builder()
+ .bootstrapHttpDirectPort(couchbaseProperties.getPort())
+ .build();
+ }
+}
diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/ViewReactiveCouchbaseConfiguration.java b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/ViewReactiveCouchbaseConfiguration.java
new file mode 100644
index 0000000000..9b4d9b0319
--- /dev/null
+++ b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/ViewReactiveCouchbaseConfiguration.java
@@ -0,0 +1,13 @@
+package com.baeldung.couchbase.configuration;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.couchbase.repository.config.EnableReactiveCouchbaseRepositories;
+
+@Configuration
+@EnableReactiveCouchbaseRepositories("com.baeldung.couchbase.domain.repository.view")
+public class ViewReactiveCouchbaseConfiguration extends ReactiveCouchbaseConfiguration {
+
+ public ViewReactiveCouchbaseConfiguration(CouchbaseProperties couchbaseProperties) {
+ super(couchbaseProperties);
+ }
+}
diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/domain/Person.java b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/domain/Person.java
new file mode 100644
index 0000000000..285de34df8
--- /dev/null
+++ b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/domain/Person.java
@@ -0,0 +1,43 @@
+package com.baeldung.couchbase.domain;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.couchbase.core.mapping.Document;
+
+import java.util.Objects;
+import java.util.UUID;
+
+@Document
+public class Person {
+
+ @Id private UUID id;
+ private String firstName;
+
+ public Person(final UUID id, final String firstName) {
+ this.id = id;
+ this.firstName = firstName;
+ }
+
+ private Person() {
+ }
+
+ public UUID getId() {
+ return id;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Person person = (Person) o;
+ return Objects.equals(id, person.id) && Objects.equals(firstName, person.firstName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, firstName);
+ }
+}
diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/domain/repository/n1ql/N1QLPersonRepository.java b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/domain/repository/n1ql/N1QLPersonRepository.java
new file mode 100644
index 0000000000..6f73a77ceb
--- /dev/null
+++ b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/domain/repository/n1ql/N1QLPersonRepository.java
@@ -0,0 +1,16 @@
+package com.baeldung.couchbase.domain.repository.n1ql;
+
+import com.baeldung.couchbase.domain.Person;
+import org.springframework.data.couchbase.core.query.N1qlPrimaryIndexed;
+import org.springframework.data.repository.reactive.ReactiveCrudRepository;
+import org.springframework.stereotype.Repository;
+import reactor.core.publisher.Flux;
+
+import java.util.UUID;
+
+@Repository
+@N1qlPrimaryIndexed
+public interface N1QLPersonRepository extends ReactiveCrudRepository {
+
+ Flux findAllByFirstName(final String firstName);
+}
diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/domain/repository/n1ql/N1QLSortingPersonRepository.java b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/domain/repository/n1ql/N1QLSortingPersonRepository.java
new file mode 100644
index 0000000000..57dd149425
--- /dev/null
+++ b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/domain/repository/n1ql/N1QLSortingPersonRepository.java
@@ -0,0 +1,13 @@
+package com.baeldung.couchbase.domain.repository.n1ql;
+
+import com.baeldung.couchbase.domain.Person;
+import org.springframework.data.couchbase.core.query.N1qlPrimaryIndexed;
+import org.springframework.data.repository.reactive.ReactiveSortingRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.UUID;
+
+@Repository
+@N1qlPrimaryIndexed
+public interface N1QLSortingPersonRepository extends ReactiveSortingRepository {
+}
diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/domain/repository/view/ViewPersonRepository.java b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/domain/repository/view/ViewPersonRepository.java
new file mode 100644
index 0000000000..28a7ec1b78
--- /dev/null
+++ b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/domain/repository/view/ViewPersonRepository.java
@@ -0,0 +1,20 @@
+package com.baeldung.couchbase.domain.repository.view;
+
+import com.baeldung.couchbase.domain.Person;
+import org.springframework.data.couchbase.core.query.View;
+import org.springframework.data.couchbase.core.query.ViewIndexed;
+import org.springframework.data.repository.reactive.ReactiveCrudRepository;
+import org.springframework.stereotype.Repository;
+import reactor.core.publisher.Flux;
+
+import java.util.UUID;
+
+@Repository
+@ViewIndexed(designDoc = ViewPersonRepository.DESIGN_DOCUMENT)
+public interface ViewPersonRepository extends ReactiveCrudRepository {
+
+ String DESIGN_DOCUMENT = "persons";
+
+ @View(designDocument = ViewPersonRepository.DESIGN_DOCUMENT)
+ Flux findByFirstName(String firstName);
+}
diff --git a/spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/CouchbaseMockConfiguration.java b/spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/CouchbaseMockConfiguration.java
new file mode 100644
index 0000000000..9d4108eccd
--- /dev/null
+++ b/spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/CouchbaseMockConfiguration.java
@@ -0,0 +1,54 @@
+package com.baeldung.couchbase.domain.repository;
+
+import com.baeldung.couchbase.configuration.CouchbaseProperties;
+import com.couchbase.mock.Bucket;
+import com.couchbase.mock.BucketConfiguration;
+import com.couchbase.mock.CouchbaseMock;
+import org.springframework.boot.test.context.TestConfiguration;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.List;
+
+@TestConfiguration
+public class CouchbaseMockConfiguration {
+
+ private CouchbaseMock couchbaseMock;
+
+ public CouchbaseMockConfiguration(final CouchbaseProperties couchbaseProperties) {
+ final BucketConfiguration bucketConfiguration = new BucketConfiguration();
+ bucketConfiguration.numNodes = 1;
+ bucketConfiguration.numReplicas = 1;
+ bucketConfiguration.numVBuckets = 1024;
+ bucketConfiguration.name = couchbaseProperties.getBucketName();
+ bucketConfiguration.type = Bucket.BucketType.COUCHBASE;
+ bucketConfiguration.password = couchbaseProperties.getBucketPassword();
+
+ try {
+ couchbaseMock = new CouchbaseMock(couchbaseProperties.getPort(), List.of(bucketConfiguration));
+ } catch (final IOException ex) {
+ throw new UncheckedIOException(ex);
+ }
+ }
+
+ @PostConstruct
+ public void postConstruct() {
+ try {
+ couchbaseMock.start();
+ } catch (final IOException ex) {
+ throw new UncheckedIOException(ex);
+ }
+ try {
+ couchbaseMock.waitForStartup();
+ } catch (final InterruptedException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ @PreDestroy
+ public void preDestroy() {
+ couchbaseMock.stop();
+ }
+}
diff --git a/spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/n1ql/N1QLPersonRepositoryLiveTest.java b/spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/n1ql/N1QLPersonRepositoryLiveTest.java
new file mode 100644
index 0000000000..0c1b6bde6c
--- /dev/null
+++ b/spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/n1ql/N1QLPersonRepositoryLiveTest.java
@@ -0,0 +1,55 @@
+package com.baeldung.couchbase.domain.repository.n1ql;
+
+import com.baeldung.couchbase.domain.Person;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import reactor.core.publisher.Flux;
+import reactor.test.StepVerifier;
+
+import java.util.UUID;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class N1QLPersonRepositoryLiveTest {
+
+ @Autowired private N1QLPersonRepository personRepository;
+
+ @Test
+ public void shouldFindAll_byLastName() {
+ //Given
+ final String firstName = "John";
+ final Person matchingPerson = new Person(UUID.randomUUID(), firstName);
+ final Person nonMatchingPerson = new Person(UUID.randomUUID(), "NotJohn");
+ wrap(() -> {
+ personRepository
+ .save(matchingPerson)
+ .subscribe();
+ personRepository
+ .save(nonMatchingPerson)
+ .subscribe();
+ //When
+ final Flux allByFirstName = personRepository.findAllByFirstName(firstName);
+ //Then
+ StepVerifier
+ .create(allByFirstName)
+ .expectNext(matchingPerson)
+ .verifyComplete();
+
+ }, matchingPerson, nonMatchingPerson);
+ }
+
+ private void wrap(final Runnable runnable, final Person... people) {
+ try {
+ runnable.run();
+ } finally {
+ for (final Person person : people) {
+ personRepository
+ .delete(person)
+ .subscribe();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/n1ql/N1QLSortingPersonRepositoryLiveTest.java b/spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/n1ql/N1QLSortingPersonRepositoryLiveTest.java
new file mode 100644
index 0000000000..4ba2206e0a
--- /dev/null
+++ b/spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/n1ql/N1QLSortingPersonRepositoryLiveTest.java
@@ -0,0 +1,60 @@
+package com.baeldung.couchbase.domain.repository.n1ql;
+
+import com.baeldung.couchbase.domain.Person;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.domain.Sort;
+import org.springframework.test.context.junit4.SpringRunner;
+import reactor.core.publisher.Flux;
+import reactor.test.StepVerifier;
+
+import java.util.UUID;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class N1QLSortingPersonRepositoryLiveTest {
+
+ @Autowired private N1QLSortingPersonRepository personRepository;
+
+ @Test
+ public void shouldFindAll_sortedByFirstName() {
+ //Given
+ final Person firstPerson = new Person(UUID.randomUUID(), "John");
+ final Person secondPerson = new Person(UUID.randomUUID(), "Mikki");
+ wrap(() -> {
+ personRepository
+ .save(firstPerson)
+ .subscribe();
+ personRepository
+ .save(secondPerson)
+ .subscribe();
+ //When
+ final Flux allByFirstName = personRepository.findAll(Sort.by(Sort.Direction.DESC, "firstName"));
+ //Then
+ StepVerifier
+ .create(allByFirstName)
+ .expectNextMatches(person -> person
+ .getFirstName()
+ .equals(secondPerson.getFirstName()))
+ .expectNextMatches(person -> person
+ .getFirstName()
+ .equals(firstPerson.getFirstName()))
+ .verifyComplete();
+ }, firstPerson, secondPerson);
+ }
+
+ //workaround for deleteAll()
+ private void wrap(final Runnable runnable, final Person... people) {
+ try {
+ runnable.run();
+ } finally {
+ for (final Person person : people) {
+ personRepository
+ .delete(person)
+ .subscribe();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/view/ViewPersonRepositoryIntegrationTest.java b/spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/view/ViewPersonRepositoryIntegrationTest.java
new file mode 100644
index 0000000000..712e7b0d37
--- /dev/null
+++ b/spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/view/ViewPersonRepositoryIntegrationTest.java
@@ -0,0 +1,79 @@
+package com.baeldung.couchbase.domain.repository.view;
+
+import com.baeldung.couchbase.configuration.CouchbaseProperties;
+import com.baeldung.couchbase.configuration.ViewReactiveCouchbaseConfiguration;
+import com.baeldung.couchbase.domain.Person;
+import com.baeldung.couchbase.domain.repository.CouchbaseMockConfiguration;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+import reactor.test.StepVerifier;
+
+import java.util.UUID;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(properties = { "spring.couchbase.port=10010" }, classes = { ViewReactiveCouchbaseConfiguration.class, CouchbaseProperties.class, CouchbaseMockConfiguration.class })
+public class ViewPersonRepositoryIntegrationTest {
+
+ @Autowired private ViewPersonRepository personRepository;
+
+ @Test
+ public void shouldSavePerson_findById_thenDeleteIt() {
+ //Given
+ final UUID id = UUID.randomUUID();
+ final Person person = new Person(id, "John");
+ wrap(() -> {
+ personRepository
+ .save(person)
+ .subscribe();
+ //When
+ final Mono byId = personRepository.findById(id);
+ //Then
+ StepVerifier
+ .create(byId)
+ .expectNextMatches(result -> result
+ .getId()
+ .equals(id))
+ .expectComplete()
+ .verify();
+ }, person);
+ }
+
+ @Test
+ public void shouldFindAll_thenDeleteIt() {
+ //Given
+ final Person person = new Person(UUID.randomUUID(), "John");
+ final Person secondPerson = new Person(UUID.randomUUID(), "Mikki");
+ wrap(() -> {
+ personRepository
+ .save(person)
+ .subscribe();
+ personRepository
+ .save(secondPerson)
+ .subscribe();
+ //When
+ final Flux all = personRepository.findAll();
+ //Then
+ StepVerifier
+ .create(all)
+ .expectNextCount(2)
+ .verifyComplete();
+ }, person, secondPerson);
+ }
+
+ private void wrap(final Runnable runnable, final Person... people) {
+ try {
+ runnable.run();
+ } finally {
+ for (final Person person : people) {
+ personRepository
+ .delete(person)
+ .subscribe();
+ }
+ }
+ }
+}
\ No newline at end of file
From 5a3143b0e43f461f0f79e4dafccde9bd47c421ca Mon Sep 17 00:00:00 2001
From: Lukasz Rys <>
Date: Sun, 1 Sep 2019 21:46:14 +0200
Subject: [PATCH 2/3] BAEL-1869: Fix List.of
---
.../configuration/ReactiveCouchbaseConfiguration.java | 5 -----
.../domain/repository/CouchbaseMockConfiguration.java | 4 ++--
2 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/ReactiveCouchbaseConfiguration.java b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/ReactiveCouchbaseConfiguration.java
index 80c040df9f..3bd66a895a 100644
--- a/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/ReactiveCouchbaseConfiguration.java
+++ b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/ReactiveCouchbaseConfiguration.java
@@ -17,11 +17,6 @@ public abstract class ReactiveCouchbaseConfiguration extends AbstractReactiveCou
this.couchbaseProperties = couchbaseProperties;
}
- @Bean(name = BeanNames.COUCHBASE_INDEX_MANAGER)
- public IndexManager indexManager() {
- return new IndexManager(true, true, false);
- }
-
@Override
protected List getBootstrapHosts() {
return couchbaseProperties.getBootstrapHosts();
diff --git a/spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/CouchbaseMockConfiguration.java b/spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/CouchbaseMockConfiguration.java
index 9d4108eccd..2a09fce4b0 100644
--- a/spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/CouchbaseMockConfiguration.java
+++ b/spring-5-data-reactive/src/test/java/com/baeldung/couchbase/domain/repository/CouchbaseMockConfiguration.java
@@ -10,7 +10,7 @@ import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.IOException;
import java.io.UncheckedIOException;
-import java.util.List;
+import java.util.Collections;
@TestConfiguration
public class CouchbaseMockConfiguration {
@@ -27,7 +27,7 @@ public class CouchbaseMockConfiguration {
bucketConfiguration.password = couchbaseProperties.getBucketPassword();
try {
- couchbaseMock = new CouchbaseMock(couchbaseProperties.getPort(), List.of(bucketConfiguration));
+ couchbaseMock = new CouchbaseMock(couchbaseProperties.getPort(), Collections.singletonList(bucketConfiguration));
} catch (final IOException ex) {
throw new UncheckedIOException(ex);
}
From b04e2c32b23a378ef145893ebf99ba20306492e2 Mon Sep 17 00:00:00 2001
From: Lukasz Rys <>
Date: Tue, 3 Sep 2019 20:50:27 +0200
Subject: [PATCH 3/3] [ BAEL-1869 ]: Delete the article from README.MD.
Reformat.
---
spring-5-data-reactive/README.md | 1 -
.../couchbase/configuration/CouchbaseProperties.java | 5 +----
.../configuration/ReactiveCouchbaseConfiguration.java | 3 ---
3 files changed, 1 insertion(+), 8 deletions(-)
diff --git a/spring-5-data-reactive/README.md b/spring-5-data-reactive/README.md
index 4e342532b2..4c2347dc77 100644
--- a/spring-5-data-reactive/README.md
+++ b/spring-5-data-reactive/README.md
@@ -8,4 +8,3 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Spring Data Reactive Repositories with MongoDB](http://www.baeldung.com/spring-data-mongodb-reactive)
- [Spring Data MongoDB Tailable Cursors](https://www.baeldung.com/spring-data-mongodb-tailable-cursors)
- [A Quick Look at R2DBC with Spring Data](https://www.baeldung.com/spring-data-r2dbc)
-- [Embedded Redis Server with Spring Boot Test]()
diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/CouchbaseProperties.java b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/CouchbaseProperties.java
index 85c6997c6a..480c96e986 100644
--- a/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/CouchbaseProperties.java
+++ b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/CouchbaseProperties.java
@@ -14,10 +14,7 @@ public class CouchbaseProperties {
private final String bucketPassword;
private final int port;
- public CouchbaseProperties(
- @Value("${spring.couchbase.bootstrap-hosts}") final List bootstrapHosts,
- @Value("${spring.couchbase.bucket.name}") final String bucketName,
- @Value("${spring.couchbase.bucket.password}") final String bucketPassword,
+ public CouchbaseProperties(@Value("${spring.couchbase.bootstrap-hosts}") final List bootstrapHosts, @Value("${spring.couchbase.bucket.name}") final String bucketName, @Value("${spring.couchbase.bucket.password}") final String bucketPassword,
@Value("${spring.couchbase.port}") final int port) {
this.bootstrapHosts = Collections.unmodifiableList(bootstrapHosts);
this.bucketName = bucketName;
diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/ReactiveCouchbaseConfiguration.java b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/ReactiveCouchbaseConfiguration.java
index 3bd66a895a..2f3b5486d8 100644
--- a/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/ReactiveCouchbaseConfiguration.java
+++ b/spring-5-data-reactive/src/main/java/com/baeldung/couchbase/configuration/ReactiveCouchbaseConfiguration.java
@@ -2,10 +2,7 @@ package com.baeldung.couchbase.configuration;
import com.couchbase.client.java.env.CouchbaseEnvironment;
import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
-import org.springframework.context.annotation.Bean;
import org.springframework.data.couchbase.config.AbstractReactiveCouchbaseConfiguration;
-import org.springframework.data.couchbase.config.BeanNames;
-import org.springframework.data.couchbase.repository.support.IndexManager;
import java.util.List;