diff --git a/couchbase/example/README.md b/couchbase/example/README.md index 3b7a2f7c..ab0c8320 100644 --- a/couchbase/example/README.md +++ b/couchbase/example/README.md @@ -4,4 +4,7 @@ This project contains samples of data access features with Spring Data (Couchbas ## Prerequisites -The examples require a running [Couchbase Server](https://www.couchbase.com/downloads) server with the travel sample bucket imported. We assume you're running Couchbase 5 and we have `spring.couchbase.bucket.password=…` accordingly to adapt RBAC authentication. +The examples require a running [Couchbase Server](https://www.couchbase.com/downloads) server with the travel sample bucket imported. We assume you're running Couchbase 6.5 and we have updated the `CouchbaseConfig` class accordingly to adapt RBAC authentication. + +For more information, see the [official documentation](https://docs.spring.io/spring-data/couchbase/docs/current/reference/html/#reference). + diff --git a/couchbase/example/src/main/java/example/springdata/couchbase/model/Airline.java b/couchbase/example/src/main/java/example/springdata/couchbase/model/Airline.java index 47f0434b..1d660b74 100644 --- a/couchbase/example/src/main/java/example/springdata/couchbase/model/Airline.java +++ b/couchbase/example/src/main/java/example/springdata/couchbase/model/Airline.java @@ -15,12 +15,14 @@ */ package example.springdata.couchbase.model; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; +import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.Version; import org.springframework.data.couchbase.core.mapping.Document; +import org.springframework.data.couchbase.core.mapping.Field; -import com.couchbase.client.java.repository.annotation.Field; -import com.couchbase.client.java.repository.annotation.Id; /** * A domain object representing an Airline @@ -29,19 +31,17 @@ import com.couchbase.client.java.repository.annotation.Id; */ @Data @Document +@JsonIgnoreProperties(ignoreUnknown = true) public class Airline { @Id private String id; - @Field - private String type; - @Field private String name; - @Field("iata") - private String iataCode; + @Field + private String iata; @Field private String icao; diff --git a/couchbase/example/src/main/java/example/springdata/couchbase/repository/AirlineRepository.java b/couchbase/example/src/main/java/example/springdata/couchbase/repository/AirlineRepository.java index c8312c18..b76bf748 100644 --- a/couchbase/example/src/main/java/example/springdata/couchbase/repository/AirlineRepository.java +++ b/couchbase/example/src/main/java/example/springdata/couchbase/repository/AirlineRepository.java @@ -18,20 +18,17 @@ package example.springdata.couchbase.repository; import example.springdata.couchbase.model.Airline; import java.util.List; - -import org.springframework.data.couchbase.core.query.N1qlPrimaryIndexed; -import org.springframework.data.couchbase.core.query.View; -import org.springframework.data.couchbase.core.query.ViewIndexed; import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; /** * Repository interface to manage {@link Airline} instances. * * @author Chandana Kithalagama * @author Mark Paluch + * @author Denis Rosa */ -@N1qlPrimaryIndexed -@ViewIndexed(designDoc = "airlines") +@Repository public interface AirlineRepository extends CrudRepository { /** @@ -40,13 +37,12 @@ public interface AirlineRepository extends CrudRepository { * @param code * @return */ - Airline findAirlineByIataCode(String code); + List findByIata(String code); /** * Query method using {@code airlines/all} view. * * @return */ - @View(designDocument = "airlines", viewName = "all") List findAllBy(); } diff --git a/couchbase/example/src/main/java/example/springdata/couchbase/repository/CouchbaseConfig.java b/couchbase/example/src/main/java/example/springdata/couchbase/repository/CouchbaseConfig.java new file mode 100644 index 00000000..3ce62537 --- /dev/null +++ b/couchbase/example/src/main/java/example/springdata/couchbase/repository/CouchbaseConfig.java @@ -0,0 +1,55 @@ +/* + * Copyright 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 + * + * 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 example.springdata.couchbase.repository; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration; + +/** + * @author Denis Rosa + * Configuration class to connnect with couchbase + */ +@Configuration +public class CouchbaseConfig extends AbstractCouchbaseConfiguration { + + + @Override + public String getConnectionString() { + return "couchbase://127.0.0.1"; + } + + @Override + public String getUserName() { + return "Administrator"; + } + + @Override + public String getPassword() { + return "password"; + } + + @Override + public String getBucketName() { + return "travel-sample"; + } + + + + @Override + protected boolean autoIndexCreation() { + return true; + } +} diff --git a/couchbase/example/src/main/java/example/springdata/couchbase/repository/CouchbaseConfiguration.java b/couchbase/example/src/main/java/example/springdata/couchbase/repository/CouchbaseConfiguration.java deleted file mode 100644 index 5d4780be..00000000 --- a/couchbase/example/src/main/java/example/springdata/couchbase/repository/CouchbaseConfiguration.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2017-2018 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 example.springdata.couchbase.repository; - -import example.springdata.couchbase.model.Airline; -import lombok.RequiredArgsConstructor; - -import java.util.List; - -import javax.annotation.PostConstruct; - -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; -import org.springframework.data.couchbase.config.BeanNames; -import org.springframework.data.couchbase.core.CouchbaseOperations; -import org.springframework.data.couchbase.repository.support.IndexManager; - -import com.couchbase.client.java.query.N1qlQuery; - -/** - * Simple configuration class. - * - * @author Chandana Kithalagama - * @author Mark Paluch - */ -@SpringBootApplication -@RequiredArgsConstructor -public class CouchbaseConfiguration { - - private final CouchbaseOperations couchbaseOperations; - - /** - * Create an {@link IndexManager} that allows index creation. - * - * @return - */ - @Bean(name = BeanNames.COUCHBASE_INDEX_MANAGER) - public IndexManager indexManager() { - return new IndexManager(true, true, false); - } - - @PostConstruct - private void postConstruct() { - - // Need to post-process travel data to add _class attribute - List airlinesWithoutClassAttribute = couchbaseOperations.findByN1QL(N1qlQuery.simple( // - "SELECT META(`travel-sample`).id AS _ID, META(`travel-sample`).cas AS _CAS, `travel-sample`.* " + // - "FROM `travel-sample` " + // - "WHERE type = \"airline\" AND _class IS MISSING;"), - Airline.class); - - airlinesWithoutClassAttribute.forEach(couchbaseOperations::save); - } -} diff --git a/couchbase/example/src/main/java/example/springdata/couchbase/repository/CouchbaseMain.java b/couchbase/example/src/main/java/example/springdata/couchbase/repository/CouchbaseMain.java new file mode 100644 index 00000000..1629210a --- /dev/null +++ b/couchbase/example/src/main/java/example/springdata/couchbase/repository/CouchbaseMain.java @@ -0,0 +1,57 @@ +/* + * Copyright 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 + * + * 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 example.springdata.couchbase.repository; + +import com.couchbase.client.java.Cluster; +import com.couchbase.client.java.manager.query.CreatePrimaryQueryIndexOptions; +import example.springdata.couchbase.model.Airline; +import lombok.RequiredArgsConstructor; +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.couchbase.core.CouchbaseTemplate; + + +/** + * Main Class of this module + * + * @author Denis Rosa + */ +@SpringBootApplication +@RequiredArgsConstructor + +public class CouchbaseMain { + + @Autowired + private final CouchbaseTemplate couchbaseTemplate; + + @Autowired + private Cluster cluster; + + /** + * Add the _class field to all Airline documents + */ + @PostConstruct + private void postConstruct() { + cluster.queryIndexes().createPrimaryIndex(couchbaseTemplate.getBucketName(), + CreatePrimaryQueryIndexOptions.createPrimaryQueryIndexOptions().ignoreIfExists(true)); + + // Need to post-process travel data to add _class attribute + cluster.query("update `travel-sample` set _class='"+Airline.class.getName()+"' where type = 'airline'"); + + } +} diff --git a/couchbase/example/src/main/resources/application.properties b/couchbase/example/src/main/resources/application.properties index 2d12d619..e900579f 100644 --- a/couchbase/example/src/main/resources/application.properties +++ b/couchbase/example/src/main/resources/application.properties @@ -1,8 +1,3 @@ -spring.couchbase.bucket.name=travel-sample -spring.couchbase.bootstrap-hosts=localhost - -# Required for Couchbase 5 -spring.couchbase.bucket.password=password # Increased timeout to fit slower environments like TravisCI spring.couchbase.env.timeouts.view=15000 diff --git a/couchbase/example/src/test/java/example/springdata/couchbase/repository/AirlineRepositoryIntegrationTests.java b/couchbase/example/src/test/java/example/springdata/couchbase/repository/AirlineRepositoryIntegrationTests.java index c7f44878..9753851b 100644 --- a/couchbase/example/src/test/java/example/springdata/couchbase/repository/AirlineRepositoryIntegrationTests.java +++ b/couchbase/example/src/test/java/example/springdata/couchbase/repository/AirlineRepositoryIntegrationTests.java @@ -34,8 +34,7 @@ import org.springframework.test.context.junit4.SpringRunner; /** * Integration tests showing basic CRUD operations through {@link AirlineRepository}. * - * @author Chandana Kithalagama - * @author Mark Paluch + * @author Denis Rosa */ @RunWith(SpringRunner.class) @SpringBootTest @@ -49,20 +48,24 @@ public class AirlineRepositoryIntegrationTests { @Autowired CouchbaseOperations couchbaseOperations; + + @Before public void before() { - airlineRepository.findById("LH").ifPresent(couchbaseOperations::remove); + if( couchbaseOperations.existsById().one("LH")) { + couchbaseOperations.removeById().one("LH"); + } } + /** * The derived query executes a N1QL query emitting a single element. */ @Test public void shouldFindAirlineN1ql() { - Airline airline = airlineRepository.findAirlineByIataCode("TQ"); - - assertThat(airline.getCallsign()).isEqualTo("TXW"); + List airlines = airlineRepository.findByIata("TQ"); + assertThat(airlines.get(0).getCallsign()).isEqualTo("TXW"); } /** @@ -73,10 +76,8 @@ public class AirlineRepositoryIntegrationTests { @Test public void shouldFindById() { - Airline airline = airlineRepository.findAirlineByIataCode("TQ"); - - assertThat(airlineRepository.findById(airline.getId())).contains(airline); - assertThat(airlineRepository.findById("unknown")).isEmpty(); + Airline airline = airlineRepository.findByIata("TQ").get(0); + assertThat(airlineRepository.findById(airline.getId()).isPresent()); } /** @@ -87,7 +88,7 @@ public class AirlineRepositoryIntegrationTests { List airlines = airlineRepository.findAllBy(); - assertThat(airlines).hasSize(187); + assertThat(airlines).hasSize(374); } /** @@ -100,7 +101,7 @@ public class AirlineRepositoryIntegrationTests { Airline airline = new Airline(); airline.setId("LH"); - airline.setIataCode("LH"); + airline.setIata("LH"); airline.setIcao("DLH"); airline.setCallsign("Lufthansa"); airline.setName("Lufthansa"); diff --git a/couchbase/pom.xml b/couchbase/pom.xml index cf8a01a5..458189c0 100644 --- a/couchbase/pom.xml +++ b/couchbase/pom.xml @@ -21,10 +21,11 @@ util + - org.springframework.boot - spring-boot-starter-data-couchbase + org.springframework.data + spring-data-couchbase diff --git a/couchbase/reactive/README.md b/couchbase/reactive/README.md index 299b26d7..e873acd4 100644 --- a/couchbase/reactive/README.md +++ b/couchbase/reactive/README.md @@ -1,51 +1,21 @@ -# Spring Data Couchbase 3.0 - Reactive examples +# Spring Data Couchbase 4.0 - Reactive examples This project contains samples of reactive data access features with Spring Data (Couchbase). -## Reactive Template API usage with `RxJavaCouchbaseOperations` - -The main reactive Template API class is `RxJavaCouchbaseTemplate`, ideally used through its interface `RxJavaCouchbaseOperations`. It defines a basic set of reactive data access operations using [RxJava 1](https://github.com/ReactiveX/RxJava/tree/1.x) `Single` and `Observable` reactive types. - -```java -Airline airline = new Airline(); - -Observable single = operations.save(airline) - -Observable airlines = operations.findByView(ViewQuery.from("airlines", "all"), Airline.class); -``` - -The test cases in `RxJavaCouchbaseOperationsIntegrationTests` show basic Template API usage. -Reactive data access reads and converts individual elements while processing the stream. - ## Reactive Repository support -Spring Data Couchbase provides reactive repository support with Project Reactor, RxJava 1 and RxJava 2 reactive types. The reactive API supports reactive type conversion between reactive types. +Spring Data Couchbase provides reactive repository support with Project Reactor: ```java -@N1qlPrimaryIndexed -@ViewIndexed(designDoc = "airlines") +@Repository public interface ReactiveAirlineRepository extends ReactiveCrudRepository { - Mono findAirlineByIataCode(String code); + Mono findByIata(String code); - @View(designDocument = "airlines", viewName = "all") Flux findAllBy(); } ``` -```java -@N1qlPrimaryIndexed -@ViewIndexed(designDoc = "airlines") -public interface RxJava1AirlineRepository extends Repository { +For more information, see the [official documentation](https://docs.spring.io/spring-data/couchbase/docs/current/reference/html/#reference). - Single findAirlineByIataCode(String code); - - @View(designDocument = "airlines", viewName = "all") - Observable findAllBy(); - - Single findById(String id); - - Single save(Airline airline); -} -``` diff --git a/couchbase/reactive/src/main/java/example/springdata/couchbase/CouchbaseConfiguration.java b/couchbase/reactive/src/main/java/example/springdata/couchbase/CouchbaseConfiguration.java deleted file mode 100644 index d730ad7a..00000000 --- a/couchbase/reactive/src/main/java/example/springdata/couchbase/CouchbaseConfiguration.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2017-2018 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 example.springdata.couchbase; - -import example.springdata.couchbase.model.Airline; -import lombok.RequiredArgsConstructor; - -import java.util.List; - -import javax.annotation.PostConstruct; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; -import org.springframework.data.couchbase.config.BeanNames; -import org.springframework.data.couchbase.core.CouchbaseOperations; -import org.springframework.data.couchbase.repository.support.IndexManager; - -import com.couchbase.client.java.query.N1qlQuery; - -/** - * Configuration class to configure reactive repositories. - * - * @author Mark Paluch - */ -@SpringBootApplication -@RequiredArgsConstructor -public class CouchbaseConfiguration { - - private final ObjectProvider couchbaseOperationsProvider; - - /** - * Create an {@link IndexManager} that allows index creation. - * - * @return - */ - @Bean(name = BeanNames.COUCHBASE_INDEX_MANAGER) - public IndexManager indexManager() { - return new IndexManager(true, true, false); - } - - @PostConstruct - private void postConstruct() { - - // Need to post-process travel data to add _class attribute - - CouchbaseOperations couchbaseOperations = couchbaseOperationsProvider.getIfUnique(); - List airlinesWithoutClassAttribute = couchbaseOperations.findByN1QL(N1qlQuery.simple( // - "SELECT META(`travel-sample`).id AS _ID, META(`travel-sample`).cas AS _CAS, `travel-sample`.* " + // - "FROM `travel-sample` " + // - "WHERE type = \"airline\" AND _class IS MISSING;"), - Airline.class); - - airlinesWithoutClassAttribute.forEach(couchbaseOperations::save); - } -} diff --git a/couchbase/reactive/src/main/java/example/springdata/couchbase/CouchbaseMain.java b/couchbase/reactive/src/main/java/example/springdata/couchbase/CouchbaseMain.java new file mode 100644 index 00000000..6c356dac --- /dev/null +++ b/couchbase/reactive/src/main/java/example/springdata/couchbase/CouchbaseMain.java @@ -0,0 +1,57 @@ +/* + * Copyright 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 + * + * 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 example.springdata.couchbase; + +import com.couchbase.client.java.Cluster; +import com.couchbase.client.java.manager.query.CreatePrimaryQueryIndexOptions; +import example.springdata.couchbase.model.Airline; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.couchbase.core.CouchbaseTemplate; + +/** + * Main Class of the module + * + * @author Denis Rosa + */ +@SpringBootApplication +@RequiredArgsConstructor +public class CouchbaseMain { + + @Autowired + private final CouchbaseTemplate couchbaseTemplate; + + @Autowired + private Cluster cluster; + + + @PostConstruct + private void postConstruct() { + + cluster.queryIndexes().createPrimaryIndex(couchbaseTemplate.getBucketName(), + CreatePrimaryQueryIndexOptions.createPrimaryQueryIndexOptions().ignoreIfExists(true)); + + // Need to post-process travel data to add _class attribute + cluster.query("update `travel-sample` set _class='"+Airline.class.getName()+"' where type = 'airline'"); + + } +} diff --git a/couchbase/reactive/src/main/java/example/springdata/couchbase/model/Airline.java b/couchbase/reactive/src/main/java/example/springdata/couchbase/model/Airline.java index 8cad44ce..ff010a4f 100644 --- a/couchbase/reactive/src/main/java/example/springdata/couchbase/model/Airline.java +++ b/couchbase/reactive/src/main/java/example/springdata/couchbase/model/Airline.java @@ -17,16 +17,17 @@ package example.springdata.couchbase.model; import lombok.Data; +import org.springframework.data.annotation.Id; import org.springframework.data.couchbase.core.mapping.Document; +import org.springframework.data.couchbase.core.mapping.Field; -import com.couchbase.client.java.repository.annotation.Field; -import com.couchbase.client.java.repository.annotation.Id; /** * A domain object representing an Airline * * @author Chandana Kithalagama * @author Mark Paluch + * @author Denis Rosa */ @Data @Document @@ -38,7 +39,7 @@ public class Airline { @Field private String name; - @Field("iata") private String iataCode; + @Field private String iata; @Field private String icao; diff --git a/couchbase/reactive/src/main/java/example/springdata/couchbase/repository/CouchbaseConfig.java b/couchbase/reactive/src/main/java/example/springdata/couchbase/repository/CouchbaseConfig.java new file mode 100644 index 00000000..3ce62537 --- /dev/null +++ b/couchbase/reactive/src/main/java/example/springdata/couchbase/repository/CouchbaseConfig.java @@ -0,0 +1,55 @@ +/* + * Copyright 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 + * + * 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 example.springdata.couchbase.repository; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration; + +/** + * @author Denis Rosa + * Configuration class to connnect with couchbase + */ +@Configuration +public class CouchbaseConfig extends AbstractCouchbaseConfiguration { + + + @Override + public String getConnectionString() { + return "couchbase://127.0.0.1"; + } + + @Override + public String getUserName() { + return "Administrator"; + } + + @Override + public String getPassword() { + return "password"; + } + + @Override + public String getBucketName() { + return "travel-sample"; + } + + + + @Override + protected boolean autoIndexCreation() { + return true; + } +} diff --git a/couchbase/reactive/src/main/java/example/springdata/couchbase/repository/ReactiveAirlineRepository.java b/couchbase/reactive/src/main/java/example/springdata/couchbase/repository/ReactiveAirlineRepository.java index e8ba17a5..85638e52 100644 --- a/couchbase/reactive/src/main/java/example/springdata/couchbase/repository/ReactiveAirlineRepository.java +++ b/couchbase/reactive/src/main/java/example/springdata/couchbase/repository/ReactiveAirlineRepository.java @@ -19,27 +19,24 @@ import example.springdata.couchbase.model.Airline; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import org.springframework.data.couchbase.core.query.N1qlPrimaryIndexed; import org.springframework.data.couchbase.core.query.View; -import org.springframework.data.couchbase.core.query.ViewIndexed; import org.springframework.data.repository.reactive.ReactiveCrudRepository; /** * Repository interface to manage {@link Airline} instances. * * @author Mark Paluch + * @author Denis Rosa */ -@N1qlPrimaryIndexed -@ViewIndexed(designDoc = "airlines") public interface ReactiveAirlineRepository extends ReactiveCrudRepository { /** - * Derived query selecting by {@code iataCode}. + * Derived query selecting by {@code iata}. * * @param code * @return */ - Mono findAirlineByIataCode(String code); + Mono findByIata(String code); /** * Query method using {@code airlines/all} view. diff --git a/couchbase/reactive/src/main/java/example/springdata/couchbase/repository/RxJava1AirlineRepository.java b/couchbase/reactive/src/main/java/example/springdata/couchbase/repository/RxJava1AirlineRepository.java deleted file mode 100644 index b98f2fac..00000000 --- a/couchbase/reactive/src/main/java/example/springdata/couchbase/repository/RxJava1AirlineRepository.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2017-2018 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 example.springdata.couchbase.repository; - -import example.springdata.couchbase.model.Airline; -import rx.Observable; -import rx.Single; - -import org.springframework.data.couchbase.core.query.N1qlPrimaryIndexed; -import org.springframework.data.couchbase.core.query.View; -import org.springframework.data.couchbase.core.query.ViewIndexed; -import org.springframework.data.repository.Repository; - -/** - * Repository interface to manage {@link Airline} instances. - * - * @author Mark Paluch - */ -@N1qlPrimaryIndexed -@ViewIndexed(designDoc = "airlines") -public interface RxJava1AirlineRepository extends Repository { - - /** - * Derived query selecting by {@code iataCode}. - * - * @param code - * @return - */ - Single findAirlineByIataCode(String code); - - /** - * Query method using {@code airlines/all} view. - * - * @return - */ - @View(designDocument = "airlines", viewName = "all") - Observable findAllBy(); - - /** - * Overloaded {@link org.springframework.data.repository.reactive.ReactiveCrudRepository#findById(Object)} method - * returning a RxJava 1 {@link Single}. - * - * @param id - * @return - */ - Single findById(String id); - - /** - * Overloaded {@link org.springframework.data.repository.reactive.ReactiveCrudRepository#save(Object)} method - * returning a RxJava 1 {@link Single}. - * - * @param airline - * @return - */ - Single save(Airline airline); -} diff --git a/couchbase/reactive/src/main/resources/application.properties b/couchbase/reactive/src/main/resources/application.properties index 2d12d619..134a5b33 100644 --- a/couchbase/reactive/src/main/resources/application.properties +++ b/couchbase/reactive/src/main/resources/application.properties @@ -1,9 +1,3 @@ -spring.couchbase.bucket.name=travel-sample -spring.couchbase.bootstrap-hosts=localhost - -# Required for Couchbase 5 -spring.couchbase.bucket.password=password - # Increased timeout to fit slower environments like TravisCI spring.couchbase.env.timeouts.view=15000 spring.couchbase.env.timeouts.query=15000 diff --git a/couchbase/reactive/src/test/java/example/springdata/couchbase/repository/ReactiveAirlineRepositoryIntegrationTests.java b/couchbase/reactive/src/test/java/example/springdata/couchbase/repository/ReactiveAirlineRepositoryIntegrationTests.java index 2e61c624..4a04a2cf 100644 --- a/couchbase/reactive/src/test/java/example/springdata/couchbase/repository/ReactiveAirlineRepositoryIntegrationTests.java +++ b/couchbase/reactive/src/test/java/example/springdata/couchbase/repository/ReactiveAirlineRepositoryIntegrationTests.java @@ -49,11 +49,8 @@ public class ReactiveAirlineRepositoryIntegrationTests { @Before public void before() { - - Airline toDelete = couchbaseOperations.findById("LH", Airline.class); - - if (toDelete != null) { - couchbaseOperations.remove(toDelete); + if (couchbaseOperations.existsById().one("LH")) { + couchbaseOperations.removeById().one("LH"); } } @@ -63,8 +60,7 @@ public class ReactiveAirlineRepositoryIntegrationTests { @Test public void shouldFindAirlineN1ql() { - StepVerifier.create(airlineRepository.findAirlineByIataCode("TQ")).assertNext(it -> { - + StepVerifier.create(airlineRepository.findByIata("TQ")).assertNext(it -> { assertThat(it.getCallsign()).isEqualTo("TXW"); }).verifyComplete(); } @@ -77,7 +73,7 @@ public class ReactiveAirlineRepositoryIntegrationTests { @Test public void shouldFindById() { - Mono airline = airlineRepository.findAirlineByIataCode("TQ") // + Mono airline = airlineRepository.findByIata("TQ") // .map(Airline::getId) // .flatMap(airlineRepository::findById); @@ -86,15 +82,14 @@ public class ReactiveAirlineRepositoryIntegrationTests { assertThat(it.getCallsign()).isEqualTo("TXW"); }).verifyComplete(); - StepVerifier.create(airlineRepository.findById("unknown")).verifyComplete(); } /** * Find all {@link Airline}s applying the {@code airlines/all} view. */ @Test - public void shouldFindByView() { - StepVerifier.create(airlineRepository.findAllBy()).expectNextCount(187).verifyComplete(); + public void shouldFindAll() { + StepVerifier.create(airlineRepository.findAllBy()).expectNextCount(374).verifyComplete(); } /** @@ -107,7 +102,7 @@ public class ReactiveAirlineRepositoryIntegrationTests { Airline airline = new Airline(); airline.setId("LH"); - airline.setIataCode("LH"); + airline.setIata("LH"); airline.setIcao("DLH"); airline.setCallsign("Lufthansa"); airline.setName("Lufthansa"); diff --git a/couchbase/reactive/src/test/java/example/springdata/couchbase/repository/RxJava1AirlineRepositoryIntegrationTests.java b/couchbase/reactive/src/test/java/example/springdata/couchbase/repository/RxJava1AirlineRepositoryIntegrationTests.java deleted file mode 100644 index af3991ae..00000000 --- a/couchbase/reactive/src/test/java/example/springdata/couchbase/repository/RxJava1AirlineRepositoryIntegrationTests.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2017-2018 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 example.springdata.couchbase.repository; - -import static org.assertj.core.api.Assertions.*; - -import example.springdata.couchbase.model.Airline; -import example.springdata.couchbase.util.CouchbaseAvailableRule; -import rx.Single; -import rx.observers.AssertableSubscriber; - -import org.junit.Before; -import org.junit.ClassRule; -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.couchbase.core.CouchbaseOperations; -import org.springframework.test.context.junit4.SpringRunner; - -/** - * Integration tests showing basic CRUD operations through {@link RxJava1AirlineRepository} - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest -public class RxJava1AirlineRepositoryIntegrationTests { - - @ClassRule // - public static CouchbaseAvailableRule COUCHBASE = CouchbaseAvailableRule.onLocalhost(); - - @Autowired RxJava1AirlineRepository airlineRepository; - - @Autowired CouchbaseOperations couchbaseOperations; - - @Before - public void before() { - - Airline toDelete = couchbaseOperations.findById("LH", Airline.class); - - if (toDelete != null) { - couchbaseOperations.remove(toDelete); - } - } - - /** - * The derived query executes a N1QL query emitting a single element. - */ - @Test - public void shouldFindAirlineN1ql() { - - AssertableSubscriber subscriber = airlineRepository.findAirlineByIataCode("TQ") // - .test() // - .awaitTerminalEvent() // - .assertCompleted(); - - assertThat(subscriber.getValueCount()).isEqualTo(1); - assertThat(subscriber.getOnNextEvents().get(0).getCallsign()).isEqualTo("TXW"); - } - - /** - * The derived query executes a N1QL query and the emitted element is used to invoke - * {@link org.springframework.data.repository.reactive.ReactiveCrudRepository#findById(Object)} for an Id-based - * lookup. Queries without a result do not emit a value. - */ - @Test - public void shouldFindById() { - - Single airline = airlineRepository.findAirlineByIataCode("TQ") // - .map(Airline::getId) // - .flatMap(airlineRepository::findById); - - AssertableSubscriber subscriber = airline.test().awaitTerminalEvent().assertCompleted(); - - assertThat(subscriber.getValueCount()).isEqualTo(1); - assertThat(subscriber.getOnNextEvents().get(0).getCallsign()).isEqualTo("TXW"); - - airlineRepository.findById("unknown").test().awaitTerminalEvent().assertNoValues(); - } - - /** - * Find all {@link Airline}s applying the {@code airlines/all} view. - */ - @Test - public void shouldFindByView() { - airlineRepository.findAllBy().test().awaitTerminalEvent().assertValueCount(187); - } - - /** - * Created elements are emitted by the - * {@link org.springframework.data.repository.reactive.ReactiveCrudRepository#save(Object)} method. - */ - @Test - public void shouldCreateAirline() { - - Airline airline = new Airline(); - - airline.setId("LH"); - airline.setIataCode("LH"); - airline.setIcao("DLH"); - airline.setCallsign("Lufthansa"); - airline.setName("Lufthansa"); - airline.setCountry("Germany"); - - Single single = airlineRepository.save(airline) // - .map(Airline::getId) // - .flatMap(airlineRepository::findById); - - single.test().awaitTerminalEvent().assertResult(airline); - } -} diff --git a/couchbase/reactive/src/test/java/example/springdata/couchbase/template/RxJavaCouchbaseOperationsIntegrationTests.java b/couchbase/reactive/src/test/java/example/springdata/couchbase/template/ReactiveJavaCouchbaseOperationsIntegrationTests.java similarity index 50% rename from couchbase/reactive/src/test/java/example/springdata/couchbase/template/RxJavaCouchbaseOperationsIntegrationTests.java rename to couchbase/reactive/src/test/java/example/springdata/couchbase/template/ReactiveJavaCouchbaseOperationsIntegrationTests.java index bdb9ed6c..4b3cce9f 100644 --- a/couchbase/reactive/src/test/java/example/springdata/couchbase/template/RxJavaCouchbaseOperationsIntegrationTests.java +++ b/couchbase/reactive/src/test/java/example/springdata/couchbase/template/ReactiveJavaCouchbaseOperationsIntegrationTests.java @@ -19,6 +19,11 @@ import static org.assertj.core.api.Assertions.*; import example.springdata.couchbase.model.Airline; import example.springdata.couchbase.util.CouchbaseAvailableRule; +import org.springframework.data.couchbase.core.CouchbaseOperations; +import org.springframework.data.couchbase.core.ReactiveCouchbaseOperations; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; import rx.Observable; import rx.observers.AssertableSubscriber; @@ -28,81 +33,62 @@ 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.couchbase.core.RxJavaCouchbaseOperations; import org.springframework.test.context.junit4.SpringRunner; -import com.couchbase.client.java.query.N1qlQuery; -import com.couchbase.client.java.view.ViewQuery; - /** * Integration tests showing basic CRUD operations through - * {@link org.springframework.data.couchbase.core.RxJavaCouchbaseOperations}. + * {@link org.springframework.data.couchbase.core.ReactiveCouchbaseOperations}. * * @author Mark Paluch + * @author Denis Rosa */ @RunWith(SpringRunner.class) @SpringBootTest -public class RxJavaCouchbaseOperationsIntegrationTests { +public class ReactiveJavaCouchbaseOperationsIntegrationTests { @ClassRule // public static CouchbaseAvailableRule COUCHBASE = CouchbaseAvailableRule.onLocalhost(); - @Autowired RxJavaCouchbaseOperations operations; + @Autowired + ReactiveCouchbaseOperations operations; + + @Autowired + CouchbaseOperations couchbaseOperations; @Before public void before() { - operations.findById("LH", Airline.class).flatMap(operations::remove).test().awaitTerminalEvent(); + if (couchbaseOperations.existsById().one("LH")) { + couchbaseOperations.removeById().one("LH"); + } } /** - * The derived query executes a N1QL query emitting a single element. + * Find all {@link Airline}s applying the _class filter . */ @Test - public void shouldFindAirlineN1ql() { - - String n1ql = "SELECT META(`travel-sample`).id AS _ID, META(`travel-sample`).cas AS _CAS, `travel-sample`.* " + // - "FROM `travel-sample` " + // - "WHERE (`iata` = \"TQ\") AND `_class` = \"example.springdata.couchbase.model.Airline\""; - - AssertableSubscriber subscriber = operations.findByN1QL(N1qlQuery.simple(n1ql), Airline.class) // - .test() // - .awaitTerminalEvent() // - .assertCompleted(); - - assertThat(subscriber.getOnNextEvents()).hasSize(1); - assertThat(subscriber.getOnNextEvents().get(0).getCallsign()).isEqualTo("TXW"); + public void shouldFindByAll() { + StepVerifier.create( operations.findByQuery( Airline.class).all()).expectNextCount(374).verifyComplete(); } /** - * Find all {@link Airline}s applying the {@code airlines/all} view. - */ - @Test - public void shouldFindByView() { - - Observable airlines = operations.findByView(ViewQuery.from("airlines", "all"), Airline.class); - - airlines.test().awaitTerminalEvent().assertValueCount(187); - } - - /** - * Created elements are emitted by {@link RxJavaCouchbaseOperations#save(Object)}. + * Created elements are emitted by {@link ReactiveCouchbaseOperations#upsertById(Class)} )}. */ @Test public void shouldCreateAirline() { - Airline airline = new Airline(); airline.setId("LH"); - airline.setIataCode("LH"); + airline.setIata("LH"); airline.setIcao("DLH"); airline.setCallsign("Lufthansa"); airline.setName("Lufthansa"); airline.setCountry("Germany"); - Observable single = operations.save(airline) // + Mono airlineMono = operations.upsertById(Airline.class) + .one(airline) // .map(Airline::getId) // - .flatMap(id -> operations.findById(id, Airline.class)); + .flatMap(id -> operations.findById(Airline.class).one(id)); - single.test().awaitTerminalEvent().assertResult(airline); + StepVerifier.create(airlineMono).expectNext(airline).verifyComplete(); } } diff --git a/pom.xml b/pom.xml index 787ae018..c71bf7cd 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ bom - + couchbase elasticsearch jdbc jpa