From 2e9efa16bc8dea7a6e798a3dbcbd077c2f0afa9e Mon Sep 17 00:00:00 2001 From: Kevin Gilmore Date: Fri, 3 Jun 2016 07:26:42 -0500 Subject: [PATCH] Spring Data Couchbase tutorial: multiple buckets and spatial queries --- spring-data-couchbase-2/README.md | 10 +- spring-data-couchbase-2b/.classpath | 36 ++++ spring-data-couchbase-2b/.project | 30 ++++ spring-data-couchbase-2b/.springBeans | 20 +++ spring-data-couchbase-2b/README.md | 36 ++++ spring-data-couchbase-2b/pom.xml | 105 +++++++++++ .../data/couchbase/MyCouchbaseConfig.java | 79 ++++++++ .../spring/data/couchbase/model/Campus.java | 102 +++++++++++ .../spring/data/couchbase/model/Person.java | 87 +++++++++ .../spring/data/couchbase/model/Student.java | 113 ++++++++++++ .../couchbase/repos/CampusRepository.java | 19 ++ .../couchbase/repos/PersonRepository.java | 11 ++ .../couchbase/repos/StudentRepository.java | 11 ++ .../service/CampusRepositoryService.java | 54 ++++++ .../data/couchbase/service/CampusService.java | 20 +++ .../service/PersonRepositoryService.java | 58 ++++++ .../data/couchbase/service/PersonService.java | 22 +++ .../service/StudentRepositoryService.java | 58 ++++++ .../couchbase/service/StudentService.java | 22 +++ .../src/main/resources/logback.xml | 17 ++ spring-data-couchbase-2b/src/site/site.xml | 25 +++ .../data/couchbase/IntegrationTest.java | 13 ++ .../data/couchbase/IntegrationTestConfig.java | 9 + .../data/couchbase/TestCouchbaseConfig.java | 17 ++ .../service/CampusRepositoryServiceTest.java | 135 ++++++++++++++ .../service/PersonRepositoryServiceTest.java | 130 ++++++++++++++ .../service/StudentRepositoryServiceTest.java | 170 ++++++++++++++++++ .../src/test/resources/logback.xml | 17 ++ 28 files changed, 1423 insertions(+), 3 deletions(-) create mode 100644 spring-data-couchbase-2b/.classpath create mode 100644 spring-data-couchbase-2b/.project create mode 100644 spring-data-couchbase-2b/.springBeans create mode 100644 spring-data-couchbase-2b/README.md create mode 100644 spring-data-couchbase-2b/pom.xml create mode 100644 spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/MyCouchbaseConfig.java create mode 100644 spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Campus.java create mode 100644 spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Person.java create mode 100644 spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Student.java create mode 100644 spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/CampusRepository.java create mode 100644 spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/PersonRepository.java create mode 100644 spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/StudentRepository.java create mode 100644 spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/CampusRepositoryService.java create mode 100644 spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/CampusService.java create mode 100644 spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryService.java create mode 100644 spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/PersonService.java create mode 100644 spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryService.java create mode 100644 spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/StudentService.java create mode 100644 spring-data-couchbase-2b/src/main/resources/logback.xml create mode 100644 spring-data-couchbase-2b/src/site/site.xml create mode 100644 spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTest.java create mode 100644 spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTestConfig.java create mode 100644 spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/TestCouchbaseConfig.java create mode 100644 spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/CampusRepositoryServiceTest.java create mode 100644 spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryServiceTest.java create mode 100644 spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryServiceTest.java create mode 100644 spring-data-couchbase-2b/src/test/resources/logback.xml diff --git a/spring-data-couchbase-2/README.md b/spring-data-couchbase-2/README.md index e58e37e090..3ed226fb33 100644 --- a/spring-data-couchbase-2/README.md +++ b/spring-data-couchbase-2/README.md @@ -2,11 +2,12 @@ ### Relevant Articles: - [Spring Data Couchbase](http://www.baeldung.com/spring-data-couchbase) +- [Entity Validation, Query Consistency, and Optimistic Locking in Spring Data Couchbase](http://www.baeldung.com/entity-validation-locking-and-query-consistency-in-spring-data-couchbase) ### Overview This Maven project contains the Java code for Spring Data Couchbase entities, repositories, and template-based services -as described in the tutorial, as well as a unit test +as described in the tutorials, as well as a unit/integration test for each service implementation. ### Working with the Code @@ -22,13 +23,16 @@ mvn clean install ``` ### Running the tests -There are three test classes in src/test/java in the package +The following test classes are in src/test/java in the package org.baeldung.spring.data.couchbase.service: - PersonServiceTest (abstract) - PersonRepositoryTest (concrete) - PersonTemplateServiceTest (concrete) +- StudentServiceTest (abstract) +- StudentRepositoryTest (concrete) +- StudentTemplateServiceTest (concrete) -The latter two may be run as JUnit tests from your IDE +The concrete test classes may be run as JUnit tests from your IDE or using the Maven command line: ``` mvn test diff --git a/spring-data-couchbase-2b/.classpath b/spring-data-couchbase-2b/.classpath new file mode 100644 index 0000000000..450036fc00 --- /dev/null +++ b/spring-data-couchbase-2b/.classpath @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-data-couchbase-2b/.project b/spring-data-couchbase-2b/.project new file mode 100644 index 0000000000..1690ad8ce2 --- /dev/null +++ b/spring-data-couchbase-2b/.project @@ -0,0 +1,30 @@ + + + spring-data-couchbase-2 + This project is a simple template for a jar utility using Spring. + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.springframework.ide.eclipse.core.springbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.springframework.ide.eclipse.core.springnature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/spring-data-couchbase-2b/.springBeans b/spring-data-couchbase-2b/.springBeans new file mode 100644 index 0000000000..0c014a97b6 --- /dev/null +++ b/spring-data-couchbase-2b/.springBeans @@ -0,0 +1,20 @@ + + + 1 + + + + + + + + + + + true + false + + + + + diff --git a/spring-data-couchbase-2b/README.md b/spring-data-couchbase-2b/README.md new file mode 100644 index 0000000000..262962f58a --- /dev/null +++ b/spring-data-couchbase-2b/README.md @@ -0,0 +1,36 @@ +## Spring Data Couchbase Tutorial Project + +### Relevant Articles: +- [Spring Data Couchbase](http://www.baeldung.com/spring-data-couchbase) +- [Entity Validation, Query Consistency, and Optimistic Locking in Spring Data Couchbase](http://www.baeldung.com/entity-validation-locking-and-query-consistency-in-spring-data-couchbase) + +### Overview +This Maven project contains the Java code for Spring Data Couchbase +entities, repositories, and repository-based services +as described in the tutorials, as well as a unit/integration test +for each service implementation. + +### Working with the Code +The project was developed and tested using Java 7 and 8 in the Eclipse-based +Spring Source Toolkit (STS) and therefore should run fine in any +recent version of Eclipse or another IDE of your choice +that supports Java 7 or later. + +### Building the Project +You can also build the project using Maven outside of any IDE: +``` +mvn clean install +``` + +### Running the tests +The following test classes are in src/test/java in the package +org.baeldung.spring.data.couchbase.service: +- CampusRepositoryServiceTest +- PersonRepositoryServiceTest +- StudentRepositoryServiceTest + +These may be run as JUnit tests from your IDE +or using the Maven command line: +``` +mvn test +``` diff --git a/spring-data-couchbase-2b/pom.xml b/spring-data-couchbase-2b/pom.xml new file mode 100644 index 0000000000..7d58f78ce5 --- /dev/null +++ b/spring-data-couchbase-2b/pom.xml @@ -0,0 +1,105 @@ + + 4.0.0 + org.baeldung + spring-data-couchbase-2b + 0.1-SNAPSHOT + spring-data-couchbase-2b + jar + + + + + + org.springframework + spring-context + ${spring-framework.version} + + + org.springframework + spring-context-support + ${spring-framework.version} + + + org.springframework.data + spring-data-couchbase + ${spring-data-couchbase.version} + + + + + org.hibernate + hibernate-validator + ${hibernate-validator.version} + + + + joda-time + joda-time + ${joda-time.version} + + + + + org.slf4j + slf4j-api + ${org.slf4j.version} + compile + + + ch.qos.logback + logback-classic + ${logback.version} + + + org.slf4j + jcl-over-slf4j + ${org.slf4j.version} + + + org.slf4j + log4j-over-slf4j + ${org.slf4j.version} + + + + + org.springframework + spring-test + ${spring-framework.version} + test + + + junit + junit + ${junit.version} + test + + + + + + + maven-compiler-plugin + 2.3.2 + + 1.7 + 1.7 + + + + + + + 1.7 + UTF-8 + 4.2.4.RELEASE + 2.1.1.RELEASE + 5.2.4.Final + 2.9.2 + 1.1.3 + 1.7.12 + 4.11 + + + + diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/MyCouchbaseConfig.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/MyCouchbaseConfig.java new file mode 100644 index 0000000000..8eeda08455 --- /dev/null +++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/MyCouchbaseConfig.java @@ -0,0 +1,79 @@ +package org.baeldung.spring.data.couchbase; + +import java.util.Arrays; +import java.util.List; + +import org.baeldung.spring.data.couchbase.model.Campus; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration; +import org.springframework.data.couchbase.core.CouchbaseTemplate; +import org.springframework.data.couchbase.core.mapping.event.ValidatingCouchbaseEventListener; +import org.springframework.data.couchbase.core.query.Consistency; +import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories; +import org.springframework.data.couchbase.repository.config.RepositoryOperationsMapping; +import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; + +import com.couchbase.client.java.Bucket; + +@Configuration +@EnableCouchbaseRepositories(basePackages={"org.baeldung.spring.data.couchbase"}) +public class MyCouchbaseConfig extends AbstractCouchbaseConfiguration { + + public static final List NODE_LIST = Arrays.asList("localhost"); + public static final String DEFAULT_BUCKET_NAME = "baeldung"; + public static final String DEFAULT_BUCKET_PASSWORD = ""; + + @Override + protected List getBootstrapHosts() { + return NODE_LIST; + } + + @Override + protected String getBucketName() { + return DEFAULT_BUCKET_NAME; + } + + @Override + protected String getBucketPassword() { + return DEFAULT_BUCKET_PASSWORD; + } + + @Bean + public Bucket campusBucket() throws Exception { + return couchbaseCluster().openBucket("baeldung2", ""); + } + + @Bean + public CouchbaseTemplate campusTemplate() throws Exception { + CouchbaseTemplate template = new CouchbaseTemplate( + couchbaseClusterInfo(), campusBucket(), + mappingCouchbaseConverter(), translationService()); + template.setDefaultConsistency(getDefaultConsistency()); + return template; + } + + @Override + public void configureRepositoryOperationsMapping(RepositoryOperationsMapping baseMapping) { + try { + baseMapping.mapEntity(Campus.class, campusTemplate()); + } catch (Exception e) { + //custom Exception handling + } + } + + @Override + protected Consistency getDefaultConsistency() { + return Consistency.READ_YOUR_OWN_WRITES; + } + + @Bean + public LocalValidatorFactoryBean localValidatorFactoryBean() { + return new LocalValidatorFactoryBean(); + } + + @Bean + public ValidatingCouchbaseEventListener validatingCouchbaseEventListener() { + return new ValidatingCouchbaseEventListener(localValidatorFactoryBean()); + } +} diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Campus.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Campus.java new file mode 100644 index 0000000000..201b14cf0b --- /dev/null +++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Campus.java @@ -0,0 +1,102 @@ +package org.baeldung.spring.data.couchbase.model; + +import javax.validation.constraints.NotNull; + +import org.springframework.data.annotation.Id; +import org.springframework.data.couchbase.core.mapping.Document; +import org.springframework.data.geo.Point; + +import com.couchbase.client.java.repository.annotation.Field; + +@Document +public class Campus { + + @Id + private String id; + @Field + @NotNull + private String name; + @Field + @NotNull + private Point location; + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public Point getLocation() { + return location; + } + public void setLocation(Point location) { + this.location = location; + } + + @Override + public int hashCode() { + int hash = 1; + if(id != null) { + hash = hash * 31 + id.hashCode(); + } + if(name != null) { + hash = hash * 31 + name.hashCode(); + } + if(location != null) { + hash = hash * 31 + location.hashCode(); + } + return hash; + } + + @Override + public boolean equals(Object obj) { + if((obj == null) || (obj.getClass() != this.getClass())) return false; + if(obj == this) return true; + Campus other = (Campus) obj; + return this.hashCode() == other.hashCode(); + } + + @SuppressWarnings("unused") + private Campus() {} + + public Campus(Builder b) { + this.id = b.id; + this.name = b.name; + this.location = b.location; + } + + public static class Builder { + private String id; + private String name; + private Point location; + + public static Builder newInstance() { + return new Builder(); + } + + public Campus build() { + return new Campus(this); + } + + public Builder id(String id) { + this.id = id; + return this; + } + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder location(Point location) { + this.location = location; + return this; + } + } +} diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Person.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Person.java new file mode 100644 index 0000000000..9220e157ed --- /dev/null +++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Person.java @@ -0,0 +1,87 @@ +package org.baeldung.spring.data.couchbase.model; + +import javax.validation.constraints.NotNull; + +import org.joda.time.DateTime; +import org.springframework.data.annotation.Id; +import org.springframework.data.couchbase.core.mapping.Document; + +import com.couchbase.client.java.repository.annotation.Field; + +@Document +public class Person { + + @Id + private String id; + @Field + @NotNull + private String firstName; + @Field + @NotNull + private String lastName; + @Field + @NotNull + private DateTime created; + @Field + private DateTime updated; + + public Person(String id, String firstName, String lastName) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + } + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getFirstName() { + return firstName; + } + public void setFirstName(String firstName) { + this.firstName = firstName; + } + public String getLastName() { + return lastName; + } + public void setLastName(String lastName) { + this.lastName = lastName; + } + public DateTime getCreated() { + return created; + } + public void setCreated(DateTime created) { + this.created = created; + } + public DateTime getUpdated() { + return updated; + } + public void setUpdated(DateTime updated) { + this.updated = updated; + } + + @Override + public int hashCode() { + int hash = 1; + if(id != null) { + hash = hash * 31 + id.hashCode(); + } + if(firstName != null) { + hash = hash * 31 + firstName.hashCode(); + } + if(lastName != null) { + hash = hash * 31 + lastName.hashCode(); + } + return hash; + } + + @Override + public boolean equals(Object obj) { + if((obj == null) || (obj.getClass() != this.getClass())) return false; + if(obj == this) return true; + Person other = (Person) obj; + return this.hashCode() == other.hashCode(); + } +} diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Student.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Student.java new file mode 100644 index 0000000000..9c266c2c62 --- /dev/null +++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Student.java @@ -0,0 +1,113 @@ +package org.baeldung.spring.data.couchbase.model; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Past; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; + +import org.joda.time.DateTime; +import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.Version; +import org.springframework.data.couchbase.core.mapping.Document; + +import com.couchbase.client.java.repository.annotation.Field; + +@Document +public class Student { + private static final String NAME_REGEX = "^[a-zA-Z .'-]+$"; + + @Id + private String id; + @Field + @NotNull + @Size(min=1, max=20) + @Pattern(regexp=NAME_REGEX) + private String firstName; + @Field + @NotNull + @Size(min=1, max=20) + @Pattern(regexp=NAME_REGEX) + private String lastName; + @Field + @Past + private DateTime dateOfBirth; + @Field + @NotNull + private DateTime created; + @Field + private DateTime updated; + @Version + private long version; + + public Student() {} + + public Student(String id, String firstName, String lastName, DateTime dateOfBirth) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.dateOfBirth = dateOfBirth; + } + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getFirstName() { + return firstName; + } + public void setFirstName(String firstName) { + this.firstName = firstName; + } + public String getLastName() { + return lastName; + } + public void setLastName(String lastName) { + this.lastName = lastName; + } + public DateTime getDateOfBirth() { + return dateOfBirth; + } + public void setDateOfBirth(DateTime dateOfBirth) { + this.dateOfBirth = dateOfBirth; + } + public DateTime getCreated() { + return created; + } + public void setCreated(DateTime created) { + this.created = created; + } + public DateTime getUpdated() { + return updated; + } + public void setUpdated(DateTime updated) { + this.updated = updated; + } + + @Override + public int hashCode() { + int hash = 1; + if(id != null) { + hash = hash * 31 + id.hashCode(); + } + if(firstName != null) { + hash = hash * 31 + firstName.hashCode(); + } + if(lastName != null) { + hash = hash * 31 + lastName.hashCode(); + } + if(dateOfBirth != null) { + hash = hash * 31 + dateOfBirth.hashCode(); + } + return hash; + } + + @Override + public boolean equals(Object obj) { + if((obj == null) || (obj.getClass() != this.getClass())) return false; + if(obj == this) return true; + Student other = (Student) obj; + return this.hashCode() == other.hashCode(); + } +} \ No newline at end of file diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/CampusRepository.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/CampusRepository.java new file mode 100644 index 0000000000..22b2fb2735 --- /dev/null +++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/CampusRepository.java @@ -0,0 +1,19 @@ +package org.baeldung.spring.data.couchbase.repos; + +import java.util.Set; + +import org.baeldung.spring.data.couchbase.model.Campus; +import org.springframework.data.couchbase.core.query.Dimensional; +import org.springframework.data.couchbase.core.query.View; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.Point; +import org.springframework.data.repository.CrudRepository; + +public interface CampusRepository extends CrudRepository { + + @View(designDocument="campus", viewName="byName") + Set findByName(String name); + + @Dimensional(dimensions=2, designDocument="campus_spatial", spatialViewName="byLocation") + Set findByLocationNear(Point point, Distance distance); +} diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/PersonRepository.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/PersonRepository.java new file mode 100644 index 0000000000..14b77759e3 --- /dev/null +++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/PersonRepository.java @@ -0,0 +1,11 @@ +package org.baeldung.spring.data.couchbase.repos; + +import java.util.List; + +import org.baeldung.spring.data.couchbase.model.Person; +import org.springframework.data.repository.CrudRepository; + +public interface PersonRepository extends CrudRepository { + List findByFirstName(String firstName); + List findByLastName(String lastName); +} diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/StudentRepository.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/StudentRepository.java new file mode 100644 index 0000000000..433964c872 --- /dev/null +++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/StudentRepository.java @@ -0,0 +1,11 @@ +package org.baeldung.spring.data.couchbase.repos; + +import java.util.List; + +import org.baeldung.spring.data.couchbase.model.Student; +import org.springframework.data.repository.CrudRepository; + +public interface StudentRepository extends CrudRepository { + List findByFirstName(String firstName); + List findByLastName(String lastName); +} diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/CampusRepositoryService.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/CampusRepositoryService.java new file mode 100644 index 0000000000..d12e59ba1f --- /dev/null +++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/CampusRepositoryService.java @@ -0,0 +1,54 @@ +package org.baeldung.spring.data.couchbase.service; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.baeldung.spring.data.couchbase.model.Campus; +import org.baeldung.spring.data.couchbase.repos.CampusRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.Point; +import org.springframework.stereotype.Service; + +@Service +@Qualifier("CampusRepositoryService") +public class CampusRepositoryService implements CampusService { + + private CampusRepository repo; + @Autowired + public void setCampusRepository(CampusRepository repo) { + this.repo = repo; + } + + @Override + public Campus find(String id) { + return repo.findOne(id); + } + + @Override + public Set findByName(String name) { + return repo.findByName(name); + } + + @Override + public Set findByLocationNear(Point point, Distance distance) { + return repo.findByLocationNear(point, distance); + } + + @Override + public Set findAll() { + Set campuses = new HashSet<>(); + Iterator it = repo.findAll().iterator(); + while(it.hasNext()) { + campuses.add(it.next()); + } + return campuses; + } + + @Override + public void save(Campus campus) { + repo.save(campus); + } +} diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/CampusService.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/CampusService.java new file mode 100644 index 0000000000..e82c14cb87 --- /dev/null +++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/CampusService.java @@ -0,0 +1,20 @@ +package org.baeldung.spring.data.couchbase.service; + +import java.util.Set; + +import org.baeldung.spring.data.couchbase.model.Campus; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.Point; + +public interface CampusService { + + Campus find(String id); + + Set findByName(String name); + + Set findByLocationNear(Point point, Distance distance); + + Set findAll(); + + void save(Campus campus); +} diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryService.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryService.java new file mode 100644 index 0000000000..90cc36780a --- /dev/null +++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryService.java @@ -0,0 +1,58 @@ +package org.baeldung.spring.data.couchbase.service; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.baeldung.spring.data.couchbase.model.Person; +import org.baeldung.spring.data.couchbase.repos.PersonRepository; +import org.joda.time.DateTime; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +@Service +@Qualifier("PersonRepositoryService") +public class PersonRepositoryService implements PersonService { + + private PersonRepository repo; + @Autowired + public void setPersonRepository(PersonRepository repo) { + this.repo = repo; + } + + public Person findOne(String id) { + return repo.findOne(id); + } + + public List findAll() { + List people = new ArrayList(); + Iterator it = repo.findAll().iterator(); + while(it.hasNext()) { + people.add(it.next()); + } + return people; + } + + public List findByFirstName(String firstName) { + return repo.findByFirstName(firstName); + } + + public List findByLastName(String lastName) { + return repo.findByLastName(lastName); + } + + public void create(Person person) { + person.setCreated(DateTime.now()); + repo.save(person); + } + + public void update(Person person) { + person.setUpdated(DateTime.now()); + repo.save(person); + } + + public void delete(Person person) { + repo.delete(person); + } +} diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/PersonService.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/PersonService.java new file mode 100644 index 0000000000..a823908b01 --- /dev/null +++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/PersonService.java @@ -0,0 +1,22 @@ +package org.baeldung.spring.data.couchbase.service; + +import java.util.List; + +import org.baeldung.spring.data.couchbase.model.Person; + +public interface PersonService { + + Person findOne(String id); + + List findAll(); + + List findByFirstName(String firstName); + + List findByLastName(String lastName); + + void create(Person person); + + void update(Person person); + + void delete(Person person); +} diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryService.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryService.java new file mode 100644 index 0000000000..58304afc1c --- /dev/null +++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryService.java @@ -0,0 +1,58 @@ +package org.baeldung.spring.data.couchbase.service; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.baeldung.spring.data.couchbase.model.Student; +import org.baeldung.spring.data.couchbase.repos.StudentRepository; +import org.joda.time.DateTime; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +@Service +@Qualifier("StudentRepositoryService") +public class StudentRepositoryService implements StudentService { + + private StudentRepository repo; + @Autowired + public void setStudentRepository(StudentRepository repo) { + this.repo = repo; + } + + public Student findOne(String id) { + return repo.findOne(id); + } + + public List findAll() { + List people = new ArrayList(); + Iterator it = repo.findAll().iterator(); + while(it.hasNext()) { + people.add(it.next()); + } + return people; + } + + public List findByFirstName(String firstName) { + return repo.findByFirstName(firstName); + } + + public List findByLastName(String lastName) { + return repo.findByLastName(lastName); + } + + public void create(Student student) { + student.setCreated(DateTime.now()); + repo.save(student); + } + + public void update(Student student) { + student.setUpdated(DateTime.now()); + repo.save(student); + } + + public void delete(Student student) { + repo.delete(student); + } +} diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/StudentService.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/StudentService.java new file mode 100644 index 0000000000..f483ef0fb6 --- /dev/null +++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/StudentService.java @@ -0,0 +1,22 @@ +package org.baeldung.spring.data.couchbase.service; + +import java.util.List; + +import org.baeldung.spring.data.couchbase.model.Student; + +public interface StudentService { + + Student findOne(String id); + + List findAll(); + + List findByFirstName(String firstName); + + List findByLastName(String lastName); + + void create(Student student); + + void update(Student student); + + void delete(Student student); +} diff --git a/spring-data-couchbase-2b/src/main/resources/logback.xml b/spring-data-couchbase-2b/src/main/resources/logback.xml new file mode 100644 index 0000000000..d9067fd1da --- /dev/null +++ b/spring-data-couchbase-2b/src/main/resources/logback.xml @@ -0,0 +1,17 @@ + + + + + web - %date [%thread] %-5level %logger{36} - %message%n + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-couchbase-2b/src/site/site.xml b/spring-data-couchbase-2b/src/site/site.xml new file mode 100644 index 0000000000..dda96feecd --- /dev/null +++ b/spring-data-couchbase-2b/src/site/site.xml @@ -0,0 +1,25 @@ + + + + + Spring Sample: ${project.name} + index.html + + + + org.springframework.maven.skins + maven-spring-skin + 1.0.5 + + + + + + + + + + + + + diff --git a/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTest.java b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTest.java new file mode 100644 index 0000000000..ce2daa92cd --- /dev/null +++ b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTest.java @@ -0,0 +1,13 @@ +package org.baeldung.spring.data.couchbase; + +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 = { MyCouchbaseConfig.class, IntegrationTestConfig.class }) +@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class }) +public abstract class IntegrationTest { +} diff --git a/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTestConfig.java b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTestConfig.java new file mode 100644 index 0000000000..6f040c34db --- /dev/null +++ b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTestConfig.java @@ -0,0 +1,9 @@ +package org.baeldung.spring.data.couchbase; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan(basePackages = "org.baeldung.spring.data.couchbase") +public class IntegrationTestConfig { +} diff --git a/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/TestCouchbaseConfig.java b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/TestCouchbaseConfig.java new file mode 100644 index 0000000000..c298ef0a61 --- /dev/null +++ b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/TestCouchbaseConfig.java @@ -0,0 +1,17 @@ +package org.baeldung.spring.data.couchbase; + +import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter; +import org.springframework.data.couchbase.core.query.Consistency; + +public class TestCouchbaseConfig extends MyCouchbaseConfig { + + @Override + public String typeKey() { + return MappingCouchbaseConverter.TYPEKEY_SYNCGATEWAY_COMPATIBLE; + } + + @Override + public Consistency getDefaultConsistency() { + return Consistency.READ_YOUR_OWN_WRITES; + } +} diff --git a/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/CampusRepositoryServiceTest.java b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/CampusRepositoryServiceTest.java new file mode 100644 index 0000000000..5a718f0807 --- /dev/null +++ b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/CampusRepositoryServiceTest.java @@ -0,0 +1,135 @@ +package org.baeldung.spring.data.couchbase.service; + +import static org.junit.Assert.*; + +import java.util.Set; + +import javax.annotation.PostConstruct; + +import org.baeldung.spring.data.couchbase.IntegrationTest; +import org.baeldung.spring.data.couchbase.model.Campus; +import org.baeldung.spring.data.couchbase.repos.CampusRepository; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.Metrics; +import org.springframework.data.geo.Point; + +public class CampusRepositoryServiceTest extends IntegrationTest { + + @Autowired + @Qualifier("CampusRepositoryService") + private CampusRepositoryService campusService; + + @Autowired + private CampusRepository campusRepo; + + private final Campus Brown = Campus.Builder.newInstance() + .id("campus:Brown") + .name("Brown") + .location(new Point(71.4025, 51.8268)) + .build(); + + private final Campus Cornell = Campus.Builder.newInstance() + .id("campus:Cornell") + .name("Cornell") + .location(new Point(76.4833, 42.4459)) + .build(); + + private final Campus Columbia = Campus.Builder.newInstance() + .id("campus:Columbia") + .name("Columbia") + .location(new Point(73.9626, 40.8075)) + .build(); + + private final Campus Dartmouth = Campus.Builder.newInstance() + .id("campus:Dartmouth") + .name("Dartmouth") + .location(new Point(72.2887, 43.7044)) + .build(); + + private final Campus Harvard = Campus.Builder.newInstance() + .id("campus:Harvard") + .name("Harvard") + .location(new Point(71.1167, 42.3770)) + .build(); + + private final Campus Penn = Campus.Builder.newInstance() + .id("campus:Penn") + .name("Penn") + .location(new Point(75.1932, 39.9522)) + .build(); + + private final Campus Princeton = Campus.Builder.newInstance() + .id("campus:Princeton") + .name("Princeton") + .location(new Point(74.6514, 40.3340)) + .build(); + + private final Campus Yale = Campus.Builder.newInstance() + .id("campus:Yale") + .name("Yale") + .location(new Point(72.9223, 41.3163)) + .build(); + + private final Point Boston = new Point(71.0589, 42.3601); + private final Point NewYorkCity = new Point(74.0059, 40.7128); + + @PostConstruct + private void loadCampuses() throws Exception { + campusRepo.save(Brown); + campusRepo.save(Columbia); + campusRepo.save(Cornell); + campusRepo.save(Dartmouth); + campusRepo.save(Harvard); + campusRepo.save(Penn); + campusRepo.save(Princeton); + campusRepo.save(Yale); + } + + @Test + public final void givenNameHarvard_whenFindByName_thenReturnsHarvard() throws Exception { + Set campuses = campusService.findByName(Harvard.getName()); + assertNotNull(campuses); + assertFalse(campuses.isEmpty()); + assertTrue(campuses.size() == 1); + assertTrue(campuses.contains(Harvard)); + } + + @Test + public final void givenHarvardId_whenFind_thenReturnsHarvard() throws Exception { + Campus actual = campusService.find(Harvard.getId()); + assertNotNull(actual); + assertEquals(Harvard, actual); + } + + @Test + public final void whenFindAll_thenReturnsAll() throws Exception { + Set campuses = campusService.findAll(); + assertTrue(campuses.contains(Brown)); + assertTrue(campuses.contains(Columbia)); + assertTrue(campuses.contains(Cornell)); + assertTrue(campuses.contains(Dartmouth)); + assertTrue(campuses.contains(Harvard)); + assertTrue(campuses.contains(Penn)); + assertTrue(campuses.contains(Princeton)); + assertTrue(campuses.contains(Yale)); + } + + @Test + public final void whenFindByLocationNearBoston_thenResultContainsHarvard() throws Exception { + Set campuses = campusService.findByLocationNear(Boston, new Distance(1, Metrics.NEUTRAL)); + assertFalse(campuses.isEmpty()); + assertTrue(campuses.contains(Harvard)); + assertFalse(campuses.contains(Columbia)); + } + + @Test + public final void whenFindByLocationNearNewYorkCity_thenResultContainsColumbia() throws Exception { + Set campuses = campusService.findByLocationNear(NewYorkCity, new Distance(1, Metrics.NEUTRAL)); + assertFalse(campuses.isEmpty()); + assertTrue(campuses.contains(Columbia)); + assertFalse(campuses.contains(Harvard)); + } +} diff --git a/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryServiceTest.java b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryServiceTest.java new file mode 100644 index 0000000000..84b6f75d56 --- /dev/null +++ b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryServiceTest.java @@ -0,0 +1,130 @@ +package org.baeldung.spring.data.couchbase.service; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.baeldung.spring.data.couchbase.IntegrationTest; +import org.baeldung.spring.data.couchbase.MyCouchbaseConfig; +import org.baeldung.spring.data.couchbase.model.Person; +import org.joda.time.DateTime; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +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.document.json.JsonObject; + +public class PersonRepositoryServiceTest extends IntegrationTest { + + private static final String typeField = "_class"; + private static final String john = "John"; + private static final String smith = "Smith"; + private static final String johnSmithId = "person:" + john + ":" + smith; + private static final Person johnSmith = new Person(johnSmithId, john, smith); + private static final JsonObject jsonJohnSmith = JsonObject.empty() + .put(typeField, Person.class.getName()) + .put("firstName", john) + .put("lastName", smith) + .put("created", DateTime.now().getMillis()); + + private static final String foo = "Foo"; + private static final String bar = "Bar"; + private static final String foobarId = "person:" + foo + ":" + bar; + private static final Person foobar = new Person(foobarId, foo, bar); + private static final JsonObject jsonFooBar = JsonObject.empty() + .put(typeField, Person.class.getName()) + .put("firstName", foo) + .put("lastName", bar) + .put("created", DateTime.now().getMillis()); + + @Autowired + @Qualifier("PersonRepositoryService") + private PersonService personService; + + @BeforeClass + public static void setupBeforeClass() { + Cluster cluster = CouchbaseCluster.create(MyCouchbaseConfig.NODE_LIST); + Bucket bucket = cluster.openBucket(MyCouchbaseConfig.DEFAULT_BUCKET_NAME, MyCouchbaseConfig.DEFAULT_BUCKET_PASSWORD); + bucket.upsert(JsonDocument.create(johnSmithId, jsonJohnSmith)); + bucket.upsert(JsonDocument.create(foobarId, jsonFooBar)); + bucket.close(); + cluster.disconnect(); + } + + @Test + public void whenFindingPersonByJohnSmithId_thenReturnsJohnSmith() { + Person actualPerson = personService.findOne(johnSmithId); + assertNotNull(actualPerson); + assertNotNull(actualPerson.getCreated()); + assertEquals(johnSmith, actualPerson); + } + + @Test + public void whenFindingAllPersons_thenReturnsTwoOrMorePersonsIncludingJohnSmithAndFooBar() { + List resultList = personService.findAll(); + assertNotNull(resultList); + assertFalse(resultList.isEmpty()); + assertTrue(resultContains(resultList, johnSmith)); + assertTrue(resultContains(resultList, foobar)); + assertTrue(resultList.size() >= 2); + } + + @Test + public void whenFindingByFirstNameJohn_thenReturnsOnlyPersonsNamedJohn() { + String expectedFirstName = john; + List resultList = personService.findByFirstName(expectedFirstName); + assertNotNull(resultList); + assertFalse(resultList.isEmpty()); + assertTrue(allResultsContainExpectedFirstName(resultList, expectedFirstName)); + } + + @Test + public void whenFindingByLastNameSmith_thenReturnsOnlyPersonsNamedSmith() { + String expectedLastName = smith; + List resultList = personService.findByLastName(expectedLastName); + assertNotNull(resultList); + assertFalse(resultList.isEmpty()); + assertTrue(allResultsContainExpectedLastName(resultList, expectedLastName)); + } + + private boolean resultContains(List resultList, Person person) { + boolean found = false; + for(Person p : resultList) { + if(p.equals(person)) { + found = true; + break; + } + } + return found; + } + + private boolean allResultsContainExpectedFirstName(List resultList, String firstName) { + boolean found = false; + for(Person p : resultList) { + if(p.getFirstName().equals(firstName)) { + found = true; + break; + } + } + return found; + } + + private boolean allResultsContainExpectedLastName(List resultList, String lastName) { + boolean found = false; + for(Person p : resultList) { + if(p.getLastName().equals(lastName)) { + found = true; + break; + } + } + return found; + } +} diff --git a/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryServiceTest.java b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryServiceTest.java new file mode 100644 index 0000000000..166f01d754 --- /dev/null +++ b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryServiceTest.java @@ -0,0 +1,170 @@ +package org.baeldung.spring.data.couchbase.service; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import javax.validation.ConstraintViolationException; + +import org.baeldung.spring.data.couchbase.IntegrationTest; +import org.baeldung.spring.data.couchbase.MyCouchbaseConfig; +import org.baeldung.spring.data.couchbase.model.Student; +import org.joda.time.DateTime; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +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.document.json.JsonObject; + +public class StudentRepositoryServiceTest extends IntegrationTest { + + private static final String typeField = "_class"; + private static final String joe = "Joe"; + private static final String college = "College"; + private static final String joeCollegeId = "student:" + joe + ":" + college; + private static final DateTime joeCollegeDob = DateTime.now().minusYears(21); + private static final Student joeCollege = new Student(joeCollegeId, joe, college, joeCollegeDob); + private static final JsonObject jsonJoeCollege = JsonObject.empty() + .put(typeField, Student.class.getName()) + .put("firstName", joe) + .put("lastName", college) + .put("created", DateTime.now().getMillis()) + .put("version", 1); + + private static final String judy = "Judy"; + private static final String jetson = "Jetson"; + private static final String judyJetsonId = "student:" + judy + ":" + jetson; + private static final DateTime judyJetsonDob = DateTime.now().minusYears(19).minusMonths(5).minusDays(3); + private static final Student judyJetson = new Student(judyJetsonId, judy, jetson, judyJetsonDob); + private static final JsonObject jsonJudyJetson = JsonObject.empty() + .put(typeField, Student.class.getName()) + .put("firstName", judy) + .put("lastName", jetson) + .put("created", DateTime.now().getMillis()) + .put("version", 1); + + @Autowired + @Qualifier("StudentRepositoryService") + private StudentService studentService; + + @BeforeClass + public static void setupBeforeClass() { + Cluster cluster = CouchbaseCluster.create(MyCouchbaseConfig.NODE_LIST); + Bucket bucket = cluster.openBucket(MyCouchbaseConfig.DEFAULT_BUCKET_NAME, MyCouchbaseConfig.DEFAULT_BUCKET_PASSWORD); + bucket.upsert(JsonDocument.create(joeCollegeId, jsonJoeCollege)); + bucket.upsert(JsonDocument.create(judyJetsonId, jsonJudyJetson)); + bucket.close(); + cluster.disconnect(); + } + + @Test + public void whenCreatingStudent_thenDocumentIsPersisted() { + String firstName = "Eric"; + String lastName = "Stratton"; + DateTime dateOfBirth = DateTime.now().minusYears(25); + String id = "student:" + firstName + ":" + lastName; + Student expectedStudent = new Student(id, firstName, lastName, dateOfBirth); + studentService.create(expectedStudent); + Student actualStudent = studentService.findOne(id); + assertNotNull(actualStudent.getCreated()); + assertNotNull(actualStudent); + assertEquals(expectedStudent.getId(), actualStudent.getId()); + } + + @Test(expected=ConstraintViolationException.class) + public void whenCreatingStudentWithInvalidFirstName_thenConstraintViolationException() { + String firstName = "Er+ic"; + String lastName = "Stratton"; + DateTime dateOfBirth = DateTime.now().minusYears(25); + String id = "student:" + firstName + ":" + lastName; + Student student = new Student(id, firstName, lastName, dateOfBirth); + studentService.create(student); + } + + @Test(expected=ConstraintViolationException.class) + public void whenCreatingStudentWithFutureDob_thenConstraintViolationException() { + String firstName = "Jane"; + String lastName = "Doe"; + DateTime dateOfBirth = DateTime.now().plusDays(1); + String id = "student:" + firstName + ":" + lastName; + Student student = new Student(id, firstName, lastName, dateOfBirth); + studentService.create(student); + } + + @Test + public void whenFindingStudentByJohnSmithId_thenReturnsJohnSmith() { + Student actualStudent = studentService.findOne(joeCollegeId); + assertNotNull(actualStudent); + assertNotNull(actualStudent.getCreated()); + assertEquals(joeCollegeId, actualStudent.getId()); + } + + @Test + public void whenFindingAllStudents_thenReturnsTwoOrMoreStudentsIncludingJoeCollegeAndJudyJetson() { + List resultList = studentService.findAll(); + assertNotNull(resultList); + assertFalse(resultList.isEmpty()); + assertTrue(resultContains(resultList, joeCollege)); + assertTrue(resultContains(resultList, judyJetson)); + assertTrue(resultList.size() >= 2); + } + + @Test + public void whenFindingByFirstNameJohn_thenReturnsOnlyStudentsNamedJohn() { + String expectedFirstName = joe; + List resultList = studentService.findByFirstName(expectedFirstName); + assertNotNull(resultList); + assertFalse(resultList.isEmpty()); + assertTrue(allResultsContainExpectedFirstName(resultList, expectedFirstName)); + } + + @Test + public void whenFindingByLastNameSmith_thenReturnsOnlyStudentsNamedSmith() { + String expectedLastName = college; + List resultList = studentService.findByLastName(expectedLastName); + assertNotNull(resultList); + assertFalse(resultList.isEmpty()); + assertTrue(allResultsContainExpectedLastName(resultList, expectedLastName)); + } + + private boolean resultContains(List resultList, Student student) { + boolean found = false; + for(Student p : resultList) { + if(p.getId().equals(student.getId())) { + found = true; + break; + } + } + return found; + } + + private boolean allResultsContainExpectedFirstName(List resultList, String firstName) { + boolean found = false; + for(Student p : resultList) { + if(p.getFirstName().equals(firstName)) { + found = true; + break; + } + } + return found; + } + + private boolean allResultsContainExpectedLastName(List resultList, String lastName) { + boolean found = false; + for(Student p : resultList) { + if(p.getLastName().equals(lastName)) { + found = true; + break; + } + } + return found; + } +} diff --git a/spring-data-couchbase-2b/src/test/resources/logback.xml b/spring-data-couchbase-2b/src/test/resources/logback.xml new file mode 100644 index 0000000000..d9067fd1da --- /dev/null +++ b/spring-data-couchbase-2b/src/test/resources/logback.xml @@ -0,0 +1,17 @@ + + + + + web - %date [%thread] %-5level %logger{36} - %message%n + + + + + + + + + + + + \ No newline at end of file