BAEL-3091: The Prototype Pattern in Java (changed code based on valid comments from a reader)

This commit is contained in:
Vivek Balasubramaniam
2019-10-29 22:27:15 +05:30
parent db85c8f275
commit d3d5b060e7
20517 changed files with 1642290 additions and 0 deletions
@@ -0,0 +1,9 @@
package com.baeldung.couchbase.async;
public interface CouchbaseEntity {
String getId();
void setId(String id);
}
@@ -0,0 +1,90 @@
package com.baeldung.couchbase.async.person;
import com.baeldung.couchbase.async.CouchbaseEntity;
public class Person implements CouchbaseEntity {
private String id;
private String type;
private String name;
private String homeTown;
Person() {
}
public Person(Builder b) {
this.id = b.id;
this.type = b.type;
this.name = b.name;
this.homeTown = b.homeTown;
}
@Override
public String getId() {
return id;
}
@Override
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getHomeTown() {
return homeTown;
}
public void setHomeTown(String homeTown) {
this.homeTown = homeTown;
}
public static class Builder {
private String id;
private String type;
private String name;
private String homeTown;
public static Builder newInstance() {
return new Builder();
}
public Person build() {
return new Person(this);
}
public Builder id(String id) {
this.id = id;
return this;
}
public Builder type(String type) {
this.type = type;
return this;
}
public Builder name(String name) {
this.name = name;
return this;
}
public Builder homeTown(String homeTown) {
this.homeTown = homeTown;
return this;
}
}
}
@@ -0,0 +1,24 @@
package com.baeldung.couchbase.async.person;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.baeldung.couchbase.async.service.AbstractCrudService;
import com.baeldung.couchbase.async.service.BucketService;
@Service
public class PersonCrudService extends AbstractCrudService<Person> {
@Autowired
public PersonCrudService(@Qualifier("TutorialBucketService") BucketService bucketService, PersonDocumentConverter converter) {
super(bucketService, converter);
}
@PostConstruct
private void init() {
loadBucket();
}
}
@@ -0,0 +1,28 @@
package com.baeldung.couchbase.async.person;
import org.springframework.stereotype.Service;
import com.baeldung.couchbase.async.service.JsonDocumentConverter;
import com.couchbase.client.java.document.JsonDocument;
import com.couchbase.client.java.document.json.JsonObject;
@Service
public class PersonDocumentConverter implements JsonDocumentConverter<Person> {
@Override
public JsonDocument toDocument(Person p) {
JsonObject content = JsonObject.empty().put("type", "Person").put("name", p.getName()).put("homeTown", p.getHomeTown());
return JsonDocument.create(p.getId(), content);
}
@Override
public Person fromDocument(JsonDocument doc) {
JsonObject content = doc.content();
Person p = new Person();
p.setId(doc.id());
p.setType("Person");
p.setName(content.getString("name"));
p.setHomeTown(content.getString("homeTown"));
return p;
}
}
@@ -0,0 +1,28 @@
package com.baeldung.couchbase.async.person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.couchbase.client.core.CouchbaseException;
@Service
public class RegistrationService {
@Autowired
private PersonCrudService crud;
public void registerNewPerson(String name, String homeTown) {
Person person = new Person();
person.setName(name);
person.setHomeTown(homeTown);
crud.create(person);
}
public Person findRegistrant(String id) {
try {
return crud.read(id);
} catch (CouchbaseException e) {
return crud.readFromReplica(id);
}
}
}
@@ -0,0 +1,27 @@
package com.baeldung.couchbase.async.service;
import com.couchbase.client.java.Bucket;
public abstract class AbstractBucketService implements BucketService {
private ClusterService clusterService;
private Bucket bucket;
protected void openBucket() {
bucket = clusterService.openBucket(getBucketName(), getBucketPassword());
}
protected abstract String getBucketName();
protected abstract String getBucketPassword();
public AbstractBucketService(ClusterService clusterService) {
this.clusterService = clusterService;
}
@Override
public Bucket getBucket() {
return bucket;
}
}
@@ -0,0 +1,142 @@
package com.baeldung.couchbase.async.service;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.baeldung.couchbase.async.CouchbaseEntity;
import com.couchbase.client.core.BackpressureException;
import com.couchbase.client.core.time.Delay;
import com.couchbase.client.java.AsyncBucket;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.ReplicaMode;
import com.couchbase.client.java.document.JsonDocument;
import com.couchbase.client.java.util.retry.RetryBuilder;
import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func1;
public abstract class AbstractCrudService<T extends CouchbaseEntity> implements CrudService<T> {
private static final Logger logger = LoggerFactory.getLogger(AbstractCrudService.class);
private BucketService bucketService;
private Bucket bucket;
private JsonDocumentConverter<T> converter;
public AbstractCrudService(BucketService bucketService, JsonDocumentConverter<T> converter) {
this.bucketService = bucketService;
this.converter = converter;
}
protected void loadBucket() {
bucket = bucketService.getBucket();
}
@Override
public void create(T t) {
if (t.getId() == null) {
t.setId(UUID.randomUUID().toString());
}
JsonDocument doc = converter.toDocument(t);
bucket.insert(doc);
}
@Override
public T read(String id) {
JsonDocument doc = bucket.get(id);
return (doc == null ? null : converter.fromDocument(doc));
}
@Override
public T readFromReplica(String id) {
List<JsonDocument> docs = bucket.getFromReplica(id, ReplicaMode.FIRST);
return (docs.isEmpty() ? null : converter.fromDocument(docs.get(0)));
}
@Override
public void update(T t) {
JsonDocument doc = converter.toDocument(t);
bucket.upsert(doc);
}
@Override
public void delete(String id) {
bucket.remove(id);
}
@Override
public List<T> readBulk(Iterable<String> ids) {
final AsyncBucket asyncBucket = bucket.async();
Observable<JsonDocument> asyncOperation = Observable.from(ids).flatMap(new Func1<String, Observable<JsonDocument>>() {
public Observable<JsonDocument> call(String key) {
return asyncBucket.get(key);
}
});
final List<T> items = new ArrayList<T>();
try {
asyncOperation.toBlocking().forEach(new Action1<JsonDocument>() {
public void call(JsonDocument doc) {
T item = converter.fromDocument(doc);
items.add(item);
}
});
} catch (Exception e) {
logger.error("Error during bulk get", e);
}
return items;
}
@Override
public void createBulk(Iterable<T> items) {
final AsyncBucket asyncBucket = bucket.async();
Observable.from(items).flatMap(new Func1<T, Observable<JsonDocument>>() {
@SuppressWarnings("unchecked")
@Override
public Observable<JsonDocument> call(final T t) {
if (t.getId() == null) {
t.setId(UUID.randomUUID().toString());
}
JsonDocument doc = converter.toDocument(t);
return asyncBucket.insert(doc).retryWhen(RetryBuilder.anyOf(BackpressureException.class).delay(Delay.exponential(TimeUnit.MILLISECONDS, 100)).max(10).build());
}
}).last().toBlocking().single();
}
@Override
public void updateBulk(Iterable<T> items) {
final AsyncBucket asyncBucket = bucket.async();
Observable.from(items).flatMap(new Func1<T, Observable<JsonDocument>>() {
@SuppressWarnings("unchecked")
@Override
public Observable<JsonDocument> call(final T t) {
JsonDocument doc = converter.toDocument(t);
return asyncBucket.upsert(doc).retryWhen(RetryBuilder.anyOf(BackpressureException.class).delay(Delay.exponential(TimeUnit.MILLISECONDS, 100)).max(10).build());
}
}).last().toBlocking().single();
}
@Override
public void deleteBulk(Iterable<String> ids) {
final AsyncBucket asyncBucket = bucket.async();
Observable.from(ids).flatMap(new Func1<String, Observable<JsonDocument>>() {
@SuppressWarnings("unchecked")
@Override
public Observable<JsonDocument> call(String key) {
return asyncBucket.remove(key).retryWhen(RetryBuilder.anyOf(BackpressureException.class).delay(Delay.exponential(TimeUnit.MILLISECONDS, 100)).max(10).build());
}
}).last().toBlocking().single();
}
@Override
public boolean exists(String id) {
return bucket.exists(id);
}
}
@@ -0,0 +1,8 @@
package com.baeldung.couchbase.async.service;
import com.couchbase.client.java.Bucket;
public interface BucketService {
Bucket getBucket();
}
@@ -0,0 +1,8 @@
package com.baeldung.couchbase.async.service;
import com.couchbase.client.java.Bucket;
public interface ClusterService {
Bucket openBucket(String name, String password);
}
@@ -0,0 +1,42 @@
package com.baeldung.couchbase.async.service;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.CouchbaseCluster;
import com.couchbase.client.java.env.CouchbaseEnvironment;
import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
@Service
public class ClusterServiceImpl implements ClusterService {
private Cluster cluster;
private Map<String, Bucket> buckets = new ConcurrentHashMap<>();
@Autowired
public ClusterServiceImpl(Cluster cluster) {
this.cluster = cluster;
}
@PostConstruct
private void init() {
CouchbaseEnvironment env = DefaultCouchbaseEnvironment.create();
cluster = CouchbaseCluster.create(env, "localhost");
}
@Override
synchronized public Bucket openBucket(String name, String password) {
if (!buckets.containsKey(name)) {
Bucket bucket = cluster.openBucket(name, password);
buckets.put(name, bucket);
}
return buckets.get(name);
}
}
@@ -0,0 +1,26 @@
package com.baeldung.couchbase.async.service;
import java.util.List;
public interface CrudService<T> {
void create(T t);
T read(String id);
T readFromReplica(String id);
void update(T t);
void delete(String id);
List<T> readBulk(Iterable<String> ids);
void createBulk(Iterable<T> items);
void updateBulk(Iterable<T> items);
void deleteBulk(Iterable<String> ids);
boolean exists(String id);
}
@@ -0,0 +1,10 @@
package com.baeldung.couchbase.async.service;
import com.couchbase.client.java.document.JsonDocument;
public interface JsonDocumentConverter<T> {
JsonDocument toDocument(T t);
T fromDocument(JsonDocument doc);
}
@@ -0,0 +1,33 @@
package com.baeldung.couchbase.async.service;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
@Qualifier("TutorialBucketService")
public class TutorialBucketService extends AbstractBucketService {
@PostConstruct
void init() {
openBucket();
}
@Autowired
public TutorialBucketService(ClusterService clusterService) {
super(clusterService);
openBucket();
}
@Override
protected String getBucketName() {
return "baeldung-tutorial";
}
@Override
protected String getBucketPassword() {
return "";
}
}
@@ -0,0 +1,87 @@
package com.baeldung.couchbase.intro;
import java.util.List;
import java.util.UUID;
import com.couchbase.client.core.CouchbaseException;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.CouchbaseCluster;
import com.couchbase.client.java.ReplicaMode;
import com.couchbase.client.java.document.JsonDocument;
import com.couchbase.client.java.document.json.JsonObject;
import com.couchbase.client.java.env.CouchbaseEnvironment;
import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
public class CodeSnippets {
static Cluster loadClusterWithDefaultEnvironment() {
return CouchbaseCluster.create("localhost");
}
static Cluster loadClusterWithCustomEnvironment() {
CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder().connectTimeout(10000).kvTimeout(3000).build();
return CouchbaseCluster.create(env, "localhost");
}
static Bucket loadDefaultBucketWithBlankPassword(Cluster cluster) {
return cluster.openBucket();
}
static Bucket loadBaeldungBucket(Cluster cluster) {
return cluster.openBucket("baeldung", "");
}
static JsonDocument insertExample(Bucket bucket) {
JsonObject content = JsonObject.empty().put("name", "John Doe").put("type", "Person").put("email", "john.doe@mydomain.com").put("homeTown", "Chicago");
String id = UUID.randomUUID().toString();
JsonDocument document = JsonDocument.create(id, content);
JsonDocument inserted = bucket.insert(document);
return inserted;
}
static JsonDocument retrieveAndUpsertExample(Bucket bucket, String id) {
JsonDocument document = bucket.get(id);
JsonObject content = document.content();
content.put("homeTown", "Kansas City");
JsonDocument upserted = bucket.upsert(document);
return upserted;
}
static JsonDocument replaceExample(Bucket bucket, String id) {
JsonDocument document = bucket.get(id);
JsonObject content = document.content();
content.put("homeTown", "Milwaukee");
JsonDocument replaced = bucket.replace(document);
return replaced;
}
static JsonDocument removeExample(Bucket bucket, String id) {
JsonDocument removed = bucket.remove(id);
return removed;
}
static JsonDocument getFirstFromReplicaExample(Bucket bucket, String id) {
try {
return bucket.get(id);
} catch (CouchbaseException e) {
List<JsonDocument> list = bucket.getFromReplica(id, ReplicaMode.FIRST);
if (!list.isEmpty()) {
return list.get(0);
}
}
return null;
}
static JsonDocument getLatestReplicaVersion(Bucket bucket, String id) {
long maxCasValue = -1;
JsonDocument latest = null;
for (JsonDocument replica : bucket.getFromReplica(id, ReplicaMode.ALL)) {
if (replica.cas() > maxCasValue) {
latest = replica;
maxCasValue = replica.cas();
}
}
return latest;
}
}
@@ -0,0 +1,6 @@
package com.baeldung.couchbase.mapreduce;
public interface CouchbaseKeyGenerator<T> {
String generateKey(T t);
}
@@ -0,0 +1,10 @@
package com.baeldung.couchbase.mapreduce;
@SuppressWarnings("serial")
public class DuplicateKeyException extends Exception {
public DuplicateKeyException(String s) {
super(s);
}
}
@@ -0,0 +1,11 @@
package com.baeldung.couchbase.mapreduce;
import java.util.UUID;
public class RandomUUIDGenerator<T> implements CouchbaseKeyGenerator<T> {
@Override
public String generateKey(T t) {
return UUID.randomUUID().toString();
}
}
@@ -0,0 +1,50 @@
package com.baeldung.couchbase.mapreduce;
public class StudentGrade {
private String name;
private String course;
private Integer grade;
private Integer hours;
public StudentGrade() { }
public StudentGrade(String name, String course, Integer grade, Integer hours) {
this.name = name;
this.course = course;
this.grade = grade;
this.hours = hours;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCourse() {
return course;
}
public void setCourse(String course) {
this.course = course;
}
public Integer getGrade() {
return grade;
}
public void setGrade(Integer grade) {
this.grade = grade;
}
public Integer getHours() {
return hours;
}
public void setHours(Integer hours) {
this.hours = hours;
}
}
@@ -0,0 +1,9 @@
package com.baeldung.couchbase.mapreduce;
public class StudentGradeKeyGenerator implements CouchbaseKeyGenerator<StudentGrade> {
@Override
public String generateKey(StudentGrade g) {
return g.getName() + ":" + g.getCourse();
}
}
@@ -0,0 +1,70 @@
package com.baeldung.couchbase.mapreduce;
import com.couchbase.client.deps.com.fasterxml.jackson.databind.ObjectMapper;
import com.couchbase.client.java.document.json.JsonArray;
import com.couchbase.client.java.view.ViewQuery;
public class StudentGradeQueryBuilder {
final ObjectMapper om = new ObjectMapper();
public ViewQuery findAll() {
return ViewQuery.from("studentGrades", "findByCourse");
}
public ViewQuery findByCourse(String course) {
return ViewQuery.from("studentGrades", "findByCourse")
.key(course);
}
public ViewQuery findByCourses(String... courses) {
return ViewQuery.from("studentGrades", "findByCourse")
.keys(JsonArray.from(courses));
}
public ViewQuery findByGradeInRange(int lower, int upper, boolean inclusiveEnd) {
return ViewQuery.from("studentGrades", "findByGrade")
.startKey(lower)
.endKey(upper)
.inclusiveEnd(inclusiveEnd);
}
public ViewQuery findByGradeLessThan(int upper) {
return ViewQuery.from("studentGrades", "findByGrade")
.endKey(upper)
.inclusiveEnd(false);
}
public ViewQuery findByGradeGreaterThan(int lower) {
return ViewQuery.from("studentGrades", "findByGrade")
.startKey(lower);
}
public ViewQuery findByCourseAndGradeInRange(String course, int minGrade, int maxGrade, boolean inclusiveEnd) {
return ViewQuery.from("studentGrades", "findByCourseAndGrade")
.startKey(JsonArray.from(course, minGrade))
.endKey(JsonArray.from(course, maxGrade))
.inclusiveEnd(inclusiveEnd);
}
public ViewQuery findTopGradesByCourse(String course, int limit) {
return ViewQuery.from("studentGrades", "findByCourseAndGrade")
.startKey(JsonArray.from(course, 100))
.endKey(JsonArray.from(course, 0))
.inclusiveEnd(true)
.descending()
.limit(limit);
}
public ViewQuery countStudentsByCourse() {
return ViewQuery.from("studentGrades", "countStudentsByCourse")
.reduce()
.groupLevel(1);
}
public ViewQuery sumCreditsByStudent() {
return ViewQuery.from("studentGrades", "sumCreditsByStudent")
.reduce()
.groupLevel(1);
}
}
@@ -0,0 +1,169 @@
package com.baeldung.couchbase.mapreduce;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.couchbase.client.deps.com.fasterxml.jackson.databind.ObjectMapper;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.CouchbaseCluster;
import com.couchbase.client.java.document.JsonDocument;
import com.couchbase.client.java.document.json.JsonArray;
import com.couchbase.client.java.document.json.JsonObject;
import com.couchbase.client.java.view.ViewQuery;
import com.couchbase.client.java.view.ViewResult;
import com.couchbase.client.java.view.ViewRow;
public class StudentGradeService {
final CouchbaseKeyGenerator<StudentGrade> keyGenerator;
final CouchbaseCluster cluster;
final Bucket bucket;
final ObjectMapper om = new ObjectMapper();
final StudentGradeQueryBuilder queryBuilder;
public StudentGradeService(CouchbaseKeyGenerator<StudentGrade> keyGenerator) {
this.keyGenerator = keyGenerator;
this.queryBuilder = new StudentGradeQueryBuilder();
cluster = CouchbaseCluster.create("127.0.0.1");
bucket = cluster.openBucket("baeldung-tutorial");
}
public String insert(StudentGrade studentGrade) throws DuplicateKeyException {
String id = keyGenerator.generateKey(studentGrade);
if(bucket.exists(id)) {
throw new DuplicateKeyException("document already exists with key " + id);
}
JsonObject content = JsonObject.empty()
.put("type", "StudentGrade")
.put("name", studentGrade.getName())
.put("course", studentGrade.getCourse())
.put("grade", studentGrade.getGrade())
.put("hours", studentGrade.getHours());
JsonDocument doc = JsonDocument.create(id, content);
bucket.insert(doc);
return id;
}
public List<JsonDocument> findAll() {
ViewQuery query = queryBuilder.findAll();
ViewResult result = bucket.query(query);
return extractDocuments(result);
}
private List<JsonDocument> extractDocuments(ViewResult result) {
List<JsonDocument> docs = new ArrayList<>();
for(ViewRow row : result.allRows()) {
JsonDocument doc = row.document();
docs.add(doc);
}
return docs;
}
public List<JsonDocument> findByCourse(String course) {
ViewQuery query = queryBuilder.findByCourse(course);
ViewResult result = bucket.query(query);
return extractDocuments(result);
}
public List<JsonDocument> findByCourses(String... courses) {
ViewQuery query = queryBuilder.findByCourses(courses);
ViewResult result = bucket.query(query);
return extractDocuments(result);
}
public List<JsonDocument> findByGradeInRange(int lower, int upper, boolean inclusiveEnd) {
ViewQuery query = queryBuilder.findByGradeInRange(lower, upper, inclusiveEnd);
ViewResult result = bucket.query(query);
return extractDocuments(result);
}
public List<JsonDocument> findByGradeLessThan(int upper) {
ViewQuery query = queryBuilder.findByGradeLessThan(upper);
ViewResult result = bucket.query(query);
return extractDocuments(result);
}
public List<JsonDocument> findByGradeGreaterThan(int lower) {
ViewQuery query = queryBuilder.findByGradeGreaterThan(lower);
ViewResult result = bucket.query(query);
return extractDocuments(result);
}
public List<JsonDocument> findByCourseAndGradeInRange(String course, int minGrade, int maxGrade, boolean inclusiveEnd) {
ViewQuery query = queryBuilder.findByCourseAndGradeInRange(course, minGrade, maxGrade, inclusiveEnd);
ViewResult result = bucket.query(query);
return extractDocuments(result);
}
public List<JsonDocument> findTopGradesByCourse(String course, int limit) {
ViewQuery query = queryBuilder.findTopGradesByCourse(course, limit);
ViewResult result = bucket.query(query);
return extractDocuments(result);
}
public Map<String, Long> countStudentsByCourse() {
ViewQuery query = ViewQuery.from("studentGrades", "countStudentsByCourse")
.reduce()
.groupLevel(1);
ViewResult result = bucket.query(query);
Map<String, Long> numStudentsByCourse = new HashMap<>();
for(ViewRow row : result.allRows()) {
JsonArray keyArray = (JsonArray) row.key();
String course = keyArray.getString(0);
long count = Long.valueOf(row.value().toString());
numStudentsByCourse.put(course, count);
}
return numStudentsByCourse;
}
public Map<String, Long> sumCreditHoursByStudent() {
ViewQuery query = ViewQuery.from("studentGrades", "sumHoursByStudent")
.reduce()
.groupLevel(1);
ViewResult result = bucket.query(query);
Map<String, Long> creditHoursByStudent = new HashMap<>();
for(ViewRow row : result.allRows()) {
String course = (String) row.key();
long sum = Long.valueOf(row.value().toString());
creditHoursByStudent.put(course, sum);
}
return creditHoursByStudent;
}
public Map<String, Long> sumGradePointsByStudent() {
ViewQuery query = ViewQuery.from("studentGrades", "sumGradePointsByStudent")
.reduce()
.groupLevel(1);
ViewResult result = bucket.query(query);
Map<String, Long> gradePointsByStudent = new HashMap<>();
for(ViewRow row : result.allRows()) {
String course = (String) row.key();
long sum = Long.valueOf(row.value().toString());
gradePointsByStudent.put(course, sum);
}
return gradePointsByStudent;
}
public Map<String, Float> calculateGpaByStudent() {
Map<String, Long> creditHoursByStudent = sumCreditHoursByStudent();
Map<String, Long> gradePointsByStudent = sumGradePointsByStudent();
Map<String, Float> result = new HashMap<>();
for(Entry<String, Long> creditHoursEntry : creditHoursByStudent.entrySet()) {
String name = creditHoursEntry.getKey();
long totalHours = creditHoursEntry.getValue();
long totalGradePoints = gradePointsByStudent.get(name);
result.put(name, ((float) totalGradePoints / totalHours));
}
return result;
}
}
@@ -0,0 +1,26 @@
package com.baeldung.couchbase.n1ql;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.Cluster;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class BucketFactory {
@Autowired
private Cluster cluster;
private Bucket travelSampleBucket;
private Bucket testBucket;
public Bucket getTravelSampleBucket() {
return (travelSampleBucket != null) ?
travelSampleBucket : cluster.openBucket("travel-sample");
}
public Bucket getTestBucket() {
return (testBucket != null) ?
testBucket : cluster.openBucket("test");
}
}
@@ -0,0 +1,34 @@
package com.baeldung.couchbase.n1ql;
import com.couchbase.client.java.query.N1qlQueryResult;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
public class CodeSnippets {
private static ObjectMapper objectMapper = new ObjectMapper();
private static final Logger logger = Logger.getLogger(CodeSnippets.class.getName());
public static List<JsonNode> extractJsonResult(N1qlQueryResult result) {
return result.allRows().stream()
.map(row -> {
try {
return objectMapper.readTree(row.value().toString());
}catch (IOException e) {
logger.log(Level.WARNING, e.getLocalizedMessage());
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
}
@@ -0,0 +1,86 @@
package com.baeldung.couchbase.spring.person;
public class Person {
private String id;
private String type;
private String name;
private String homeTown;
Person() {
}
public Person(Builder b) {
this.id = b.id;
this.type = b.type;
this.name = b.name;
this.homeTown = b.homeTown;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getHomeTown() {
return homeTown;
}
public void setHomeTown(String homeTown) {
this.homeTown = homeTown;
}
public static class Builder {
private String id;
private String type;
private String name;
private String homeTown;
public static Builder newInstance() {
return new Builder();
}
public Person build() {
return new Person(this);
}
public Builder id(String id) {
this.id = id;
return this;
}
public Builder type(String type) {
this.type = type;
return this;
}
public Builder name(String name) {
this.name = name;
return this;
}
public Builder homeTown(String homeTown) {
this.homeTown = homeTown;
return this;
}
}
}
@@ -0,0 +1,69 @@
package com.baeldung.couchbase.spring.person;
import java.util.List;
import java.util.UUID;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baeldung.couchbase.spring.service.CrudService;
import com.baeldung.couchbase.spring.service.TutorialBucketService;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.ReplicaMode;
import com.couchbase.client.java.document.JsonDocument;
@Service
public class PersonCrudService implements CrudService<Person> {
@Autowired
private TutorialBucketService bucketService;
@Autowired
private PersonDocumentConverter converter;
private Bucket bucket;
@PostConstruct
private void init() {
bucket = bucketService.getBucket();
}
@Override
public void create(Person person) {
if (person.getId() == null) {
person.setId(UUID.randomUUID().toString());
}
JsonDocument document = converter.toDocument(person);
bucket.insert(document);
}
@Override
public Person read(String id) {
JsonDocument doc = bucket.get(id);
return (doc != null ? converter.fromDocument(doc) : null);
}
@Override
public Person readFromReplica(String id) {
List<JsonDocument> docs = bucket.getFromReplica(id, ReplicaMode.FIRST);
return (docs.isEmpty() ? null : converter.fromDocument(docs.get(0)));
}
@Override
public void update(Person person) {
JsonDocument document = converter.toDocument(person);
bucket.upsert(document);
}
@Override
public void delete(String id) {
bucket.remove(id);
}
@Override
public boolean exists(String id) {
return bucket.exists(id);
}
}
@@ -0,0 +1,28 @@
package com.baeldung.couchbase.spring.person;
import org.springframework.stereotype.Service;
import com.baeldung.couchbase.spring.service.JsonDocumentConverter;
import com.couchbase.client.java.document.JsonDocument;
import com.couchbase.client.java.document.json.JsonObject;
@Service
public class PersonDocumentConverter implements JsonDocumentConverter<Person> {
@Override
public JsonDocument toDocument(Person p) {
JsonObject content = JsonObject.empty().put("type", "Person").put("name", p.getName()).put("homeTown", p.getHomeTown());
return JsonDocument.create(p.getId(), content);
}
@Override
public Person fromDocument(JsonDocument doc) {
JsonObject content = doc.content();
Person p = new Person();
p.setId(doc.id());
p.setType("Person");
p.setName(content.getString("name"));
p.setHomeTown(content.getString("homeTown"));
return p;
}
}
@@ -0,0 +1,28 @@
package com.baeldung.couchbase.spring.person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.couchbase.client.core.CouchbaseException;
@Service
public class RegistrationService {
@Autowired
private PersonCrudService crud;
public void registerNewPerson(String name, String homeTown) {
Person person = new Person();
person.setName(name);
person.setHomeTown(homeTown);
crud.create(person);
}
public Person findRegistrant(String id) {
try {
return crud.read(id);
} catch (CouchbaseException e) {
return crud.readFromReplica(id);
}
}
}
@@ -0,0 +1,9 @@
package com.baeldung.couchbase.spring.service;
import com.couchbase.client.java.Bucket;
public interface BucketService {
Bucket getBucket();
}
@@ -0,0 +1,17 @@
package com.baeldung.couchbase.spring.service;
import java.util.List;
import com.couchbase.client.java.AsyncBucket;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.document.JsonDocument;
public interface ClusterService {
Bucket openBucket(String name, String password);
List<JsonDocument> getDocuments(Bucket bucket, Iterable<String> keys);
List<JsonDocument> getDocumentsAsync(AsyncBucket bucket, Iterable<String> keys);
}
@@ -0,0 +1,81 @@
package com.baeldung.couchbase.spring.service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.couchbase.client.java.AsyncBucket;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.CouchbaseCluster;
import com.couchbase.client.java.document.JsonDocument;
import com.couchbase.client.java.env.CouchbaseEnvironment;
import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func1;
@Service
public class ClusterServiceImpl implements ClusterService {
private static final Logger logger = LoggerFactory.getLogger(ClusterServiceImpl.class);
private Cluster cluster;
private Map<String, Bucket> buckets = new ConcurrentHashMap<>();
@PostConstruct
private void init() {
CouchbaseEnvironment env = DefaultCouchbaseEnvironment.create();
cluster = CouchbaseCluster.create(env, "localhost");
}
@Override
synchronized public Bucket openBucket(String name, String password) {
if (!buckets.containsKey(name)) {
Bucket bucket = cluster.openBucket(name, password);
buckets.put(name, bucket);
}
return buckets.get(name);
}
@Override
public List<JsonDocument> getDocuments(Bucket bucket, Iterable<String> keys) {
List<JsonDocument> docs = new ArrayList<>();
for (String key : keys) {
JsonDocument doc = bucket.get(key);
if (doc != null) {
docs.add(doc);
}
}
return docs;
}
@Override
public List<JsonDocument> getDocumentsAsync(final AsyncBucket asyncBucket, Iterable<String> keys) {
Observable<JsonDocument> asyncBulkGet = Observable.from(keys).flatMap(new Func1<String, Observable<JsonDocument>>() {
public Observable<JsonDocument> call(String key) {
return asyncBucket.get(key);
}
});
final List<JsonDocument> docs = new ArrayList<>();
try {
asyncBulkGet.toBlocking().forEach(new Action1<JsonDocument>() {
public void call(JsonDocument doc) {
docs.add(doc);
}
});
} catch (Exception e) {
logger.error("Error during bulk get", e);
}
return docs;
}
}
@@ -0,0 +1,16 @@
package com.baeldung.couchbase.spring.service;
public interface CrudService<T> {
void create(T t);
T read(String id);
T readFromReplica(String id);
void update(T t);
void delete(String id);
boolean exists(String id);
}
@@ -0,0 +1,10 @@
package com.baeldung.couchbase.spring.service;
import com.couchbase.client.java.document.JsonDocument;
public interface JsonDocumentConverter<T> {
JsonDocument toDocument(T t);
T fromDocument(JsonDocument doc);
}
@@ -0,0 +1,29 @@
package com.baeldung.couchbase.spring.service;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.couchbase.client.java.Bucket;
@Service
@Qualifier("TutorialBucketService")
public class TutorialBucketService implements BucketService {
@Autowired
private ClusterService couchbase;
private Bucket bucket;
@PostConstruct
private void init() {
bucket = couchbase.openBucket("baeldung-tutorial", "");
}
@Override
public Bucket getBucket() {
return bucket;
}
}
+19
View File
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<logger name="org.springframework" level="WARN" />
<logger name="org.springframework.transaction" level="WARN" />
<!-- in order to debug some marshalling issues, this needs to be TRACE -->
<logger name="org.springframework.web.servlet.mvc" level="WARN" />
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
@@ -0,0 +1,13 @@
package com.baeldung.couchbase.async;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { AsyncIntegrationTestConfig.class })
@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class })
public abstract class AsyncIntegrationTest {
}
@@ -0,0 +1,9 @@
package com.baeldung.couchbase.async;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = { "com.baeldung.couchbase.async" })
public class AsyncIntegrationTestConfig {
}
@@ -0,0 +1,24 @@
package com.baeldung.couchbase.async.person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.CouchbaseCluster;
import com.couchbase.client.java.env.CouchbaseEnvironment;
import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
@Configuration
@ComponentScan(basePackages = {"com.baeldung.couchbase.async.service", "com.baeldung.couchbase.n1ql"})
public class PersonCrudServiceIntegrationTestConfig {
@Bean
public Cluster cluster() {
CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder()
.connectTimeout(60000)
.build();
return CouchbaseCluster.create(env, "127.0.0.1");
}
}
@@ -0,0 +1,220 @@
package com.baeldung.couchbase.async.person;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.baeldung.couchbase.async.AsyncIntegrationTest;
import com.baeldung.couchbase.async.service.BucketService;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.document.JsonDocument;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {PersonCrudServiceIntegrationTestConfig.class})
public class PersonCrudServiceLiveTest extends AsyncIntegrationTest {
@Autowired
private PersonCrudService personService;
@Autowired
@Qualifier("TutorialBucketService")
private BucketService bucketService;
@Autowired
private PersonDocumentConverter converter;
private Bucket bucket;
@Before
public void init() {
bucket = bucketService.getBucket();
}
@Test
public final void givenRandomPerson_whenCreate_thenPersonPersisted() {
// create person
Person person = randomPerson();
personService.create(person);
// check results
assertNotNull(person.getId());
assertNotNull(bucket.get(person.getId()));
// cleanup
bucket.remove(person.getId());
}
@Test
public final void givenId_whenRead_thenReturnsPerson() {
// create and insert person document
String id = insertRandomPersonDocument().id();
// read person and check results
assertNotNull(personService.read(id));
// cleanup
bucket.remove(id);
}
@Test
public final void givenNewHometown_whenUpdate_thenNewHometownPersisted() {
// create and insert person document
JsonDocument doc = insertRandomPersonDocument();
// update person
Person expected = converter.fromDocument(doc);
String updatedHomeTown = RandomStringUtils.randomAlphabetic(12);
expected.setHomeTown(updatedHomeTown);
personService.update(expected);
// check results
JsonDocument actual = bucket.get(expected.getId());
assertNotNull(actual);
assertNotNull(actual.content());
assertEquals(expected.getHomeTown(), actual.content().getString("homeTown"));
// cleanup
bucket.remove(expected.getId());
}
@Test
public final void givenRandomPerson_whenDelete_thenPersonNotInBucket() {
// create and insert person document
String id = insertRandomPersonDocument().id();
// delete person and check results
personService.delete(id);
assertNull(bucket.get(id));
}
@Test
public final void givenIds_whenReadBulk_thenReturnsOnlyPersonsWithMatchingIds() {
List<String> ids = new ArrayList<>();
// add some person documents
for (int i = 0; i < 5; i++) {
ids.add(insertRandomPersonDocument().id());
}
// perform bulk read
List<Person> persons = personService.readBulk(ids);
// check results
for (Person person : persons) {
assertTrue(ids.contains(person.getId()));
}
// cleanup
for (String id : ids) {
bucket.remove(id);
}
}
@Test
public final void givenPersons_whenInsertBulk_thenPersonsAreInserted() {
// create some persons
List<Person> persons = new ArrayList<>();
for (int i = 0; i < 5; i++) {
persons.add(randomPerson());
}
// perform bulk insert
personService.createBulk(persons);
// check results
for (Person person : persons) {
assertNotNull(bucket.get(person.getId()));
}
// cleanup
for (Person person : persons) {
bucket.remove(person.getId());
}
}
@Test
public final void givenPersons_whenUpdateBulk_thenPersonsAreUpdated() {
List<String> ids = new ArrayList<>();
// add some person documents
for (int i = 0; i < 5; i++) {
ids.add(insertRandomPersonDocument().id());
}
// load persons from Couchbase
List<Person> persons = new ArrayList<>();
for (String id : ids) {
persons.add(converter.fromDocument(bucket.get(id)));
}
// modify persons
for (Person person : persons) {
person.setHomeTown(RandomStringUtils.randomAlphabetic(10));
}
// perform bulk update
personService.updateBulk(persons);
// check results
for (Person person : persons) {
JsonDocument doc = bucket.get(person.getId());
assertEquals(person.getName(), doc.content().getString("name"));
assertEquals(person.getHomeTown(), doc.content().getString("homeTown"));
}
// cleanup
for (String id : ids) {
bucket.remove(id);
}
}
@Test
public void givenIds_whenDeleteBulk_thenPersonsAreDeleted() {
List<String> ids = new ArrayList<>();
// add some person documents
for (int i = 0; i < 5; i++) {
ids.add(insertRandomPersonDocument().id());
}
// perform bulk delete
personService.deleteBulk(ids);
// check results
for (String id : ids) {
assertNull(bucket.get(id));
}
}
private JsonDocument insertRandomPersonDocument() {
Person expected = randomPersonWithId();
JsonDocument doc = converter.toDocument(expected);
return bucket.insert(doc);
}
private Person randomPerson() {
return Person.Builder.newInstance().name(RandomStringUtils.randomAlphabetic(10)).homeTown(RandomStringUtils.randomAlphabetic(10)).build();
}
private Person randomPersonWithId() {
return Person.Builder.newInstance().id(UUID.randomUUID().toString()).name(RandomStringUtils.randomAlphabetic(10)).homeTown(RandomStringUtils.randomAlphabetic(10)).build();
}
}
@@ -0,0 +1,35 @@
package com.baeldung.couchbase.async.service;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import com.baeldung.couchbase.async.AsyncIntegrationTest;
import com.baeldung.couchbase.async.AsyncIntegrationTestConfig;
import com.baeldung.couchbase.async.service.ClusterService;
import com.couchbase.client.java.Bucket;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { AsyncIntegrationTestConfig.class })
@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class })
public class ClusterServiceLiveTest extends AsyncIntegrationTest {
@Autowired
private ClusterService couchbaseService;
private Bucket defaultBucket;
@Test
public void whenOpenBucket_thenBucketIsNotNull() throws Exception {
defaultBucket = couchbaseService.openBucket("default", "");
assertNotNull(defaultBucket);
assertFalse(defaultBucket.isClosed());
defaultBucket.close();
}
}
@@ -0,0 +1,150 @@
package com.baeldung.couchbase.mapreduce;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.couchbase.client.java.document.JsonDocument;
import com.couchbase.client.java.view.ViewResult;
import com.couchbase.client.java.view.ViewRow;
public class StudentGradeServiceLiveTest {
private static final Logger logger = LoggerFactory.getLogger(StudentGradeServiceLiveTest.class);
static StudentGradeService studentGradeService;
static Set<String> gradeIds = new HashSet<>();
@BeforeClass
public static void setUpBeforeClass() throws Exception {
studentGradeService = new StudentGradeService(new StudentGradeKeyGenerator());
insertStudentGrade(new StudentGrade("John Doe", "History", 80, 3));
insertStudentGrade(new StudentGrade("Jane Doe", "History", 89, 3));
insertStudentGrade(new StudentGrade("Bob Smith", "History", 90, 3));
insertStudentGrade(new StudentGrade("Mary Jones", "History", 92, 3));
insertStudentGrade(new StudentGrade("Jane Doe", "Math", 59, 3));
insertStudentGrade(new StudentGrade("Bob Smith", "Math", 91, 3));
insertStudentGrade(new StudentGrade("Mary Jones", "Math", 86, 3));
insertStudentGrade(new StudentGrade("John Doe", "Science", 85, 4));
insertStudentGrade(new StudentGrade("Bob Smith", "Science", 97, 4));
insertStudentGrade(new StudentGrade("Mary Jones", "Science", 84, 4));
}
private static void insertStudentGrade(StudentGrade studentGrade) {
try {
String id = studentGradeService.insert(studentGrade);
gradeIds.add(id);
} catch (DuplicateKeyException e) {
}
}
@Test
public final void whenFindAll_thenSuccess() {
List<JsonDocument> docs = studentGradeService.findAll();
printDocuments(docs);
}
@Test
public final void whenFindByCourse_thenSuccess() {
List<JsonDocument> docs = studentGradeService.findByCourse("History");
printDocuments(docs);
}
@Test
public final void whenFindByCourses_thenSuccess() {
List<JsonDocument> docs = studentGradeService.findByCourses("History", "Science");
printDocuments(docs);
}
@Test
public final void whenFindByGradeInRange_thenSuccess() {
List<JsonDocument> docs = studentGradeService.findByGradeInRange(80, 89, true);
printDocuments(docs);
}
@Test
public final void whenFindByGradeLessThan_thenSuccess() {
List<JsonDocument> docs = studentGradeService.findByGradeLessThan(60);
printDocuments(docs);
}
@Test
public final void whenFindByGradeGreaterThan_thenSuccess() {
List<JsonDocument> docs = studentGradeService.findByGradeGreaterThan(90);
printDocuments(docs);
}
@Test
public final void whenFindByCourseAndGradeInRange_thenSuccess() {
List<JsonDocument> docs = studentGradeService.findByCourseAndGradeInRange("Math", 80, 89, true);
printDocuments(docs);
}
@Test
public final void whenFindTopGradesByCourse_thenSuccess() {
List<JsonDocument> docs = studentGradeService.findTopGradesByCourse("Science", 2);
printDocuments(docs);
}
@Test
public final void whenCountStudentsByCourse_thenSuccess() {
Map<String, Long> map = studentGradeService.countStudentsByCourse();
printMap(map);
}
@Test
public final void whenSumCreditHoursByStudent_thenSuccess() {
Map<String, Long> map = studentGradeService.sumCreditHoursByStudent();
printMap(map);
}
@Test
public final void whenSumGradePointsByStudent_thenSuccess() {
Map<String, Long> map = studentGradeService.sumGradePointsByStudent();
printMap(map);
}
@Test
public final void whenCalculateGpaByStudent_thenSuccess() {
Map<String, Float> map = studentGradeService.calculateGpaByStudent();
printGpaMap(map);
}
private void printMap(Map<String, Long> map) {
for(Map.Entry<String, Long> entry : map.entrySet()) {
logger.info(entry.getKey() + "=" + entry.getValue());
}
}
private void printGpaMap(Map<String, Float> map) {
for(Map.Entry<String, Float> entry : map.entrySet()) {
logger.info(entry.getKey() + "=" + entry.getValue());
}
}
private void printDocuments(List<JsonDocument> docs) {
for(JsonDocument doc : docs) {
String key = doc.id();
logger.info(key + " = " + doc.content().toString());
}
}
private void printViewResultDocuments(ViewResult result) {
for(ViewRow row : result.allRows()) {
JsonDocument doc = row.document();
String key = doc.id();
logger.info(key + "=" + doc.content().toString());
}
}
private void printViewResultRows(ViewResult result) {
for(ViewRow row : result.allRows()) {
logger.info(row.toString());
}
}
}
@@ -0,0 +1,26 @@
package com.baeldung.couchbase.n1ql;
import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.CouchbaseCluster;
import com.couchbase.client.java.env.CouchbaseEnvironment;
import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
@Configuration
@ComponentScan(basePackages = { "com.baeldung.couchbase.n1ql" })
public class IntegrationTestConfig {
@Bean
public Cluster cluster() {
CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder()
.connectTimeout(60000)
.build();
return CouchbaseCluster.create(env, "127.0.0.1");
}
}
@@ -0,0 +1,251 @@
package com.baeldung.couchbase.n1ql;
import static com.baeldung.couchbase.n1ql.CodeSnippets.extractJsonResult;
import static com.couchbase.client.java.query.Select.select;
import static com.couchbase.client.java.query.dsl.Expression.i;
import static com.couchbase.client.java.query.dsl.Expression.s;
import static com.couchbase.client.java.query.dsl.Expression.x;
import static org.junit.Assert.assertNotNull;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.document.JsonDocument;
import com.couchbase.client.java.document.json.JsonArray;
import com.couchbase.client.java.document.json.JsonObject;
import com.couchbase.client.java.query.N1qlQuery;
import com.couchbase.client.java.query.N1qlQueryResult;
import com.couchbase.client.java.query.N1qlQueryRow;
import com.couchbase.client.java.query.Statement;
import com.fasterxml.jackson.databind.JsonNode;
import rx.Observable;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { IntegrationTestConfig.class })
public class N1QLLiveTest {
@Autowired
private Cluster cluster;
@Autowired
private BucketFactory bucketFactory;
@Test
public void givenAutowiredCluster_whenNotNull_thenNotNull() {
assertNotNull(cluster);
}
@Test
public void givenBucketFactory_whenGetTestBucket_thenNotNull() {
assertNotNull(bucketFactory.getTestBucket());
}
@Test
public void givenBucketFactory_whenGetTravelSampleBucket_thenNotNull() {
assertNotNull(bucketFactory.getTravelSampleBucket());
}
@Test
public void givenDocument_whenInsert_thenResult() {
Bucket bucket = bucketFactory.getTestBucket();
JsonObject personObj = JsonObject.create()
.put("name", "John")
.put("email", "john@doe.com")
.put("interests", JsonArray.from("Java", "Nigerian Jollof"));
String id = UUID.randomUUID().toString();
JsonDocument doc = JsonDocument.create(id, personObj);
bucket.insert(doc);
assertNotNull(bucket.get(id));
}
@Test
public void whenBasicSelectQuery_thenGetQueryResult() {
Bucket bucket = bucketFactory.getTravelSampleBucket();
N1qlQueryResult result
= bucket.query(N1qlQuery.simple("SELECT * FROM test"));
result.forEach(System.out::println);
System.out.println("result count: " + result.info().resultCount());
System.out.println("error count: " + result.info().errorCount());
}
@Test
public void givenSelectStatement_whenQuery_thenResult() {
Bucket bucket = bucketFactory.getTravelSampleBucket();
String query = "SELECT name FROM `travel-sample` " +
"WHERE type = 'airport' LIMIT 100";
N1qlQueryResult result1 = bucket.query(N1qlQuery.simple(query));
System.out.println("Result Count " + result1.info().resultCount());
N1qlQueryRow row = result1.allRows().get(0);
JsonObject rowJson = row.value();
System.out.println("Name in First Row " + rowJson.get("name"));
}
@Test
public void givenSelectStatement2_whenQuery_thenResult() {
Bucket bucket = bucketFactory.getTravelSampleBucket();
JsonObject pVal = JsonObject.create().put("type", "airport");
String query = "SELECT * FROM `travel-sample` " +
"WHERE type = $type LIMIT 100";
N1qlQueryResult r2 = bucket.query(N1qlQuery.parameterized(query, pVal));
System.out.println(r2.allRows());
List<JsonNode> list = extractJsonResult(r2);
System.out.println(
list.get(0).get("travel-sample").get("airportname").asText());
}
@Test
public void givenSelectDSL_whenQuery_thenResult() {
Bucket bucket = bucketFactory.getTravelSampleBucket();
Statement statement = select("*")
.from(i("travel-sample"))
.where(x("type").eq(s("airport")))
.limit(100);
N1qlQueryResult r3 = bucket.query(N1qlQuery.simple(statement));
List<JsonNode> list2 = extractJsonResult(r3);
System.out.println("First Airport Name: " + list2.get(0).get("travel-sample").get("airportname").asText());
}
@Test
public void givenSelectStatementWithOperators_whenQuery_thenResult() {
Bucket bucket = bucketFactory.getTravelSampleBucket();
String query2 = "SELECT t.city, " +
"t.airportname || \" (\" || t.faa || \")\" AS portname_faa " +
"FROM `travel-sample` t " +
"WHERE t.type=\"airport\"" +
"AND t.country LIKE '%States'" +
"AND t.geo.lat >= 70 " +
"LIMIT 2";
N1qlQueryResult r4 = bucket.query(N1qlQuery.simple(query2));
List<JsonNode> list3 = extractJsonResult(r4);
System.out.println("First Doc : " + list3.get(0));
}
@Test
public void givenSelectStatementWithDSL2_whenQuery_thenResult() {
Bucket bucket = bucketFactory.getTravelSampleBucket();
Statement st2 = select(
x("t.city, t.airportname")
.concat(s(" (")).concat(x("t.faa")).concat(s(")")).as("portname_faa"))
.from(i("travel-sample").as("t"))
.where( x("t.type").eq(s("airport"))
.and(x("t.country").like(s("%States")))
.and(x("t.geo.lat").gte(70)))
.limit(2);
N1qlQueryResult r5 = bucket.query(N1qlQuery.simple(st2));
List<JsonNode> list5 = extractJsonResult(r5);
System.out.println("First Doc : " + list5.get(0));
System.out.println("Query from Statement2: " + st2.toString());
}
@Test
public void givenInsertStatement_whenQuery_thenUpdate() {
Bucket bucket = bucketFactory.getTravelSampleBucket();
String query = "INSERT INTO `travel-sample` (KEY, VALUE) " +
" VALUES(" +
"\"cust1293\", " +
"{\"id\":\"1293\",\"name\":\"Sample Airline\", \"type\":\"airline\"})" +
" RETURNING META().id as docid, *";
N1qlQueryResult r1 = bucket.query(N1qlQuery.simple(query));
r1.forEach(System.out::println);
}
@Test
public void givenDocument_whenInsert_thenResults() {
Bucket bucket = bucketFactory.getTravelSampleBucket();
JsonObject ob = JsonObject.create()
.put("id", "1293")
.put("name", "Sample Airline")
.put("type", "airline");
bucket.insert(JsonDocument.create("cust1295", ob));
}
@Test
public void givenDocuments_whenBatchInsert_thenResult() {
Bucket bucket = bucketFactory.getTravelSampleBucket();
List<JsonDocument> documents = IntStream.rangeClosed(0,10)
.mapToObj( i -> {
JsonObject content = JsonObject.create()
.put("id", i)
.put("type", "airline")
.put("name", "Sample Airline " + i);
return JsonDocument.create("cust_" + i, content);
})
.collect(Collectors.toList());
List<JsonDocument> r5 = Observable
.from(documents)
.flatMap(doc -> bucket.async().insert(doc))
.toList()
.last()
.toBlocking()
.single();
r5.forEach(System.out::println);
}
@Test
public void givenUpdateStatement_whenQuery_thenUpdate() {
Bucket bucket = bucketFactory.getTravelSampleBucket();
String query2 = "UPDATE `travel-sample` USE KEYS \"cust_1\" " +
"SET name=\"Sample Airline Updated\" RETURNING name";
N1qlQueryResult result = bucket.query(N1qlQuery.simple(query2));
result.forEach(System.out::println);
}
@Test
public void givenDocument_whenUpsert_thenUpdate() {
Bucket bucket = bucketFactory.getTravelSampleBucket();
JsonObject o2 = JsonObject.create()
.put("name", "Sample Airline Updated");
bucket.upsert(JsonDocument.create("cust_1", o2));
}
@Test
public void givenUnestUpdateStatement_whenQuery_thenResult() {
Bucket bucket = bucketFactory.getTravelSampleBucket();
String query3 = "UPDATE `travel-sample` USE KEYS \"cust_2\" " +
"UNSET name RETURNING *";
N1qlQueryResult result1 = bucket.query(N1qlQuery.simple(query3));
result1.forEach(System.out::println);
}
@Test
public void givenDeleteStatement_whenQuery_thenDelete() {
Bucket bucket = bucketFactory.getTravelSampleBucket();
String query4 = "DELETE FROM `travel-sample` USE KEYS \"cust_50\"";
N1qlQueryResult result4 = bucket.query(N1qlQuery.simple(query4));
}
@Test
public void givenDeleteStatement2_whenQuery_thenDelete() {
Bucket bucket = bucketFactory.getTravelSampleBucket();
String query5 = "DELETE FROM `travel-sample` WHERE id = 0 RETURNING *";
N1qlQueryResult result5 = bucket.query(N1qlQuery.simple(query5));
}
}
@@ -0,0 +1,13 @@
package com.baeldung.couchbase.spring;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { IntegrationTestConfig.class })
@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class })
public abstract class IntegrationTest {
}
@@ -0,0 +1,9 @@
package com.baeldung.couchbase.spring;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = { "com.baeldung.couchbase.spring" })
public class IntegrationTestConfig {
}
@@ -0,0 +1,75 @@
package com.baeldung.couchbase.spring.person;
import static org.junit.Assert.*;
import javax.annotation.PostConstruct;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import com.baeldung.couchbase.spring.IntegrationTest;
public class PersonCrudServiceLiveTest extends IntegrationTest {
private static final String CLARK_KENT = "Clark Kent";
private static final String SMALLVILLE = "Smallville";
private static final String CLARK_KENT_ID = "Person:ClarkKent";
private Person clarkKent;
@Autowired
private PersonCrudService personService;
@PostConstruct
private void init() {
clarkKent = personService.read(CLARK_KENT_ID);
if (clarkKent == null) {
clarkKent = buildClarkKent();
personService.create(clarkKent);
}
}
@Test
public final void givenRandomPerson_whenCreate_thenPersonPersisted() {
Person person = randomPerson();
personService.create(person);
String id = person.getId();
assertNotNull(personService.read(id));
}
@Test
public final void givenClarkKentId_whenRead_thenReturnsClarkKent() {
Person person = personService.read(CLARK_KENT_ID);
assertNotNull(person);
}
@Test
public final void givenNewHometown_whenUpdate_thenNewHometownPersisted() {
Person expected = randomPerson();
personService.create(expected);
String updatedHomeTown = RandomStringUtils.randomAlphabetic(12);
expected.setHomeTown(updatedHomeTown);
personService.update(expected);
Person actual = personService.read(expected.getId());
assertNotNull(actual);
assertEquals(expected.getHomeTown(), actual.getHomeTown());
}
@Test
public final void givenRandomPerson_whenDelete_thenPersonNotInBucket() {
Person person = randomPerson();
personService.create(person);
String id = person.getId();
personService.delete(id);
assertNull(personService.read(id));
}
private Person buildClarkKent() {
return Person.Builder.newInstance().id(CLARK_KENT_ID).name(CLARK_KENT).homeTown(SMALLVILLE).build();
}
private Person randomPerson() {
return Person.Builder.newInstance().name(RandomStringUtils.randomAlphabetic(10)).homeTown(RandomStringUtils.randomAlphabetic(10)).build();
}
}
@@ -0,0 +1,34 @@
package com.baeldung.couchbase.spring.service;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import com.baeldung.couchbase.spring.IntegrationTest;
import com.baeldung.couchbase.spring.IntegrationTestConfig;
import com.couchbase.client.java.Bucket;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { IntegrationTestConfig.class })
@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class })
public class ClusterServiceLiveTest extends IntegrationTest {
@Autowired
private ClusterService couchbaseService;
private Bucket defaultBucket;
@Test
public void whenOpenBucket_thenBucketIsNotNull() throws Exception {
defaultBucket = couchbaseService.openBucket("default", "");
assertNotNull(defaultBucket);
assertFalse(defaultBucket.isClosed());
defaultBucket.close();
}
}
+19
View File
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<logger name="org.springframework" level="WARN" />
<logger name="org.springframework.transaction" level="WARN" />
<!-- in order to debug some marshalling issues, this needs to be TRACE -->
<logger name="org.springframework.web.servlet.mvc" level="WARN" />
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>