diff --git a/spring-data-couchbase-2/.classpath b/spring-data-couchbase-2/.classpath new file mode 100644 index 0000000000..f4c34adf1f --- /dev/null +++ b/spring-data-couchbase-2/.classpath @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/spring-data-couchbase-2/.project b/spring-data-couchbase-2/.project new file mode 100644 index 0000000000..1690ad8ce2 --- /dev/null +++ b/spring-data-couchbase-2/.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-2/.springBeans b/spring-data-couchbase-2/.springBeans new file mode 100644 index 0000000000..0c014a97b6 --- /dev/null +++ b/spring-data-couchbase-2/.springBeans @@ -0,0 +1,20 @@ + + + 1 + + + + + + + + + + + true + false + + + + + diff --git a/spring-data-couchbase-2/pom.xml b/spring-data-couchbase-2/pom.xml new file mode 100644 index 0000000000..93b3dbddb4 --- /dev/null +++ b/spring-data-couchbase-2/pom.xml @@ -0,0 +1,105 @@ + + 4.0.0 + org.baeldung + spring-data-couchbase-2 + 0.1-SNAPSHOT + spring-data-couchbase-2 + 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.0.0.RELEASE + 5.2.4.Final + 2.9.2 + 1.1.3 + 1.7.12 + 4.11 + + + + diff --git a/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/MyCouchbaseConfig.java b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/MyCouchbaseConfig.java new file mode 100644 index 0000000000..5c0b1a93ca --- /dev/null +++ b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/MyCouchbaseConfig.java @@ -0,0 +1,32 @@ +package org.baeldung.spring.data.couchbase; + +import java.util.Arrays; +import java.util.List; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration; +import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories; + +@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 BUCKET_NAME = "baeldung"; + public static final String BUCKET_PASSWORD = ""; + + @Override + protected List getBootstrapHosts() { + return NODE_LIST; + } + + @Override + protected String getBucketName() { + return BUCKET_NAME; + } + + @Override + protected String getBucketPassword() { + return BUCKET_PASSWORD; + } +} diff --git a/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/model/Person.java b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/model/Person.java new file mode 100644 index 0000000000..9220e157ed --- /dev/null +++ b/spring-data-couchbase-2/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-2/src/main/java/org/baeldung/spring/data/couchbase/repos/PersonRepository.java b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/repos/PersonRepository.java new file mode 100644 index 0000000000..14b77759e3 --- /dev/null +++ b/spring-data-couchbase-2/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-2/src/main/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryService.java b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryService.java new file mode 100644 index 0000000000..90cc36780a --- /dev/null +++ b/spring-data-couchbase-2/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-2/src/main/java/org/baeldung/spring/data/couchbase/service/PersonService.java b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/service/PersonService.java new file mode 100644 index 0000000000..a823908b01 --- /dev/null +++ b/spring-data-couchbase-2/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-2/src/main/java/org/baeldung/spring/data/couchbase/service/PersonTemplateService.java b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/service/PersonTemplateService.java new file mode 100644 index 0000000000..45e9b90a19 --- /dev/null +++ b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/service/PersonTemplateService.java @@ -0,0 +1,55 @@ +package org.baeldung.spring.data.couchbase.service; + +import java.util.List; + +import org.baeldung.spring.data.couchbase.model.Person; +import org.joda.time.DateTime; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.couchbase.core.CouchbaseTemplate; +import org.springframework.stereotype.Service; + +import com.couchbase.client.java.view.ViewQuery; + +@Service +@Qualifier("PersonTemplateService") +public class PersonTemplateService implements PersonService { + + private static final String DESIGN_DOC = "person"; + + private CouchbaseTemplate template; + @Autowired + public void setCouchbaseTemplate(CouchbaseTemplate template) { + this.template = template; + } + + public Person findOne(String id) { + return template.findById(id, Person.class); + } + + public List findAll() { + return template.findByView(ViewQuery.from(DESIGN_DOC, "all"), Person.class); + } + + public List findByFirstName(String firstName) { + return template.findByView(ViewQuery.from(DESIGN_DOC, "byFirstName"), Person.class); + } + + public List findByLastName(String lastName) { + return template.findByView(ViewQuery.from(DESIGN_DOC, "byLastName"), Person.class); + } + + public void create(Person person) { + person.setCreated(DateTime.now()); + template.insert(person); + } + + public void update(Person person) { + person.setUpdated(DateTime.now()); + template.update(person); + } + + public void delete(Person person) { + template.remove(person); + } +} diff --git a/spring-data-couchbase-2/src/main/resources/logback.xml b/spring-data-couchbase-2/src/main/resources/logback.xml new file mode 100644 index 0000000000..d9067fd1da --- /dev/null +++ b/spring-data-couchbase-2/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-2/src/site/site.xml b/spring-data-couchbase-2/src/site/site.xml new file mode 100644 index 0000000000..dda96feecd --- /dev/null +++ b/spring-data-couchbase-2/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-2/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTest.java b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTest.java new file mode 100644 index 0000000000..ce2daa92cd --- /dev/null +++ b/spring-data-couchbase-2/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-2/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTestConfig.java b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTestConfig.java new file mode 100644 index 0000000000..6f040c34db --- /dev/null +++ b/spring-data-couchbase-2/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-2/src/test/java/org/baeldung/spring/data/couchbase/TestCouchbaseConfig.java b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/TestCouchbaseConfig.java new file mode 100644 index 0000000000..4edfb165bf --- /dev/null +++ b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/TestCouchbaseConfig.java @@ -0,0 +1,11 @@ +package org.baeldung.spring.data.couchbase; + +import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter; + +public class TestCouchbaseConfig extends MyCouchbaseConfig { + + @Override + public String typeKey() { + return MappingCouchbaseConverter.TYPEKEY_SYNCGATEWAY_COMPATIBLE; + } +} diff --git a/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryServiceTest.java b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryServiceTest.java new file mode 100644 index 0000000000..ce5cf7667d --- /dev/null +++ b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryServiceTest.java @@ -0,0 +1,13 @@ +package org.baeldung.spring.data.couchbase.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +public class PersonRepositoryServiceTest extends PersonServiceTest { + + @Autowired + @Qualifier("PersonRepositoryService") + public void setPersonService(PersonService service) { + this.personService = service; + } +} diff --git a/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/PersonServiceTest.java b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/PersonServiceTest.java new file mode 100644 index 0000000000..bedae26e00 --- /dev/null +++ b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/PersonServiceTest.java @@ -0,0 +1,126 @@ +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 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 abstract class PersonServiceTest extends IntegrationTest { + + static final String typeField = "_class"; + static final String john = "John"; + static final String smith = "Smith"; + static final String johnSmithId = "person:" + john + ":" + smith; + static final Person johnSmith = new Person(johnSmithId, john, smith); + static final JsonObject jsonJohnSmith = JsonObject.empty() + .put(typeField, Person.class.getName()) + .put("firstName", john) + .put("lastName", smith) + .put("created", DateTime.now().getMillis()); + + static final String foo = "Foo"; + static final String bar = "Bar"; + static final String foobarId = "person:" + foo + ":" + bar; + static final Person foobar = new Person(foobarId, foo, bar); + static final JsonObject jsonFooBar = JsonObject.empty() + .put(typeField, Person.class.getName()) + .put("firstName", foo) + .put("lastName", bar) + .put("created", DateTime.now().getMillis()); + + PersonService personService; + + @BeforeClass + public static void setupBeforeClass() { + Cluster cluster = CouchbaseCluster.create(MyCouchbaseConfig.NODE_LIST); + Bucket bucket = cluster.openBucket(MyCouchbaseConfig.BUCKET_NAME, MyCouchbaseConfig.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-2/src/test/java/org/baeldung/spring/data/couchbase/service/PersonTemplateServiceTest.java b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/PersonTemplateServiceTest.java new file mode 100644 index 0000000000..0238fa21fb --- /dev/null +++ b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/PersonTemplateServiceTest.java @@ -0,0 +1,13 @@ +package org.baeldung.spring.data.couchbase.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +public class PersonTemplateServiceTest extends PersonServiceTest { + + @Autowired + @Qualifier("PersonTemplateService") + public void setPersonService(PersonService service) { + this.personService = service; + } +} diff --git a/spring-data-couchbase-2/src/test/resources/logback.xml b/spring-data-couchbase-2/src/test/resources/logback.xml new file mode 100644 index 0000000000..d9067fd1da --- /dev/null +++ b/spring-data-couchbase-2/src/test/resources/logback.xml @@ -0,0 +1,17 @@ + + + + + web - %date [%thread] %-5level %logger{36} - %message%n + + + + + + + + + + + + \ No newline at end of file