Skip to content

Commit

Permalink
spring-projects#265 - Add reactive examples.
Browse files Browse the repository at this point in the history
Original pull request: spring-projects#275.
  • Loading branch information
mp911de committed Nov 24, 2017
1 parent b61875f commit bd7b5e5
Show file tree
Hide file tree
Showing 11 changed files with 710 additions and 0 deletions.
1 change: 1 addition & 0 deletions couchbase/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

<modules>
<module>example</module>
<module>reactive</module>
<module>util</module>
</modules>

Expand Down
51 changes: 51 additions & 0 deletions couchbase/reactive/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Spring Data Couchbase 3.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<Airline> single = operations.save(airline)

Observable<Airline> 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.

```java
@N1qlPrimaryIndexed
@ViewIndexed(designDoc = "airlines")
public interface ReactiveAirlineRepository extends ReactiveCrudRepository<Airline, String> {

Mono<Airline> findAirlineByIataCode(String code);

@View(designDocument = "airlines", viewName = "all")
Flux<Airline> findAllBy();
}
```

```java
@N1qlPrimaryIndexed
@ViewIndexed(designDoc = "airlines")
public interface RxJava1AirlineRepository extends Repository<Airline, String> {

Single<Airline> findAirlineByIataCode(String code);

@View(designDocument = "airlines", viewName = "all")
Observable<Airline> findAllBy();

Single<Airline> findById(String id);

Single<Airline> save(Airline airline);
}
```
46 changes: 46 additions & 0 deletions couchbase/reactive/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.springframework.data.examples</groupId>
<artifactId>spring-data-couchbase-examples</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</parent>

<artifactId>spring-data-couchbase-reactive</artifactId>
<name>Spring Data Couchbase - Reactive features</name>

<dependencies>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-couchbase</artifactId>
</dependency>

<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
</dependency>

<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjava-reactive-streams</artifactId>
</dependency>

<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-data-couchbase-example-utils</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package 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.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.data.couchbase.config.AbstractReactiveCouchbaseDataConfiguration;
import org.springframework.data.couchbase.config.BeanNames;
import org.springframework.data.couchbase.config.CouchbaseConfigurer;
import org.springframework.data.couchbase.core.CouchbaseOperations;
import org.springframework.data.couchbase.repository.config.EnableReactiveCouchbaseRepositories;
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(exclude = CouchbaseRepositoriesAutoConfiguration.class) // see DATACOUCH-350
@RequiredArgsConstructor
@EnableReactiveCouchbaseRepositories
public class CouchbaseConfiguration extends AbstractReactiveCouchbaseDataConfiguration {

private final CouchbaseConfigurer couchbaseConfigurer;
private final ObjectProvider<CouchbaseOperations> couchbaseOperationsProvider;

@Override
protected CouchbaseConfigurer couchbaseConfigurer() {
return couchbaseConfigurer;
}

/**
* 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<Airline> 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);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.couchbase.model;

import lombok.Data;

import org.springframework.data.couchbase.core.mapping.Document;

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
*/
@Data
@Document
public class Airline {

@Id private String id;

@Field private String type;

@Field private String name;

@Field("iata") private String iataCode;

@Field private String icao;

@Field private String callsign;

@Field private String country;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.couchbase.repository;

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
*/
@N1qlPrimaryIndexed
@ViewIndexed(designDoc = "airlines")
public interface ReactiveAirlineRepository extends ReactiveCrudRepository<Airline, String> {

/**
* Derived query selecting by {@code iataCode}.
*
* @param code
* @return
*/
Mono<Airline> findAirlineByIataCode(String code);

/**
* Query method using {@code airlines/all} view.
*
* @return
*/
@View(designDocument = "airlines", viewName = "all")
Flux<Airline> findAllBy();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package 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<Airline, String> {

/**
* Derived query selecting by {@code iataCode}.
*
* @param code
* @return
*/
Single<Airline> findAirlineByIataCode(String code);

/**
* Query method using {@code airlines/all} view.
*
* @return
*/
@View(designDocument = "airlines", viewName = "all")
Observable<Airline> findAllBy();

/**
* Overloaded {@link org.springframework.data.repository.reactive.ReactiveCrudRepository#findById(Object)} method
* returning a RxJava 1 {@link Single}.
*
* @param id
* @return
*/
Single<Airline> findById(String id);

/**
* Overloaded {@link org.springframework.data.repository.reactive.ReactiveCrudRepository#save(Object)} method
* returning a RxJava 1 {@link Single}.
*
* @param airline
* @return
*/
Single<Airline> save(Airline airline);
}
9 changes: 9 additions & 0 deletions couchbase/reactive/src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
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
Loading

0 comments on commit bd7b5e5

Please sign in to comment.