DATACOUCH-135 - Migrate to Couchbase SDK 2.0 and add N1QL find method.
Adaptation were made to use SDK 2.0: - Reworked the configuration approach (more parts to be configured, like Environment, Cluster and Bucket) - Added a new xml schema for configuration of 2.0 version - Adapted the template - Added N1QL support in the template (findByN1QL) - Removed the cache package - Adapted the repository - Better separated Unit Tests from Integration Tests All integration and unit tests pass, except one (SimpleCouchbaseRepositoryTests.shouldFindCustom). Customisation of a ViewQuery will be addressed in another ticket.
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package org.springframework.data.couchbase;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.couchbase.client.java.env.CouchbaseEnvironment;
|
||||
import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
import org.springframework.data.couchbase.core.WriteResultChecking;
|
||||
|
||||
@Configuration
|
||||
public class IntegrationTestApplicationConfig extends AbstractCouchbaseConfiguration {
|
||||
|
||||
@Autowired
|
||||
private Environment springEnv;
|
||||
|
||||
@Bean
|
||||
public String couchbaseAdminUser() {
|
||||
return springEnv.getProperty("couchbase.adminUser", "Administrator");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public String couchbaseAdminPassword() {
|
||||
return springEnv.getProperty("couchbase.adminUser", "password");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getBootstrapHosts() {
|
||||
return Collections.singletonList(springEnv.getProperty("couchbase.host", "127.0.0.1"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBucketName() {
|
||||
return springEnv.getProperty("couchbase.bucket", "default");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBucketPassword() {
|
||||
return springEnv.getProperty("couchbase.password", "");
|
||||
}
|
||||
|
||||
|
||||
//TODO maybe create the bucket if doesn't exist
|
||||
|
||||
@Override
|
||||
protected CouchbaseEnvironment getEnvironment() {
|
||||
return DefaultCouchbaseEnvironment.builder()
|
||||
.connectTimeout(10000)
|
||||
.kvTimeout(10000)
|
||||
.queryTimeout(10000)
|
||||
.viewTimeout(10000)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CouchbaseTemplate couchbaseTemplate() throws Exception {
|
||||
CouchbaseTemplate template = super.couchbaseTemplate();
|
||||
template.setWriteResultChecking(WriteResultChecking.LOG);
|
||||
return template;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReader;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class CouchbaseTemplateParserIntegrationTests {
|
||||
|
||||
DefaultListableBeanFactory factory;
|
||||
BeanDefinitionReader reader;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
factory = new DefaultListableBeanFactory();
|
||||
reader = new XmlBeanDefinitionReader(factory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readsCouchbaseTemplateAttributesCorrectly() {
|
||||
reader.loadBeanDefinitions(new ClassPathResource("configurations/couchbase-template-bean.xml"));
|
||||
|
||||
BeanDefinition definition = factory.getBeanDefinition("couchbaseTemplate");
|
||||
assertEquals(1, definition.getConstructorArgumentValues().getArgumentCount());
|
||||
|
||||
factory.getBean("couchbaseTemplate");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readsCouchbaseTemplateWithTranslationServiceAttributesCorrectly() {
|
||||
reader.loadBeanDefinitions(new ClassPathResource("configurations/couchbase-template-with-translation-service-bean.xml"));
|
||||
|
||||
BeanDefinition definition = factory.getBeanDefinition("couchbaseTemplate");
|
||||
assertEquals(2, definition.getConstructorArgumentValues().getArgumentCount());
|
||||
|
||||
factory.getBean("couchbaseTemplate");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test case for DATACOUCH-47.
|
||||
*/
|
||||
@Test
|
||||
public void allowsMultipleBuckets() {
|
||||
reader.loadBeanDefinitions(new ClassPathResource("configurations/couchbase-multi-bucket-bean.xml"));
|
||||
|
||||
factory.getBean("cb-template-first");
|
||||
factory.getBean("cb-template-second");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,643 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.core;
|
||||
|
||||
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.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.core.IsEqual.equalTo;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import com.couchbase.client.java.document.RawJsonDocument;
|
||||
import com.couchbase.client.java.error.DocumentDoesNotExistException;
|
||||
import com.couchbase.client.java.query.Query;
|
||||
import com.couchbase.client.java.query.QueryResult;
|
||||
import com.couchbase.client.java.query.dsl.Expression;
|
||||
import com.couchbase.client.java.view.Stale;
|
||||
import com.couchbase.client.java.view.ViewQuery;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.couchbase.IntegrationTestApplicationConfig;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
import org.springframework.data.couchbase.core.mapping.Field;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = IntegrationTestApplicationConfig.class)
|
||||
@TestExecutionListeners(CouchbaseTemplateViewListener.class)
|
||||
public class CouchbaseTemplateTests {
|
||||
|
||||
@Autowired
|
||||
private Bucket client;
|
||||
|
||||
@Autowired
|
||||
private CouchbaseTemplate template;
|
||||
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
|
||||
private void removeIfExist(String key) {
|
||||
try {
|
||||
client.remove(key);
|
||||
}
|
||||
catch (DocumentDoesNotExistException e) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveSimpleEntityCorrectly() throws Exception {
|
||||
String id = "beers:awesome-stout";
|
||||
String name = "The Awesome Stout";
|
||||
boolean active = false;
|
||||
Beer beer = new Beer(id).setName(name).setActive(active);
|
||||
|
||||
template.save(beer);
|
||||
RawJsonDocument resultDoc = client.get(id, RawJsonDocument.class);
|
||||
assertNotNull(resultDoc);
|
||||
String result = resultDoc.content();
|
||||
assertNotNull(result);
|
||||
Map<String, Object> resultConv = MAPPER.readValue(result, new TypeReference<Map<String, Object>>() {});
|
||||
|
||||
assertEquals("org.springframework.data.couchbase.core.Beer", resultConv.get("_class"));
|
||||
assertEquals(false, resultConv.get("is_active"));
|
||||
assertEquals("The Awesome Stout", resultConv.get("name"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveDocumentWithExpiry() throws Exception {
|
||||
String id = "simple-doc-with-expiry";
|
||||
DocumentWithExpiry doc = new DocumentWithExpiry(id);
|
||||
template.save(doc);
|
||||
assertNotNull(client.get(id));
|
||||
Thread.sleep(3000);
|
||||
assertNull(client.get(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void insertDoesNotOverride() throws Exception {
|
||||
String id = "double-insert-test";
|
||||
removeIfExist(id);
|
||||
|
||||
SimplePerson doc = new SimplePerson(id, "Mr. A");
|
||||
template.insert(doc);
|
||||
RawJsonDocument resultDoc = client.get(id, RawJsonDocument.class);
|
||||
assertNotNull(resultDoc);
|
||||
String result = resultDoc.content();
|
||||
|
||||
Map<String, String> resultConv = MAPPER.readValue(result, new TypeReference<Map<String, String>>() {});
|
||||
assertEquals("Mr. A", resultConv.get("name"));
|
||||
|
||||
doc = new SimplePerson(id, "Mr. B");
|
||||
template.insert(doc);
|
||||
|
||||
resultDoc = client.get(id, RawJsonDocument.class);
|
||||
assertNotNull(resultDoc);
|
||||
result = resultDoc.content();
|
||||
|
||||
resultConv = MAPPER.readValue(result, new TypeReference<Map<String, String>>() {});
|
||||
assertEquals("Mr. A", resultConv.get("name"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void updateDoesNotInsert() {
|
||||
String id = "update-does-not-insert";
|
||||
SimplePerson doc = new SimplePerson(id, "Nice Guy");
|
||||
template.update(doc);
|
||||
assertNull(client.get(id));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void removeDocument() {
|
||||
String id = "beers:to-delete-stout";
|
||||
Beer beer = new Beer(id);
|
||||
|
||||
template.save(beer);
|
||||
Object result = client.get(id);
|
||||
assertNotNull(result);
|
||||
|
||||
template.remove(beer);
|
||||
result = client.get(id);
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void storeListsAndMaps() {
|
||||
String id = "persons:lots-of-names";
|
||||
List<String> names = new ArrayList<String>();
|
||||
names.add("Michael");
|
||||
names.add("Thomas");
|
||||
names.add(null);
|
||||
List<Integer> votes = new LinkedList<Integer>();
|
||||
Map<String, Boolean> info1 = new HashMap<String, Boolean>();
|
||||
info1.put("foo", true);
|
||||
info1.put("bar", false);
|
||||
info1.put("nullValue", null);
|
||||
Map<String, Integer> info2 = new HashMap<String, Integer>();
|
||||
|
||||
ComplexPerson complex = new ComplexPerson(id, names, votes, info1, info2);
|
||||
|
||||
template.save(complex);
|
||||
assertNotNull(client.get(id));
|
||||
|
||||
ComplexPerson response = template.findById(id, ComplexPerson.class);
|
||||
assertEquals(names, response.getFirstnames());
|
||||
assertEquals(votes, response.getVotes());
|
||||
assertEquals(id, response.getId());
|
||||
assertEquals(info1, response.getInfo1());
|
||||
assertEquals(info2, response.getInfo2());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void validFindById() {
|
||||
String id = "beers:findme-stout";
|
||||
String name = "The Findme Stout";
|
||||
boolean active = true;
|
||||
Beer beer = new Beer(id).setName(name).setActive(active);
|
||||
template.save(beer);
|
||||
|
||||
Beer found = template.findById(id, Beer.class);
|
||||
|
||||
assertNotNull(found);
|
||||
assertEquals(id, found.getId());
|
||||
assertEquals(name, found.getName());
|
||||
assertEquals(active, found.getActive());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldLoadAndMapViewDocs() {
|
||||
ViewQuery query = ViewQuery.from("test_beers", "by_name");
|
||||
query.stale(Stale.FALSE);
|
||||
|
||||
final List<Beer> beers = template.findByView(query, Beer.class);
|
||||
assertTrue(beers.size() > 0);
|
||||
|
||||
for (Beer beer : beers) {
|
||||
assertNotNull(beer.getId());
|
||||
assertNotNull(beer.getName());
|
||||
assertNotNull(beer.getActive());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldQueryRaw() {
|
||||
Query query = Query.simple(select("name").from(i(client.name()))
|
||||
.where(x("name").isNotMissing()));
|
||||
|
||||
QueryResult queryResult = template.queryN1QL(query);
|
||||
assertNotNull(queryResult);
|
||||
assertTrue(queryResult.errors().toString(), queryResult.finalSuccess());
|
||||
assertFalse(queryResult.allRows().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldQueryWithMapping() {
|
||||
FullFragment ff1 = new FullFragment("fullFragment1", 1, "fullFragment", "test1");
|
||||
FullFragment ff2 = new FullFragment("fullFragment2", 2, "fullFragment", "test2");
|
||||
template.save(Arrays.asList(ff1, ff2));
|
||||
|
||||
Query query = Query.simple(select(i("value")) //"value" is a n1ql keyword apparently
|
||||
.from(i(client.name()))
|
||||
.where(x("type").eq(s("fullFragment"))
|
||||
.and(x("criteria").gt(1))));
|
||||
|
||||
List<Fragment> fragments = template.findByN1QL(query, Fragment.class);
|
||||
assertNotNull(fragments);
|
||||
assertFalse(fragments.isEmpty());
|
||||
assertEquals(1, fragments.size());
|
||||
assertEquals("test2", fragments.get(0).value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeserialiseLongs() {
|
||||
final long time = new Date().getTime();
|
||||
SimpleWithLong simpleWithLong = new SimpleWithLong("simpleWithLong:simple", time);
|
||||
template.save(simpleWithLong);
|
||||
simpleWithLong = template.findById("simpleWithLong:simple", SimpleWithLong.class);
|
||||
assertNotNull(simpleWithLong);
|
||||
assertEquals(time, simpleWithLong.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeserialiseEnums() {
|
||||
SimpleWithEnum simpleWithEnum = new SimpleWithEnum("simpleWithEnum:enum", SimpleWithEnum.Type.BIG);
|
||||
template.save(simpleWithEnum);
|
||||
simpleWithEnum = template.findById("simpleWithEnum:enum", SimpleWithEnum.class);
|
||||
assertNotNull(simpleWithEnum);
|
||||
assertEquals(simpleWithEnum.getType(), SimpleWithEnum.Type.BIG);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeserialiseClass() {
|
||||
SimpleWithClass simpleWithClass = new SimpleWithClass("simpleWithClass:class", Integer.class);
|
||||
simpleWithClass.setValue("The dish ran away with the spoon.");
|
||||
template.save(simpleWithClass);
|
||||
simpleWithClass = template.findById("simpleWithClass:class", SimpleWithClass.class);
|
||||
assertNotNull(simpleWithClass);
|
||||
assertThat(simpleWithClass.getValue(), equalTo("The dish ran away with the spoon."));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHandleCASVersionOnInsert() throws Exception {
|
||||
removeIfExist("versionedClass:1");
|
||||
|
||||
VersionedClass versionedClass = new VersionedClass("versionedClass:1", "foobar");
|
||||
assertEquals(0, versionedClass.getVersion());
|
||||
template.insert(versionedClass);
|
||||
RawJsonDocument rawStored = client.get("versionedClass:1", RawJsonDocument.class);
|
||||
assertEquals(rawStored.cas(), versionedClass.getVersion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void versionShouldNotUpdateOnSecondInsert() throws Exception {
|
||||
removeIfExist("versionedClass:2");
|
||||
|
||||
VersionedClass versionedClass = new VersionedClass("versionedClass:2", "foobar");
|
||||
template.insert(versionedClass);
|
||||
long version1 = versionedClass.getVersion();
|
||||
template.insert(versionedClass);
|
||||
long version2 = versionedClass.getVersion();
|
||||
|
||||
assertTrue(version1 > 0);
|
||||
assertTrue(version2 > 0);
|
||||
assertEquals(version1, version2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSaveDocumentOnMatchingVersion() throws Exception {
|
||||
removeIfExist("versionedClass:3");
|
||||
|
||||
VersionedClass versionedClass = new VersionedClass("versionedClass:3", "foobar");
|
||||
template.insert(versionedClass);
|
||||
long version1 = versionedClass.getVersion();
|
||||
|
||||
versionedClass.setField("foobar2");
|
||||
template.save(versionedClass);
|
||||
long version2 = versionedClass.getVersion();
|
||||
|
||||
assertTrue(version1 > 0);
|
||||
assertTrue(version2 > 0);
|
||||
assertNotEquals(version1, version2);
|
||||
|
||||
assertEquals("foobar2", template.findById("versionedClass:3", VersionedClass.class).getField());
|
||||
}
|
||||
|
||||
@Test(expected = OptimisticLockingFailureException.class)
|
||||
public void shouldNotSaveDocumentOnNotMatchingVersion() throws Exception {
|
||||
removeIfExist("versionedClass:4");
|
||||
|
||||
VersionedClass versionedClass = new VersionedClass("versionedClass:4", "foobar");
|
||||
template.insert(versionedClass);
|
||||
|
||||
RawJsonDocument toCompare = RawJsonDocument.create("versionedClass:4", "different");
|
||||
assertNotNull(client.upsert(toCompare));
|
||||
|
||||
versionedClass.setField("foobar2");
|
||||
//save (aka upsert) won't error in case of CAS mismatch anymore
|
||||
template.update(versionedClass);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldUpdateDocumentOnMatchingVersion() throws Exception {
|
||||
removeIfExist("versionedClass:5");
|
||||
|
||||
VersionedClass versionedClass = new VersionedClass("versionedClass:5", "foobar");
|
||||
template.insert(versionedClass);
|
||||
long version1 = versionedClass.getVersion();
|
||||
|
||||
versionedClass.setField("foobar2");
|
||||
template.update(versionedClass);
|
||||
long version2 = versionedClass.getVersion();
|
||||
|
||||
assertTrue(version1 > 0);
|
||||
assertTrue(version2 > 0);
|
||||
assertNotEquals(version1, version2);
|
||||
|
||||
assertEquals("foobar2", template.findById("versionedClass:5", VersionedClass.class).getField());
|
||||
}
|
||||
|
||||
@Test(expected = OptimisticLockingFailureException.class)
|
||||
public void shouldNotUpdateDocumentOnNotMatchingVersion() throws Exception {
|
||||
removeIfExist("versionedClass:6");
|
||||
|
||||
VersionedClass versionedClass = new VersionedClass("versionedClass:6", "foobar");
|
||||
template.insert(versionedClass);
|
||||
|
||||
RawJsonDocument toCompare = RawJsonDocument.create("versionedClass:6", "different");
|
||||
assertNotNull(client.upsert(toCompare));
|
||||
|
||||
versionedClass.setField("foobar2");
|
||||
template.update(versionedClass);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldLoadVersionPropertyOnFind() throws Exception {
|
||||
removeIfExist("versionedClass:7");
|
||||
|
||||
VersionedClass versionedClass = new VersionedClass("versionedClass:7", "foobar");
|
||||
template.insert(versionedClass);
|
||||
assertTrue(versionedClass.getVersion() > 0);
|
||||
|
||||
VersionedClass foundClass = template.findById("versionedClass:7", VersionedClass.class);
|
||||
assertEquals(versionedClass.getVersion(), foundClass.getVersion());
|
||||
}
|
||||
|
||||
/**
|
||||
* A sample document with just an id and property.
|
||||
*/
|
||||
@Document
|
||||
static class SimplePerson {
|
||||
|
||||
@Id
|
||||
private final String id;
|
||||
@Field
|
||||
private final String name;
|
||||
|
||||
public SimplePerson(String id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A sample document that expires in 2 seconds.
|
||||
*/
|
||||
@Document(expiry = 2)
|
||||
static class DocumentWithExpiry {
|
||||
|
||||
@Id
|
||||
private final String id;
|
||||
|
||||
public DocumentWithExpiry(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
@Document
|
||||
static class ComplexPerson {
|
||||
|
||||
@Id
|
||||
private final String id;
|
||||
@Field
|
||||
private final List<String> firstnames;
|
||||
@Field
|
||||
private final List<Integer> votes;
|
||||
|
||||
@Field
|
||||
private final Map<String, Boolean> info1;
|
||||
@Field
|
||||
private final Map<String, Integer> info2;
|
||||
|
||||
public ComplexPerson(String id, List<String> firstnames,
|
||||
List<Integer> votes, Map<String, Boolean> info1,
|
||||
Map<String, Integer> info2) {
|
||||
this.id = id;
|
||||
this.firstnames = firstnames;
|
||||
this.votes = votes;
|
||||
this.info1 = info1;
|
||||
this.info2 = info2;
|
||||
}
|
||||
|
||||
List<String> getFirstnames() {
|
||||
return firstnames;
|
||||
}
|
||||
|
||||
List<Integer> getVotes() {
|
||||
return votes;
|
||||
}
|
||||
|
||||
Map<String, Boolean> getInfo1() {
|
||||
return info1;
|
||||
}
|
||||
|
||||
Map<String, Integer> getInfo2() {
|
||||
return info2;
|
||||
}
|
||||
|
||||
String getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
@Document
|
||||
static class SimpleWithLong {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
private long value;
|
||||
|
||||
SimpleWithLong(final String id, final long value) {
|
||||
this.id = id;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
long getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
void setValue(final long value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
static class SimpleWithEnum {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
private enum Type {
|
||||
BIG
|
||||
}
|
||||
|
||||
private Type type;
|
||||
|
||||
SimpleWithEnum(final String id, final Type type) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
void setId(final String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
void setType(final Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
static class SimpleWithClass {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
private Class<Integer> integerClass;
|
||||
|
||||
private String value;
|
||||
|
||||
SimpleWithClass(final String id, final Class<Integer> integerClass) {
|
||||
this.id = id;
|
||||
this.integerClass = integerClass;
|
||||
}
|
||||
|
||||
String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
void setId(final String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
Class<Integer> getIntegerClass() {
|
||||
return integerClass;
|
||||
}
|
||||
|
||||
void setIntegerClass(final Class<Integer> integerClass) {
|
||||
this.integerClass = integerClass;
|
||||
}
|
||||
|
||||
String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
void setValue(final String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
static class VersionedClass {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
@Version
|
||||
private long version;
|
||||
|
||||
private String field;
|
||||
|
||||
VersionedClass(String id, String field) {
|
||||
this.id = id;
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public String getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
public void setField(String field) {
|
||||
this.field = field;
|
||||
}
|
||||
}
|
||||
|
||||
@Document
|
||||
static class FullFragment {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
private long criteria;
|
||||
|
||||
private String type;
|
||||
|
||||
private String value;
|
||||
|
||||
public FullFragment(String id, long criteria, String type, String value) {
|
||||
this.id = id;
|
||||
this.criteria = criteria;
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public long getCriteria() {
|
||||
return criteria;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setCriteria(long criteria) {
|
||||
this.criteria = criteria;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
static class Fragment {
|
||||
public String value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.core;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import com.couchbase.client.java.view.DefaultView;
|
||||
import com.couchbase.client.java.view.DesignDocument;
|
||||
import com.couchbase.client.java.view.View;
|
||||
|
||||
import org.springframework.test.context.TestContext;
|
||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class CouchbaseTemplateViewListener extends DependencyInjectionTestExecutionListener {
|
||||
|
||||
@Override
|
||||
public void beforeTestClass(final TestContext testContext) throws Exception {
|
||||
Bucket client = (Bucket) testContext.getApplicationContext().getBean("couchbaseBucket");
|
||||
populateTestData(client);
|
||||
createAndWaitForDesignDocs(client);
|
||||
}
|
||||
|
||||
private void populateTestData(Bucket client) {
|
||||
CouchbaseTemplate template = new CouchbaseTemplate(client);
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
Beer b = new Beer("testbeer-" + i).setName("MyBeer " + i).setActive(true);
|
||||
template.save(b);
|
||||
}
|
||||
}
|
||||
|
||||
private void createAndWaitForDesignDocs(Bucket client) {
|
||||
String mapFunction = "function (doc, meta) { if(doc._class == "
|
||||
+ "\"org.springframework.data.couchbase.core.Beer\") { emit(doc.name, null); } }";
|
||||
View view = DefaultView.create("by_name", mapFunction);
|
||||
DesignDocument designDoc = DesignDocument.create("test_beers", Collections.singletonList(view));
|
||||
client.bucketManager().upsertDesignDocument(designDoc);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.monitor;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.isEmptyString;
|
||||
import static org.hamcrest.core.IsNot.not;
|
||||
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.couchbase.IntegrationTestApplicationConfig;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = IntegrationTestApplicationConfig.class)
|
||||
public class ClientInfoTests {
|
||||
|
||||
/**
|
||||
* Contains a reference to the actual CouchbaseClient.
|
||||
*/
|
||||
@Autowired
|
||||
private Bucket client;
|
||||
|
||||
private ClientInfo ci;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
ci = new ClientInfo(client);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hostNames() {
|
||||
String hostnames = ci.getHostNames();
|
||||
assertThat(hostnames, not(isEmptyString()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.monitor;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.couchbase.IntegrationTestApplicationConfig;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = IntegrationTestApplicationConfig.class)
|
||||
public class ClusterInfoTests {
|
||||
|
||||
/**
|
||||
* Contains a reference to the actual CouchbaseClient.
|
||||
*/
|
||||
@Autowired
|
||||
private Bucket client;
|
||||
|
||||
private ClusterInfo ci;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
ci = new ClusterInfo(client);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void totalDiskAssigned() {
|
||||
assertThat(ci.getTotalDiskAssigned(), greaterThan(0L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void totalRAMUsed() {
|
||||
assertThat(ci.getTotalRAMUsed(), greaterThan(0L));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.repository;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import com.couchbase.client.java.PersistTo;
|
||||
import com.couchbase.client.java.ReplicateTo;
|
||||
import com.couchbase.client.java.view.DefaultView;
|
||||
import com.couchbase.client.java.view.DesignDocument;
|
||||
import com.couchbase.client.java.view.View;
|
||||
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
import org.springframework.test.context.TestContext;
|
||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class CouchbaseRepositoryViewListener extends DependencyInjectionTestExecutionListener {
|
||||
|
||||
@Override
|
||||
public void beforeTestClass(final TestContext testContext) throws Exception {
|
||||
Bucket client = (Bucket) testContext.getApplicationContext().getBean("couchbaseBucket");
|
||||
populateTestData(client);
|
||||
createAndWaitForDesignDocs(client);
|
||||
}
|
||||
|
||||
private void populateTestData(final Bucket client) {
|
||||
CouchbaseTemplate template = new CouchbaseTemplate(client);
|
||||
for (int i = 0; i < 100; i++) {
|
||||
template.save(new User("testuser-" + i, "uname-" + i), PersistTo.MASTER, ReplicateTo.NONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void createAndWaitForDesignDocs(final Bucket client) {
|
||||
String mapFunction = "function (doc, meta) { if(doc._class == \"org.springframework.data.couchbase.repository.User\") { emit(null, null); } }";
|
||||
View view = DefaultView.create("customFindAllView", mapFunction, "_count");
|
||||
List<View> views = Collections.singletonList(view);
|
||||
DesignDocument designDoc = DesignDocument.create("user", views);
|
||||
client.bucketManager().upsertDesignDocument(designDoc);
|
||||
|
||||
view = DefaultView.create("customCountView", mapFunction, "_count");
|
||||
views = Collections.singletonList(view);
|
||||
designDoc = DesignDocument.create("userCustom", views);
|
||||
client.bucketManager().upsertDesignDocument(designDoc);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.repository;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import com.couchbase.client.java.view.Stale;
|
||||
import com.couchbase.client.java.view.ViewQuery;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
||||
import org.springframework.data.couchbase.IntegrationTestApplicationConfig;
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
import org.springframework.data.couchbase.repository.support.CouchbaseRepositoryFactory;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author David Harrigan
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = IntegrationTestApplicationConfig.class)
|
||||
@TestExecutionListeners(CouchbaseRepositoryViewListener.class)
|
||||
public class CouchbaseRepositoryViewTests {
|
||||
|
||||
@Autowired
|
||||
private Bucket client;
|
||||
|
||||
@Autowired
|
||||
private CouchbaseTemplate template;
|
||||
|
||||
private CustomUserRepository repository;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
repository = new CouchbaseRepositoryFactory(template).getRepository(CustomUserRepository.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindAllWithCustomView() {
|
||||
client.query(ViewQuery.from("user", "customFindAllView").stale(Stale.FALSE));
|
||||
Iterable<User> allUsers = repository.findAll();
|
||||
int i = 0;
|
||||
for (final User allUser : allUsers) {
|
||||
i++;
|
||||
}
|
||||
assertThat(i, is(100));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCountWithCustomView() {
|
||||
client.query(ViewQuery.from("userCustom", "customCountView").stale(Stale.FALSE));
|
||||
final long value = repository.count();
|
||||
assertThat(value, is(100L));
|
||||
}
|
||||
|
||||
@Test(expected = InvalidDataAccessResourceUsageException.class)
|
||||
public void shouldTrimOffFindOnCustomFinder() {
|
||||
repository.findAllSomething();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.repository;
|
||||
|
||||
import org.springframework.data.couchbase.core.view.View;
|
||||
|
||||
/**
|
||||
* @author David Harrigan
|
||||
*/
|
||||
public interface CustomUserRepository extends CouchbaseRepository<User, String> {
|
||||
|
||||
@Override
|
||||
@View(designDocument = "user", viewName = "customFindAllView")
|
||||
Iterable<User> findAll();
|
||||
|
||||
@Override
|
||||
@View(designDocument = "userCustom", viewName = "customCountView")
|
||||
long count();
|
||||
|
||||
Iterable<User> findAllSomething();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.repository;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import com.couchbase.client.java.PersistTo;
|
||||
import com.couchbase.client.java.ReplicateTo;
|
||||
import com.couchbase.client.java.view.DefaultView;
|
||||
import com.couchbase.client.java.view.DesignDocument;
|
||||
import com.couchbase.client.java.view.View;
|
||||
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
import org.springframework.test.context.TestContext;
|
||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class SimpleCouchbaseRepositoryListener extends DependencyInjectionTestExecutionListener {
|
||||
|
||||
@Override
|
||||
public void beforeTestClass(final TestContext testContext) throws Exception {
|
||||
Bucket client = (Bucket) testContext.getApplicationContext().getBean("couchbaseBucket");
|
||||
populateTestData(client);
|
||||
createAndWaitForDesignDocs(client);
|
||||
}
|
||||
|
||||
private void populateTestData(Bucket client) {
|
||||
CouchbaseTemplate template = new CouchbaseTemplate(client);
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
User u = new User("testuser-" + i, "uname-" + i);
|
||||
template.save(u, PersistTo.MASTER, ReplicateTo.NONE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void createAndWaitForDesignDocs(Bucket client) {
|
||||
String mapFunction = "function (doc, meta) { if(doc._class == \"org.springframework.data.couchbase.repository." +
|
||||
"User\") { emit(null, null); } }";
|
||||
View view = DefaultView.create("all", mapFunction, "_count");
|
||||
List<View> views = Collections.singletonList(view);
|
||||
DesignDocument designDoc = DesignDocument.create("user", views);
|
||||
client.bucketManager().upsertDesignDocument(designDoc);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.repository;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import com.couchbase.client.java.view.Stale;
|
||||
import com.couchbase.client.java.view.ViewQuery;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.couchbase.IntegrationTestApplicationConfig;
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
import org.springframework.data.couchbase.repository.support.CouchbaseRepositoryFactory;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = IntegrationTestApplicationConfig.class)
|
||||
@TestExecutionListeners(SimpleCouchbaseRepositoryListener.class)
|
||||
public class SimpleCouchbaseRepositoryTests {
|
||||
|
||||
@Autowired
|
||||
private Bucket client;
|
||||
|
||||
@Autowired
|
||||
private CouchbaseTemplate template;
|
||||
|
||||
private UserRepository repository;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
RepositoryFactorySupport factory = new CouchbaseRepositoryFactory(template);
|
||||
repository = factory.getRepository(UserRepository.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleCrud() {
|
||||
String key = "my_unique_user_key";
|
||||
User instance = new User(key, "foobar");
|
||||
repository.save(instance);
|
||||
|
||||
User found = repository.findOne(key);
|
||||
assertEquals(instance.getKey(), found.getKey());
|
||||
assertEquals(instance.getUsername(), found.getUsername());
|
||||
|
||||
assertTrue(repository.exists(key));
|
||||
repository.delete(found);
|
||||
|
||||
assertNull(repository.findOne(key));
|
||||
assertFalse(repository.exists(key));
|
||||
}
|
||||
|
||||
@Test
|
||||
/**
|
||||
* This test uses/assumes a default viewName called "all" that is configured on Couchbase.
|
||||
*/
|
||||
public void shouldFindAll() {
|
||||
// do a non-stale query to populate data for testing.
|
||||
client.query(ViewQuery.from("user", "all").stale(Stale.FALSE));
|
||||
|
||||
Iterable<User> allUsers = repository.findAll();
|
||||
int size = 0;
|
||||
for (User u : allUsers) {
|
||||
size++;
|
||||
assertNotNull(u.getKey());
|
||||
assertNotNull(u.getUsername());
|
||||
}
|
||||
assertEquals(100, size);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCount() {
|
||||
// do a non-stale query to populate data for testing.
|
||||
client.query(ViewQuery.from("user", "all").stale(Stale.FALSE));
|
||||
|
||||
assertEquals(100, repository.count());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindCustom() {
|
||||
Iterable<User> users = repository.customViewQuery(ViewQuery.from("", "").limit(2).stale(Stale.FALSE));
|
||||
int size = 0;
|
||||
for (User u : users) {
|
||||
size++;
|
||||
assertNotNull(u.getKey());
|
||||
assertNotNull(u.getUsername());
|
||||
}
|
||||
assertEquals(2, size);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.repository;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class User {
|
||||
|
||||
@Id
|
||||
private final String key;
|
||||
|
||||
private final String username;
|
||||
|
||||
public User(String key, String username) {
|
||||
this.key = key;
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.repository;
|
||||
|
||||
import com.couchbase.client.java.view.ViewQuery;
|
||||
|
||||
import org.springframework.data.couchbase.core.view.View;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public interface UserRepository extends CouchbaseRepository<User, String> {
|
||||
|
||||
@View(designDocument = "user", viewName = "all")
|
||||
Iterable<User> customViewQuery(ViewQuery query);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.repository.cdi;
|
||||
|
||||
import org.springframework.data.couchbase.repository.CouchbaseRepository;
|
||||
import org.springframework.data.couchbase.repository.User;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public interface CdiPersonRepository extends CouchbaseRepository<Person, String>, CdiPersonRepositoryCustom {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.repository.cdi;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public interface CdiPersonRepositoryCustom {
|
||||
|
||||
int returnTwo();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.repository.cdi;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class CdiPersonRepositoryImpl implements CdiPersonRepositoryCustom {
|
||||
|
||||
@Override
|
||||
public int returnTwo() {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.repository.cdi;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.couchbase.client.java.Bucket;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
class CdiRepositoryClient {
|
||||
|
||||
@Inject
|
||||
private CdiPersonRepository cdiPersonRepository;
|
||||
|
||||
@Inject
|
||||
private Bucket couchbaseClient;
|
||||
|
||||
public CdiPersonRepository getCdiPersonRepository() {
|
||||
return cdiPersonRepository;
|
||||
}
|
||||
|
||||
public Bucket getCouchbaseClient() {
|
||||
return couchbaseClient;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.repository.cdi;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import com.couchbase.client.java.view.DefaultView;
|
||||
import com.couchbase.client.java.view.DesignDocument;
|
||||
import com.couchbase.client.java.view.View;
|
||||
import org.apache.webbeans.cditest.CdiTestContainer;
|
||||
import org.apache.webbeans.cditest.CdiTestContainerLoader;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class CdiRepositoryTests {
|
||||
|
||||
private static CdiTestContainer cdiContainer;
|
||||
private CdiPersonRepository repository;
|
||||
private Bucket couchbaseClient;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() throws Exception {
|
||||
cdiContainer = CdiTestContainerLoader.getCdiContainer();
|
||||
cdiContainer.startApplicationScope();
|
||||
cdiContainer.bootContainer();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void shutdown() throws Exception {
|
||||
cdiContainer.stopContexts();
|
||||
cdiContainer.shutdownContainer();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
CdiRepositoryClient repositoryClient = cdiContainer.getInstance(CdiRepositoryClient.class);
|
||||
repository = repositoryClient.getCdiPersonRepository();
|
||||
|
||||
couchbaseClient = repositoryClient.getCouchbaseClient();
|
||||
createAndWaitForDesignDocs(couchbaseClient);
|
||||
|
||||
}
|
||||
|
||||
private void createAndWaitForDesignDocs(Bucket client) {
|
||||
String mapFunction = "function (doc, meta) { if(doc._class == \"" + Person.class.getName()
|
||||
+ "\") { emit(null, null); } }";
|
||||
View view = DefaultView.create("all", mapFunction, "_count");
|
||||
List<View> views = Collections.singletonList(view);
|
||||
DesignDocument designDoc = DesignDocument.create("person", views);
|
||||
client.bucketManager().upsertDesignDocument(designDoc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACOUCH-109
|
||||
*/
|
||||
@Test
|
||||
public void testCdiRepository() {
|
||||
assertNotNull(repository);
|
||||
repository.deleteAll();
|
||||
|
||||
Person bean = new Person("key", "username");
|
||||
|
||||
repository.save(bean);
|
||||
|
||||
assertTrue(repository.exists(bean.getId()));
|
||||
|
||||
Person retrieved = repository.findOne(bean.getId());
|
||||
assertNotNull(retrieved);
|
||||
assertEquals(bean.getName(), retrieved.getName());
|
||||
assertEquals(bean.getId(), retrieved.getId());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACOUCH-109
|
||||
*/
|
||||
@Test
|
||||
public void testCustomRepository() {
|
||||
|
||||
assertEquals(2, repository.returnTwo());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.repository.cdi;
|
||||
|
||||
import javax.enterprise.inject.Disposes;
|
||||
import javax.enterprise.inject.Produces;
|
||||
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import com.couchbase.client.java.CouchbaseCluster;
|
||||
|
||||
import org.springframework.data.couchbase.config.CouchbaseBucketFactoryBean;
|
||||
|
||||
/**
|
||||
* Producer for {@link Bucket}. A default {@link CouchbaseCluster} with defaults
|
||||
* from {@link CouchbaseBucketFactoryBean} are sufficient for our test.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Simon Baslé
|
||||
*/
|
||||
class CouchbaseClientProducer {
|
||||
|
||||
@Produces
|
||||
public Bucket createCouchbaseClient() throws Exception {
|
||||
//FIXME produce a Cluster and close it properly?
|
||||
CouchbaseBucketFactoryBean couchbaseFactoryBean = new CouchbaseBucketFactoryBean(
|
||||
CouchbaseCluster.create(), "default");
|
||||
couchbaseFactoryBean.afterPropertiesSet();
|
||||
return couchbaseFactoryBean.getObject();
|
||||
}
|
||||
|
||||
public void close(@Disposes Bucket couchbaseClient) {
|
||||
couchbaseClient.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.repository.cdi;
|
||||
|
||||
import javax.enterprise.inject.Produces;
|
||||
|
||||
import com.couchbase.client.java.Bucket;
|
||||
|
||||
import org.springframework.data.couchbase.core.CouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
|
||||
/**
|
||||
* Produces a {@link CouchbaseOperations} instance for test usage.
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
class CouchbaseOperationsProducer {
|
||||
|
||||
@Produces
|
||||
public CouchbaseOperations createCouchbaseOperations(Bucket couchbaseClient) throws Exception {
|
||||
|
||||
CouchbaseTemplate couchbaseTemplate = new CouchbaseTemplate(couchbaseClient);
|
||||
|
||||
return couchbaseTemplate;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.repository.cdi;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.couchbase.core.mapping.Field;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class Person {
|
||||
|
||||
@Id private String id;
|
||||
|
||||
@Field private String name;
|
||||
|
||||
public Person() {}
|
||||
|
||||
public Person(String id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user