From b9f23f3fd5f492392ba07de37698679ba302ba47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20Basl=C3=A9?=
Date: Thu, 2 Jul 2015 18:50:08 +0200
Subject: [PATCH] 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.
---
README.md | 6 +
pom.xml | 267 +++---
.../IntegrationTestApplicationConfig.java | 67 ++
...uchbaseTemplateParserIntegrationTests.java | 75 ++
.../core/CouchbaseTemplateTests.java | 643 +++++++++++++++
.../core/CouchbaseTemplateViewListener.java | 58 ++
.../couchbase/monitor/ClientInfoTests.java | 47 +-
.../couchbase/monitor/ClusterInfoTests.java | 49 +-
.../CouchbaseRepositoryViewListener.java | 39 +-
.../CouchbaseRepositoryViewTests.java | 23 +-
.../repository/CustomUserRepository.java | 0
.../SimpleCouchbaseRepositoryListener.java | 30 +-
.../SimpleCouchbaseRepositoryTests.java | 24 +-
.../data/couchbase/repository/User.java | 0
.../couchbase/repository/UserRepository.java | 5 +-
.../repository/cdi/CdiPersonRepository.java | 0
.../cdi/CdiPersonRepositoryCustom.java | 0
.../cdi/CdiPersonRepositoryImpl.java | 0
.../repository/cdi/CdiRepositoryClient.java | 7 +-
.../repository/cdi/CdiRepositoryTests.java | 22 +-
.../cdi/CouchbaseClientProducer.java | 21 +-
.../cdi/CouchbaseOperationsProducer.java | 6 +-
.../data/couchbase/repository/cdi/Person.java | 0
src/integration/resources/META-INF/beans.xml | 6 +
.../couchbase-multi-bucket-bean.xml | 18 +-
.../couchbase-template-bean.xml | 4 +-
...template-with-translation-service-bean.xml | 4 +-
.../resources/namespace/couchbase.properties | 0
.../data/couchbase/cache/CouchbaseCache.java | 167 ----
.../cache/CouchbaseCacheManager.java | 105 ---
.../AbstractCouchbaseConfiguration.java | 117 ++-
.../data/couchbase/config/BeanNames.java | 26 +-
.../config/CouchbaseBucketFactoryBean.java | 78 ++
.../config/CouchbaseBucketParser.java | 103 +++
.../config/CouchbaseClusterParser.java | 156 ++++
.../CouchbaseEnvironmentFactoryBean.java | 259 ++++++
.../CouchbaseEnvironmentNoShutdownProxy.java | 242 ++++++
.../config/CouchbaseEnvironmentParser.java | 141 ++++
.../couchbase/config/CouchbaseJmxParser.java | 34 +-
.../config/CouchbaseNamespaceHandler.java | 17 +-
.../couchbase/config/CouchbaseParser.java | 89 --
.../config/CouchbaseTemplateParser.java | 13 +-
.../CouchbaseTranslationServiceParser.java | 13 +-
.../data/couchbase/config/package-info.java | 5 +
.../data/couchbase/core/BucketCallback.java | 8 +-
...chbaseDataIntegrityViolationException.java | 4 +-
.../core/CouchbaseExceptionTranslator.java | 90 +-
.../couchbase/core/CouchbaseFactoryBean.java | 318 --------
.../couchbase/core/CouchbaseOperations.java | 92 ++-
.../CouchbaseQueryExecutionException.java | 33 +
.../couchbase/core/CouchbaseTemplate.java | 769 +++++++++---------
.../core/OperationCancellationException.java | 6 +-
.../core/OperationInterruptedException.java | 6 +-
.../couchbase/core/WriteResultChecking.java | 4 +-
.../convert/AbstractCouchbaseConverter.java | 4 +-
.../core/convert/ConverterRegistration.java | 10 +-
.../core/convert/CouchbaseConverter.java | 12 +-
.../CouchbaseDocumentPropertyAccessor.java | 8 +-
.../core/convert/CouchbaseTypeMapper.java | 4 +-
.../core/convert/CouchbaseWriter.java | 6 +-
.../core/convert/CustomConversions.java | 31 +-
.../core/convert/DateConverters.java | 28 +-
.../convert/DefaultCouchbaseTypeMapper.java | 4 +-
.../convert/MappingCouchbaseConverter.java | 59 +-
.../JacksonTranslationService.java | 69 +-
.../translation/TranslationService.java | 24 +-
.../BasicCouchbasePersistentEntity.java | 19 +-
.../BasicCouchbasePersistentProperty.java | 28 +-
.../core/mapping/CouchbaseDocument.java | 42 +-
.../couchbase/core/mapping/CouchbaseList.java | 35 +-
.../core/mapping/CouchbaseMappingContext.java | 26 +-
.../mapping/CouchbasePersistentEntity.java | 8 +-
.../mapping/CouchbasePersistentProperty.java | 6 +-
.../core/mapping/CouchbaseSimpleTypes.java | 27 +-
.../core/mapping/CouchbaseStorable.java | 18 +-
.../data/couchbase/core/mapping/Document.java | 16 +-
.../data/couchbase/core/mapping/Field.java | 4 +-
.../event/AbstractCouchbaseEventListener.java | 24 +-
.../core/mapping/event/AfterDeleteEvent.java | 4 +-
.../core/mapping/event/AfterSaveEvent.java | 4 +-
.../mapping/event/BeforeConvertEvent.java | 4 +-
.../core/mapping/event/BeforeDeleteEvent.java | 4 +-
.../core/mapping/event/BeforeSaveEvent.java | 4 +-
.../mapping/event/CouchbaseMappingEvent.java | 4 +-
.../mapping/event/LoggingEventListener.java | 13 +-
.../ValidatingCouchbaseEventListener.java | 22 +-
.../data/couchbase/core/package-info.java | 26 +
.../couchbase/monitor/AbstractMonitor.java | 74 --
.../data/couchbase/monitor/ClientInfo.java | 39 +-
.../data/couchbase/monitor/ClusterInfo.java | 50 +-
.../data/couchbase/monitor/package-info.java | 5 +
.../couchbase/repository/package-info.java | 7 +
.../query/ViewBasedCouchbaseQuery.java | 15 +-
.../support/SimpleCouchbaseRepository.java | 55 +-
src/main/resources/META-INF/spring.schemas | 4 +-
src/main/resources/changelog.txt | 18 +-
src/main/resources/notice.txt | 6 +-
.../couchbase/config/spring-couchbase-2.0.xsd | 166 ++++
.../config/spring-couchbase-env-2.0.xsd | 58 ++
.../data/couchbase/BucketCreator.java | 74 --
.../data/couchbase/TestApplicationConfig.java | 94 ---
.../couchbase/UnitTestApplicationConfig.java | 67 ++
.../cache/CouchbaseCacheManagerTests.java | 110 ---
.../couchbase/cache/CouchbaseCacheTests.java | 158 ----
.../AbstractCouchbaseConfigurationTests.java | 86 --
.../config/CouchbaseBucketParserTest.java | 136 ++++
.../config/CouchbaseClusterParserTest.java | 154 ++++
.../CouchbaseEnvironmentParserTest.java | 109 +++
.../CouchbaseParserIntegrationTests.java | 43 -
...uchbaseTemplateParserIntegrationTests.java | 74 --
.../data/couchbase/core/Beer.java | 4 +-
.../core/CouchbaseTemplateTests.java | 536 ------------
.../core/CouchbaseTemplateViewListener.java | 54 --
.../JacksonTranslationServiceTests.java | 57 +-
...BasicCouchbasePersistentPropertyTests.java | 13 +-
.../core/mapping/CustomConvertersTests.java | 27 +-
.../MappingCouchbaseConverterTests.java | 51 +-
.../AbstractCouchbaseEventListenerTests.java | 11 +-
.../event/EventContextConfiguration.java | 4 +-
.../event/SimpleMappingEventListener.java | 4 +-
.../couchbase/core/mapping/event/User.java | 4 +-
...ValidatingCouchbaseEventListenerTests.java | 16 +-
.../couchbaseBucket-bean.xml} | 14 +-
.../configurations/couchbaseCluster-bean.xml | 26 +
.../configurations/couchbaseEnv-bean.xml | 48 ++
template.mf | 3 +-
126 files changed, 4203 insertions(+), 3184 deletions(-)
create mode 100644 src/integration/java/org/springframework/data/couchbase/IntegrationTestApplicationConfig.java
create mode 100644 src/integration/java/org/springframework/data/couchbase/config/CouchbaseTemplateParserIntegrationTests.java
create mode 100644 src/integration/java/org/springframework/data/couchbase/core/CouchbaseTemplateTests.java
create mode 100644 src/integration/java/org/springframework/data/couchbase/core/CouchbaseTemplateViewListener.java
rename src/{test => integration}/java/org/springframework/data/couchbase/monitor/ClientInfoTests.java (66%)
rename src/{test => integration}/java/org/springframework/data/couchbase/monitor/ClusterInfoTests.java (65%)
rename src/{test => integration}/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryViewListener.java (58%)
rename src/{test => integration}/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryViewTests.java (81%)
rename src/{test => integration}/java/org/springframework/data/couchbase/repository/CustomUserRepository.java (100%)
rename src/{test => integration}/java/org/springframework/data/couchbase/repository/SimpleCouchbaseRepositoryListener.java (64%)
rename src/{test => integration}/java/org/springframework/data/couchbase/repository/SimpleCouchbaseRepositoryTests.java (82%)
rename src/{test => integration}/java/org/springframework/data/couchbase/repository/User.java (100%)
rename src/{test => integration}/java/org/springframework/data/couchbase/repository/UserRepository.java (89%)
rename src/{test => integration}/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepository.java (100%)
rename src/{test => integration}/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepositoryCustom.java (100%)
rename src/{test => integration}/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepositoryImpl.java (100%)
rename src/{test => integration}/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryClient.java (82%)
rename src/{test => integration}/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryTests.java (80%)
rename src/{test => integration}/java/org/springframework/data/couchbase/repository/cdi/CouchbaseClientProducer.java (58%)
rename src/{test => integration}/java/org/springframework/data/couchbase/repository/cdi/CouchbaseOperationsProducer.java (88%)
rename src/{test => integration}/java/org/springframework/data/couchbase/repository/cdi/Person.java (100%)
create mode 100644 src/integration/resources/META-INF/beans.xml
rename src/{test/resources/namespace => integration/resources/configurations}/couchbase-multi-bucket-bean.xml (50%)
rename src/{test/resources/namespace => integration/resources/configurations}/couchbase-template-bean.xml (88%)
rename src/{test/resources/namespace => integration/resources/configurations}/couchbase-template-with-translation-service-bean.xml (91%)
rename src/{test => integration}/resources/namespace/couchbase.properties (100%)
delete mode 100644 src/main/java/org/springframework/data/couchbase/cache/CouchbaseCache.java
delete mode 100644 src/main/java/org/springframework/data/couchbase/cache/CouchbaseCacheManager.java
create mode 100644 src/main/java/org/springframework/data/couchbase/config/CouchbaseBucketFactoryBean.java
create mode 100644 src/main/java/org/springframework/data/couchbase/config/CouchbaseBucketParser.java
create mode 100644 src/main/java/org/springframework/data/couchbase/config/CouchbaseClusterParser.java
create mode 100644 src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentFactoryBean.java
create mode 100644 src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentNoShutdownProxy.java
create mode 100644 src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentParser.java
delete mode 100644 src/main/java/org/springframework/data/couchbase/config/CouchbaseParser.java
create mode 100644 src/main/java/org/springframework/data/couchbase/config/package-info.java
delete mode 100644 src/main/java/org/springframework/data/couchbase/core/CouchbaseFactoryBean.java
create mode 100644 src/main/java/org/springframework/data/couchbase/core/CouchbaseQueryExecutionException.java
create mode 100644 src/main/java/org/springframework/data/couchbase/core/package-info.java
delete mode 100644 src/main/java/org/springframework/data/couchbase/monitor/AbstractMonitor.java
create mode 100644 src/main/java/org/springframework/data/couchbase/monitor/package-info.java
create mode 100644 src/main/java/org/springframework/data/couchbase/repository/package-info.java
create mode 100644 src/main/resources/org/springframework/data/couchbase/config/spring-couchbase-2.0.xsd
create mode 100644 src/main/resources/org/springframework/data/couchbase/config/spring-couchbase-env-2.0.xsd
delete mode 100644 src/test/java/org/springframework/data/couchbase/BucketCreator.java
delete mode 100644 src/test/java/org/springframework/data/couchbase/TestApplicationConfig.java
create mode 100644 src/test/java/org/springframework/data/couchbase/UnitTestApplicationConfig.java
delete mode 100644 src/test/java/org/springframework/data/couchbase/cache/CouchbaseCacheManagerTests.java
delete mode 100644 src/test/java/org/springframework/data/couchbase/cache/CouchbaseCacheTests.java
delete mode 100644 src/test/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfigurationTests.java
create mode 100644 src/test/java/org/springframework/data/couchbase/config/CouchbaseBucketParserTest.java
create mode 100644 src/test/java/org/springframework/data/couchbase/config/CouchbaseClusterParserTest.java
create mode 100644 src/test/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentParserTest.java
delete mode 100644 src/test/java/org/springframework/data/couchbase/config/CouchbaseParserIntegrationTests.java
delete mode 100644 src/test/java/org/springframework/data/couchbase/config/CouchbaseTemplateParserIntegrationTests.java
delete mode 100644 src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateTests.java
delete mode 100644 src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateViewListener.java
rename src/test/resources/{namespace/couchbase-bean.xml => configurations/couchbaseBucket-bean.xml} (53%)
create mode 100644 src/test/resources/configurations/couchbaseCluster-bean.xml
create mode 100644 src/test/resources/configurations/couchbaseEnv-bean.xml
diff --git a/README.md b/README.md
index cec96fc7..b068acb1 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,9 @@
+# Spring Data Couchbase - v2
+This branch is a work in progress, it will contain the do-over of the `Spring-Data Couchbase` connector
+for the `Couchbase Java SDK 2.x` generation.
+
+Below is the v1 README as of `75bce39`:
+
# Spring Data Couchbase
The primary goal of the [Spring Data](http://www.springsource.org/spring-data) project is to make it easier to build
diff --git a/pom.xml b/pom.xml
index 9739b8ed..46ca3124 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,155 +1,164 @@
-
+
- 4.0.0
+ 4.0.0
- org.springframework.data
- spring-data-couchbase
- 1.4.0.BUILD-SNAPSHOT
+ org.springframework.data
+ spring-data-couchbase
+ 2.0.0.BUILD-SNAPSHOT
- Spring Data Couchbase
- Spring Data integration for Couchbase
- https://github.com/SpringSource/spring-data-couchbase
+ Spring Data Couchbase
+ Spring Data integration for Couchbase
+ https://github.com/SpringSource/spring-data-couchbase
-
- org.springframework.data.build
- spring-data-parent
- 1.7.0.BUILD-SNAPSHOT
-
+
+ org.springframework.data.build
+ spring-data-parent
+ 1.7.0.BUILD-SNAPSHOT
+
-
+
- DATACOUCH
+ DATACOUCH
- 1.4.7
- 2.3.2
- 1.11.0.BUILD-SNAPSHOT
- 1.0.0.GA
-
+ 2.2.0-dp
+ 2.3.2
+ 1.11.0.BUILD-SNAPSHOT
+ 1.0.0.GA
+
-
+
-
- org.springframework
- spring-context
-
-
- org.springframework
- spring-web
-
-
- org.springframework
- spring-tx
-
+
+ org.springframework
+ spring-context
+
+
+ org.springframework
+ spring-web
+
+
+ org.springframework
+ spring-tx
+
-
- ${project.groupId}
- spring-data-commons
- ${springdata.commons}
-
+
+ ${project.groupId}
+ spring-data-commons
+ ${springdata.commons}
+
-
- com.couchbase.client
- couchbase-client
- ${couchbase}
-
+
+ com.couchbase.client
+ java-client
+ ${couchbase}
+
-
- org.springframework
- spring-test
- ${spring}
- test
-
+
+ org.springframework
+ spring-test
+ ${spring}
+ test
+
-
- org.hibernate
- hibernate-validator
- 4.2.0.Final
- test
-
+
+ org.hibernate
+ hibernate-validator
+ 4.2.0.Final
+ test
+
-
- org.apache.httpcomponents
- httpclient
- 4.3.3
- test
-
+
+ org.apache.httpcomponents
+ httpclient
+ 4.3.3
+ test
+
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson}
-
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson}
+
-
- joda-time
- joda-time
- ${jodatime}
- true
-
+
+ joda-time
+ joda-time
+ ${jodatime}
+ true
+
-
-
- javax.validation
- validation-api
- ${validation}
- true
-
+
+
+ javax.validation
+ validation-api
+ ${validation}
+ true
+
-
-
- javax.enterprise
- cdi-api
- ${cdi}
- provided
- true
-
+
+
+ javax.enterprise
+ cdi-api
+ ${cdi}
+ provided
+ true
+
-
- org.apache.openwebbeans.test
- cditest-owb
- ${webbeans}
- test
-
+
+ org.apache.openwebbeans.test
+ cditest-owb
+ ${webbeans}
+ test
+
-
- javax.servlet
- servlet-api
- 3.0-alpha-1
- test
-
+
+ javax.servlet
+ servlet-api
+ 3.0-alpha-1
+ test
+
-
+
-
-
- spring-libs-snapshot
- https://repo.spring.io/libs-snapshot
-
-
+
+
+ spring-libs-snapshot
+ https://repo.spring.io/libs-snapshot
+
+
+ couchbase
+ couchbase repo
+ http://files.couchbase.com/maven2
+
+ false
+
+
+
-
-
- spring-plugins-release
- https://repo.spring.io/plugins-release
-
-
+
+
+ spring-plugins-release
+ https://repo.spring.io/plugins-release
+
+
-
-
-
- org.apache.maven.plugins
- maven-assembly-plugin
-
-
- org.codehaus.mojo
- wagon-maven-plugin
-
-
- org.asciidoctor
- asciidoctor-maven-plugin
-
-
-
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+ org.codehaus.mojo
+ wagon-maven-plugin
+
+
+ org.asciidoctor
+ asciidoctor-maven-plugin
+
+
+
-
+
\ No newline at end of file
diff --git a/src/integration/java/org/springframework/data/couchbase/IntegrationTestApplicationConfig.java b/src/integration/java/org/springframework/data/couchbase/IntegrationTestApplicationConfig.java
new file mode 100644
index 00000000..f9d8e863
--- /dev/null
+++ b/src/integration/java/org/springframework/data/couchbase/IntegrationTestApplicationConfig.java
@@ -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 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;
+ }
+}
diff --git a/src/integration/java/org/springframework/data/couchbase/config/CouchbaseTemplateParserIntegrationTests.java b/src/integration/java/org/springframework/data/couchbase/config/CouchbaseTemplateParserIntegrationTests.java
new file mode 100644
index 00000000..c235f80a
--- /dev/null
+++ b/src/integration/java/org/springframework/data/couchbase/config/CouchbaseTemplateParserIntegrationTests.java
@@ -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");
+ }
+
+}
diff --git a/src/integration/java/org/springframework/data/couchbase/core/CouchbaseTemplateTests.java b/src/integration/java/org/springframework/data/couchbase/core/CouchbaseTemplateTests.java
new file mode 100644
index 00000000..a7db9bf7
--- /dev/null
+++ b/src/integration/java/org/springframework/data/couchbase/core/CouchbaseTemplateTests.java
@@ -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 resultConv = MAPPER.readValue(result, new TypeReference>() {});
+
+ 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 resultConv = MAPPER.readValue(result, new TypeReference>() {});
+ 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>() {});
+ 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 names = new ArrayList();
+ names.add("Michael");
+ names.add("Thomas");
+ names.add(null);
+ List votes = new LinkedList();
+ Map info1 = new HashMap();
+ info1.put("foo", true);
+ info1.put("bar", false);
+ info1.put("nullValue", null);
+ Map info2 = new HashMap();
+
+ 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 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 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 firstnames;
+ @Field
+ private final List votes;
+
+ @Field
+ private final Map info1;
+ @Field
+ private final Map info2;
+
+ public ComplexPerson(String id, List firstnames,
+ List votes, Map info1,
+ Map info2) {
+ this.id = id;
+ this.firstnames = firstnames;
+ this.votes = votes;
+ this.info1 = info1;
+ this.info2 = info2;
+ }
+
+ List getFirstnames() {
+ return firstnames;
+ }
+
+ List getVotes() {
+ return votes;
+ }
+
+ Map getInfo1() {
+ return info1;
+ }
+
+ Map 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 integerClass;
+
+ private String value;
+
+ SimpleWithClass(final String id, final Class integerClass) {
+ this.id = id;
+ this.integerClass = integerClass;
+ }
+
+ String getId() {
+ return id;
+ }
+
+ void setId(final String id) {
+ this.id = id;
+ }
+
+ Class getIntegerClass() {
+ return integerClass;
+ }
+
+ void setIntegerClass(final Class 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;
+ }
+}
diff --git a/src/integration/java/org/springframework/data/couchbase/core/CouchbaseTemplateViewListener.java b/src/integration/java/org/springframework/data/couchbase/core/CouchbaseTemplateViewListener.java
new file mode 100644
index 00000000..07900d62
--- /dev/null
+++ b/src/integration/java/org/springframework/data/couchbase/core/CouchbaseTemplateViewListener.java
@@ -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);
+ }
+
+}
diff --git a/src/test/java/org/springframework/data/couchbase/monitor/ClientInfoTests.java b/src/integration/java/org/springframework/data/couchbase/monitor/ClientInfoTests.java
similarity index 66%
rename from src/test/java/org/springframework/data/couchbase/monitor/ClientInfoTests.java
rename to src/integration/java/org/springframework/data/couchbase/monitor/ClientInfoTests.java
index a8b9e8a3..62d71e0d 100644
--- a/src/test/java/org/springframework/data/couchbase/monitor/ClientInfoTests.java
+++ b/src/integration/java/org/springframework/data/couchbase/monitor/ClientInfoTests.java
@@ -16,45 +16,44 @@
package org.springframework.data.couchbase.monitor;
-import com.couchbase.client.CouchbaseClient;
+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.TestApplicationConfig;
+import org.springframework.data.couchbase.IntegrationTestApplicationConfig;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.isEmptyString;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.hamcrest.core.IsNot.not;
-import static org.junit.Assert.assertFalse;
-
/**
* @author Michael Nitschinger
*/
@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes = TestApplicationConfig.class)
+@ContextConfiguration(classes = IntegrationTestApplicationConfig.class)
public class ClientInfoTests {
- /**
- * Contains a reference to the actual CouchbaseClient.
- */
- @Autowired
- private CouchbaseClient client;
+ /**
+ * Contains a reference to the actual CouchbaseClient.
+ */
+ @Autowired
+ private Bucket client;
- private ClientInfo ci;
+ private ClientInfo ci;
- @Before
- public void setup() throws Exception {
- ci = new ClientInfo(client);
- }
+ @Before
+ public void setup() throws Exception {
+ ci = new ClientInfo(client);
+ }
- @Test
- public void hostNames() {
- String hostnames = ci.getHostNames();
- assertThat(hostnames, not(isEmptyString()));
- }
+ @Test
+ public void hostNames() {
+ String hostnames = ci.getHostNames();
+ assertThat(hostnames, not(isEmptyString()));
+ }
}
diff --git a/src/test/java/org/springframework/data/couchbase/monitor/ClusterInfoTests.java b/src/integration/java/org/springframework/data/couchbase/monitor/ClusterInfoTests.java
similarity index 65%
rename from src/test/java/org/springframework/data/couchbase/monitor/ClusterInfoTests.java
rename to src/integration/java/org/springframework/data/couchbase/monitor/ClusterInfoTests.java
index dafa7cf1..63c5441c 100644
--- a/src/test/java/org/springframework/data/couchbase/monitor/ClusterInfoTests.java
+++ b/src/integration/java/org/springframework/data/couchbase/monitor/ClusterInfoTests.java
@@ -16,46 +16,47 @@
package org.springframework.data.couchbase.monitor;
-import com.couchbase.client.CouchbaseClient;
+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.TestApplicationConfig;
+import org.springframework.data.couchbase.IntegrationTestApplicationConfig;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.greaterThan;
-
/**
* @author Michael Nitschinger
*/
@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes = TestApplicationConfig.class)
+@ContextConfiguration(classes = IntegrationTestApplicationConfig.class)
public class ClusterInfoTests {
- /**
- * Contains a reference to the actual CouchbaseClient.
- */
- @Autowired
- private CouchbaseClient client;
+ /**
+ * Contains a reference to the actual CouchbaseClient.
+ */
+ @Autowired
+ private Bucket client;
- private ClusterInfo ci;
+ private ClusterInfo ci;
- @Before
- public void setup() throws Exception {
- ci = new ClusterInfo(client);
- }
+ @Before
+ public void setup() throws Exception {
+ ci = new ClusterInfo(client);
+ }
- @Test
- public void totalDiskAssigned() {
- assertThat(ci.getTotalDiskAssigned(), greaterThan(0L));
- }
+ @Test
+ public void totalDiskAssigned() {
+ assertThat(ci.getTotalDiskAssigned(), greaterThan(0L));
+ }
- @Test
- public void totalRAMUsed() {
- assertThat(ci.getTotalRAMUsed(), greaterThan(0L));
- }
+ @Test
+ public void totalRAMUsed() {
+ assertThat(ci.getTotalRAMUsed(), greaterThan(0L));
+ }
}
diff --git a/src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryViewListener.java b/src/integration/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryViewListener.java
similarity index 58%
rename from src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryViewListener.java
rename to src/integration/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryViewListener.java
index fa5531f1..13420e40 100644
--- a/src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryViewListener.java
+++ b/src/integration/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryViewListener.java
@@ -16,11 +16,16 @@
package org.springframework.data.couchbase.repository;
-import com.couchbase.client.CouchbaseClient;
-import com.couchbase.client.protocol.views.DesignDocument;
-import com.couchbase.client.protocol.views.ViewDesign;
-import net.spy.memcached.PersistTo;
-import net.spy.memcached.ReplicateTo;
+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;
@@ -32,29 +37,29 @@ public class CouchbaseRepositoryViewListener extends DependencyInjectionTestExec
@Override
public void beforeTestClass(final TestContext testContext) throws Exception {
- CouchbaseClient client = (CouchbaseClient) testContext.getApplicationContext().getBean("couchbaseClient");
+ Bucket client = (Bucket) testContext.getApplicationContext().getBean("couchbaseBucket");
populateTestData(client);
createAndWaitForDesignDocs(client);
}
- private void populateTestData(final CouchbaseClient 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.ZERO);
+ template.save(new User("testuser-" + i, "uname-" + i), PersistTo.MASTER, ReplicateTo.NONE);
}
}
- private void createAndWaitForDesignDocs(final CouchbaseClient client) {
- DesignDocument designDoc = new DesignDocument("user");
+ private void createAndWaitForDesignDocs(final Bucket client) {
String mapFunction = "function (doc, meta) { if(doc._class == \"org.springframework.data.couchbase.repository.User\") { emit(null, null); } }";
- designDoc.setView(new ViewDesign("customFindAllView", mapFunction, "_count"));
+ View view = DefaultView.create("customFindAllView", mapFunction, "_count");
+ List views = Collections.singletonList(view);
+ DesignDocument designDoc = DesignDocument.create("user", views);
+ client.bucketManager().upsertDesignDocument(designDoc);
- client.createDesignDoc(designDoc);
-
- designDoc = new DesignDocument("userCustom");
- designDoc.setView(new ViewDesign("customCountView", mapFunction, "_count"));
-
- client.createDesignDoc(designDoc);
+ view = DefaultView.create("customCountView", mapFunction, "_count");
+ views = Collections.singletonList(view);
+ designDoc = DesignDocument.create("userCustom", views);
+ client.bucketManager().upsertDesignDocument(designDoc);
}
}
diff --git a/src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryViewTests.java b/src/integration/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryViewTests.java
similarity index 81%
rename from src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryViewTests.java
rename to src/integration/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryViewTests.java
index 585b5faa..2bc75eac 100644
--- a/src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryViewTests.java
+++ b/src/integration/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryViewTests.java
@@ -16,34 +16,35 @@
package org.springframework.data.couchbase.repository;
-import com.couchbase.client.CouchbaseClient;
-import com.couchbase.client.protocol.views.Query;
+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.TestApplicationConfig;
+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;
-import static com.couchbase.client.protocol.views.Stale.FALSE;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
/**
* @author David Harrigan
*/
@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes = TestApplicationConfig.class)
+@ContextConfiguration(classes = IntegrationTestApplicationConfig.class)
@TestExecutionListeners(CouchbaseRepositoryViewListener.class)
public class CouchbaseRepositoryViewTests {
@Autowired
- private CouchbaseClient client;
+ private Bucket client;
@Autowired
private CouchbaseTemplate template;
@@ -57,7 +58,7 @@ public class CouchbaseRepositoryViewTests {
@Test
public void shouldFindAllWithCustomView() {
- client.query(client.getView("user", "customFindAllView"), new Query().setStale(FALSE));
+ client.query(ViewQuery.from("user", "customFindAllView").stale(Stale.FALSE));
Iterable allUsers = repository.findAll();
int i = 0;
for (final User allUser : allUsers) {
@@ -68,7 +69,7 @@ public class CouchbaseRepositoryViewTests {
@Test
public void shouldCountWithCustomView() {
- client.query(client.getView("userCustom", "customCountView"), new Query().setStale(FALSE));
+ client.query(ViewQuery.from("userCustom", "customCountView").stale(Stale.FALSE));
final long value = repository.count();
assertThat(value, is(100L));
}
diff --git a/src/test/java/org/springframework/data/couchbase/repository/CustomUserRepository.java b/src/integration/java/org/springframework/data/couchbase/repository/CustomUserRepository.java
similarity index 100%
rename from src/test/java/org/springframework/data/couchbase/repository/CustomUserRepository.java
rename to src/integration/java/org/springframework/data/couchbase/repository/CustomUserRepository.java
diff --git a/src/test/java/org/springframework/data/couchbase/repository/SimpleCouchbaseRepositoryListener.java b/src/integration/java/org/springframework/data/couchbase/repository/SimpleCouchbaseRepositoryListener.java
similarity index 64%
rename from src/test/java/org/springframework/data/couchbase/repository/SimpleCouchbaseRepositoryListener.java
rename to src/integration/java/org/springframework/data/couchbase/repository/SimpleCouchbaseRepositoryListener.java
index b6c28330..b87fd345 100644
--- a/src/test/java/org/springframework/data/couchbase/repository/SimpleCouchbaseRepositoryListener.java
+++ b/src/integration/java/org/springframework/data/couchbase/repository/SimpleCouchbaseRepositoryListener.java
@@ -16,11 +16,16 @@
package org.springframework.data.couchbase.repository;
-import com.couchbase.client.CouchbaseClient;
-import com.couchbase.client.protocol.views.DesignDocument;
-import com.couchbase.client.protocol.views.ViewDesign;
-import net.spy.memcached.PersistTo;
-import net.spy.memcached.ReplicateTo;
+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;
@@ -32,27 +37,28 @@ public class SimpleCouchbaseRepositoryListener extends DependencyInjectionTestEx
@Override
public void beforeTestClass(final TestContext testContext) throws Exception {
- CouchbaseClient client = (CouchbaseClient) testContext.getApplicationContext().getBean("couchbaseClient");
+ Bucket client = (Bucket) testContext.getApplicationContext().getBean("couchbaseBucket");
populateTestData(client);
createAndWaitForDesignDocs(client);
}
- private void populateTestData(CouchbaseClient 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.ZERO);
+ template.save(u, PersistTo.MASTER, ReplicateTo.NONE);
}
}
- private void createAndWaitForDesignDocs(CouchbaseClient client) {
- DesignDocument designDoc = new DesignDocument("user");
+ private void createAndWaitForDesignDocs(Bucket client) {
String mapFunction = "function (doc, meta) { if(doc._class == \"org.springframework.data.couchbase.repository." +
"User\") { emit(null, null); } }";
- designDoc.setView(new ViewDesign("all", mapFunction, "_count"));
- client.createDesignDoc(designDoc);
+ View view = DefaultView.create("all", mapFunction, "_count");
+ List views = Collections.singletonList(view);
+ DesignDocument designDoc = DesignDocument.create("user", views);
+ client.bucketManager().upsertDesignDocument(designDoc);
}
}
diff --git a/src/test/java/org/springframework/data/couchbase/repository/SimpleCouchbaseRepositoryTests.java b/src/integration/java/org/springframework/data/couchbase/repository/SimpleCouchbaseRepositoryTests.java
similarity index 82%
rename from src/test/java/org/springframework/data/couchbase/repository/SimpleCouchbaseRepositoryTests.java
rename to src/integration/java/org/springframework/data/couchbase/repository/SimpleCouchbaseRepositoryTests.java
index 00033329..75676d96 100644
--- a/src/test/java/org/springframework/data/couchbase/repository/SimpleCouchbaseRepositoryTests.java
+++ b/src/integration/java/org/springframework/data/couchbase/repository/SimpleCouchbaseRepositoryTests.java
@@ -16,15 +16,17 @@
package org.springframework.data.couchbase.repository;
-import com.couchbase.client.CouchbaseClient;
-import com.couchbase.client.protocol.views.Query;
-import com.couchbase.client.protocol.views.Stale;
+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.beans.factory.annotation.Qualifier;
-import org.springframework.data.couchbase.TestApplicationConfig;
+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;
@@ -32,18 +34,16 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import static org.junit.Assert.*;
-
/**
* @author Michael Nitschinger
*/
@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes = TestApplicationConfig.class)
+@ContextConfiguration(classes = IntegrationTestApplicationConfig.class)
@TestExecutionListeners(SimpleCouchbaseRepositoryListener.class)
public class SimpleCouchbaseRepositoryTests {
@Autowired
- private CouchbaseClient client;
+ private Bucket client;
@Autowired
private CouchbaseTemplate template;
@@ -79,7 +79,7 @@ public class SimpleCouchbaseRepositoryTests {
*/
public void shouldFindAll() {
// do a non-stale query to populate data for testing.
- client.query(client.getView("user", "all"), new Query().setStale(Stale.FALSE));
+ client.query(ViewQuery.from("user", "all").stale(Stale.FALSE));
Iterable allUsers = repository.findAll();
int size = 0;
@@ -94,14 +94,14 @@ public class SimpleCouchbaseRepositoryTests {
@Test
public void shouldCount() {
// do a non-stale query to populate data for testing.
- client.query(client.getView("user", "all"), new Query().setStale(Stale.FALSE));
+ client.query(ViewQuery.from("user", "all").stale(Stale.FALSE));
assertEquals(100, repository.count());
}
@Test
public void shouldFindCustom() {
- Iterable users = repository.customViewQuery(new Query().setLimit(2).setStale(Stale.FALSE));
+ Iterable users = repository.customViewQuery(ViewQuery.from("", "").limit(2).stale(Stale.FALSE));
int size = 0;
for (User u : users) {
size++;
diff --git a/src/test/java/org/springframework/data/couchbase/repository/User.java b/src/integration/java/org/springframework/data/couchbase/repository/User.java
similarity index 100%
rename from src/test/java/org/springframework/data/couchbase/repository/User.java
rename to src/integration/java/org/springframework/data/couchbase/repository/User.java
diff --git a/src/test/java/org/springframework/data/couchbase/repository/UserRepository.java b/src/integration/java/org/springframework/data/couchbase/repository/UserRepository.java
similarity index 89%
rename from src/test/java/org/springframework/data/couchbase/repository/UserRepository.java
rename to src/integration/java/org/springframework/data/couchbase/repository/UserRepository.java
index d8c04262..866a3ea5 100644
--- a/src/test/java/org/springframework/data/couchbase/repository/UserRepository.java
+++ b/src/integration/java/org/springframework/data/couchbase/repository/UserRepository.java
@@ -16,7 +16,8 @@
package org.springframework.data.couchbase.repository;
-import com.couchbase.client.protocol.views.Query;
+import com.couchbase.client.java.view.ViewQuery;
+
import org.springframework.data.couchbase.core.view.View;
/**
@@ -25,6 +26,6 @@ import org.springframework.data.couchbase.core.view.View;
public interface UserRepository extends CouchbaseRepository {
@View(designDocument = "user", viewName = "all")
- Iterable customViewQuery(Query query);
+ Iterable customViewQuery(ViewQuery query);
}
diff --git a/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepository.java b/src/integration/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepository.java
similarity index 100%
rename from src/test/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepository.java
rename to src/integration/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepository.java
diff --git a/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepositoryCustom.java b/src/integration/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepositoryCustom.java
similarity index 100%
rename from src/test/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepositoryCustom.java
rename to src/integration/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepositoryCustom.java
diff --git a/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepositoryImpl.java b/src/integration/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepositoryImpl.java
similarity index 100%
rename from src/test/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepositoryImpl.java
rename to src/integration/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepositoryImpl.java
diff --git a/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryClient.java b/src/integration/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryClient.java
similarity index 82%
rename from src/test/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryClient.java
rename to src/integration/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryClient.java
index 9fab73d0..d6c99c74 100644
--- a/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryClient.java
+++ b/src/integration/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryClient.java
@@ -18,8 +18,7 @@ package org.springframework.data.couchbase.repository.cdi;
import javax.inject.Inject;
-import com.couchbase.client.CouchbaseClient;
-import org.springframework.data.couchbase.repository.UserRepository;
+import com.couchbase.client.java.Bucket;
/**
* @author Mark Paluch
@@ -30,13 +29,13 @@ class CdiRepositoryClient {
private CdiPersonRepository cdiPersonRepository;
@Inject
- private CouchbaseClient couchbaseClient;
+ private Bucket couchbaseClient;
public CdiPersonRepository getCdiPersonRepository() {
return cdiPersonRepository;
}
- public CouchbaseClient getCouchbaseClient() {
+ public Bucket getCouchbaseClient() {
return couchbaseClient;
}
}
diff --git a/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryTests.java b/src/integration/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryTests.java
similarity index 80%
rename from src/test/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryTests.java
rename to src/integration/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryTests.java
index b4c91043..91ab94e6 100644
--- a/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryTests.java
+++ b/src/integration/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryTests.java
@@ -18,6 +18,13 @@ 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;
@@ -25,10 +32,6 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
-import com.couchbase.client.CouchbaseClient;
-import com.couchbase.client.protocol.views.DesignDocument;
-import com.couchbase.client.protocol.views.ViewDesign;
-
/**
* @author Mark Paluch
*/
@@ -36,7 +39,7 @@ public class CdiRepositoryTests {
private static CdiTestContainer cdiContainer;
private CdiPersonRepository repository;
- private CouchbaseClient couchbaseClient;
+ private Bucket couchbaseClient;
@BeforeClass
public static void init() throws Exception {
@@ -61,12 +64,13 @@ public class CdiRepositoryTests {
}
- private void createAndWaitForDesignDocs(CouchbaseClient client) {
- DesignDocument designDoc = new DesignDocument("person");
+ private void createAndWaitForDesignDocs(Bucket client) {
String mapFunction = "function (doc, meta) { if(doc._class == \"" + Person.class.getName()
+ "\") { emit(null, null); } }";
- designDoc.setView(new ViewDesign("all", mapFunction, "_count"));
- client.createDesignDoc(designDoc);
+ View view = DefaultView.create("all", mapFunction, "_count");
+ List views = Collections.singletonList(view);
+ DesignDocument designDoc = DesignDocument.create("person", views);
+ client.bucketManager().upsertDesignDocument(designDoc);
}
/**
diff --git a/src/test/java/org/springframework/data/couchbase/repository/cdi/CouchbaseClientProducer.java b/src/integration/java/org/springframework/data/couchbase/repository/cdi/CouchbaseClientProducer.java
similarity index 58%
rename from src/test/java/org/springframework/data/couchbase/repository/cdi/CouchbaseClientProducer.java
rename to src/integration/java/org/springframework/data/couchbase/repository/cdi/CouchbaseClientProducer.java
index 1c1f2c9a..c32da14f 100644
--- a/src/test/java/org/springframework/data/couchbase/repository/cdi/CouchbaseClientProducer.java
+++ b/src/integration/java/org/springframework/data/couchbase/repository/cdi/CouchbaseClientProducer.java
@@ -19,27 +19,30 @@ package org.springframework.data.couchbase.repository.cdi;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
-import org.springframework.data.couchbase.core.CouchbaseFactoryBean;
+import com.couchbase.client.java.Bucket;
+import com.couchbase.client.java.CouchbaseCluster;
-import com.couchbase.client.CouchbaseClient;
+import org.springframework.data.couchbase.config.CouchbaseBucketFactoryBean;
/**
- * Producer for {@link CouchbaseClient}. Defaults from {@link CouchbaseFactoryBean} are sufficient for our test.
+ * 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 CouchbaseClient createCouchbaseClient() throws Exception {
-
- CouchbaseFactoryBean couchbaseFactoryBean = new CouchbaseFactoryBean();
- couchbaseFactoryBean.setBucket("default");
+ 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 CouchbaseClient couchbaseClient) {
- couchbaseClient.shutdown();
+ public void close(@Disposes Bucket couchbaseClient) {
+ couchbaseClient.close();
}
}
diff --git a/src/test/java/org/springframework/data/couchbase/repository/cdi/CouchbaseOperationsProducer.java b/src/integration/java/org/springframework/data/couchbase/repository/cdi/CouchbaseOperationsProducer.java
similarity index 88%
rename from src/test/java/org/springframework/data/couchbase/repository/cdi/CouchbaseOperationsProducer.java
rename to src/integration/java/org/springframework/data/couchbase/repository/cdi/CouchbaseOperationsProducer.java
index bf3f1d84..f95eacab 100644
--- a/src/test/java/org/springframework/data/couchbase/repository/cdi/CouchbaseOperationsProducer.java
+++ b/src/integration/java/org/springframework/data/couchbase/repository/cdi/CouchbaseOperationsProducer.java
@@ -18,11 +18,11 @@ 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;
-import com.couchbase.client.CouchbaseClient;
-
/**
* Produces a {@link CouchbaseOperations} instance for test usage.
* @author Mark Paluch
@@ -30,7 +30,7 @@ import com.couchbase.client.CouchbaseClient;
class CouchbaseOperationsProducer {
@Produces
- public CouchbaseOperations createCouchbaseOperations(CouchbaseClient couchbaseClient) throws Exception {
+ public CouchbaseOperations createCouchbaseOperations(Bucket couchbaseClient) throws Exception {
CouchbaseTemplate couchbaseTemplate = new CouchbaseTemplate(couchbaseClient);
diff --git a/src/test/java/org/springframework/data/couchbase/repository/cdi/Person.java b/src/integration/java/org/springframework/data/couchbase/repository/cdi/Person.java
similarity index 100%
rename from src/test/java/org/springframework/data/couchbase/repository/cdi/Person.java
rename to src/integration/java/org/springframework/data/couchbase/repository/cdi/Person.java
diff --git a/src/integration/resources/META-INF/beans.xml b/src/integration/resources/META-INF/beans.xml
new file mode 100644
index 00000000..71dc6db1
--- /dev/null
+++ b/src/integration/resources/META-INF/beans.xml
@@ -0,0 +1,6 @@
+
+
+
+
diff --git a/src/test/resources/namespace/couchbase-multi-bucket-bean.xml b/src/integration/resources/configurations/couchbase-multi-bucket-bean.xml
similarity index 50%
rename from src/test/resources/namespace/couchbase-multi-bucket-bean.xml
rename to src/integration/resources/configurations/couchbase-multi-bucket-bean.xml
index be4d32aa..1a480dd1 100644
--- a/src/test/resources/namespace/couchbase-multi-bucket-bean.xml
+++ b/src/integration/resources/configurations/couchbase-multi-bucket-bean.xml
@@ -6,18 +6,12 @@
xsi:schemaLocation="http://www.springframework.org/schema/data/couchbase http://www.springframework.org/schema/data/couchbase/spring-couchbase.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/repository http://www.springframework.org/schema/data/repository/spring-repository.xsd">
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/src/test/resources/namespace/couchbase-template-bean.xml b/src/integration/resources/configurations/couchbase-template-bean.xml
similarity index 88%
rename from src/test/resources/namespace/couchbase-template-bean.xml
rename to src/integration/resources/configurations/couchbase-template-bean.xml
index 6ccb176b..9b0ada0b 100644
--- a/src/test/resources/namespace/couchbase-template-bean.xml
+++ b/src/integration/resources/configurations/couchbase-template-bean.xml
@@ -5,7 +5,9 @@
xsi:schemaLocation="http://www.springframework.org/schema/data/couchbase http://www.springframework.org/schema/data/couchbase/spring-couchbase.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
-
+
+
+
diff --git a/src/test/resources/namespace/couchbase-template-with-translation-service-bean.xml b/src/integration/resources/configurations/couchbase-template-with-translation-service-bean.xml
similarity index 91%
rename from src/test/resources/namespace/couchbase-template-with-translation-service-bean.xml
rename to src/integration/resources/configurations/couchbase-template-with-translation-service-bean.xml
index 77402784..e2f31a1f 100644
--- a/src/test/resources/namespace/couchbase-template-with-translation-service-bean.xml
+++ b/src/integration/resources/configurations/couchbase-template-with-translation-service-bean.xml
@@ -5,7 +5,9 @@
xsi:schemaLocation="http://www.springframework.org/schema/data/couchbase http://www.springframework.org/schema/data/couchbase/spring-couchbase.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
-
+
+
+
diff --git a/src/test/resources/namespace/couchbase.properties b/src/integration/resources/namespace/couchbase.properties
similarity index 100%
rename from src/test/resources/namespace/couchbase.properties
rename to src/integration/resources/namespace/couchbase.properties
diff --git a/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCache.java b/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCache.java
deleted file mode 100644
index 32625792..00000000
--- a/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCache.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * 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.cache;
-
-import com.couchbase.client.CouchbaseClient;
-import org.springframework.cache.Cache;
-import org.springframework.cache.support.SimpleValueWrapper;
-
-/**
- * The {@link CouchbaseCache} class implements the Spring Cache interface on top of Couchbase Server and the Couchbase
- * Java SDK.
- *
- * @see
- * Official Spring Cache Reference
- * @author Michael Nitschinger
- * @author Konrad Król
- */
-public class CouchbaseCache implements Cache {
-
- /**
- * The actual CouchbaseClient instance.
- */
- private final CouchbaseClient client;
-
- /**
- * The name of the cache.
- */
- private final String name;
-
- /**
- * TTL value for objects in this cache
- */
- private final int ttl;
-
- /**
- * Construct the cache and pass in the CouchbaseClient instance.
- *
- * @param name the name of the cache reference.
- * @param client the CouchbaseClient instance.
- */
- public CouchbaseCache(final String name, final CouchbaseClient client) {
- this.name = name;
- this.client = client;
- this.ttl = 0;
- }
-
- /**
- * Construct the cache and pass in the CouchbaseClient instance.
- *
- * @param name the name of the cache reference.
- * @param client the CouchbaseClient instance.
- * @param ttl TTL value for objects in this cache
- */
- public CouchbaseCache(final String name, final CouchbaseClient client, int ttl) {
- this.name = name;
- this.client = client;
- this.ttl = ttl;
- }
-
- /**
- * Returns the name of the cache.
- *
- * @return the name of the cache.
- */
- public final String getName() {
- return name;
- }
-
- /**
- * Returns the actual CouchbaseClient instance.
- *
- * @return the actual CouchbaseClient instance.
- */
- public final CouchbaseClient getNativeCache() {
- return client;
- }
-
- /**
- * Returns the TTL value for this cache.
- *
- * @return TTL value
- */
- public final int getTtl() {
- return ttl;
- }
-
- /**
- * Get an element from the cache.
- *
- * @param key the key to lookup against.
- * @return the fetched value from Couchbase.
- */
- public final ValueWrapper get(final Object key) {
- String documentId = key.toString();
- Object result = client.get(documentId);
- return (result != null ? new SimpleValueWrapper(result) : null);
- }
-
- @SuppressWarnings("unchecked")
- public final T get(final Object key, final Class clazz) {
- String documentId = key.toString();
- return (T) client.get(documentId);
- }
-
- /**
- * Store a object in Couchbase.
- *
- * @param key the Key of the storable object.
- * @param value the Object to store.
- */
- public final void put(final Object key, final Object value) {
- if (value != null) {
- String documentId = key.toString();
- client.set(documentId, ttl, value);
- } else {
- evict(key);
- }
- }
-
- /**
- * Remove an object from Couchbase.
- *
- * @param key the Key of the object to delete.
- */
- public final void evict(final Object key) {
- String documentId = key.toString();
- client.delete(documentId);
- }
-
- /**
- * Clear the complete cache.
- *
- * Note that this action is very destructive, so only use it with care.
- * Also note that "flush" may not be enabled on the bucket.
- */
- public final void clear() {
- client.flush();
- }
-
- /*
- * (non-Javadoc)
- * @see org.springframework.cache.Cache#putIfAbsent(java.lang.Object, java.lang.Object)
- */
- public ValueWrapper putIfAbsent(Object key, Object value) {
-
- if(get(key) == null) {
- put(key, value);
- return null;
- }
-
- return new SimpleValueWrapper(value);
- }
-}
diff --git a/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCacheManager.java b/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCacheManager.java
deleted file mode 100644
index 26e5b6cb..00000000
--- a/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCacheManager.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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.cache;
-
-import com.couchbase.client.CouchbaseClient;
-import org.springframework.cache.Cache;
-import org.springframework.cache.support.AbstractCacheManager;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.Map;
-
-/**
- * The {@link CouchbaseCacheManager} orchestrates {@link CouchbaseCache} instances.
- *
- * Since more than one current {@link CouchbaseClient} connection can be used for caching, the
- * {@link CouchbaseCacheManager} orchestrates and handles them for the Spring Cache abstraction layer.
- *
- * @author Michael Nitschinger
- * @author Konrad Król
- */
-public class CouchbaseCacheManager extends AbstractCacheManager {
-
- /**
- * Holds the reference to all stored CouchbaseClient cache connections.
- */
- private final HashMap clients;
-
- /**
- * Holds the TTL configuration for each cache.
- */
- private final HashMap ttlConfiguration;
-
- /**
- * Construct a new CouchbaseCacheManager.
- *
- * @param clients one ore more CouchbaseClients to reference.
- */
- public CouchbaseCacheManager(final HashMap clients) {
- this.clients = clients;
- this.ttlConfiguration = new HashMap();
- }
-
- /**
- * Construct a new CouchbaseCacheManager.
- *
- * @param clients one ore more CouchbaseClients to reference.
- * @param ttlConfiguration one or more TTL values (in seconds)
- */
- public CouchbaseCacheManager(final HashMap clients, final HashMap ttlConfiguration) {
- this.clients = clients;
- this.ttlConfiguration = ttlConfiguration;
- }
-
- /**
- * Returns a Map of all CouchbaseClients with name.
- *
- * @return the actual CouchbaseClient instances.
- */
- public final HashMap getClients() {
- return clients;
- }
-
- /**
- * Populates all caches.
- *
- * @return a collection of loaded caches.
- */
- @Override
- protected final Collection extends Cache> loadCaches() {
- Collection caches = new LinkedHashSet();
-
- for (Map.Entry cache : clients.entrySet()) {
- caches.add(new CouchbaseCache(cache.getKey(), cache.getValue(), getTtl(cache.getKey())));
- }
-
- return caches;
- }
-
- /**
- * Returns TTL value for single cache
- * @param name cache name
- * @return either the cache TTL value or 0 as a default value
- */
- private int getTtl ( String name ) {
- Integer expirationTime = ttlConfiguration.get(name);
- return (expirationTime != null ? expirationTime : 0);
- }
-
-}
diff --git a/src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java b/src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java
index 8f3f5ca5..274638f7 100644
--- a/src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java
+++ b/src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,14 +16,23 @@
package org.springframework.data.couchbase.config;
-import com.couchbase.client.CouchbaseClient;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import com.couchbase.client.java.Bucket;
+import com.couchbase.client.java.Cluster;
+import com.couchbase.client.java.CouchbaseCluster;
+import com.couchbase.client.java.env.CouchbaseEnvironment;
+import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
+
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.data.annotation.Persistent;
-import org.springframework.data.couchbase.core.CouchbaseFactoryBean;
import org.springframework.data.couchbase.core.CouchbaseTemplate;
import org.springframework.data.couchbase.core.convert.CustomConversions;
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
@@ -37,29 +46,21 @@ import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-
/**
* Base class for Spring Data Couchbase configuration using JavaConfig.
*
* @author Michael Nitschinger
+ * @author Simon Baslé
*/
@Configuration
public abstract class AbstractCouchbaseConfiguration {
/**
- * The list of hostnames (or IP addresses to bootstrap from).
+ * The list of hostnames (or IP addresses) to bootstrap from.
*
* @return the list of bootstrap hosts.
*/
- protected abstract List bootstrapHosts();
+ protected abstract List getBootstrapHosts();
/**
* The name of the bucket to connect to.
@@ -76,39 +77,54 @@ public abstract class AbstractCouchbaseConfiguration {
protected abstract String getBucketPassword();
/**
- * Return the {@link CouchbaseClient} instance to connect to.
+ * Is the {@link #getEnvironment()} to be destroyed by Spring?
+ *
+ * @return true if Spring should destroy the environment with the context, false otherwise.
+ */
+ protected boolean isEnvironmentManagedBySpring() {
+ return true;
+ }
+
+ /**
+ * Override this method if you want a customized {@link CouchbaseEnvironment}.
+ * This environment will be managed by Spring, which will call its shutdown()
+ * method upon bean destruction, unless you override {@link #isEnvironmentManagedBySpring()}
+ * as well to return false.
+ *
+ * @return a customized environment, defaults to a {@link DefaultCouchbaseEnvironment}.
+ */
+ protected CouchbaseEnvironment getEnvironment() {
+ return DefaultCouchbaseEnvironment.create();
+ }
+
+ @Bean(destroyMethod = "shutdown", name = BeanNames.COUCHBASE_ENV)
+ public CouchbaseEnvironment couchbaseEnvironment() {
+ CouchbaseEnvironment env = getEnvironment();
+ if (isEnvironmentManagedBySpring()) {
+ return env;
+ }
+ return new CouchbaseEnvironmentNoShutdownProxy(env);
+ }
+
+ /**
+ * Returns the {@link Cluster} instance to connect to.
*
* @throws Exception on Bean construction failure.
*/
- @Bean(destroyMethod = "shutdown")
- public CouchbaseClient couchbaseClient() throws Exception {
- setLoggerProperty(couchbaseLogger());
-
- return new CouchbaseClient(
- bootstrapUris(bootstrapHosts()),
- getBucketName(),
- getBucketPassword()
- );
+ @Bean(destroyMethod = "disconnect", name = BeanNames.COUCHBASE_CLUSTER)
+ public Cluster couchbaseCluster() throws Exception {
+ return CouchbaseCluster.create(couchbaseEnvironment(), getBootstrapHosts());
}
/**
- * Specifies the logger to use (defaults to SLF4J).
+ * Return the {@link Bucket} instance to connect to.
*
- * @return the logger property string.
+ * @throws Exception on Bean construction failure.
*/
- protected String couchbaseLogger() {
- return CouchbaseFactoryBean.DEFAULT_LOGGER_PROPERTY;
- }
-
- /**
- * Prepare the logging property before initializing couchbase.
- *
- * @param logger the logger path to use.
- */
- protected static void setLoggerProperty(final String logger) {
- Properties systemProperties = System.getProperties();
- systemProperties.setProperty("net.spy.log.LoggerImpl", logger);
- System.setProperties(systemProperties);
+ @Bean(destroyMethod = "close", name = BeanNames.COUCHBASE_BUCKET)
+ public Bucket couchbaseClient() throws Exception {
+ //@Bean method can use another @Bean method in the same @Configuration by directly invoking it
+ return couchbaseCluster().openBucket(getBucketName(), getBucketPassword());
}
/**
@@ -116,7 +132,7 @@ public abstract class AbstractCouchbaseConfiguration {
*
* @throws Exception on Bean construction failure.
*/
- @Bean
+ @Bean(name = BeanNames.COUCHBASE_TEMPLATE)
public CouchbaseTemplate couchbaseTemplate() throws Exception {
return new CouchbaseTemplate(couchbaseClient(), mappingCouchbaseConverter(), translationService());
}
@@ -159,8 +175,6 @@ public abstract class AbstractCouchbaseConfiguration {
return mappingContext;
}
-
-
/**
* Register custom Converters in a {@link CustomConversions} object if required. These
* {@link CustomConversions} will be registered with the {@link #mappingCouchbaseConverter()} and
@@ -202,7 +216,7 @@ public abstract class AbstractCouchbaseConfiguration {
* will be considered {@code com.acme} unless the method is overridden to implement alternate behavior.
*
* @return the base package to scan for mapped {@link Document} classes or {@literal null} to not enable scanning for
- * entities.
+ * entities.
*/
protected String getMappingBasePackage() {
return getClass().getPackage().getName();
@@ -225,19 +239,4 @@ public abstract class AbstractCouchbaseConfiguration {
protected FieldNamingStrategy fieldNamingStrategy() {
return abbreviateFieldNames() ? new CamelCaseAbbreviatingFieldNamingStrategy() : PropertyNameFieldNamingStrategy.INSTANCE;
}
-
- /**
- * Converts the given list of hostnames into parsable URIs.
- *
- * @param hosts the list of hosts to convert.
- * @return the converted URIs.
- */
- protected static List bootstrapUris(List hosts) throws URISyntaxException {
- List uris = new ArrayList();
- for (String host : hosts) {
- uris.add(new URI("http://" + host + ":8091/pools"));
- }
- return uris;
- }
-
}
diff --git a/src/main/java/org/springframework/data/couchbase/config/BeanNames.java b/src/main/java/org/springframework/data/couchbase/config/BeanNames.java
index 4e43ec8d..05add28b 100644
--- a/src/main/java/org/springframework/data/couchbase/config/BeanNames.java
+++ b/src/main/java/org/springframework/data/couchbase/config/BeanNames.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -20,22 +20,32 @@ package org.springframework.data.couchbase.config;
* Contains default bean names that will be used when no "id" is supplied to the beans.
*
* @author Michael Nitschinger
+ * @author Simon Baslé
*/
-public class BeanNames {
+class BeanNames {
/**
- * Refers to the " " bean.
+ * Refers to the "<couchbase:env />" bean.
*/
- static final String COUCHBASE = "couchbase";
+ static final String COUCHBASE_ENV = "couchbaseEnv";
+ /**
+ * Refers to the "<couchbase:cluster />" bean.
+ */
+ static final String COUCHBASE_CLUSTER = "couchbaseCluster";
/**
- * Refers to the " " bean.
+ * Refers to the "<couchbase:bucket />" bean.
+ */
+ static final String COUCHBASE_BUCKET = "couchbaseBucket";
+
+ /**
+ * Refers to the "<couchbase:template />" bean.
*/
static final String COUCHBASE_TEMPLATE = "couchbaseTemplate";
/**
- * Refers to the " " bean
+ * Refers to the "<couchbase:translation-service />" bean
*/
- static final String TRANSLATION_SERVICE = "translationService";
+ static final String TRANSLATION_SERVICE = "couchbaseTranslationService";
}
diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseBucketFactoryBean.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseBucketFactoryBean.java
new file mode 100644
index 00000000..a4dd771e
--- /dev/null
+++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseBucketFactoryBean.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2012-2015 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 com.couchbase.client.java.Bucket;
+import com.couchbase.client.java.Cluster;
+import com.couchbase.client.java.CouchbaseBucket;
+
+import org.springframework.beans.factory.config.AbstractFactoryBean;
+import org.springframework.dao.DataAccessException;
+import org.springframework.dao.support.PersistenceExceptionTranslator;
+import org.springframework.data.couchbase.core.CouchbaseExceptionTranslator;
+
+/**
+ * The Factory Bean to help {@link CouchbaseBucketParser} constructing a {@link Bucket} from a given
+ * {@link Cluster} reference.
+ *
+ * @author Simon Baslé
+ */
+public class CouchbaseBucketFactoryBean extends AbstractFactoryBean implements PersistenceExceptionTranslator {
+
+ private final Cluster cluster;
+ private final String bucketName;
+ private final String bucketPassword;
+
+ private final PersistenceExceptionTranslator exceptionTranslator = new CouchbaseExceptionTranslator();
+
+ public CouchbaseBucketFactoryBean(Cluster cluster) {
+ this(cluster, null, null);
+ }
+
+ public CouchbaseBucketFactoryBean(Cluster cluster, String bucketName) {
+ this(cluster, bucketName, null);
+ }
+
+ public CouchbaseBucketFactoryBean(Cluster cluster, String bucketName, String bucketPassword) {
+ this.cluster = cluster;
+ this.bucketName = bucketName;
+ this.bucketPassword = bucketPassword;
+ }
+
+ @Override
+ public Class> getObjectType() {
+ return CouchbaseBucket.class;
+ }
+
+ @Override
+ protected Bucket createInstance() throws Exception {
+ if (bucketName == null) {
+ return cluster.openBucket();
+ }
+ else if (bucketPassword == null) {
+ return cluster.openBucket(bucketName);
+ }
+ else {
+ return cluster.openBucket(bucketName, bucketPassword);
+ }
+ }
+
+ @Override
+ public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
+ return exceptionTranslator.translateExceptionIfPossible(ex);
+ }
+}
diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseBucketParser.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseBucketParser.java
new file mode 100644
index 00000000..431b2456
--- /dev/null
+++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseBucketParser.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2012-2015 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 com.couchbase.client.java.Bucket;
+import com.couchbase.client.java.Cluster;
+import org.w3c.dom.Element;
+
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.StringUtils;
+
+/**
+ * The parser for XML definition of a {@link Bucket}, to be constructed from a {@link Cluster} reference.
+ * If no reference is given, the default reference {@value BeanNames#COUCHBASE_CLUSTER} is used.
+ *
+ * See attributes {@link #CLUSTER_REF_ATTR}, {@link #BUCKETNAME_ATTR} and {@link #BUCKETPASSWORD_ATTR}.
+ *
+ * @author Simon Baslé
+ */
+public class CouchbaseBucketParser extends AbstractSingleBeanDefinitionParser {
+
+ /**
+ * The cluster-ref attribute in a bucket definition defines the cluster to build from.
+ */
+ public static final String CLUSTER_REF_ATTR = "cluster-ref";
+
+ /**
+ * The bucketName attribute in a bucket definition defines the name of the bucket to open.
+ */
+ public static final String BUCKETNAME_ATTR = "bucketName";
+
+ /**
+ * The bucketPassword attribute in a bucket definition defines the password of the bucket to open.
+ */
+ public static final String BUCKETPASSWORD_ATTR = "bucketPassword";
+
+ /**
+ * Resolve the bean ID and assign a default if not set.
+ *
+ * @param element the XML element which contains the attributes.
+ * @param definition the bean definition to work with.
+ * @param parserContext encapsulates the parsing state and configuration.
+ * @return the ID to work with.
+ */
+ @Override
+ protected String resolveId(final Element element, final AbstractBeanDefinition definition, final ParserContext parserContext) {
+ String id = super.resolveId(element, definition, parserContext);
+ return StringUtils.hasText(id) ? id : BeanNames.COUCHBASE_BUCKET;
+ }
+
+ /**
+ * Defines the bean class that will be constructed.
+ *
+ * @param element the XML element which contains the attributes.
+ * @return the class type to instantiate.
+ */
+ @Override
+ protected Class getBeanClass(final Element element) {
+ return CouchbaseBucketFactoryBean.class;
+ }
+
+ /**
+ * Parse the bean definition and build up the bean.
+ *
+ * @param element the XML element which contains the attributes.
+ * @param builder the builder which builds the bean.
+ */
+ @Override
+ protected void doParse(final Element element, final BeanDefinitionBuilder builder) {
+ String clusterRef = element.getAttribute(CLUSTER_REF_ATTR);
+ if (!StringUtils.hasText(clusterRef)) {
+ clusterRef = BeanNames.COUCHBASE_CLUSTER;
+ }
+ builder.addConstructorArgReference(clusterRef);
+
+ String bucketName = element.getAttribute(BUCKETNAME_ATTR);
+ if (StringUtils.hasText(bucketName)) {
+ builder.addConstructorArgValue(bucketName);
+ }
+
+ String bucketPassword = element.getAttribute(BUCKETPASSWORD_ATTR);
+ if (StringUtils.hasText(bucketPassword)) {
+ builder.addConstructorArgValue(bucketPassword);
+ }
+ }
+}
diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseClusterParser.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseClusterParser.java
new file mode 100644
index 00000000..1e78bf08
--- /dev/null
+++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseClusterParser.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2012-2015 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 java.util.ArrayList;
+import java.util.List;
+
+import com.couchbase.client.java.Cluster;
+import com.couchbase.client.java.CouchbaseCluster;
+import com.couchbase.client.java.env.CouchbaseEnvironment;
+import org.w3c.dom.Element;
+
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.StringUtils;
+import org.springframework.util.xml.DomUtils;
+
+/**
+ * The XML parser for a {@link Cluster} definition.
+ *
+ * Such a definition can be tuned by either referencing a {@link CouchbaseEnvironment} via
+ * the {@value #CLUSTER_ENVIRONMENT_REF} attribute or define a custom environment inline via
+ * the <{@value #CLUSTER_ENVIRONMENT_TAG}> tag (not recommended, environments should be
+ * shared as possible). If no environment reference or inline description is provided, the
+ * default environment reference {@value BeanNames#COUCHBASE_ENV} is used.
+ *
+ * To bootstrap the connection, one can provide IPs or hostnames of nodes to connect to
+ * via 1 or more <{@value #CLUSTER_NODE_TAG}> tags.
+ *
+ * @author Simon Baslé
+ */
+public class CouchbaseClusterParser extends AbstractSingleBeanDefinitionParser {
+
+ /**
+ * The <node> elements in a cluster definition define the bootstrap hosts to use
+ */
+ public static final String CLUSTER_NODE_TAG = "node";
+
+ /**
+ * The unique <env> element in a cluster definition define the environment customizations.
+ *
+ * @see CouchbaseEnvironmentParser CouchbaseEnvironmentParser for the possible fields.
+ * @see #CLUSTER_ENVIRONMENT_REF CLUSTER_ENVIRONMENT_REF as an alternative (giving a reference to
+ * an env instead of inline description, lower precedence)
+ */
+ public static final String CLUSTER_ENVIRONMENT_TAG = "env";
+
+ /**
+ * The <env-ref> attribute allows to use a reference to an {@link CouchbaseEnvironment} to
+ * tune the connection.
+ *
+ * @see #CLUSTER_ENVIRONMENT_TAG CLUSTER_ENVIRONMENT_TAG for an inline alternative
+ * (which takes priority over this reference)
+ */
+ public static final String CLUSTER_ENVIRONMENT_REF = "env-ref";
+
+ /**
+ * Resolve the bean ID and assign a default if not set.
+ *
+ * @param element the XML element which contains the attributes.
+ * @param definition the bean definition to work with.
+ * @param parserContext encapsulates the parsing state and configuration.
+ * @return the ID to work with.
+ */
+ @Override
+ protected String resolveId(final Element element, final AbstractBeanDefinition definition, final ParserContext parserContext) {
+ String id = super.resolveId(element, definition, parserContext);
+ return StringUtils.hasText(id) ? id : BeanNames.COUCHBASE_CLUSTER;
+ }
+
+ /**
+ * Defines the bean class that will be constructed.
+ *
+ * @param element the XML element which contains the attributes.
+ * @return the class type to instantiate.
+ */
+ @Override
+ protected Class getBeanClass(final Element element) {
+ return CouchbaseCluster.class;
+ }
+
+ /**
+ * Parse the bean definition and build up the bean.
+ *
+ * @param element the XML element which contains the attributes.
+ * @param bean the builder which builds the bean.
+ */
+ @Override
+ protected void doParse(final Element element, final BeanDefinitionBuilder bean) {
+ bean.setFactoryMethod("create");
+ bean.setDestroyMethodName("disconnect");
+
+ parseEnvironment(bean, element);
+
+ List nodes = DomUtils.getChildElementsByTagName(element, CLUSTER_NODE_TAG);
+ if (nodes != null && nodes.size() > 0) {
+ List bootstrapUrls = new ArrayList(nodes.size());
+ for (int i = 0; i < nodes.size(); i++) {
+ bootstrapUrls.add(nodes.get(i).getTextContent());
+ }
+ bean.addConstructorArgValue(bootstrapUrls);
+ }
+ }
+
+ /**
+ * @return true if a custom environment was parsed and injected (either reference or inline), false if
+ * the default environment reference was used.
+ */
+ protected boolean parseEnvironment(BeanDefinitionBuilder clusterBuilder, Element clusterElement) {
+ //any inline environment description would take precedence over a reference
+ Element envElement = DomUtils.getChildElementByTagName(clusterElement, CLUSTER_ENVIRONMENT_TAG);
+ if (envElement != null && envElement.hasAttributes()) {
+ injectEnvElement(clusterBuilder, envElement);
+ return true;
+ }
+
+ //secondly try to see if an env has been referenced
+ String envRef = clusterElement.getAttribute(CLUSTER_ENVIRONMENT_REF);
+ if (StringUtils.hasText(envRef)) {
+ injectEnvReference(clusterBuilder, envRef);
+ return true;
+ }
+
+ //if no custom value provided, consider it a reference to the default bean for Couchbase Environment
+ injectEnvReference(clusterBuilder, BeanNames.COUCHBASE_ENV);
+ return false;
+ }
+
+ protected void injectEnvElement(BeanDefinitionBuilder clusterBuilder, Element envElement) {
+ BeanDefinitionBuilder envDefinitionBuilder = BeanDefinitionBuilder
+ .genericBeanDefinition(CouchbaseEnvironmentFactoryBean.class);
+ new CouchbaseEnvironmentParser().doParse(envElement, envDefinitionBuilder);
+
+ clusterBuilder.addConstructorArgValue(envDefinitionBuilder.getBeanDefinition());
+ }
+
+ protected void injectEnvReference(BeanDefinitionBuilder clusterBuilder, String envRef) {
+ clusterBuilder.addConstructorArgReference(envRef);
+ }
+}
diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentFactoryBean.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentFactoryBean.java
new file mode 100644
index 00000000..e452b50e
--- /dev/null
+++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentFactoryBean.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2012-2015 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 com.couchbase.client.core.retry.BestEffortRetryStrategy;
+import com.couchbase.client.core.retry.FailFastRetryStrategy;
+import com.couchbase.client.core.retry.RetryStrategy;
+import com.couchbase.client.java.env.CouchbaseEnvironment;
+import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
+
+import org.springframework.beans.factory.config.AbstractFactoryBean;
+
+/**
+ * Factory Bean to help create a CouchbaseEnvironment (by offering setters for supported tuning methods).
+ *
+ * @author Simon Baslé
+ */
+/*package*/ class CouchbaseEnvironmentFactoryBean extends AbstractFactoryBean {
+
+ private static final CouchbaseEnvironment DEFAULT_ENV = DefaultCouchbaseEnvironment.create();
+ public static final String RETRYSTRATEGY_FAILFAST = "FailFast";
+ public static final String RETRYSTRATEGY_BESTEFFORT = "BestEffort";
+
+ private long managementTimeout = DEFAULT_ENV.managementTimeout();
+ private long queryTimeout = DEFAULT_ENV.queryTimeout();
+ private long viewTimeout = DEFAULT_ENV.viewTimeout();
+ private long kvTimeout = DEFAULT_ENV.kvTimeout();
+ private long connectTimeout = DEFAULT_ENV.connectTimeout();
+ private long disconnectTimeout = DEFAULT_ENV.disconnectTimeout();
+ private boolean dnsSrvEnabled = DEFAULT_ENV.dnsSrvEnabled();
+
+ private boolean dcpEnabled = DEFAULT_ENV.dcpEnabled();
+ private boolean sslEnabled = DEFAULT_ENV.sslEnabled();
+ private String sslKeystoreFile = DEFAULT_ENV.sslKeystoreFile();
+ private String sslKeystorePassword = DEFAULT_ENV.sslKeystorePassword();
+ private boolean queryEnabled = DEFAULT_ENV.queryEnabled();
+ private int queryPort = DEFAULT_ENV.queryPort();
+ private boolean bootstrapHttpEnabled = DEFAULT_ENV.bootstrapHttpEnabled();
+ private boolean bootstrapCarrierEnabled = DEFAULT_ENV.bootstrapCarrierEnabled();
+ private int bootstrapHttpDirectPort = DEFAULT_ENV.bootstrapHttpDirectPort();
+ private int bootstrapHttpSslPort = DEFAULT_ENV.bootstrapHttpSslPort();
+ private int bootstrapCarrierDirectPort = DEFAULT_ENV.bootstrapCarrierDirectPort();
+ private int bootstrapCarrierSslPort = DEFAULT_ENV.bootstrapCarrierSslPort();
+ private int ioPoolSize = DEFAULT_ENV.ioPoolSize();
+ private int computationPoolSize = DEFAULT_ENV.computationPoolSize();
+ private int responseBufferSize = DEFAULT_ENV.responseBufferSize();
+ private int requestBufferSize = DEFAULT_ENV.requestBufferSize();
+ private int kvEndpoints = DEFAULT_ENV.kvEndpoints();
+ private int viewEndpoints = DEFAULT_ENV.viewEndpoints();
+ private int queryEndpoints = DEFAULT_ENV.queryEndpoints();
+ private RetryStrategy retryStrategy = DEFAULT_ENV.retryStrategy();
+ private long maxRequestLifetime = DEFAULT_ENV.maxRequestLifetime();
+ private long keepAliveInterval = DEFAULT_ENV.keepAliveInterval();
+ private long autoreleaseAfter = DEFAULT_ENV.autoreleaseAfter();
+ private boolean bufferPoolingEnabled = DEFAULT_ENV.bufferPoolingEnabled();
+
+ //These are tunings that are not practical to be exposed in a xml configuration
+ //or not supposed to be modified that easily:
+// observeIntervalDelay
+// reconnectDelay
+// retryDelay
+// userAgent
+// packageNameAndVersion
+// ioPool
+// scheduler
+// eventBus
+
+ @Override
+ public Class> getObjectType() {
+ return DefaultCouchbaseEnvironment.class;
+ }
+
+ @Override
+ protected CouchbaseEnvironment createInstance() throws Exception {
+ return DefaultCouchbaseEnvironment.builder()
+ .managementTimeout(managementTimeout)
+ .queryTimeout(queryTimeout)
+ .viewTimeout(viewTimeout)
+ .kvTimeout(kvTimeout)
+ .connectTimeout(connectTimeout)
+ .disconnectTimeout(disconnectTimeout)
+ .dnsSrvEnabled(dnsSrvEnabled)
+ .dcpEnabled(dcpEnabled)
+ .sslEnabled(sslEnabled)
+ .sslKeystoreFile(sslKeystoreFile)
+ .sslKeystorePassword(sslKeystorePassword)
+ .queryEnabled(queryEnabled)
+ .queryPort(queryPort)
+ .bootstrapHttpEnabled(bootstrapHttpEnabled)
+ .bootstrapCarrierEnabled(bootstrapCarrierEnabled)
+ .bootstrapHttpDirectPort(bootstrapHttpDirectPort)
+ .bootstrapHttpSslPort(bootstrapHttpSslPort)
+ .bootstrapCarrierDirectPort(bootstrapCarrierDirectPort)
+ .bootstrapCarrierSslPort(bootstrapCarrierSslPort)
+ .ioPoolSize(ioPoolSize)
+ .computationPoolSize(computationPoolSize)
+ .responseBufferSize(responseBufferSize)
+ .requestBufferSize(requestBufferSize)
+ .kvEndpoints(kvEndpoints)
+ .viewEndpoints(viewEndpoints)
+ .queryEndpoints(queryEndpoints)
+ .retryStrategy(retryStrategy)
+ .maxRequestLifetime(maxRequestLifetime)
+ .keepAliveInterval(keepAliveInterval)
+ .autoreleaseAfter(autoreleaseAfter)
+ .bufferPoolingEnabled(bufferPoolingEnabled)
+ .build();
+ }
+
+ /**
+ * Sets the {@link RetryStrategy} to use from an enum-like String value.
+ * Either "FailFast" or "BestEffort" are recognized.
+ *
+ * @param retryStrategy the string value enum from which to choose a strategy.
+ */
+ public void setRetryStrategy(String retryStrategy) {
+ if (RETRYSTRATEGY_FAILFAST.equals(retryStrategy)){
+ this.retryStrategy = FailFastRetryStrategy.INSTANCE;
+ } else if (RETRYSTRATEGY_BESTEFFORT.equals(retryStrategy)) {
+ this.retryStrategy = BestEffortRetryStrategy.INSTANCE;
+ }
+ }
+
+ //==== SETTERS for the factory bean ====
+
+ public void setManagementTimeout(long managementTimeout) {
+ this.managementTimeout = managementTimeout;
+ }
+
+ public void setQueryTimeout(long queryTimeout) {
+ this.queryTimeout = queryTimeout;
+ }
+
+ public void setViewTimeout(long viewTimeout) {
+ this.viewTimeout = viewTimeout;
+ }
+
+ public void setKvTimeout(long kvTimeout) {
+ this.kvTimeout = kvTimeout;
+ }
+
+ public void setConnectTimeout(long connectTimeout) {
+ this.connectTimeout = connectTimeout;
+ }
+
+ public void setDisconnectTimeout(long disconnectTimeout) {
+ this.disconnectTimeout = disconnectTimeout;
+ }
+
+ public void setDnsSrvEnabled(boolean dnsSrvEnabled) {
+ this.dnsSrvEnabled = dnsSrvEnabled;
+ }
+
+ public void setDcpEnabled(boolean dcpEnabled) {
+ this.dcpEnabled = dcpEnabled;
+ }
+
+ public void setSslEnabled(boolean sslEnabled) {
+ this.sslEnabled = sslEnabled;
+ }
+
+ public void setSslKeystoreFile(String sslKeystoreFile) {
+ this.sslKeystoreFile = sslKeystoreFile;
+ }
+
+ public void setSslKeystorePassword(String sslKeystorePassword) {
+ this.sslKeystorePassword = sslKeystorePassword;
+ }
+
+ public void setQueryEnabled(boolean queryEnabled) {
+ this.queryEnabled = queryEnabled;
+ }
+
+ public void setQueryPort(int queryPort) {
+ this.queryPort = queryPort;
+ }
+
+ public void setBootstrapHttpEnabled(boolean bootstrapHttpEnabled) {
+ this.bootstrapHttpEnabled = bootstrapHttpEnabled;
+ }
+
+ public void setBootstrapCarrierEnabled(boolean bootstrapCarrierEnabled) {
+ this.bootstrapCarrierEnabled = bootstrapCarrierEnabled;
+ }
+
+ public void setBootstrapHttpDirectPort(int bootstrapHttpDirectPort) {
+ this.bootstrapHttpDirectPort = bootstrapHttpDirectPort;
+ }
+
+ public void setBootstrapHttpSslPort(int bootstrapHttpSslPort) {
+ this.bootstrapHttpSslPort = bootstrapHttpSslPort;
+ }
+
+ public void setBootstrapCarrierDirectPort(int bootstrapCarrierDirectPort) {
+ this.bootstrapCarrierDirectPort = bootstrapCarrierDirectPort;
+ }
+
+ public void setBootstrapCarrierSslPort(int bootstrapCarrierSslPort) {
+ this.bootstrapCarrierSslPort = bootstrapCarrierSslPort;
+ }
+
+ public void setIoPoolSize(int ioPoolSize) {
+ this.ioPoolSize = ioPoolSize;
+ }
+
+ public void setComputationPoolSize(int computationPoolSize) {
+ this.computationPoolSize = computationPoolSize;
+ }
+
+ public void setResponseBufferSize(int responseBufferSize) {
+ this.responseBufferSize = responseBufferSize;
+ }
+
+ public void setRequestBufferSize(int requestBufferSize) {
+ this.requestBufferSize = requestBufferSize;
+ }
+
+ public void setKvEndpoints(int kvEndpoints) {
+ this.kvEndpoints = kvEndpoints;
+ }
+
+ public void setViewEndpoints(int viewEndpoints) {
+ this.viewEndpoints = viewEndpoints;
+ }
+
+ public void setQueryEndpoints(int queryEndpoints) {
+ this.queryEndpoints = queryEndpoints;
+ }
+
+ public void setMaxRequestLifetime(long maxRequestLifetime) {
+ this.maxRequestLifetime = maxRequestLifetime;
+ }
+
+ public void setKeepAliveInterval(long keepAliveInterval) {
+ this.keepAliveInterval = keepAliveInterval;
+ }
+
+ public void setAutoreleaseAfter(long autoreleaseAfter) {
+ this.autoreleaseAfter = autoreleaseAfter;
+ }
+
+ public void setBufferPoolingEnabled(boolean bufferPoolingEnabled) {
+ this.bufferPoolingEnabled = bufferPoolingEnabled;
+ }
+}
diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentNoShutdownProxy.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentNoShutdownProxy.java
new file mode 100644
index 00000000..6733a942
--- /dev/null
+++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentNoShutdownProxy.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2012-2015 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 com.couchbase.client.core.event.EventBus;
+import com.couchbase.client.core.retry.RetryStrategy;
+import com.couchbase.client.core.time.Delay;
+import com.couchbase.client.deps.io.netty.channel.EventLoopGroup;
+import com.couchbase.client.java.env.CouchbaseEnvironment;
+import rx.Observable;
+import rx.Scheduler;
+
+/**
+ * A proxy around a {@link CouchbaseEnvironment} that prevents its {@link #shutdown()} method
+ * to be invoked. Useful when the delegate is not to be lifecycle-managed by Spring.
+ *
+ * @author Simon Baslé
+ */
+public class CouchbaseEnvironmentNoShutdownProxy implements CouchbaseEnvironment {
+
+ private final CouchbaseEnvironment delegate;
+
+ public CouchbaseEnvironmentNoShutdownProxy(CouchbaseEnvironment delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public Observable shutdown() {
+ return Observable.just(false);
+ }
+
+ //===== DELEGATION METHODS =====
+
+ @Override
+ public EventLoopGroup ioPool() {
+ return delegate.ioPool();
+ }
+
+ @Override
+ public Scheduler scheduler() {
+ return delegate.scheduler();
+ }
+
+ @Override
+ public boolean dcpEnabled() {
+ return delegate.dcpEnabled();
+ }
+
+ @Override
+ public boolean sslEnabled() {
+ return delegate.sslEnabled();
+ }
+
+ @Override
+ public String sslKeystoreFile() {
+ return delegate.sslKeystoreFile();
+ }
+
+ @Override
+ public String sslKeystorePassword() {
+ return delegate.sslKeystorePassword();
+ }
+
+ @Override
+ public boolean queryEnabled() {
+ return delegate.queryEnabled();
+ }
+
+ @Override
+ public int queryPort() {
+ return delegate.queryPort();
+ }
+
+ @Override
+ public boolean bootstrapHttpEnabled() {
+ return delegate.bootstrapHttpEnabled();
+ }
+
+ @Override
+ public boolean bootstrapCarrierEnabled() {
+ return delegate.bootstrapCarrierEnabled();
+ }
+
+ @Override
+ public int bootstrapHttpDirectPort() {
+ return delegate.bootstrapHttpDirectPort();
+ }
+
+ @Override
+ public int bootstrapHttpSslPort() {
+ return delegate.bootstrapHttpSslPort();
+ }
+
+ @Override
+ public int bootstrapCarrierDirectPort() {
+ return delegate.bootstrapCarrierDirectPort();
+ }
+
+ @Override
+ public int bootstrapCarrierSslPort() {
+ return delegate.bootstrapCarrierSslPort();
+ }
+
+ @Override
+ public int ioPoolSize() {
+ return delegate.ioPoolSize();
+ }
+
+ @Override
+ public int computationPoolSize() {
+ return delegate.computationPoolSize();
+ }
+
+ @Override
+ public Delay observeIntervalDelay() {
+ return delegate.observeIntervalDelay();
+ }
+
+ @Override
+ public Delay reconnectDelay() {
+ return delegate.reconnectDelay();
+ }
+
+ @Override
+ public Delay retryDelay() {
+ return delegate.retryDelay();
+ }
+
+ @Override
+ public int requestBufferSize() {
+ return delegate.requestBufferSize();
+ }
+
+ @Override
+ public int responseBufferSize() {
+ return delegate.responseBufferSize();
+ }
+
+ @Override
+ public int kvEndpoints() {
+ return delegate.kvEndpoints();
+ }
+
+ @Override
+ public int viewEndpoints() {
+ return delegate.viewEndpoints();
+ }
+
+ @Override
+ public int queryEndpoints() {
+ return delegate.queryEndpoints();
+ }
+
+ @Override
+ public String userAgent() {
+ return delegate.userAgent();
+ }
+
+ @Override
+ public String packageNameAndVersion() {
+ return delegate.packageNameAndVersion();
+ }
+
+ @Override
+ public RetryStrategy retryStrategy() {
+ return delegate.retryStrategy();
+ }
+
+ @Override
+ public long maxRequestLifetime() {
+ return delegate.maxRequestLifetime();
+ }
+
+ @Override
+ public long autoreleaseAfter() {
+ return delegate.autoreleaseAfter();
+ }
+
+ @Override
+ public long keepAliveInterval() {
+ return delegate.keepAliveInterval();
+ }
+
+ @Override
+ public EventBus eventBus() {
+ return delegate.eventBus();
+ }
+
+ @Override
+ public boolean bufferPoolingEnabled() {
+ return delegate.bufferPoolingEnabled();
+ }
+
+ @Override
+ public long managementTimeout() {
+ return delegate.managementTimeout();
+ }
+
+ @Override
+ public long queryTimeout() {
+ return delegate.queryTimeout();
+ }
+
+ @Override
+ public long viewTimeout() {
+ return delegate.viewTimeout();
+ }
+
+ @Override
+ public long kvTimeout() {
+ return delegate.kvTimeout();
+ }
+
+ @Override
+ public long connectTimeout() {
+ return delegate.connectTimeout();
+ }
+
+ @Override
+ public long disconnectTimeout() {
+ return delegate.disconnectTimeout();
+ }
+
+ @Override
+ public boolean dnsSrvEnabled() {
+ return delegate.dnsSrvEnabled();
+ }
+}
diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentParser.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentParser.java
new file mode 100644
index 00000000..b4bf013f
--- /dev/null
+++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentParser.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2012-2015 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.springframework.data.config.ParsingUtils.setPropertyValue;
+
+import com.couchbase.client.core.retry.RetryStrategy;
+import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
+import org.w3c.dom.Element;
+
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.StringUtils;
+
+/**
+ * Allows creation of a {@link DefaultCouchbaseEnvironment} via spring XML configuration.
+ *
+ * The following properties are supported:
+ * {@link DefaultCouchbaseEnvironment.Builder#managementTimeout(long) managementTimeout}
+ * {@link DefaultCouchbaseEnvironment.Builder#queryTimeout(long) queryTimeout}
+ * {@link DefaultCouchbaseEnvironment.Builder#viewTimeout(long) viewTimeout}
+ * {@link DefaultCouchbaseEnvironment.Builder#kvTimeout(long) kvTimeout}
+ * {@link DefaultCouchbaseEnvironment.Builder#connectTimeout(long) connectTimeout}
+ * {@link DefaultCouchbaseEnvironment.Builder#disconnectTimeout(long) disconnectTimeout}
+ * {@link DefaultCouchbaseEnvironment.Builder#dnsSrvEnabled(boolean) dnsSrvEnabled}
+ *
+ * {@link DefaultCouchbaseEnvironment.Builder#dcpEnabled(boolean) dcpEnabled}
+ * {@link DefaultCouchbaseEnvironment.Builder#sslEnabled(boolean) sslEnabled}
+ * {@link DefaultCouchbaseEnvironment.Builder#sslKeystoreFile(String) sslKeystoreFile}
+ * {@link DefaultCouchbaseEnvironment.Builder#sslKeystorePassword(String) sslKeystorePassword}
+ * {@link DefaultCouchbaseEnvironment.Builder#queryEnabled(boolean) queryEnabled}
+ * {@link DefaultCouchbaseEnvironment.Builder#queryPort(int) queryPort}
+ * {@link DefaultCouchbaseEnvironment.Builder#bootstrapHttpEnabled(boolean) bootstrapHttpEnabled}
+ * {@link DefaultCouchbaseEnvironment.Builder#bootstrapCarrierEnabled(boolean) bootstrapCarrierEnabled}
+ * {@link DefaultCouchbaseEnvironment.Builder#bootstrapHttpDirectPort(int) bootstrapHttpDirectPort}
+ * {@link DefaultCouchbaseEnvironment.Builder#bootstrapHttpSslPort(int) bootstrapHttpSslPort}
+ * {@link DefaultCouchbaseEnvironment.Builder#bootstrapCarrierDirectPort(int) bootstrapCarrierDirectPort}
+ * {@link DefaultCouchbaseEnvironment.Builder#bootstrapCarrierSslPort(int) bootstrapCarrierSslPort}
+ * {@link DefaultCouchbaseEnvironment.Builder#ioPoolSize(int) ioPoolSize}
+ * {@link DefaultCouchbaseEnvironment.Builder#computationPoolSize(int) computationPoolSize}
+ * {@link DefaultCouchbaseEnvironment.Builder#responseBufferSize(int) responseBufferSize}
+ * {@link DefaultCouchbaseEnvironment.Builder#requestBufferSize(int) requestBufferSize}
+ * {@link DefaultCouchbaseEnvironment.Builder#kvEndpoints(int) kvEndpoints}
+ * {@link DefaultCouchbaseEnvironment.Builder#viewEndpoints(int) viewEndpoints}
+ * {@link DefaultCouchbaseEnvironment.Builder#queryEndpoints(int) queryEndpoints}
+ * {@link DefaultCouchbaseEnvironment.Builder#retryStrategy(RetryStrategy) retryStrategy}
+ * {@link DefaultCouchbaseEnvironment.Builder#maxRequestLifetime(long) maxRequestLifetime}
+ * {@link DefaultCouchbaseEnvironment.Builder#keepAliveInterval(long) keepAliveInterval}
+ * {@link DefaultCouchbaseEnvironment.Builder#autoreleaseAfter(long) autoreleaseAfter}
+ * {@link DefaultCouchbaseEnvironment.Builder#bufferPoolingEnabled(boolean) bufferPoolingEnabled}
+ *
+ *
+ * @author Simon Baslé
+ */
+public class CouchbaseEnvironmentParser extends AbstractSingleBeanDefinitionParser {
+
+ /**
+ * Resolve the bean ID and assign a default if not set.
+ *
+ * @param element the XML element which contains the attributes.
+ * @param definition the bean definition to work with.
+ * @param parserContext encapsulates the parsing state and configuration.
+ * @return the ID to work with.
+ */
+ @Override
+ protected String resolveId(final Element element, final AbstractBeanDefinition definition, final ParserContext parserContext) {
+ String id = super.resolveId(element, definition, parserContext);
+ return StringUtils.hasText(id) ? id : BeanNames.COUCHBASE_ENV;
+ }
+
+ /**
+ * Defines the bean class that will be constructed.
+ *
+ * @param element the XML element which contains the attributes.
+ * @return the class type to instantiate.
+ */
+ @Override
+ protected Class getBeanClass(final Element element) {
+ return CouchbaseEnvironmentFactoryBean.class;
+ }
+
+ /**
+ * Parse the bean definition and build up the bean.
+ *
+ * @param envElement the XML element which contains the attributes.
+ * @param envDefinitionBuilder the builder which builds the bean.
+ */
+ @Override
+ protected void doParse(final Element envElement, final BeanDefinitionBuilder envDefinitionBuilder) {
+ setPropertyValue(envDefinitionBuilder, envElement, "managementTimeout", "managementTimeout");
+ setPropertyValue(envDefinitionBuilder, envElement, "queryTimeout", "queryTimeout");
+ setPropertyValue(envDefinitionBuilder, envElement, "viewTimeout", "viewTimeout");
+ setPropertyValue(envDefinitionBuilder, envElement, "kvTimeout", "kvTimeout");
+ setPropertyValue(envDefinitionBuilder, envElement, "connectTimeout", "connectTimeout");
+ setPropertyValue(envDefinitionBuilder, envElement, "disconnectTimeout", "disconnectTimeout");
+ setPropertyValue(envDefinitionBuilder, envElement, "dnsSrvEnabled", "dnsSrvEnabled");
+
+ setPropertyValue(envDefinitionBuilder, envElement, "dcpEnabled", "dcpEnabled");
+ setPropertyValue(envDefinitionBuilder, envElement, "sslEnabled", "sslEnabled");
+ setPropertyValue(envDefinitionBuilder, envElement, "sslKeystoreFile", "sslKeystoreFile");
+ setPropertyValue(envDefinitionBuilder, envElement, "sslKeystorePassword", "sslKeystorePassword");
+ setPropertyValue(envDefinitionBuilder, envElement, "queryEnabled", "queryEnabled");
+ setPropertyValue(envDefinitionBuilder, envElement, "queryPort", "queryPort");
+ setPropertyValue(envDefinitionBuilder, envElement, "bootstrapHttpEnabled", "bootstrapHttpEnabled");
+ setPropertyValue(envDefinitionBuilder, envElement, "bootstrapCarrierEnabled", "bootstrapCarrierEnabled");
+ setPropertyValue(envDefinitionBuilder, envElement, "bootstrapHttpDirectPort", "bootstrapHttpDirectPort");
+ setPropertyValue(envDefinitionBuilder, envElement, "bootstrapHttpSslPort", "bootstrapHttpSslPort");
+ setPropertyValue(envDefinitionBuilder, envElement, "bootstrapCarrierDirectPort", "bootstrapCarrierDirectPort");
+ setPropertyValue(envDefinitionBuilder, envElement, "bootstrapCarrierSslPort", "bootstrapCarrierSslPort");
+ setPropertyValue(envDefinitionBuilder, envElement, "ioPoolSize", "ioPoolSize");
+ setPropertyValue(envDefinitionBuilder, envElement, "computationPoolSize", "computationPoolSize");
+ setPropertyValue(envDefinitionBuilder, envElement, "responseBufferSize", "responseBufferSize");
+ setPropertyValue(envDefinitionBuilder, envElement, "requestBufferSize", "requestBufferSize");
+ setPropertyValue(envDefinitionBuilder, envElement, "kvEndpoints", "kvEndpoints");
+ setPropertyValue(envDefinitionBuilder, envElement, "viewEndpoints", "viewEndpoints");
+ setPropertyValue(envDefinitionBuilder, envElement, "queryEndpoints", "queryEndpoints");
+ setPropertyValue(envDefinitionBuilder, envElement, "maxRequestLifetime", "maxRequestLifetime");
+ setPropertyValue(envDefinitionBuilder, envElement, "keepAliveInterval", "keepAliveInterval");
+ setPropertyValue(envDefinitionBuilder, envElement, "autoreleaseAfter", "autoreleaseAfter");
+ setPropertyValue(envDefinitionBuilder, envElement, "bufferPoolingEnabled", "bufferPoolingEnabled");
+
+ //retry strategy is particular, in the xsd this is an enum (FailFast, BestEffort)
+ setPropertyValue(envDefinitionBuilder, envElement, "retryStrategy", "retryStrategy");
+ }
+}
diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseJmxParser.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseJmxParser.java
index fa916cdf..6541b132 100644
--- a/src/main/java/org/springframework/data/couchbase/config/CouchbaseJmxParser.java
+++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseJmxParser.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,6 +16,9 @@
package org.springframework.data.couchbase.config;
+import com.couchbase.client.java.Bucket;
+import org.w3c.dom.Element;
+
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
@@ -25,15 +28,15 @@ import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.couchbase.monitor.ClientInfo;
import org.springframework.data.couchbase.monitor.ClusterInfo;
import org.springframework.util.StringUtils;
-import org.w3c.dom.Element;
/**
* Enables Parsing of the " " configuration bean.
- *
+ *
* In order to enable JMX, different JmxComponents need to be registered. The dependency to the original
- * {@link com.couchbase.client.CouchbaseClient} object is solved by through the "couchbase-ref" attribute.
+ * {@link Bucket} object is solved through the "bucket-ref" attribute.
*
* @author Michael Nitschinger
+ * @author Simon Baslé
*/
public class CouchbaseJmxParser implements BeanDefinitionParser {
@@ -45,27 +48,28 @@ public class CouchbaseJmxParser implements BeanDefinitionParser {
* @return null, because no bean instance needs to be returned.
*/
public BeanDefinition parse(final Element element, final ParserContext parserContext) {
- String name = element.getAttribute("couchbase-ref");
- if (!StringUtils.hasText(name)) {
- name = BeanNames.COUCHBASE;
+ String bucketName = element.getAttribute("bucket-ref");
+ if (!StringUtils.hasText(bucketName)) {
+ bucketName = BeanNames.COUCHBASE_BUCKET;
}
- registerJmxComponents(name, element, parserContext);
+ registerJmxComponents(bucketName, element, parserContext);
return null;
}
/**
* Register the JMX components in the context.
*
- * @param refName the reference name to the couchbase client.
* @param element the XML element which contains the attributes.
* @param parserContext encapsulates the parsing state and configuration.
+ * @parma refBucketName the reference name to the couchbase bucket.
*/
- protected void registerJmxComponents(final String refName, final Element element, final ParserContext parserContext) {
+ protected void registerJmxComponents(final String refBucketName,
+ final Element element, final ParserContext parserContext) {
Object eleSource = parserContext.extractSource(element);
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
- createBeanDefEntry(ClientInfo.class, compositeDef, refName, eleSource, parserContext);
- createBeanDefEntry(ClusterInfo.class, compositeDef, refName, eleSource, parserContext);
+ createBeanDefEntry(ClientInfo.class, compositeDef, refBucketName, eleSource, parserContext);
+ createBeanDefEntry(ClusterInfo.class, compositeDef, refBucketName, eleSource, parserContext);
parserContext.registerComponent(compositeDef);
}
@@ -75,12 +79,12 @@ public class CouchbaseJmxParser implements BeanDefinitionParser {
*
* @param clazz the class type to register.
* @param compositeDef component that can hold nested components.
- * @param refName the reference name to the couchbase client.
+ * @param refName the reference name to the couchbase bucket.
* @param eleSource source element to reference.
* @param parserContext encapsulates the parsing state and configuration.
*/
protected void createBeanDefEntry(final Class> clazz, final CompositeComponentDefinition compositeDef,
- final String refName, final Object eleSource, final ParserContext parserContext) {
+ final String refName, final Object eleSource, final ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
builder.getRawBeanDefinition().setSource(eleSource);
builder.addConstructorArgReference(refName);
diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseNamespaceHandler.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseNamespaceHandler.java
index 7a1b0f82..bebed47d 100644
--- a/src/main/java/org/springframework/data/couchbase/config/CouchbaseNamespaceHandler.java
+++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseNamespaceHandler.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,13 +16,11 @@
package org.springframework.data.couchbase.config;
+import org.springframework.beans.factory.xml.NamespaceHandler;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
-import org.springframework.data.couchbase.repository.config.CouchbaseRepositoryConfigurationExtension;
-import org.springframework.data.repository.config.RepositoryBeanDefinitionParser;
-import org.springframework.data.repository.config.RepositoryConfigurationExtension;
/**
- * {@link org.springframework.beans.factory.xml.NamespaceHandler} for Couchbase configuration.
+ * {@link NamespaceHandler} for Couchbase configuration.
*
* This handler acts as a container for one or more bean parsers and registers them. During parsing, the elements
* get analyzed and the appropriate registered parser is called.
@@ -35,9 +33,10 @@ public class CouchbaseNamespaceHandler extends NamespaceHandlerSupport {
* Register bean definition parsers in the namespace handler.
*/
public final void init() {
- RepositoryConfigurationExtension extension = new CouchbaseRepositoryConfigurationExtension();
- registerBeanDefinitionParser("repositories", new RepositoryBeanDefinitionParser(extension));
- registerBeanDefinitionParser("couchbase", new CouchbaseParser());
+ //TODO repositories (CouchbaseRepositoryConfigurationExtension and RepositoryBeanDefinitionParser)
+ registerBeanDefinitionParser("env", new CouchbaseEnvironmentParser());
+ registerBeanDefinitionParser("cluster", new CouchbaseClusterParser());
+ registerBeanDefinitionParser("bucket", new CouchbaseBucketParser());
registerBeanDefinitionParser("jmx", new CouchbaseJmxParser());
registerBeanDefinitionParser("template", new CouchbaseTemplateParser());
registerBeanDefinitionParser("translation-service", new CouchbaseTranslationServiceParser());
diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseParser.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseParser.java
deleted file mode 100644
index 52b01da5..00000000
--- a/src/main/java/org/springframework/data/couchbase/config/CouchbaseParser.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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 com.couchbase.client.CouchbaseClient;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.data.config.ParsingUtils;
-import org.springframework.data.couchbase.core.CouchbaseFactoryBean;
-import org.springframework.util.StringUtils;
-import org.w3c.dom.Element;
-
-import java.util.Properties;
-
-/**
- * Parser for " " bean definitions.
- *
- * The outcome of this bean definition parser will be a constructed {@link CouchbaseClient}.
- *
- * @author Michael Nitschinger
- */
-public class CouchbaseParser extends AbstractSingleBeanDefinitionParser {
-
- /**
- * Defines the bean class that will be constructed.
- *
- * @param element the XML element which contains the attributes.
- *
- * @return the class type to instantiate.
- */
- @Override
- protected Class getBeanClass(final Element element) {
- return CouchbaseFactoryBean.class;
- }
-
- /**
- * Parse the bean definition and build up the bean.
- *
- * @param element the XML element which contains the attributes.
- * @param bean the builder which builds the bean.
- */
- @Override
- protected void doParse(final Element element, final BeanDefinitionBuilder bean) {
- ParsingUtils.setPropertyValue(bean, element, "host", "host");
- ParsingUtils.setPropertyValue(bean, element, "bucket", "bucket");
- ParsingUtils.setPropertyValue(bean, element, "password", "password");
-
- setLogger();
- }
-
- private void setLogger() {
- Properties systemProperties = System.getProperties();
- systemProperties.put("net.spy.log.LoggerImpl", CouchbaseFactoryBean.DEFAULT_LOGGER_PROPERTY);
- System.setProperties(systemProperties);
- }
-
- /**
- * Resolve the bean ID and assign a default if not set.
- *
- * @param element the XML element which contains the attributes.
- * @param definition the bean definition to work with.
- * @param parserContext encapsulates the parsing state and configuration.
- *
- * @return the ID to work with.
- */
- @Override
- protected String resolveId(final Element element, final AbstractBeanDefinition definition,
- final ParserContext parserContext) {
- String id = super.resolveId(element, definition, parserContext);
- return StringUtils.hasText(id) ? id : BeanNames.COUCHBASE;
- }
-
-}
diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseTemplateParser.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseTemplateParser.java
index 66a2b0d8..59a63b5c 100644
--- a/src/main/java/org/springframework/data/couchbase/config/CouchbaseTemplateParser.java
+++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseTemplateParser.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,13 +16,14 @@
package org.springframework.data.couchbase.config;
+import org.w3c.dom.Element;
+
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.couchbase.core.CouchbaseTemplate;
import org.springframework.util.StringUtils;
-import org.w3c.dom.Element;
/**
* Parser for " " bean definitions.
@@ -39,7 +40,6 @@ public class CouchbaseTemplateParser extends AbstractSingleBeanDefinitionParser
* @param element the XML element which contains the attributes.
* @param definition the bean definition to work with.
* @param parserContext encapsulates the parsing state and configuration.
- *
* @return the ID to work with.
*/
@Override
@@ -52,7 +52,6 @@ public class CouchbaseTemplateParser extends AbstractSingleBeanDefinitionParser
* Defines the bean class that will be constructed.
*
* @param element the XML element which contains the attributes.
- *
* @return the class type to instantiate.
*/
@Override
@@ -68,11 +67,11 @@ public class CouchbaseTemplateParser extends AbstractSingleBeanDefinitionParser
*/
@Override
protected void doParse(final Element element, final BeanDefinitionBuilder bean) {
- String clientRef = element.getAttribute("client-ref");
+ String bucketRef = element.getAttribute("bucket-ref");
String converterRef = element.getAttribute("converter-ref");
String translationServiceRef = element.getAttribute("translation-service-ref");
- bean.addConstructorArgReference(StringUtils.hasText(clientRef) ? clientRef : BeanNames.COUCHBASE);
+ bean.addConstructorArgReference(StringUtils.hasText(bucketRef) ? bucketRef : BeanNames.COUCHBASE_BUCKET);
if (StringUtils.hasText(converterRef)) {
bean.addConstructorArgReference(converterRef);
diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseTranslationServiceParser.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseTranslationServiceParser.java
index eb4920cc..89f2e52a 100644
--- a/src/main/java/org/springframework/data/couchbase/config/CouchbaseTranslationServiceParser.java
+++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseTranslationServiceParser.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -17,13 +17,14 @@
package org.springframework.data.couchbase.config;
import com.fasterxml.jackson.databind.ObjectMapper;
+import org.w3c.dom.Element;
+
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.couchbase.core.convert.translation.JacksonTranslationService;
import org.springframework.util.StringUtils;
-import org.w3c.dom.Element;
/**
* Enables Parsing of the " " configuration bean.
@@ -36,7 +37,6 @@ public class CouchbaseTranslationServiceParser extends AbstractSingleBeanDefinit
* Defines the bean class that will be constructed.
*
* @param element the XML element which contains the attributes.
- *
* @return the class type to instantiate.
*/
@Override
@@ -55,17 +55,18 @@ public class CouchbaseTranslationServiceParser extends AbstractSingleBeanDefinit
final String objectMapper = element.getAttribute("objectMapper");
if (StringUtils.hasText(objectMapper)) {
bean.addPropertyReference("objectMapper", objectMapper);
- } else {
+ }
+ else {
bean.addPropertyValue("objectMapper", new ObjectMapper());
}
}
+
/**
* Resolve the bean ID and assign a default if not set.
*
* @param element the XML element which contains the attributes.
* @param definition the bean definition to work with.
* @param parserContext encapsulates the parsing state and configuration.
- *
* @return the ID to work with (e.g., "translationService")
*/
@Override
diff --git a/src/main/java/org/springframework/data/couchbase/config/package-info.java b/src/main/java/org/springframework/data/couchbase/config/package-info.java
new file mode 100644
index 00000000..4bfb6547
--- /dev/null
+++ b/src/main/java/org/springframework/data/couchbase/config/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * This package contains all classes needed for specific configuration of
+ * Spring Data Couchbase.
+ */
+package org.springframework.data.couchbase.config;
\ No newline at end of file
diff --git a/src/main/java/org/springframework/data/couchbase/core/BucketCallback.java b/src/main/java/org/springframework/data/couchbase/core/BucketCallback.java
index dfdcd8a3..8e7d90ef 100644
--- a/src/main/java/org/springframework/data/couchbase/core/BucketCallback.java
+++ b/src/main/java/org/springframework/data/couchbase/core/BucketCallback.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -30,8 +30,8 @@ public interface BucketCallback {
* The enclosed body will be executed on the connected bucket.
*
* @return the result of the enclosed execution.
- * @throws TimeoutException if the enclosed operation timed out.
- * @throws ExecutionException if the result could not be retrieved because of a thrown exception before.
+ * @throws TimeoutException if the enclosed operation timed out.
+ * @throws ExecutionException if the result could not be retrieved because of a thrown exception before.
* @throws InterruptedException if the enclosed operation was interrupted.
*/
T doInBucket() throws TimeoutException, ExecutionException, InterruptedException;
diff --git a/src/main/java/org/springframework/data/couchbase/core/CouchbaseDataIntegrityViolationException.java b/src/main/java/org/springframework/data/couchbase/core/CouchbaseDataIntegrityViolationException.java
index 16e24f16..d4aed17c 100644
--- a/src/main/java/org/springframework/data/couchbase/core/CouchbaseDataIntegrityViolationException.java
+++ b/src/main/java/org/springframework/data/couchbase/core/CouchbaseDataIntegrityViolationException.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013, 2014 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
diff --git a/src/main/java/org/springframework/data/couchbase/core/CouchbaseExceptionTranslator.java b/src/main/java/org/springframework/data/couchbase/core/CouchbaseExceptionTranslator.java
index fd03b81e..369d4c4f 100644
--- a/src/main/java/org/springframework/data/couchbase/core/CouchbaseExceptionTranslator.java
+++ b/src/main/java/org/springframework/data/couchbase/core/CouchbaseExceptionTranslator.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,19 +16,41 @@
package org.springframework.data.couchbase.core;
-import com.couchbase.client.ObservedException;
-import com.couchbase.client.ObservedModifiedException;
-import com.couchbase.client.ObservedTimeoutException;
-import com.couchbase.client.protocol.views.InvalidViewException;
-import com.couchbase.client.vbucket.ConnectionException;
+import java.util.concurrent.TimeoutException;
+
+import com.couchbase.client.core.BackpressureException;
+import com.couchbase.client.core.BucketClosedException;
+import com.couchbase.client.core.DocumentConcurrentlyModifiedException;
+import com.couchbase.client.core.ReplicaNotConfiguredException;
+import com.couchbase.client.core.RequestCancelledException;
+import com.couchbase.client.core.ServiceNotAvailableException;
+import com.couchbase.client.core.config.ConfigurationException;
+import com.couchbase.client.core.endpoint.SSLException;
+import com.couchbase.client.core.endpoint.kv.AuthenticationException;
+import com.couchbase.client.core.env.EnvironmentException;
+import com.couchbase.client.core.state.NotConnectedException;
+import com.couchbase.client.java.error.BucketDoesNotExistException;
+import com.couchbase.client.java.error.CASMismatchException;
+import com.couchbase.client.java.error.DesignDocumentException;
+import com.couchbase.client.java.error.DocumentAlreadyExistsException;
+import com.couchbase.client.java.error.DurabilityException;
+import com.couchbase.client.java.error.InvalidPasswordException;
+import com.couchbase.client.java.error.RequestTooBigException;
+import com.couchbase.client.java.error.TemporaryFailureException;
+import com.couchbase.client.java.error.TemporaryLockFailureException;
+import com.couchbase.client.java.error.TranscodingException;
+import com.couchbase.client.java.error.ViewDoesNotExistException;
+
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.dao.DataRetrievalFailureException;
+import org.springframework.dao.DuplicateKeyException;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
+import org.springframework.dao.QueryTimeoutException;
+import org.springframework.dao.TransientDataAccessResourceException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
-import java.util.concurrent.CancellationException;
-
/**
* Simple {@link PersistenceExceptionTranslator} for Couchbase.
@@ -38,6 +60,7 @@ import java.util.concurrent.CancellationException;
* should not be translated.
*
* @author Michael Nitschinger
+ * @author Simon Baslé
*/
public class CouchbaseExceptionTranslator implements PersistenceExceptionTranslator {
@@ -45,28 +68,59 @@ public class CouchbaseExceptionTranslator implements PersistenceExceptionTransla
* Translate Couchbase specific exceptions to spring exceptions if possible.
*
* @param ex the exception to translate.
- *
* @return the translated exception or null.
*/
@Override
public final DataAccessException translateExceptionIfPossible(final RuntimeException ex) {
- if (ex instanceof ConnectionException) {
+ if (ex instanceof InvalidPasswordException
+ || ex instanceof NotConnectedException
+ || ex instanceof ConfigurationException
+ || ex instanceof EnvironmentException
+ || ex instanceof InvalidPasswordException
+ || ex instanceof SSLException
+ || ex instanceof ServiceNotAvailableException
+ || ex instanceof BucketClosedException
+ || ex instanceof BucketDoesNotExistException
+ || ex instanceof AuthenticationException) {
return new DataAccessResourceFailureException(ex.getMessage(), ex);
}
- if (ex instanceof ObservedException
- || ex instanceof ObservedTimeoutException
- || ex instanceof ObservedModifiedException) {
+ if (ex instanceof DocumentAlreadyExistsException) {
+ return new DuplicateKeyException(ex.getMessage(), ex);
+ }
+
+ if (ex instanceof CASMismatchException
+ || ex instanceof DocumentConcurrentlyModifiedException
+ || ex instanceof ReplicaNotConfiguredException
+ || ex instanceof DurabilityException) {
return new DataIntegrityViolationException(ex.getMessage(), ex);
}
- if (ex instanceof CancellationException) {
- throw new OperationCancellationException(ex.getMessage(), ex);
+ if (ex instanceof RequestCancelledException
+ || ex instanceof BackpressureException) {
+ return new OperationCancellationException(ex.getMessage(), ex);
}
- if (ex instanceof InvalidViewException) {
- throw new InvalidDataAccessResourceUsageException(ex.getMessage(), ex);
+ if (ex instanceof ViewDoesNotExistException
+ || ex instanceof RequestTooBigException
+ || ex instanceof DesignDocumentException) {
+ return new InvalidDataAccessResourceUsageException(ex.getMessage(), ex);
+ }
+
+ if (ex instanceof TemporaryLockFailureException
+ || ex instanceof TemporaryFailureException) {
+ return new TransientDataAccessResourceException(ex.getMessage(), ex);
+ }
+
+ if ((ex instanceof RuntimeException && ex.getCause() instanceof TimeoutException)) {
+ return new QueryTimeoutException(ex.getMessage(), ex);
+ }
+
+ if (ex instanceof TranscodingException) {
+ //note: the more specific CouchbaseQueryExecutionException should be thrown by the template
+ //when dealing with TranscodingException in the query/n1ql methods.
+ return new DataRetrievalFailureException(ex.getMessage(), ex);
}
// Unable to translate exception, therefore just throw the original!
diff --git a/src/main/java/org/springframework/data/couchbase/core/CouchbaseFactoryBean.java b/src/main/java/org/springframework/data/couchbase/core/CouchbaseFactoryBean.java
deleted file mode 100644
index 8918efb9..00000000
--- a/src/main/java/org/springframework/data/couchbase/core/CouchbaseFactoryBean.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * 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 com.couchbase.client.CouchbaseClient;
-import com.couchbase.client.CouchbaseConnectionFactory;
-import com.couchbase.client.CouchbaseConnectionFactoryBuilder;
-import net.spy.memcached.FailureMode;
-import org.springframework.beans.factory.BeanCreationException;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.dao.DataAccessException;
-import org.springframework.dao.support.PersistenceExceptionTranslator;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Convenient Factory for configuring a {@link CouchbaseClient}.
- *
- * To set the properties correctly on the {@link CouchbaseClient} a {@link CouchbaseConnectionFactoryBuilder} is used.
- * After all properties are set, the client is constructed and used.
- *
- * @author Michael Nitschinger
- */
-public class CouchbaseFactoryBean implements FactoryBean, InitializingBean,
- DisposableBean, PersistenceExceptionTranslator {
-
- /**
- * Defines the default hostname to be used if no other list is supplied.
- */
- public static final String DEFAULT_NODE = "127.0.0.1";
-
- /**
- * Defines the default bucket name to be used if no other bucket name is supplied.
- */
- public static final String DEFAULT_BUCKET = "default";
-
- /**
- * Defines the password of the default bucket.
- */
- public static final String DEFAULT_PASSWORD = "";
-
- /**
- * The name of the default shutdown method to call when the context is destroyed.
- */
- public static final String DEFAULT_DESTROY_METHOD = "shutdown";
-
- /**
- * Use SLF4J as the default logger if not instructed otherwise.
- */
- public static final String DEFAULT_LOGGER_PROPERTY = "net.spy.memcached.compat.log.SLF4JLogger";
-
- /**
- * Holds the enclosed {@link CouchbaseClient}.
- */
- private CouchbaseClient couchbaseClient;
-
- /**
- * The exception translator is used to properly map exceptions to spring-type exceptions.
- */
- private PersistenceExceptionTranslator exceptionTranslator = new CouchbaseExceptionTranslator();
-
- /**
- * Contains the actual bucket name.
- */
- private String bucket;
-
- /**
- * Contains the actual bucket password.
- */
- private String password;
-
- /**
- * Contains the list of nodes to connect to.
- */
- private List nodes;
-
- /**
- * The builder which allows to customize client settings.
- */
- private final CouchbaseConnectionFactoryBuilder builder = new CouchbaseConnectionFactoryBuilder();
-
- /**
- * Set the observe poll interval in miliseconds.
- *
- * @param interval the observe poll interval.
- */
- public void setObservePollInterval(final int interval) {
- builder.setObsPollInterval(interval);
- }
-
- /**
- * Set the maximum number of polls.
- *
- * @param max the maximum number of polls.
- */
- public void setObservePollMax(final int max) {
- builder.setObsPollMax(max);
- }
-
- /**
- * Set the reconnect threshold time in seconds.
- *
- * @param time the reconnect threshold time.
- */
- public void setReconnectThresholdTime(final int time) {
- builder.setReconnectThresholdTime(time, TimeUnit.SECONDS);
- }
-
- /**
- * Set the view timeout in miliseconds.
- *
- * @param timeout the view timeout.
- */
- public void setViewTimeout(final int timeout) {
- builder.setViewTimeout(timeout);
- }
-
- /**
- * Set the failure mode if memcached buckets are used.
- *
- * See the proper values of {@link FailureMode} to use.
- *
- * @param mode the failure mode.
- */
- public void setFailureMode(final String mode) {
- builder.setFailureMode(FailureMode.valueOf(mode));
- }
-
- /**
- * Set the operation timeout in miliseconds.
- *
- * @param timeout the operation timeout.
- */
- public void setOpTimeout(final int timeout) {
- builder.setOpTimeout(timeout);
- }
-
- /**
- * Set the operation queue maximum block time in miliseconds.
- *
- * @param time the operation queue maximum block time.
- */
- public void setOpQueueMaxBlockTime(final int time) {
- builder.setOpQueueMaxBlockTime(time);
- }
-
- /**
- * Shutdown the client when the bean is destroyed.
- *
- * @throws Exception if shutdown failed.
- */
- @Override
- public void destroy() throws Exception {
- couchbaseClient.shutdown();
- }
-
- /**
- * Return the underlying {@link CouchbaseClient}.
- *
- * @return the client object.
- * @throws Exception if returning the client failed.
- */
- @Override
- public CouchbaseClient getObject() throws Exception {
- return couchbaseClient;
- }
-
- /**
- * Returns the object type of the client.
- *
- * @return the {@link CouchbaseClient} class.
- */
- @Override
- public Class> getObjectType() {
- return CouchbaseClient.class;
- }
-
- /**
- * The client should be returned as a singleton.
- *
- * @return returns true.
- */
- @Override
- public boolean isSingleton() {
- return true;
- }
-
- /**
- * Set the bucket to be used.
- *
- * @param bucket the bucket to use.
- */
- public void setBucket(final String bucket) {
- this.bucket = bucket;
- }
-
- /**
- * Set the password.
- *
- * @param password the password to use.
- */
- public void setPassword(final String password) {
- this.password = password;
- }
-
- /**
- * Set the array of nodes from a delimited list of hosts.
- *
- * @param hosts a comma separated list of hosts.
- */
- public void setHost(final String hosts) {
- this.nodes = convertHosts(hosts);
- }
-
- /**
- * Convert a list of hosts into a URI format that can be used by the {@link CouchbaseClient}.
- *
- * To make it simple to use, the list of hosts can be passed in as a comma separated list. This list gets parsed
- * and converted into a URI format that is suitable for the underlying {@link CouchbaseClient} object.
- *
- * @param hosts the host list to convert.
- * @return the converted list with URIs.
- */
- private List convertHosts(final String hosts) {
- String[] split = hosts.split(",");
- List nodes = new ArrayList();
-
- try {
- for (int i = 0; i < split.length; i++) {
- nodes.add(new URI("http://" + split[i] + ":8091/pools"));
- }
- } catch (URISyntaxException ex) {
- throw new BeanCreationException("Could not convert host list." + ex);
- }
-
- return nodes;
- }
-
- /**
- * Set the nodes as an array of URIs.
- *
- * @param nodes the nodes to connect to.
- */
- public void setNodes(final URI[] nodes) {
- this.nodes = filterNonNullElementsAsList(nodes);
- }
-
- /**
- * Convert the array of elements to a list and filter empty or null elements.
- *
- * @param elements the elements to convert.
- * @param the type of the elements.
- * @return the converted list.
- */
- private List filterNonNullElementsAsList(T[] elements) {
- if (elements == null) {
- return Collections.emptyList();
- }
-
- List candidateElements = new ArrayList();
- for (T element : elements) {
- if (element != null) {
- candidateElements.add(element);
- }
- }
-
- return Collections.unmodifiableList(candidateElements);
- }
-
- /**
- * Instantiate the {@link CouchbaseClient}.
- *
- * @throws Exception if something goes wrong during instantiation.
- */
- @Override
- public void afterPropertiesSet() throws Exception {
- nodes = nodes != null ? nodes : Arrays.asList(new URI("http://" + DEFAULT_NODE + ":8091/pools"));
- bucket = bucket != null ? bucket : DEFAULT_BUCKET;
- password = password != null ? password : DEFAULT_PASSWORD;
-
- CouchbaseConnectionFactory factory = builder.buildCouchbaseConnection(nodes, bucket, password);
- couchbaseClient = new CouchbaseClient(factory);
- }
-
- /**
- * Translate exception if possible.
- *
- * @param ex the exception to translate.
- * @return the translate exception.
- */
- @Override
- public DataAccessException translateExceptionIfPossible(final RuntimeException ex) {
- return exceptionTranslator.translateExceptionIfPossible(ex);
- }
-
-}
diff --git a/src/main/java/org/springframework/data/couchbase/core/CouchbaseOperations.java b/src/main/java/org/springframework/data/couchbase/core/CouchbaseOperations.java
index a50d8c98..0610c9e0 100644
--- a/src/main/java/org/springframework/data/couchbase/core/CouchbaseOperations.java
+++ b/src/main/java/org/springframework/data/couchbase/core/CouchbaseOperations.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -17,20 +17,26 @@
package org.springframework.data.couchbase.core;
-import com.couchbase.client.CouchbaseClient;
-import com.couchbase.client.protocol.views.Query;
-import com.couchbase.client.protocol.views.ViewResponse;
-import net.spy.memcached.PersistTo;
-import net.spy.memcached.ReplicateTo;
-import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
-
import java.util.Collection;
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.query.Query;
+import com.couchbase.client.java.query.QueryParams;
+import com.couchbase.client.java.query.QueryResult;
+import com.couchbase.client.java.query.Statement;
+import com.couchbase.client.java.view.ViewQuery;
+import com.couchbase.client.java.view.ViewResult;
+
+import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
+
/**
* Defines common operations on the Couchbase data source, most commonly implemented by {@link CouchbaseTemplate}.
*
* @author Michael Nitschinger
+ * @author Simon Baslé
*/
public interface CouchbaseOperations {
@@ -169,50 +175,71 @@ public interface CouchbaseOperations {
*
* @param id the unique ID of the document.
* @param entityClass the entity to map to.
- *
* @return returns the found object or null otherwise.
*/
T findById(String id, Class entityClass);
+ //TODO add javadoc link to setIncludeDocs when GA
+
/**
* Query a View for a list of documents of type T.
*
- * There is no need to {@link Query#setIncludeDocs(boolean)} explicitely, because it will be set to true all the
- * time. It is valid to pass in a empty constructed {@link Query} object.
+ * There is no need to setIncludeDocs(boolean) explicitly, because it will be set to true all the
+ * time. It is valid to pass in a empty constructed {@link ViewQuery} object.
*
* This method does not work with reduced views, because they by design do not contain references to original
* objects. Use the provided {@link #queryView} method for more flexibility and direct access.
*
- * @param design the name of the design document.
- * @param view the name of the viewName.
- * @param query the Query object to customize the viewName query.
+ * @param query the Query object (also specifying view design document and view name).
* @param entityClass the entity to map to.
- *
* @return the converted collection
*/
- List findByView(String design, String view, Query query, Class entityClass);
+ List findByView(ViewQuery query, Class entityClass);
/**
- * Query a View with direct access to the {@link ViewResponse}.
+ * Query a View with direct access to the {@link ViewResult}.
* This method is available to ease the working with views by still wrapping exceptions into the Spring
* infrastructure.
* It is especially needed if you want to run reduced viewName queries, because they can't be mapped onto entities
* directly.
*
- * @param design the name of the designDocument document.
- * @param view the name of the viewName.
- * @param query the Query object to customize the viewName query.
- *
- * @return ViewResponse containing the results of the query.
+ * @param query the Query object (also specifying view design document and view name).
+ * @return ViewResult containing the results of the query.
*/
- ViewResponse queryView(String design, String view, Query query);
+ ViewResult queryView(ViewQuery query);
+
+ /**
+ * Query the N1QL Service for JSON data of type T. This is done via a {@link Query} that can
+ * contain a {@link Statement}, additional query parameters ({@link QueryParams})
+ * and placeholder values if the statement contains placeholders.
+ * Use {@link Query}'s factory methods to construct this.
+ *
+ * @param n1ql the N1QL query.
+ * @param entityClass the target class for the returned entities.
+ * @param the entity class
+ * @return the list of entities matching this query.
+ */
+ List findByN1QL(Query n1ql, Class entityClass);
+
+ /**
+ * Query the N1QL Service with direct access to the {@link QueryResult}.
+ *
+ * This is done via a {@link Query} that can
+ * contain a {@link Statement}, additional query parameters ({@link QueryParams})
+ * and placeholder values if the statement contains placeholders.
+ *
+ * Use {@link Query}'s factory methods to construct this.
+ *
+ * @param n1ql the N1QL query.
+ * @return {@link QueryResult} containing the results of the n1ql query.
+ */
+ QueryResult queryN1QL(Query n1ql);
/**
* Checks if the given document exists.
*
* @param id the unique ID of the document.
- *
* @return whether the document could be found or not.
*/
boolean exists(String id);
@@ -262,11 +289,17 @@ public interface CouchbaseOperations {
*
* @param action the action to execute in the callback.
* @param the return type.
- *
* @return the return type.
*/
T execute(BucketCallback action);
+ /**
+ * Returns the linked {@link Bucket} to this template.
+ *
+ * @return the client used for the template.
+ */
+ Bucket getCouchbaseBucket();
+
/**
* Returns the underlying {@link CouchbaseConverter}.
*
@@ -274,11 +307,4 @@ public interface CouchbaseOperations {
*/
CouchbaseConverter getConverter();
- /**
- * Returns the linked {@link CouchbaseClient} to this template.
- *
- * @return the client used for the template.
- */
- CouchbaseClient getCouchbaseClient();
-
}
diff --git a/src/main/java/org/springframework/data/couchbase/core/CouchbaseQueryExecutionException.java b/src/main/java/org/springframework/data/couchbase/core/CouchbaseQueryExecutionException.java
new file mode 100644
index 00000000..7cb25a90
--- /dev/null
+++ b/src/main/java/org/springframework/data/couchbase/core/CouchbaseQueryExecutionException.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2012-2015 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 org.springframework.dao.DataRetrievalFailureException;
+
+/**
+ * An {@link DataRetrievalFailureException} that denotes an error during a query (N1QL).
+ */
+public class CouchbaseQueryExecutionException extends DataRetrievalFailureException {
+
+ public CouchbaseQueryExecutionException(String msg) {
+ super(msg);
+ }
+
+ public CouchbaseQueryExecutionException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+}
diff --git a/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java b/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java
index b91594d3..7f707c05 100644
--- a/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java
+++ b/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013-2014 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,22 +16,38 @@
package org.springframework.data.couchbase.core;
-import com.couchbase.client.CouchbaseClient;
-import com.couchbase.client.protocol.views.Query;
-import com.couchbase.client.protocol.views.View;
-import com.couchbase.client.protocol.views.ViewResponse;
-import com.couchbase.client.protocol.views.ViewRow;
-import net.spy.memcached.CASResponse;
-import net.spy.memcached.CASValue;
-import net.spy.memcached.PersistTo;
-import net.spy.memcached.ReplicateTo;
-import net.spy.memcached.internal.OperationFuture;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
+import com.couchbase.client.java.Bucket;
+import com.couchbase.client.java.PersistTo;
+import com.couchbase.client.java.ReplicateTo;
+import com.couchbase.client.java.document.Document;
+import com.couchbase.client.java.document.RawJsonDocument;
+import com.couchbase.client.java.document.json.JsonObject;
+import com.couchbase.client.java.error.CASMismatchException;
+import com.couchbase.client.java.error.TranscodingException;
+import com.couchbase.client.java.query.Query;
+import com.couchbase.client.java.query.QueryResult;
+import com.couchbase.client.java.query.QueryRow;
+import com.couchbase.client.java.view.ViewQuery;
+import com.couchbase.client.java.view.ViewResult;
+import com.couchbase.client.java.view.ViewRow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.dao.QueryTimeoutException;
+import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
import org.springframework.data.couchbase.core.convert.translation.JacksonTranslationService;
@@ -50,34 +66,16 @@ import org.springframework.data.couchbase.core.mapping.event.CouchbaseMappingEve
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.BeanWrapper;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-
/**
* @author Michael Nitschinger
* @author Oliver Gierke
+ * @author Simon Baslé
*/
public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventPublisherAware {
private static final Logger LOGGER = LoggerFactory.getLogger(CouchbaseTemplate.class);
- private static final Collection ITERABLE_CLASSES;
private static final WriteResultChecking DEFAULT_WRITE_RESULT_CHECKING = WriteResultChecking.NONE;
-
- private final CouchbaseClient client;
- protected final MappingContext extends CouchbasePersistentEntity>, CouchbasePersistentProperty> mappingContext;
- private final CouchbaseExceptionTranslator exceptionTranslator = new CouchbaseExceptionTranslator();
- private final TranslationService translationService;
- private ApplicationEventPublisher eventPublisher;
-
- private CouchbaseConverter couchbaseConverter;
- private WriteResultChecking writeResultChecking = DEFAULT_WRITE_RESULT_CHECKING;
+ private static final Collection ITERABLE_CLASSES;
static {
final Set iterableClasses = new HashSet();
@@ -87,181 +85,66 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP
ITERABLE_CLASSES = Collections.unmodifiableCollection(iterableClasses);
}
- public void setWriteResultChecking(final WriteResultChecking resultChecking) {
- writeResultChecking = resultChecking == null ? DEFAULT_WRITE_RESULT_CHECKING : resultChecking;
- }
+ private final Bucket client;
+ private final CouchbaseConverter converter;
+ private final TranslationService translationService;
- public CouchbaseTemplate(final CouchbaseClient client) {
+
+ private ApplicationEventPublisher eventPublisher;
+ private WriteResultChecking writeResultChecking = DEFAULT_WRITE_RESULT_CHECKING;
+ private PersistenceExceptionTranslator exceptionTranslator = new CouchbaseExceptionTranslator();
+
+ protected final MappingContext extends CouchbasePersistentEntity>, CouchbasePersistentProperty> mappingContext;
+
+ public CouchbaseTemplate(final Bucket client) {
this(client, null, null);
}
- public CouchbaseTemplate(final CouchbaseClient client, final TranslationService translationService) {
+ public CouchbaseTemplate(final Bucket client, final TranslationService translationService) {
this(client, null, translationService);
}
- public CouchbaseTemplate(final CouchbaseClient client, final CouchbaseConverter couchbaseConverter, final TranslationService translationService) {
+ public CouchbaseTemplate(final Bucket client, final CouchbaseConverter converter,
+ final TranslationService translationService) {
this.client = client;
- this.couchbaseConverter = couchbaseConverter == null ? getDefaultConverter() : couchbaseConverter;
+ this.converter = converter == null ? getDefaultConverter() : converter;
this.translationService = translationService == null ? getDefaultTranslationService() : translationService;
- mappingContext = this.couchbaseConverter.getMappingContext();
+ this.mappingContext = this.converter.getMappingContext();
}
- @Override
- public void setApplicationEventPublisher(final ApplicationEventPublisher eventPublisher) {
- this.eventPublisher = eventPublisher;
+ private TranslationService getDefaultTranslationService() {
+ JacksonTranslationService t = new JacksonTranslationService();
+ t.afterPropertiesSet();
+ return t;
}
- private static CouchbaseConverter getDefaultConverter() {
- final MappingCouchbaseConverter converter = new MappingCouchbaseConverter(new CouchbaseMappingContext());
- converter.afterPropertiesSet();
- return converter;
+ private CouchbaseConverter getDefaultConverter() {
+ MappingCouchbaseConverter c = new MappingCouchbaseConverter(new CouchbaseMappingContext());
+ c.afterPropertiesSet();
+ return c;
}
- private static TranslationService getDefaultTranslationService() {
- final JacksonTranslationService jacksonTranslationService = new JacksonTranslationService();
- jacksonTranslationService.afterPropertiesSet();
- return jacksonTranslationService;
- }
-
- private Object translateEncode(final CouchbaseStorable source) {
- return translationService.encode(source);
- }
-
-
- private CouchbaseStorable translateDecode(final String source, final CouchbaseStorable target) {
- return translationService.decode(source, target);
- }
-
- @Override
- public final void insert(final Object objectToInsert) {
- insert(objectToInsert, PersistTo.ZERO, ReplicateTo.ZERO);
- }
-
- @Override
- public final void insert(final Collection> batchToInsert) {
- for (final Object toInsert : batchToInsert) {
- insert(toInsert);
+ /**
+ * Encode a {@link CouchbaseDocument} into a storable representation (JSON) then prepare
+ * it for storage as a {@link Document}.
+ */
+ private Document encodeAndWrap(final CouchbaseDocument source, Long version) {
+ String encodedContent = translationService.encode(source);
+ if (version == null) {
+ return RawJsonDocument.create(source.getId(), source.getExpiration(), encodedContent);
+ }
+ else {
+ return RawJsonDocument.create(source.getId(), source.getExpiration(), encodedContent, version);
}
}
- @Override
- public void save(final Object objectToSave) {
- save(objectToSave, PersistTo.ZERO, ReplicateTo.ZERO);
- }
- @Override
- public void save(final Collection> batchToSave) {
- for (final Object toSave : batchToSave) {
- save(toSave);
- }
- }
-
- @Override
- public void update(final Object objectToUpdate) {
- update(objectToUpdate, PersistTo.ZERO, ReplicateTo.ZERO);
- }
-
- @Override
- public void update(final Collection> batchToUpdate) {
- for (final Object toUpdate : batchToUpdate) {
- update(toUpdate);
- }
- }
-
- @Override
- public final T findById(final String id, final Class entityClass) {
- CASValue result = execute(new BucketCallback() {
- @Override
- public CASValue doInBucket() {
- return client.gets(id);
- }
- });
-
- if (result == null) {
- return null;
- }
-
- final CouchbaseDocument converted = new CouchbaseDocument(id);
- Object readEntity = couchbaseConverter.read(entityClass, (CouchbaseDocument) translateDecode(
- (String) result.getValue(), converted));
-
- final BeanWrapper beanWrapper = BeanWrapper.create(readEntity, couchbaseConverter.getConversionService());
- CouchbasePersistentEntity> persistentEntity = mappingContext.getPersistentEntity(readEntity.getClass());
- if (persistentEntity.hasVersionProperty()) {
- beanWrapper.setProperty(persistentEntity.getVersionProperty(), result.getCas());
- }
-
- return (T) readEntity;
- }
-
-
- @Override
- public List findByView(final String designName, final String viewName, final Query query, final Class entityClass) {
-
- if (query.willIncludeDocs()) {
- query.setIncludeDocs(false);
- }
- if (query.willReduce()) {
- query.setReduce(false);
- }
-
- final ViewResponse response = queryView(designName, viewName, query);
-
- final List result = new ArrayList(response.size());
- for (final ViewRow row : response) {
- result.add(findById(row.getId(), entityClass));
- }
-
- return result;
- }
-
- @Override
- public ViewResponse queryView(final String designName, final String viewName, final Query query) {
- return execute(new BucketCallback() {
- @Override
- public ViewResponse doInBucket() {
- final View view = client.getView(designName, viewName);
- return client.query(view, query);
- }
- });
- }
-
- @Override
- public void remove(final Object objectToRemove) {
- remove(objectToRemove, PersistTo.ZERO, ReplicateTo.ZERO);
- }
-
- @Override
- public void remove(final Collection> batchToRemove) {
- for (final Object toRemove : batchToRemove) {
- remove(toRemove);
- }
- }
-
- @Override
- public T execute(final BucketCallback action) {
- try {
- return action.doInBucket();
- } catch (RuntimeException e) {
- throw exceptionTranslator.translateExceptionIfPossible(e);
- } catch (TimeoutException e) {
- throw new QueryTimeoutException(e.getMessage(), e);
- } catch (InterruptedException e) {
- throw new OperationInterruptedException(e.getMessage(), e);
- } catch (ExecutionException e) {
- throw new OperationInterruptedException(e.getMessage(), e);
- }
- }
-
- @Override
- public boolean exists(final String id) {
- final String result = execute(new BucketCallback() {
- @Override
- public String doInBucket() {
- return (String) client.get(id);
- }
- });
- return result != null;
+ /**
+ * Decode a {@link Document Document<String>} containing a JSON string
+ * into a {@link CouchbaseStorable}
+ */
+ private CouchbaseStorable decodeAndUnwrap(final Document source, final CouchbaseStorable target) {
+ return translationService.decode(source.content(), target); //TODO rework and check
}
/**
@@ -277,201 +160,31 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP
}
}
- @Override
- public CouchbaseConverter getConverter() {
- return couchbaseConverter;
- }
-
- @Override
- public void save(Object objectToSave, final PersistTo persistTo, final ReplicateTo replicateTo) {
- ensureNotIterable(objectToSave);
-
- final BeanWrapper beanWrapper = BeanWrapper.create(objectToSave, couchbaseConverter.getConversionService());
- CouchbasePersistentEntity> persistentEntity = mappingContext.getPersistentEntity(objectToSave.getClass());
- final CouchbasePersistentProperty versionProperty = persistentEntity.getVersionProperty();
- final Long version = versionProperty != null ? beanWrapper.getProperty(versionProperty, Long.class) : null;
-
- maybeEmitEvent(new BeforeConvertEvent(objectToSave));
- final CouchbaseDocument converted = new CouchbaseDocument();
- couchbaseConverter.write(objectToSave, converted);
-
- maybeEmitEvent(new BeforeSaveEvent(objectToSave, converted));
- execute(new BucketCallback() {
- @Override
- public Boolean doInBucket() throws InterruptedException, ExecutionException {
- if (version == null) {
- OperationFuture setFuture = client.set(converted.getId(), converted.getExpiration(),
- translateEncode(converted), persistTo, replicateTo);
- boolean future = setFuture.get();
- if (!future) {
- handleWriteResultError("Saving document failed: " + setFuture.getStatus().getMessage());
- }
- return future;
- } else {
- OperationFuture casFuture = client.asyncCas(converted.getId(), version,
- converted.getExpiration(), translateEncode(converted), persistTo, replicateTo);
- CASResponse cas = casFuture.get();
- if (cas == CASResponse.EXISTS) {
- throw new OptimisticLockingFailureException("Saving document with version value failed: " + cas);
- } else {
- long newCas = casFuture.getCas();
- beanWrapper.setProperty(versionProperty, newCas);
- return true;
- }
- }
- }
- });
- maybeEmitEvent(new AfterSaveEvent(objectToSave, converted));
- }
-
- @Override
- public void save(Collection> batchToSave, PersistTo persistTo, ReplicateTo replicateTo) {
- for (Object toSave : batchToSave) {
- save(toSave, persistTo, replicateTo);
- }
- }
-
- @Override
- public void insert(Object objectToInsert, final PersistTo persistTo, final ReplicateTo replicateTo) {
- ensureNotIterable(objectToInsert);
-
- final CouchbasePersistentEntity> persistentEntity = mappingContext.getPersistentEntity(objectToInsert.getClass());
- final BeanWrapper beanWrapper = BeanWrapper.create(objectToInsert, couchbaseConverter.getConversionService());
-
- if (persistentEntity != null && persistentEntity.hasVersionProperty()) {
- final Long version = beanWrapper.getProperty(persistentEntity.getVersionProperty(), Long.class);
- if (version == 0) {
- beanWrapper.setProperty(persistentEntity.getVersionProperty(), 0);
- }
- }
-
- maybeEmitEvent(new BeforeConvertEvent(objectToInsert));
- final CouchbaseDocument converted = new CouchbaseDocument();
- couchbaseConverter.write(objectToInsert, converted);
-
- maybeEmitEvent(new BeforeSaveEvent(objectToInsert, converted));
- execute(new BucketCallback() {
- @Override
- public Boolean doInBucket() throws InterruptedException, ExecutionException {
- OperationFuture addFuture = client.add(converted.getId(), converted.getExpiration(),
- translateEncode(converted), persistTo, replicateTo);
- boolean result = addFuture.get();
- if(result == false) {
- handleWriteResultError("Inserting document failed: "
- + addFuture.getStatus().getMessage());
- }
-
- if (result && persistentEntity.hasVersionProperty()) {
- beanWrapper.setProperty(persistentEntity.getVersionProperty(), addFuture.getCas());
- }
- return result;
- }
- });
- maybeEmitEvent(new AfterSaveEvent(objectToInsert, converted));
- }
-
- @Override
- public void insert(Collection> batchToInsert, PersistTo persistTo, ReplicateTo replicateTo) {
- for (Object toInsert : batchToInsert) {
- insert(toInsert, persistTo,replicateTo);
- }
- }
-
- @Override
- public void update(Object objectToUpdate, final PersistTo persistTo, final ReplicateTo replicateTo) {
- ensureNotIterable(objectToUpdate);
-
- final BeanWrapper beanWrapper = BeanWrapper.create(objectToUpdate, couchbaseConverter.getConversionService());
- CouchbasePersistentEntity> persistentEntity = mappingContext.getPersistentEntity(objectToUpdate.getClass());
- final CouchbasePersistentProperty versionProperty = persistentEntity.getVersionProperty();
- final Long version = versionProperty != null ? beanWrapper.getProperty(versionProperty, Long.class) : null;
-
- maybeEmitEvent(new BeforeConvertEvent(objectToUpdate));
- final CouchbaseDocument converted = new CouchbaseDocument();
- couchbaseConverter.write(objectToUpdate, converted);
-
- maybeEmitEvent(new BeforeSaveEvent(objectToUpdate, converted));
- execute(new BucketCallback() {
- @Override
- public Boolean doInBucket() throws InterruptedException, ExecutionException {
- if (version == null) {
- return client.replace(converted.getId(), converted.getExpiration(), translateEncode(converted), persistTo,
- replicateTo).get();
- } else {
- OperationFuture casFuture = client.asyncCas(converted.getId(), version,
- converted.getExpiration(), translateEncode(converted), persistTo, replicateTo);
- CASResponse cas = casFuture.get();
-
- if (cas == CASResponse.EXISTS) {
- throw new OptimisticLockingFailureException("Updating document with version value failed: " + cas);
- } else {
- long newCas = casFuture.getCas();
- beanWrapper.setProperty(versionProperty, newCas);
- return true;
- }
- }
- }
- });
- maybeEmitEvent(new AfterSaveEvent(objectToUpdate, converted));
- }
-
- @Override
- public void update(Collection> batchToUpdate, PersistTo persistTo, ReplicateTo replicateTo) {
- for (Object toUpdate : batchToUpdate) {
- update(toUpdate, persistTo, replicateTo);
- }
- }
-
- @Override
- public void remove(final Object objectToRemove, final PersistTo persistTo, final ReplicateTo replicateTo) {
- ensureNotIterable(objectToRemove);
-
- maybeEmitEvent(new BeforeDeleteEvent(objectToRemove));
- if (objectToRemove instanceof String) {
- execute(new BucketCallback() {
- @Override
- public Boolean doInBucket() throws InterruptedException, ExecutionException {
- return client.delete((String) objectToRemove, persistTo, replicateTo).get();
- }
- });
- maybeEmitEvent(new AfterDeleteEvent(objectToRemove));
- return;
- }
-
- final CouchbaseDocument converted = new CouchbaseDocument();
- couchbaseConverter.write(objectToRemove, converted);
-
- execute(new BucketCallback>() {
- @Override
- public OperationFuture doInBucket() {
- return client.delete(converted.getId());
- }
- });
- maybeEmitEvent(new AfterDeleteEvent(objectToRemove));
- }
-
- @Override
- public void remove(Collection> batchToRemove, PersistTo persistTo, ReplicateTo replicateTo) {
- for (Object toRemove : batchToRemove) {
- remove(toRemove, persistTo, replicateTo);
- }
- }
-
/**
* Handle write errors according to the set {@link #writeResultChecking} setting.
*
* @param message the message to use.
*/
- private void handleWriteResultError(String message) {
+ private void handleWriteResultError(String message, Exception cause) {
if (writeResultChecking == WriteResultChecking.NONE) {
return;
}
if (writeResultChecking == WriteResultChecking.EXCEPTION) {
- throw new CouchbaseDataIntegrityViolationException(message);
- } else {
- LOGGER.error(message);
+ throw new CouchbaseDataIntegrityViolationException(message, cause);
}
+ else {
+ LOGGER.error(message, cause);
+ }
+ }
+
+ public void setWriteResultChecking(WriteResultChecking writeResultChecking) {
+ this.writeResultChecking = writeResultChecking == null ? DEFAULT_WRITE_RESULT_CHECKING : writeResultChecking;
+ }
+
+ @Override
+ public void setApplicationEventPublisher(final ApplicationEventPublisher eventPublisher) {
+ this.eventPublisher = eventPublisher;
}
/**
@@ -487,7 +200,315 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP
}
@Override
- public CouchbaseClient getCouchbaseClient() {
- return client;
+ public void save(Object objectToSave) {
+ save(objectToSave, PersistTo.NONE, ReplicateTo.NONE);
+ }
+
+ @Override
+ public void save(Object objectToSave, PersistTo persistTo, ReplicateTo replicateTo) {
+ doPersist(objectToSave, persistTo, replicateTo, false, false);
+ }
+
+ @Override
+ public void save(Collection> batchToSave) {
+ save(batchToSave, PersistTo.NONE, ReplicateTo.NONE);
+ }
+
+ @Override
+ public void save(Collection> batchToSave, PersistTo persistTo, ReplicateTo replicateTo) {
+ for (Object o : batchToSave) {
+ doPersist(o, persistTo, replicateTo, false, false);
+ }
+ }
+
+ @Override
+ public void insert(Object objectToInsert) {
+ insert(objectToInsert, PersistTo.NONE, ReplicateTo.NONE);
+ }
+
+ @Override
+ public void insert(Object objectToInsert, PersistTo persistTo, ReplicateTo replicateTo) {
+ doPersist(objectToInsert, persistTo, replicateTo, true, false);
+ }
+
+ @Override
+ public void insert(Collection> batchToInsert) {
+ insert(batchToInsert, PersistTo.NONE, ReplicateTo.NONE);
+ }
+
+ @Override
+ public void insert(Collection> batchToInsert, PersistTo persistTo, ReplicateTo replicateTo) {
+ for (Object o : batchToInsert) {
+ doPersist(o, persistTo, replicateTo, true, false);
+ }
+ }
+
+ @Override
+ public void update(Object objectToUpdate) {
+ update(objectToUpdate, PersistTo.NONE, ReplicateTo.NONE);
+ }
+
+ @Override
+ public void update(Object objectToUpdate, PersistTo persistTo, ReplicateTo replicateTo) {
+ doPersist(objectToUpdate, persistTo, replicateTo, false, true);
+ }
+
+ @Override
+ public void update(Collection> batchToUpdate) {
+ update(batchToUpdate, PersistTo.NONE, ReplicateTo.NONE);
+ }
+
+ @Override
+ public void update(Collection> batchToUpdate, PersistTo persistTo, ReplicateTo replicateTo) {
+ for (Object o : batchToUpdate) {
+ doPersist(o, persistTo, replicateTo, false, true);
+ }
+ }
+
+ @Override
+ public T findById(final String id, Class entityClass) {
+ RawJsonDocument result = execute(new BucketCallback() {
+ @Override
+ public RawJsonDocument doInBucket() {
+ return client.get(id, RawJsonDocument.class);
+ }
+ });
+
+ return mapToEntity(id, result, entityClass);
+ }
+
+ @Override
+ public List findByView(ViewQuery query, Class entityClass) {
+ query.includeDocs(false);
+ query.reduce(false);
+
+ try {
+ final ViewResult response = queryView(query);
+ if (response.error() != null) {
+ throw new CouchbaseQueryExecutionException("Unable to execute view query due to the following view error: " +
+ response.error().toString());
+ }
+
+ List allRows = response.allRows();
+
+ final List result = new ArrayList(allRows.size());
+ for (final ViewRow row : allRows) {
+ result.add(mapToEntity(row.id(), row.document(RawJsonDocument.class), entityClass));
+ }
+
+ return result;
+ }
+ catch (TranscodingException e) {
+ throw new CouchbaseQueryExecutionException("Unable to execute view query", e);
+ }
+ }
+
+ @Override
+ public ViewResult queryView(final ViewQuery query) {
+ return execute(new BucketCallback() {
+ @Override
+ public ViewResult doInBucket() {
+ return client.query(query);
+ }
+ });
+ }
+
+ @Override
+ public List findByN1QL(Query n1ql, Class entityClass) {
+ try {
+ QueryResult queryResult = queryN1QL(n1ql);
+
+ if (queryResult.finalSuccess()) {
+ List allRows = queryResult.allRows();
+ List result = new ArrayList(allRows.size());
+ for (QueryRow row : allRows) {
+ String json = row.value().toString();
+ T decoded = translationService.decodeFragment(json, entityClass);
+ result.add(decoded);
+ }
+ return result;
+ }
+ else {
+ StringBuilder message = new StringBuilder("Unable to execute query due to the following n1ql errors: ");
+ for (JsonObject error : queryResult.errors()) {
+ message.append('\n').append(error);
+ }
+ throw new CouchbaseQueryExecutionException(message.toString());
+ }
+ }
+ catch (TranscodingException e) {
+ throw new CouchbaseQueryExecutionException("Unable to execute query", e);
+ }
+ }
+
+ @Override
+ public QueryResult queryN1QL(final Query query) {
+ return execute(new BucketCallback() {
+ @Override
+ public QueryResult doInBucket() throws TimeoutException, ExecutionException, InterruptedException {
+ return client.query(query);
+ }
+ });
+ }
+
+ @Override
+ public boolean exists(final String id) {
+ return execute(new BucketCallback() {
+ @Override
+ public Boolean doInBucket() throws TimeoutException, ExecutionException, InterruptedException {
+ return client.exists(id);
+ }
+ });
+ }
+
+ @Override
+ public void remove(Object objectToRemove) {
+ remove(objectToRemove, PersistTo.NONE, ReplicateTo.NONE);
+ }
+
+ @Override
+ public void remove(Object objectToRemove, PersistTo persistTo, ReplicateTo replicateTo) {
+ doRemove(objectToRemove, persistTo, replicateTo);
+ }
+
+ @Override
+ public void remove(Collection> batchToRemove) {
+ remove(batchToRemove, PersistTo.NONE, ReplicateTo.NONE);
+ }
+
+ @Override
+ public void remove(Collection> batchToRemove, PersistTo persistTo, ReplicateTo replicateTo) {
+ for (Object o : batchToRemove) {
+ doRemove(o, persistTo, replicateTo);
+ }
+ }
+
+ @Override
+ public T execute(BucketCallback action) {
+ try {
+ return action.doInBucket();
+ }
+ catch (RuntimeException e) {
+ throw exceptionTranslator.translateExceptionIfPossible(e);
+ }
+ catch (TimeoutException e) {
+ throw new QueryTimeoutException(e.getMessage(), e);
+ }
+ catch (InterruptedException e) {
+ throw new OperationInterruptedException(e.getMessage(), e);
+ }
+ catch (ExecutionException e) {
+ throw new OperationInterruptedException(e.getMessage(), e);
+ }
+ }
+
+ private void doPersist(Object objectToPersist, final PersistTo persistTo, final ReplicateTo replicateTo,
+ final boolean failOnExist, final boolean failOnMissing) {
+ ensureNotIterable(objectToPersist);
+
+ final String operationDesc = failOnExist ? "Insert" : failOnMissing ? "Update" : "Upsert";
+
+ final BeanWrapper beanWrapper = BeanWrapper.create(objectToPersist, converter.getConversionService());
+ final CouchbasePersistentEntity> persistentEntity = mappingContext.getPersistentEntity(objectToPersist.getClass());
+ final CouchbasePersistentProperty versionProperty = persistentEntity.getVersionProperty();
+ final Long version = versionProperty != null ? beanWrapper.getProperty(versionProperty, Long.class) : null;
+
+ maybeEmitEvent(new BeforeConvertEvent(objectToPersist));
+ final CouchbaseDocument converted = new CouchbaseDocument();
+ converter.write(objectToPersist, converted);
+
+ maybeEmitEvent(new BeforeSaveEvent(objectToPersist, converted));
+ execute(new BucketCallback() {
+ @Override
+ public Boolean doInBucket() throws InterruptedException, ExecutionException {
+ Document doc = encodeAndWrap(converted, version);
+ Document storedDoc;
+ try {
+ if (!failOnExist && !failOnMissing) {
+ storedDoc = client.upsert(doc, persistTo, replicateTo);
+ }
+ else if (failOnMissing) {
+ storedDoc = client.replace(doc, persistTo, replicateTo);
+ }
+ else {
+ storedDoc = client.insert(doc, persistTo, replicateTo);
+ }
+
+ if (persistentEntity.hasVersionProperty() && storedDoc != null && storedDoc.cas() != 0) {
+ //inject new cas into the bean
+ beanWrapper.setProperty(versionProperty, storedDoc.cas());
+ return true;
+ }
+ return false;
+ }
+ catch (CASMismatchException e) {
+ throw new OptimisticLockingFailureException(operationDesc +
+ " document with version value failed: " + version);
+ }
+ catch (Exception e) {
+ handleWriteResultError(operationDesc + " document failed: " + e.getMessage(), e);
+ return false; //this could be skipped if WriteResultChecking.EXCEPTION
+ }
+ }
+ });
+ maybeEmitEvent(new AfterSaveEvent(objectToPersist, converted));
+ }
+
+ private void doRemove(final Object objectToRemove, final PersistTo persistTo, final ReplicateTo replicateTo) {
+ ensureNotIterable(objectToRemove);
+
+ maybeEmitEvent(new BeforeDeleteEvent(objectToRemove));
+ if (objectToRemove instanceof String) {
+ execute(new BucketCallback() {
+ @Override
+ public Boolean doInBucket() throws InterruptedException, ExecutionException {
+ RawJsonDocument deletedDoc = client.remove((String) objectToRemove, persistTo, replicateTo,
+ RawJsonDocument.class);
+ return deletedDoc != null;
+ }
+ });
+ maybeEmitEvent(new AfterDeleteEvent(objectToRemove));
+ return;
+ }
+
+ final CouchbaseDocument converted = new CouchbaseDocument();
+ converter.write(objectToRemove, converted);
+
+ execute(new BucketCallback() {
+ @Override
+ public Boolean doInBucket() {
+ RawJsonDocument deletedDoc = client.remove(converted.getId(), persistTo, replicateTo
+ , RawJsonDocument.class);
+ return deletedDoc != null;
+ }
+ });
+ maybeEmitEvent(new AfterDeleteEvent(objectToRemove));
+ }
+
+ private T mapToEntity(String id, Document data, Class entityClass) {
+ if (data == null) {
+ return null;
+ }
+
+ final CouchbaseDocument converted = new CouchbaseDocument(id);
+ Object readEntity = converter.read(entityClass, (CouchbaseDocument) decodeAndUnwrap(data, converted));
+
+ final BeanWrapper beanWrapper = BeanWrapper.create(readEntity, converter.getConversionService());
+ CouchbasePersistentEntity> persistentEntity = mappingContext.getPersistentEntity(readEntity.getClass());
+ if (persistentEntity.hasVersionProperty()) {
+ beanWrapper.setProperty(persistentEntity.getVersionProperty(), data.cas());
+ }
+
+ return (T) readEntity;
+ }
+
+ @Override
+ public Bucket getCouchbaseBucket() {
+ return this.client;
+ }
+
+ @Override
+ public CouchbaseConverter getConverter() {
+ return this.converter;
}
}
diff --git a/src/main/java/org/springframework/data/couchbase/core/OperationCancellationException.java b/src/main/java/org/springframework/data/couchbase/core/OperationCancellationException.java
index 1eb960ed..933147f3 100644
--- a/src/main/java/org/springframework/data/couchbase/core/OperationCancellationException.java
+++ b/src/main/java/org/springframework/data/couchbase/core/OperationCancellationException.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -27,6 +27,7 @@ public class OperationCancellationException extends TransientDataAccessException
/**
* Constructor for OperationCancellationException.
+ *
* @param msg the detail message
*/
public OperationCancellationException(final String msg) {
@@ -35,6 +36,7 @@ public class OperationCancellationException extends TransientDataAccessException
/**
* Constructor for OperationCancellationException.
+ *
* @param msg the detail message
* @param cause the root cause from the data access API in use
*/
diff --git a/src/main/java/org/springframework/data/couchbase/core/OperationInterruptedException.java b/src/main/java/org/springframework/data/couchbase/core/OperationInterruptedException.java
index ae29899b..e3f1076a 100644
--- a/src/main/java/org/springframework/data/couchbase/core/OperationInterruptedException.java
+++ b/src/main/java/org/springframework/data/couchbase/core/OperationInterruptedException.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -27,6 +27,7 @@ public class OperationInterruptedException extends TransientDataAccessException
/**
* Constructor for OperationInterruptedException.
+ *
* @param msg the detail message
*/
public OperationInterruptedException(final String msg) {
@@ -35,6 +36,7 @@ public class OperationInterruptedException extends TransientDataAccessException
/**
* Constructor for OperationInterruptedException.
+ *
* @param msg the detail message
* @param cause the root cause from the data access API in use
*/
diff --git a/src/main/java/org/springframework/data/couchbase/core/WriteResultChecking.java b/src/main/java/org/springframework/data/couchbase/core/WriteResultChecking.java
index d9e7a4d6..2b711107 100644
--- a/src/main/java/org/springframework/data/couchbase/core/WriteResultChecking.java
+++ b/src/main/java/org/springframework/data/couchbase/core/WriteResultChecking.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013, 2014 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
diff --git a/src/main/java/org/springframework/data/couchbase/core/convert/AbstractCouchbaseConverter.java b/src/main/java/org/springframework/data/couchbase/core/convert/AbstractCouchbaseConverter.java
index f8bb8340..58d8d9b4 100644
--- a/src/main/java/org/springframework/data/couchbase/core/convert/AbstractCouchbaseConverter.java
+++ b/src/main/java/org/springframework/data/couchbase/core/convert/AbstractCouchbaseConverter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
diff --git a/src/main/java/org/springframework/data/couchbase/core/convert/ConverterRegistration.java b/src/main/java/org/springframework/data/couchbase/core/convert/ConverterRegistration.java
index c6ce1e37..2b55fdcc 100644
--- a/src/main/java/org/springframework/data/couchbase/core/convert/ConverterRegistration.java
+++ b/src/main/java/org/springframework/data/couchbase/core/convert/ConverterRegistration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2014 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -86,7 +86,7 @@ class ConverterRegistration {
}
/**
- * Returns whether the source type is a Mongo simple one.
+ * Returns whether the source type is a Couchbase simple one.
*
* @return
*/
@@ -95,7 +95,7 @@ class ConverterRegistration {
}
/**
- * Returns whether the target type is a Mongo simple one.
+ * Returns whether the target type is a Couchbase simple one.
*
* @return
*/
@@ -104,7 +104,7 @@ class ConverterRegistration {
}
/**
- * Returns whether the given type is a type that Mongo can handle basically.
+ * Returns whether the given type is a type that Couchbase can handle basically.
*
* @param type
* @return
diff --git a/src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseConverter.java b/src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseConverter.java
index a8fb6b37..64ffa4fc 100644
--- a/src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseConverter.java
+++ b/src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseConverter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -28,8 +28,8 @@ import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProper
* @author Michael Nitschinger
*/
public interface CouchbaseConverter
- extends EntityConverter,
- CouchbasePersistentProperty, Object, CouchbaseDocument>,
- CouchbaseWriter,
- EntityReader {
+ extends EntityConverter,
+ CouchbasePersistentProperty, Object, CouchbaseDocument>,
+ CouchbaseWriter,
+ EntityReader {
}
diff --git a/src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseDocumentPropertyAccessor.java b/src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseDocumentPropertyAccessor.java
index 9727b81f..824e8561 100644
--- a/src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseDocumentPropertyAccessor.java
+++ b/src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseDocumentPropertyAccessor.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,13 +16,13 @@
package org.springframework.data.couchbase.core.convert;
+import java.util.Map;
+
import org.springframework.context.expression.MapAccessor;
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.TypedValue;
-import java.util.Map;
-
/**
* A property accessor for document properties.
*
diff --git a/src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseTypeMapper.java b/src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseTypeMapper.java
index 105d0d47..93615e11 100644
--- a/src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseTypeMapper.java
+++ b/src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseTypeMapper.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
diff --git a/src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseWriter.java b/src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseWriter.java
index 5d5a6384..f8e9de8f 100644
--- a/src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseWriter.java
+++ b/src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseWriter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -24,5 +24,5 @@ import org.springframework.data.convert.EntityWriter;
* @author Michael Nitschinger
*/
public interface CouchbaseWriter extends
- EntityWriter {
+ EntityWriter {
}
\ No newline at end of file
diff --git a/src/main/java/org/springframework/data/couchbase/core/convert/CustomConversions.java b/src/main/java/org/springframework/data/couchbase/core/convert/CustomConversions.java
index bef04b59..29a16236 100644
--- a/src/main/java/org/springframework/data/couchbase/core/convert/CustomConversions.java
+++ b/src/main/java/org/springframework/data/couchbase/core/convert/CustomConversions.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,26 +16,30 @@
package org.springframework.data.couchbase.core.convert;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.core.convert.support.GenericConversionService;
-import org.springframework.data.convert.JodaTimeConverters;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.util.Assert;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
/**
* Value object to capture custom conversion.
- *
+ *
* Types that can be mapped directly onto JSON are considered simple ones, because they neither need deeper
* inspection nor nested conversion.
*
@@ -69,6 +73,7 @@ public class CustomConversions {
/**
* Create a new instance with a given list of conversers.
+ *
* @param converters the list of custom converters.
*/
public CustomConversions(final List> converters) {
@@ -155,10 +160,12 @@ public class CustomConversions {
for (GenericConverter.ConvertiblePair pair : genericConverter.getConvertibleTypes()) {
register(new ConverterRegistration(pair, isReading, isWriting));
}
- } else if (converter instanceof Converter) {
+ }
+ else if (converter instanceof Converter) {
Class>[] arguments = GenericTypeResolver.resolveTypeArguments(converter.getClass(), Converter.class);
register(new ConverterRegistration(arguments[0], arguments[1], isReading, isWriting));
- } else {
+ }
+ else {
throw new IllegalArgumentException("Unsupported Converter type!");
}
}
@@ -279,7 +286,7 @@ public class CustomConversions {
}
/**
- * Inspects the given {@link org.springframework.core.convert.converter.GenericConverter.ConvertiblePair} for ones
+ * Inspects the given {@link GenericConverter.ConvertiblePair} for ones
* that have a source compatible type as source. Additionally checks assignability of the target type if one is
* given.
*
@@ -289,7 +296,7 @@ public class CustomConversions {
* @return
*/
private static Class> getCustomTarget(Class> sourceType, Class> requestedTargetType,
- Iterable pairs) {
+ Iterable pairs) {
Assert.notNull(sourceType);
Assert.notNull(pairs);
diff --git a/src/main/java/org/springframework/data/couchbase/core/convert/DateConverters.java b/src/main/java/org/springframework/data/couchbase/core/convert/DateConverters.java
index 435534d0..f1e6a5eb 100644
--- a/src/main/java/org/springframework/data/couchbase/core/convert/DateConverters.java
+++ b/src/main/java/org/springframework/data/couchbase/core/convert/DateConverters.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2014 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,21 +16,22 @@
package org.springframework.data.couchbase.core.convert;
-import org.joda.time.DateMidnight;
-import org.joda.time.DateTime;
-import org.joda.time.LocalDate;
-import org.joda.time.LocalDateTime;
-import org.springframework.core.convert.converter.Converter;
-import org.springframework.data.convert.ReadingConverter;
-import org.springframework.data.convert.WritingConverter;
-import org.springframework.util.ClassUtils;
-
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
+import org.joda.time.DateMidnight;
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
+import org.joda.time.LocalDateTime;
+
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.data.convert.ReadingConverter;
+import org.springframework.data.convert.WritingConverter;
+import org.springframework.util.ClassUtils;
+
/**
* Out of the box conversions for java dates and calendars.
*
@@ -38,7 +39,8 @@ import java.util.List;
*/
public final class DateConverters {
- private DateConverters() {}
+ private DateConverters() {
+ }
private static final boolean JODA_TIME_IS_PRESENT = ClassUtils.isPresent("org.joda.time.LocalDate", null);
@@ -85,7 +87,7 @@ public final class DateConverters {
@Override
public Long convert(Calendar source) {
- return source == null ? null : source.getTimeInMillis() / 1000;
+ return source == null ? null : source.getTimeInMillis() / 1000;
}
}
diff --git a/src/main/java/org/springframework/data/couchbase/core/convert/DefaultCouchbaseTypeMapper.java b/src/main/java/org/springframework/data/couchbase/core/convert/DefaultCouchbaseTypeMapper.java
index 2c5f9326..004a241a 100644
--- a/src/main/java/org/springframework/data/couchbase/core/convert/DefaultCouchbaseTypeMapper.java
+++ b/src/main/java/org/springframework/data/couchbase/core/convert/DefaultCouchbaseTypeMapper.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
diff --git a/src/main/java/org/springframework/data/couchbase/core/convert/MappingCouchbaseConverter.java b/src/main/java/org/springframework/data/couchbase/core/convert/MappingCouchbaseConverter.java
index 5c809fa5..75919923 100644
--- a/src/main/java/org/springframework/data/couchbase/core/convert/MappingCouchbaseConverter.java
+++ b/src/main/java/org/springframework/data/couchbase/core/convert/MappingCouchbaseConverter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013-2014 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,6 +16,13 @@
package org.springframework.data.couchbase.core.convert;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.CollectionFactory;
@@ -31,14 +38,20 @@ import org.springframework.data.mapping.AssociationHandler;
import org.springframework.data.mapping.PreferredConstructor.Parameter;
import org.springframework.data.mapping.PropertyHandler;
import org.springframework.data.mapping.context.MappingContext;
-import org.springframework.data.mapping.model.*;
+import org.springframework.data.mapping.model.BeanWrapper;
+import org.springframework.data.mapping.model.DefaultSpELExpressionEvaluator;
+import org.springframework.data.mapping.model.MappingException;
+import org.springframework.data.mapping.model.ParameterValueProvider;
+import org.springframework.data.mapping.model.PersistentEntityParameterValueProvider;
+import org.springframework.data.mapping.model.PropertyValueProvider;
+import org.springframework.data.mapping.model.SpELContext;
+import org.springframework.data.mapping.model.SpELExpressionEvaluator;
+import org.springframework.data.mapping.model.SpELExpressionParameterValueProvider;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
-import java.util.*;
-
/**
* A mapping converter for Couchbase.
*
@@ -154,7 +167,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
protected R read(final CouchbasePersistentEntity entity, final CouchbaseDocument source, final Object parent) {
final DefaultSpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator(source, spELContext);
ParameterValueProvider provider =
- getParameterProvider(entity, source, evaluator, parent);
+ getParameterProvider(entity, source, evaluator, parent);
EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity);
R instance = instantiator.createInstance(entity, provider);
@@ -197,7 +210,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
* @return the actual property value.
*/
protected Object getValueInternal(final CouchbasePersistentProperty property, final CouchbaseDocument source,
- final Object parent) {
+ final Object parent) {
return new CouchbasePropertyValueProvider(source, spELContext, parent).getPropertyValue(property);
}
@@ -211,14 +224,14 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
* @return a new parameter value provider.
*/
private ParameterValueProvider getParameterProvider(
- final CouchbasePersistentEntity> entity, final CouchbaseDocument source,
- final DefaultSpELExpressionEvaluator evaluator, final Object parent) {
+ final CouchbasePersistentEntity> entity, final CouchbaseDocument source,
+ final DefaultSpELExpressionEvaluator evaluator, final Object parent) {
CouchbasePropertyValueProvider provider = new CouchbasePropertyValueProvider(source, evaluator, parent);
PersistentEntityParameterValueProvider parameterProvider =
- new PersistentEntityParameterValueProvider(entity, provider, parent);
+ new PersistentEntityParameterValueProvider(entity, provider, parent);
return new ConverterAwareSpELExpressionParameterValueProvider(evaluator, conversionService, parameterProvider,
- parent);
+ parent);
}
/**
@@ -231,7 +244,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
*/
@SuppressWarnings("unchecked")
protected Map readMap(final TypeInformation> type, final CouchbaseDocument source,
- final Object parent) {
+ final Object parent) {
Assert.notNull(source);
Class> mapType = typeMapper.readType(source, type).getType();
@@ -368,7 +381,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
* @param entity the persistent entity to convert from.
*/
protected void writeInternal(final Object source, final CouchbaseDocument target,
- final CouchbasePersistentEntity> entity) {
+ final CouchbasePersistentEntity> entity) {
if (source == null) {
return;
}
@@ -377,7 +390,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
throw new MappingException("No mapping metadata found for entity of type " + source.getClass().getName());
}
- final BeanWrapper wrapper = BeanWrapper.create(source, conversionService);
+ final BeanWrapper wrapper = BeanWrapper.create(source, conversionService);
final CouchbasePersistentProperty idProperty = entity.getIdProperty();
final CouchbasePersistentProperty versionProperty = entity.getVersionProperty();
@@ -428,7 +441,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
*/
@SuppressWarnings("unchecked")
private void writePropertyInternal(final Object source, final CouchbaseDocument target,
- final CouchbasePersistentProperty prop) {
+ final CouchbasePersistentProperty prop) {
if (source == null) {
return;
}
@@ -459,7 +472,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
addCustomTypeKeyIfNecessary(type, source, propertyDoc);
CouchbasePersistentEntity> entity = isSubtype(prop.getType(), source.getClass()) ? mappingContext
- .getPersistentEntity(source.getClass()) : mappingContext.getPersistentEntity(type);
+ .getPersistentEntity(source.getClass()) : mappingContext.getPersistentEntity(type);
writeInternal(source, propertyDoc, entity);
target.put(name, propertyDoc);
}
@@ -487,7 +500,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
* @return the written couchbase document.
*/
private CouchbaseDocument writeMapInternal(final Map source, final CouchbaseDocument target,
- final TypeInformation> type) {
+ final TypeInformation> type) {
for (Map.Entry entry : source.entrySet()) {
Object key = entry.getKey();
Object val = entry.getValue();
@@ -533,7 +546,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
* @return the created couchbase list.
*/
private CouchbaseList writeCollectionInternal(final Collection> source, final CouchbaseList target,
- final TypeInformation> type) {
+ final TypeInformation> type) {
TypeInformation> componentType = type == null ? null : type.getComponentType();
for (Object element : source) {
@@ -573,7 +586,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class;
Collection items = targetType.getType().isArray() ? new ArrayList() : CollectionFactory
- .createCollection(collectionType, source.size(false));
+ .createCollection(collectionType, source.size(false));
TypeInformation> componentType = targetType.getComponentType();
Class> rawComponentType = componentType == null ? null : componentType.getType();
@@ -709,12 +722,12 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
private final Object parent;
public CouchbasePropertyValueProvider(final CouchbaseDocument source, final SpELContext factory,
- final Object parent) {
+ final Object parent) {
this(source, new DefaultSpELExpressionEvaluator(source, factory), parent);
}
public CouchbasePropertyValueProvider(final CouchbaseDocument source,
- final DefaultSpELExpressionEvaluator evaluator, final Object parent) {
+ final DefaultSpELExpressionEvaluator evaluator, final Object parent) {
Assert.notNull(source);
Assert.notNull(evaluator);
@@ -744,7 +757,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
* A expression parameter value provider.
*/
private class ConverterAwareSpELExpressionParameterValueProvider extends
- SpELExpressionParameterValueProvider {
+ SpELExpressionParameterValueProvider {
private final Object parent;
@@ -757,7 +770,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
@Override
protected T potentiallyConvertSpelValue(final Object object,
- final Parameter parameter) {
+ final Parameter parameter) {
return readValue(object, parameter.getType(), parent);
}
}
diff --git a/src/main/java/org/springframework/data/couchbase/core/convert/translation/JacksonTranslationService.java b/src/main/java/org/springframework/data/couchbase/core/convert/translation/JacksonTranslationService.java
index 6c3b5881..228e8f6a 100644
--- a/src/main/java/org/springframework/data/couchbase/core/convert/translation/JacksonTranslationService.java
+++ b/src/main/java/org/springframework/data/couchbase/core/convert/translation/JacksonTranslationService.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,12 +16,18 @@
package org.springframework.data.couchbase.core.convert.translation;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Map;
+
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.ObjectMapper;
+
import org.springframework.beans.factory.InitializingBean;
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
import org.springframework.data.couchbase.core.mapping.CouchbaseList;
@@ -29,9 +35,6 @@ import org.springframework.data.couchbase.core.mapping.CouchbaseStorable;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mapping.model.SimpleTypeHolder;
-import java.io.*;
-import java.util.Map;
-
/**
* A Jackson JSON Translator that implements the {@link TranslationService} contract.
*
@@ -58,11 +61,10 @@ public class JacksonTranslationService implements TranslationService, Initializi
* Encode a {@link CouchbaseStorable} to a JSON string.
*
* @param source the source document to encode.
- *
* @return the encoded JSON String.
*/
@Override
- public final Object encode(final CouchbaseStorable source) {
+ public final String encode(final CouchbaseStorable source) {
Writer writer = new StringWriter();
try {
@@ -70,7 +72,8 @@ public class JacksonTranslationService implements TranslationService, Initializi
encodeRecursive(source, generator);
generator.close();
writer.close();
- } catch (IOException ex) {
+ }
+ catch (IOException ex) {
throw new RuntimeException("Could not encode JSON", ex);
}
@@ -82,7 +85,6 @@ public class JacksonTranslationService implements TranslationService, Initializi
*
* @param source the source document
* @param generator the JSON generator.
- *
* @throws IOException
*/
private void encodeRecursive(final CouchbaseStorable source, final JsonGenerator generator) throws IOException {
@@ -101,7 +103,8 @@ public class JacksonTranslationService implements TranslationService, Initializi
if (simpleTypeHolder.isSimpleType(clazz) && !isEnumOrClass(clazz)) {
generator.writeObject(value);
- } else {
+ }
+ else {
objectMapper.writeValue(generator, value);
}
@@ -119,11 +122,10 @@ public class JacksonTranslationService implements TranslationService, Initializi
*
* @param source the source formatted document.
* @param target the target of the populated data.
- *
* @return the decoded structure.
*/
@Override
- public final CouchbaseStorable decode(final Object source, final CouchbaseStorable target) {
+ public final CouchbaseStorable decode(final String source, final CouchbaseStorable target) {
try {
JsonParser parser = factory.createParser((String) source);
while (parser.nextToken() != null) {
@@ -131,14 +133,17 @@ public class JacksonTranslationService implements TranslationService, Initializi
if (currentToken == JsonToken.START_OBJECT) {
return decodeObject(parser, (CouchbaseDocument) target);
- } else if (currentToken == JsonToken.START_ARRAY) {
+ }
+ else if (currentToken == JsonToken.START_ARRAY) {
return decodeArray(parser, new CouchbaseList());
- } else {
+ }
+ else {
throw new MappingException("JSON to decode needs to start as array or object!");
}
}
parser.close();
- } catch (IOException ex) {
+ }
+ catch (IOException ex) {
throw new RuntimeException("Could not decode JSON", ex);
}
return target;
@@ -149,7 +154,6 @@ public class JacksonTranslationService implements TranslationService, Initializi
*
* @param parser the JSON parser with the content.
* @param target the target where the content should be stored.
- *
* @throws IOException
* @returns the decoded object.
*/
@@ -160,11 +164,14 @@ public class JacksonTranslationService implements TranslationService, Initializi
while (currentToken != null && currentToken != JsonToken.END_OBJECT) {
if (currentToken == JsonToken.START_OBJECT) {
target.put(fieldName, decodeObject(parser, new CouchbaseDocument()));
- } else if (currentToken == JsonToken.START_ARRAY) {
+ }
+ else if (currentToken == JsonToken.START_ARRAY) {
target.put(fieldName, decodeArray(parser, new CouchbaseList()));
- } else if (currentToken == JsonToken.FIELD_NAME) {
+ }
+ else if (currentToken == JsonToken.FIELD_NAME) {
fieldName = parser.getCurrentName();
- } else {
+ }
+ else {
target.put(fieldName, decodePrimitive(currentToken, parser));
}
@@ -179,7 +186,6 @@ public class JacksonTranslationService implements TranslationService, Initializi
*
* @param parser the JSON parser with the content.
* @param target the target where the content should be stored.
- *
* @throws IOException
* @returns the decoded list.
*/
@@ -189,9 +195,11 @@ public class JacksonTranslationService implements TranslationService, Initializi
while (currentToken != null && currentToken != JsonToken.END_ARRAY) {
if (currentToken == JsonToken.START_OBJECT) {
target.put(decodeObject(parser, new CouchbaseDocument()));
- } else if (currentToken == JsonToken.START_ARRAY) {
+ }
+ else if (currentToken == JsonToken.START_ARRAY) {
target.put(decodeArray(parser, new CouchbaseList()));
- } else {
+ }
+ else {
target.put(decodePrimitive(currentToken, parser));
}
@@ -206,9 +214,7 @@ public class JacksonTranslationService implements TranslationService, Initializi
*
* @param token the type of token.
* @param parser the parser with the content.
- *
* @return the decoded primitve.
- *
* @throws IOException
*/
private Object decodePrimitive(final JsonToken token, final JsonParser parser) throws IOException {
@@ -221,7 +227,8 @@ public class JacksonTranslationService implements TranslationService, Initializi
case VALUE_NUMBER_INT:
try {
return parser.getValueAsInt();
- } catch (final JsonParseException e) {
+ }
+ catch (final JsonParseException e) {
return parser.getValueAsLong();
}
case VALUE_NUMBER_FLOAT:
@@ -229,7 +236,17 @@ public class JacksonTranslationService implements TranslationService, Initializi
case VALUE_NULL:
return null;
default:
- throw new MappingException("Could not decode primitve value " + token);
+ throw new MappingException("Could not decode primitive value " + token);
+ }
+ }
+
+ @Override
+ public T decodeFragment(String source, Class target) {
+ try {
+ return objectMapper.readValue(source, target);
+ }
+ catch (IOException e) {
+ throw new RuntimeException("Cannot decode ad-hoc JSON", e);
}
}
diff --git a/src/main/java/org/springframework/data/couchbase/core/convert/translation/TranslationService.java b/src/main/java/org/springframework/data/couchbase/core/convert/translation/TranslationService.java
index 0c2df4e1..4e9cde91 100644
--- a/src/main/java/org/springframework/data/couchbase/core/convert/translation/TranslationService.java
+++ b/src/main/java/org/springframework/data/couchbase/core/convert/translation/TranslationService.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,6 +16,8 @@
package org.springframework.data.couchbase.core.convert.translation;
+import com.couchbase.client.java.query.QueryRow;
+
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
import org.springframework.data.couchbase.core.mapping.CouchbaseStorable;
@@ -27,12 +29,12 @@ import org.springframework.data.couchbase.core.mapping.CouchbaseStorable;
public interface TranslationService {
/**
- * Encodes a {@link CouchbaseDocument} into the target format.
+ * Encodes a JSON String into the target format.
*
- * @param source the source document to encode.
+ * @param source the source contents to encode.
* @return the encoded document representation.
*/
- Object encode(CouchbaseStorable source);
+ String encode(CouchbaseStorable source);
/**
* Decodes the target format into a {@link CouchbaseDocument}
@@ -41,5 +43,15 @@ public interface TranslationService {
* @param target the target of the populated data.
* @return a properly populated document to work with.
*/
- CouchbaseStorable decode(Object source, CouchbaseStorable target);
+ CouchbaseStorable decode(String source, CouchbaseStorable target);
+
+ /**
+ * Decodes an ad-hoc JSON object into a corresponding "case" class.
+ *
+ * @param source the JSON for the ad-hoc JSON object (from a N1QL {@link QueryRow} for instance).
+ * @param target the target class information.
+ * @param the target class.
+ * @return an ad-hoc instance of the decoded JSON into the corresponding "case" class.
+ */
+ T decodeFragment(String source, Class target);
}
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/BasicCouchbasePersistentEntity.java b/src/main/java/org/springframework/data/couchbase/core/mapping/BasicCouchbasePersistentEntity.java
index 1b70f6b9..16f84223 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/BasicCouchbasePersistentEntity.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/BasicCouchbasePersistentEntity.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -31,7 +31,7 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
* @author Michael Nitschinger
*/
public class BasicCouchbasePersistentEntity extends BasicPersistentEntity
- implements CouchbasePersistentEntity, ApplicationContextAware {
+ implements CouchbasePersistentEntity, ApplicationContextAware {
/**
* Contains the evaluation context.
@@ -40,6 +40,7 @@ public class BasicCouchbasePersistentEntity extends BasicPersistentEntity typeInformation) {
@@ -55,9 +56,9 @@ public class BasicCouchbasePersistentEntity extends BasicPersistentEntity extends BasicPersistentEntity
* This object is used to gather information out of properties on objects that need to be persisted. For example, it
* supports overriding of the actual property name by providing custom annotations.
*
* @author Michael Nitschinger
*/
public class BasicCouchbasePersistentProperty
- extends AnnotationBasedPersistentProperty
- implements CouchbasePersistentProperty {
+ extends AnnotationBasedPersistentProperty
+ implements CouchbasePersistentProperty {
private final FieldNamingStrategy fieldNamingStrategy;
@@ -50,11 +50,11 @@ public class BasicCouchbasePersistentProperty
* @param simpleTypeHolder the type holder.
*/
public BasicCouchbasePersistentProperty(final Field field, final PropertyDescriptor propertyDescriptor,
- final CouchbasePersistentEntity> owner, final SimpleTypeHolder simpleTypeHolder,
- final FieldNamingStrategy fieldNamingStrategy) {
+ final CouchbasePersistentEntity> owner, final SimpleTypeHolder simpleTypeHolder,
+ final FieldNamingStrategy fieldNamingStrategy) {
super(field, propertyDescriptor, owner, simpleTypeHolder);
this.fieldNamingStrategy = fieldNamingStrategy == null ? PropertyNameFieldNamingStrategy.INSTANCE
- : fieldNamingStrategy;
+ : fieldNamingStrategy;
}
/**
@@ -67,14 +67,14 @@ public class BasicCouchbasePersistentProperty
/**
* Returns the field name of the property.
- *
+ *
* The field name can be different from the actual property name by using a
* custom annotation.
*/
@Override
public String getFieldName() {
org.springframework.data.couchbase.core.mapping.Field annotation = getField().
- getAnnotation(org.springframework.data.couchbase.core.mapping.Field.class);
+ getAnnotation(org.springframework.data.couchbase.core.mapping.Field.class);
if (annotation != null && StringUtils.hasText(annotation.value())) {
return annotation.value();
@@ -84,7 +84,7 @@ public class BasicCouchbasePersistentProperty
if (!StringUtils.hasText(fieldName)) {
throw new MappingException(String.format("Invalid (null or empty) field name returned for property %s by %s!",
- this, fieldNamingStrategy.getClass()));
+ this, fieldNamingStrategy.getClass()));
}
return fieldName;
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseDocument.java b/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseDocument.java
index d4ee881e..07a1de7f 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseDocument.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseDocument.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,20 +16,20 @@
package org.springframework.data.couchbase.core.mapping;
-import org.springframework.data.mapping.model.SimpleTypeHolder;
-
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import org.springframework.data.mapping.model.SimpleTypeHolder;
+
/**
* A {@link CouchbaseDocument} is an abstract representation of a document stored inside Couchbase Server.
- *
+ *
* It acts like a {@link HashMap}, but only allows those types to be written that are supported by the underlying
* storage format, which is currently JSON. Note that JSON conversion is not happening here, but performed at a
* different stage based on the payload stored in the {@link CouchbaseDocument}.
- *
+ *
* In addition to the actual content, meta data is also stored. This especially refers to the document ID and its
* expiration time. Note that this information is not mandatory, since documents can be nested and therefore only the
* topmost document most likely has an ID.
@@ -115,7 +115,7 @@ public class CouchbaseDocument implements CouchbaseStorable {
*
* @param key the key of the attribute.
* @return the value to which the specified key is mapped, or
- * null if does not contain a mapping for the key.
+ * null if does not contain a mapping for the key.
*/
public final Object get(final String key) {
return payload.get(key);
@@ -123,7 +123,7 @@ public class CouchbaseDocument implements CouchbaseStorable {
/**
* Returns the current payload, including all recursive elements.
- *
+ *
* It either returns the raw results or makes sure that the recusrive elements
* are also exported properly.
*
@@ -134,7 +134,8 @@ public class CouchbaseDocument implements CouchbaseStorable {
for (Map.Entry entry : payload.entrySet()) {
if (entry.getValue() instanceof CouchbaseDocument) {
toExport.put(entry.getKey(), ((CouchbaseDocument) entry.getValue()).export());
- } else if (entry.getValue() instanceof CouchbaseList) {
+ }
+ else if (entry.getValue() instanceof CouchbaseList) {
toExport.put(entry.getKey(), ((CouchbaseList) entry.getValue()).export());
}
}
@@ -187,7 +188,8 @@ public class CouchbaseDocument implements CouchbaseStorable {
for (Object value : payload.values()) {
if (value instanceof CouchbaseDocument) {
totalSize += ((CouchbaseDocument) value).size(true);
- } else if (value instanceof CouchbaseList) {
+ }
+ else if (value instanceof CouchbaseList) {
totalSize += ((CouchbaseList) value).size(true);
}
}
@@ -197,7 +199,7 @@ public class CouchbaseDocument implements CouchbaseStorable {
/**
* Returns the underlying payload.
- *
+ *
* Note that unlike {@link #export()}, the nested objects are not converted, so the "raw" map is returned.
*
* @return the underlying payload.
@@ -208,7 +210,7 @@ public class CouchbaseDocument implements CouchbaseStorable {
/**
* Returns the expiration time of the document.
- *
+ *
* If the expiration time is 0, then the document will be persisted until
* deleted manually ("forever").
*
@@ -220,7 +222,7 @@ public class CouchbaseDocument implements CouchbaseStorable {
/**
* Set the expiration time of the document.
- *
+ *
* If the expiration time is 0, then the document will be persisted until
* deleted manually ("forever").
*
@@ -255,19 +257,19 @@ public class CouchbaseDocument implements CouchbaseStorable {
/**
* Verifies that only values of a certain and supported type
* can be stored.
- *
+ *
* If this is not the case, a {@link IllegalArgumentException} is
* thrown.
*
* @param value the object to verify its type.
*/
private void verifyValueType(final Object value) {
- if(value == null) {
+ if (value == null) {
return;
}
final Class> clazz = value.getClass();
if (simpleTypeHolder.isSimpleType(clazz)) {
- return;
+ return;
}
throw new IllegalArgumentException("Attribute of type " + clazz.getCanonicalName() + " cannot be stored and must be converted.");
}
@@ -280,9 +282,9 @@ public class CouchbaseDocument implements CouchbaseStorable {
@Override
public String toString() {
return "CouchbaseDocument{" +
- "id=" + id +
- ", exp=" + expiration +
- ", payload=" + payload +
- '}';
+ "id=" + id +
+ ", exp=" + expiration +
+ ", payload=" + payload +
+ '}';
}
}
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseList.java b/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseList.java
index 96c67f6a..ef791031 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseList.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseList.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,16 +16,16 @@
package org.springframework.data.couchbase.core.mapping;
-import org.springframework.data.mapping.model.SimpleTypeHolder;
-
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import org.springframework.data.mapping.model.SimpleTypeHolder;
+
/**
* A {@link CouchbaseList} is an abstract list that represents an array stored in a (most of the times JSON) document.
- *
+ *
* This {@link CouchbaseList} is part of the potentially nested structure inside one or more
* {@link CouchbaseDocument}s. It can also contain them recursively, depending on how the document is modeled.
*/
@@ -78,9 +78,10 @@ public class CouchbaseList implements CouchbaseStorable {
additionalTypes.add(CouchbaseDocument.class);
additionalTypes.add(CouchbaseList.class);
if (simpleTypeHolder != null) {
- this.simpleTypeHolder = new SimpleTypeHolder(additionalTypes, simpleTypeHolder);
- } else {
- this.simpleTypeHolder = new SimpleTypeHolder(additionalTypes, true);
+ this.simpleTypeHolder = new SimpleTypeHolder(additionalTypes, simpleTypeHolder);
+ }
+ else {
+ this.simpleTypeHolder = new SimpleTypeHolder(additionalTypes, true);
}
}
@@ -133,7 +134,8 @@ public class CouchbaseList implements CouchbaseStorable {
for (Object value : payload) {
if (value instanceof CouchbaseDocument) {
totalSize += ((CouchbaseDocument) value).size(true);
- } else if (value instanceof CouchbaseList) {
+ }
+ else if (value instanceof CouchbaseList) {
totalSize += ((CouchbaseList) value).size(true);
}
}
@@ -143,7 +145,7 @@ public class CouchbaseList implements CouchbaseStorable {
/**
* Returns the current payload, including all recursive elements.
- *
+ *
* It either returns the raw results or makes sure that the recusrive elements
* are also exported properly.
*
@@ -157,7 +159,8 @@ public class CouchbaseList implements CouchbaseStorable {
if (entry instanceof CouchbaseDocument) {
toExport.remove(elem);
toExport.add(elem, ((CouchbaseDocument) entry).export());
- } else if (entry instanceof CouchbaseList) {
+ }
+ else if (entry instanceof CouchbaseList) {
toExport.remove(elem);
toExport.add(elem, ((CouchbaseList) entry).export());
}
@@ -188,14 +191,14 @@ public class CouchbaseList implements CouchbaseStorable {
/**
* Verifies that only values of a certain and supported type
* can be stored.
- *
+ *
* If this is not the case, a {@link IllegalArgumentException} is
* thrown.
*
* @param value the object to verify its type.
*/
private void verifyValueType(final Object value) {
- if(value == null) {
+ if (value == null) {
return;
}
@@ -205,7 +208,7 @@ public class CouchbaseList implements CouchbaseStorable {
}
throw new IllegalArgumentException("Attribute of type "
- + clazz.getCanonicalName() + "can not be stored and must be converted.");
+ + clazz.getCanonicalName() + "can not be stored and must be converted.");
}
/**
@@ -216,7 +219,7 @@ public class CouchbaseList implements CouchbaseStorable {
@Override
public String toString() {
return "CouchbaseList{" +
- "payload=" + payload +
- '}';
+ "payload=" + payload +
+ '}';
}
}
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseMappingContext.java b/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseMappingContext.java
index 89730dda..36d677ee 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseMappingContext.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseMappingContext.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,6 +16,9 @@
package org.springframework.data.couchbase.core.mapping;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
@@ -25,9 +28,6 @@ import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.util.TypeInformation;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.Field;
-
/**
* Default implementation of a {@link org.springframework.data.mapping.context.MappingContext} for Couchbase using
* {@link BasicCouchbasePersistentEntity} and {@link BasicCouchbasePersistentProperty} as primary abstractions.
@@ -35,8 +35,8 @@ import java.lang.reflect.Field;
* @author Michael Nitschinger
*/
public class CouchbaseMappingContext
- extends AbstractMappingContext, CouchbasePersistentProperty>
- implements ApplicationContextAware {
+ extends AbstractMappingContext, CouchbasePersistentProperty>
+ implements ApplicationContextAware {
/**
* Contains the application context to configure the application.
@@ -58,7 +58,7 @@ public class CouchbaseMappingContext
* Defaults to a strategy using the plain property name.
*
* @param fieldNamingStrategy the {@link FieldNamingStrategy} to be used to determine the field name if no manual
- * mapping is applied.
+ * mapping is applied.
*/
public void setFieldNamingStrategy(final FieldNamingStrategy fieldNamingStrategy) {
this.fieldNamingStrategy = fieldNamingStrategy == null ? DEFAULT_NAMING_STRATEGY : fieldNamingStrategy;
@@ -91,7 +91,7 @@ public class CouchbaseMappingContext
*/
@Override
protected CouchbasePersistentProperty createPersistentProperty(final Field field, final PropertyDescriptor descriptor,
- final BasicCouchbasePersistentEntity> owner, final SimpleTypeHolder simpleTypeHolder) {
+ final BasicCouchbasePersistentEntity> owner, final SimpleTypeHolder simpleTypeHolder) {
return new BasicCouchbasePersistentProperty(field, descriptor, owner, simpleTypeHolder, fieldNamingStrategy);
}
@@ -101,9 +101,9 @@ public class CouchbaseMappingContext
* @param applicationContext the application context to be assigned.
* @throws BeansException if the context can not be set properly.
*/
- @Override
- public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
- context = applicationContext;
- }
+ @Override
+ public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
+ context = applicationContext;
+ }
}
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbasePersistentEntity.java b/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbasePersistentEntity.java
index 7ce3e4bb..cfaf7e5e 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbasePersistentEntity.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbasePersistentEntity.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -24,13 +24,13 @@ import org.springframework.data.mapping.PersistentEntity;
* @author Michael Nitschinger
*/
public interface CouchbasePersistentEntity extends
- PersistentEntity {
+ PersistentEntity {
/**
* Returns the expiry time for the document.
*
* @return the expiration time.
*/
- int getExpiry();
+ int getExpiry();
}
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbasePersistentProperty.java b/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbasePersistentProperty.java
index be133dda..dd2cce4d 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbasePersistentProperty.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbasePersistentProperty.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -27,7 +27,7 @@ public interface CouchbasePersistentProperty extends PersistentProperty
* The field name can be different from the actual property name by using a custom annotation.
*/
String getFieldName();
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseSimpleTypes.java b/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseSimpleTypes.java
index 7e83efe5..6d450894 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseSimpleTypes.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseSimpleTypes.java
@@ -1,18 +1,37 @@
+/*
+ * Copyright 2012-2015 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.mapping;
-import org.springframework.data.mapping.model.SimpleTypeHolder;
-
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
+import com.couchbase.client.java.document.RawJsonDocument;
+import com.couchbase.client.java.document.json.JsonArray;
+
+import org.springframework.data.mapping.model.SimpleTypeHolder;
+
public abstract class CouchbaseSimpleTypes {
static {
Set> simpleTypes = new HashSet>();
- simpleTypes.add(CouchbaseDocument.class);
- simpleTypes.add(CouchbaseList.class);
+ simpleTypes.add(RawJsonDocument.class);
+ simpleTypes.add(JsonArray.class);
COUCHBASE_SIMPLE_TYPES = Collections.unmodifiableSet(simpleTypes);
}
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseStorable.java b/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseStorable.java
index 217fe348..088b1bb9 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseStorable.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseStorable.java
@@ -1,8 +1,24 @@
+/*
+ * Copyright 2012-2015 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.mapping;
/**
* Marker Interface to identify either a {@link CouchbaseDocument} or a {@link CouchbaseList}.
- *
+ *
* This interface will be extended in the future to refactor the needed infrastructure into the common interface.
*
* @author Michael Nitschinger
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/Document.java b/src/main/java/org/springframework/data/couchbase/core/mapping/Document.java
index 0d5cf7f3..4dff8e6b 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/Document.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/Document.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,9 +16,13 @@
package org.springframework.data.couchbase.core.mapping;
-import org.springframework.data.annotation.Persistent;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
-import java.lang.annotation.*;
+import org.springframework.data.annotation.Persistent;
/**
* Identifies a domain object to be persisted to Couchbase.
@@ -28,9 +32,9 @@ import java.lang.annotation.*;
@Persistent
@Inherited
@Retention(RetentionPolicy.RUNTIME)
-@Target({ ElementType.TYPE })
+@Target({ElementType.TYPE})
public @interface Document {
-
+
/**
* An optional expiry time for the document.
*/
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/Field.java b/src/main/java/org/springframework/data/couchbase/core/mapping/Field.java
index 2793dc69..5bb09e30 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/Field.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/Field.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/event/AbstractCouchbaseEventListener.java b/src/main/java/org/springframework/data/couchbase/core/mapping/event/AbstractCouchbaseEventListener.java
index f96cc187..d947add2 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/event/AbstractCouchbaseEventListener.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/event/AbstractCouchbaseEventListener.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -18,6 +18,7 @@ package org.springframework.data.couchbase.core.mapping.event;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
import org.springframework.context.ApplicationListener;
import org.springframework.core.GenericTypeResolver;
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
@@ -42,25 +43,28 @@ public class AbstractCouchbaseEventListener implements ApplicationListener event) {
- E source = (E) event.getSource();
- // Check for matching domain type and invoke callbacks
- if (source != null && !domainClass.isAssignableFrom(source.getClass())) {
- return;
- }
+ E source = (E) event.getSource();
+ // Check for matching domain type and invoke callbacks
+ if (source != null && !domainClass.isAssignableFrom(source.getClass())) {
+ return;
+ }
if (event instanceof BeforeDeleteEvent) {
onBeforeDelete(event.getSource(), event.getDocument());
return;
- } else if (event instanceof AfterDeleteEvent) {
+ }
+ else if (event instanceof AfterDeleteEvent) {
onAfterDelete(event.getSource(), event.getDocument());
return;
}
if (event instanceof BeforeConvertEvent) {
onBeforeConvert(source);
- } else if (event instanceof BeforeSaveEvent) {
+ }
+ else if (event instanceof BeforeSaveEvent) {
onBeforeSave(source, event.getDocument());
- } else if (event instanceof AfterSaveEvent) {
+ }
+ else if (event instanceof AfterSaveEvent) {
onAfterSave(source, event.getDocument());
}
}
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/event/AfterDeleteEvent.java b/src/main/java/org/springframework/data/couchbase/core/mapping/event/AfterDeleteEvent.java
index 607ef88a..29c850c8 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/event/AfterDeleteEvent.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/event/AfterDeleteEvent.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/event/AfterSaveEvent.java b/src/main/java/org/springframework/data/couchbase/core/mapping/event/AfterSaveEvent.java
index 517ec20d..174ce998 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/event/AfterSaveEvent.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/event/AfterSaveEvent.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/event/BeforeConvertEvent.java b/src/main/java/org/springframework/data/couchbase/core/mapping/event/BeforeConvertEvent.java
index 8a6fec1e..c1055abd 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/event/BeforeConvertEvent.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/event/BeforeConvertEvent.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/event/BeforeDeleteEvent.java b/src/main/java/org/springframework/data/couchbase/core/mapping/event/BeforeDeleteEvent.java
index 9cc83ba8..e5a15760 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/event/BeforeDeleteEvent.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/event/BeforeDeleteEvent.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/event/BeforeSaveEvent.java b/src/main/java/org/springframework/data/couchbase/core/mapping/event/BeforeSaveEvent.java
index 397cc7ca..0cbe7451 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/event/BeforeSaveEvent.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/event/BeforeSaveEvent.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/event/CouchbaseMappingEvent.java b/src/main/java/org/springframework/data/couchbase/core/mapping/event/CouchbaseMappingEvent.java
index de5da3d4..c2a975be 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/event/CouchbaseMappingEvent.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/event/CouchbaseMappingEvent.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/event/LoggingEventListener.java b/src/main/java/org/springframework/data/couchbase/core/mapping/event/LoggingEventListener.java
index 4793fbe6..9edaa2e7 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/event/LoggingEventListener.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/event/LoggingEventListener.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -18,6 +18,7 @@ package org.springframework.data.couchbase.core.mapping.event;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
import org.springframework.context.ApplicationListener;
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
@@ -31,10 +32,14 @@ public class LoggingEventListener extends AbstractCouchbaseEventListener
private static final Logger LOGGER = LoggerFactory.getLogger(LoggingEventListener.class);
@Override
- public void onBeforeDelete(Object source, CouchbaseDocument doc) { LOGGER.info("onBeforeDelete: {}, {}", source, doc); }
+ public void onBeforeDelete(Object source, CouchbaseDocument doc) {
+ LOGGER.info("onBeforeDelete: {}, {}", source, doc);
+ }
@Override
- public void onAfterDelete(Object source, CouchbaseDocument doc) { LOGGER.info("onAfterDelete: {} {}", source, doc); }
+ public void onAfterDelete(Object source, CouchbaseDocument doc) {
+ LOGGER.info("onAfterDelete: {} {}", source, doc);
+ }
@Override
public void onAfterSave(Object source, CouchbaseDocument doc) {
diff --git a/src/main/java/org/springframework/data/couchbase/core/mapping/event/ValidatingCouchbaseEventListener.java b/src/main/java/org/springframework/data/couchbase/core/mapping/event/ValidatingCouchbaseEventListener.java
index 353bebd2..9860fc58 100644
--- a/src/main/java/org/springframework/data/couchbase/core/mapping/event/ValidatingCouchbaseEventListener.java
+++ b/src/main/java/org/springframework/data/couchbase/core/mapping/event/ValidatingCouchbaseEventListener.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,14 +16,16 @@
package org.springframework.data.couchbase.core.mapping.event;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
-import org.springframework.util.Assert;
+import java.util.Set;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
-import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
+import org.springframework.util.Assert;
/**
* javax.validation dependant entities validator. When it is registered as Spring component its automatically invoked
@@ -49,10 +51,12 @@ public class ValidatingCouchbaseEventListener extends AbstractCouchbaseEventList
}
@Override
- @SuppressWarnings({ "rawtypes", "unchecked" })
+ @SuppressWarnings({"rawtypes", "unchecked"})
public void onBeforeSave(Object source, CouchbaseDocument dbo) {
- LOG.debug("Validating object: {}", source);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Validating object: {}", source);
+ }
Set violations = validator.validate(source);
if (!violations.isEmpty()) {
diff --git a/src/main/java/org/springframework/data/couchbase/core/package-info.java b/src/main/java/org/springframework/data/couchbase/core/package-info.java
new file mode 100644
index 00000000..ddb60dfc
--- /dev/null
+++ b/src/main/java/org/springframework/data/couchbase/core/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2012-2015 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.
+ */
+
+/**
+ * This package contains the specific implementations and core classes for
+ * Spring Data Couchbase internals. It also contains Couchbase implementation
+ * to support the Spring Data template abstraction.
+ *
+ * The template provides lower level access to the underlying database and also serves as the foundation for
+ * repositories. Any time a repository is too high-level for you needs chances are good that the templates will serve
+ * you well.
+ */
+package org.springframework.data.couchbase.core;
\ No newline at end of file
diff --git a/src/main/java/org/springframework/data/couchbase/monitor/AbstractMonitor.java b/src/main/java/org/springframework/data/couchbase/monitor/AbstractMonitor.java
deleted file mode 100644
index 531dc944..00000000
--- a/src/main/java/org/springframework/data/couchbase/monitor/AbstractMonitor.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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 com.couchbase.client.CouchbaseClient;
-import org.springframework.web.client.RestTemplate;
-
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Base class to encapsulate common configuration settings.
- *
- * @author Michael Nitschinger
- */
-public abstract class AbstractMonitor {
-
- private CouchbaseClient client;
-
- private RestTemplate template = new RestTemplate();
-
- protected AbstractMonitor(final CouchbaseClient client) {
- this.client = client;
- }
-
- public CouchbaseClient getClient() {
- return client;
- }
-
- protected RestTemplate getTemplate() {
- return template;
- }
-
- protected String randomAvailableHostname() {
- List available = (ArrayList) client.getAvailableServers();
- Collections.shuffle(available);
- return ((InetSocketAddress) available.get(0)).getHostName();
- }
-
- /**
- * Fetches stats for all nodes.
- *
- * @return stats for each node
- */
- protected Map> getStats() {
- return client.getStats();
- }
-
- /**
- * Returns stats for an individual node.
- */
- protected Map getStats(SocketAddress node) {
- return getStats().get(node);
- }
-
-}
diff --git a/src/main/java/org/springframework/data/couchbase/monitor/ClientInfo.java b/src/main/java/org/springframework/data/couchbase/monitor/ClientInfo.java
index ba863f39..ad8f0e99 100644
--- a/src/main/java/org/springframework/data/couchbase/monitor/ClientInfo.java
+++ b/src/main/java/org/springframework/data/couchbase/monitor/ClientInfo.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,28 +16,35 @@
package org.springframework.data.couchbase.monitor;
-import com.couchbase.client.CouchbaseClient;
+import java.net.InetAddress;
+
+import com.couchbase.client.java.Bucket;
+import com.couchbase.client.java.bucket.BucketInfo;
+
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedResource;
-import java.net.SocketAddress;
-
/**
* Exposes basic client information.
*
* @author Michael Nitschinger
+ * @author Simon Baslé
*/
-@ManagedResource(description = "Client Information")
-public class ClientInfo extends AbstractMonitor {
+@ManagedResource(description = "Client Information")
+public class ClientInfo {
- public ClientInfo(final CouchbaseClient client) {
- super(client);
+ private final Bucket bucket;
+ private final BucketInfo info;
+
+ public ClientInfo(final Bucket bucket) {
+ this.bucket = bucket;
+ this.info = bucket.bucketManager().info();
}
@ManagedAttribute(description = "Hostnames of connected nodes")
public String getHostNames() {
StringBuilder result = new StringBuilder();
- for (SocketAddress node : getStats().keySet()) {
+ for (InetAddress node : info.nodeList()) {
result.append(node.toString()).append(",");
}
return result.toString();
@@ -45,17 +52,9 @@ public class ClientInfo extends AbstractMonitor {
@ManagedAttribute(description = "Number of connected nodes")
public int getNumberOfNodes() {
- return getStats().keySet().size();
+ return info.nodeCount();
}
- @ManagedAttribute(description = "Number of connected active nodes")
- public int getNumberOfActiveNodes() {
- return getClient().getAvailableServers().size();
- }
-
- @ManagedAttribute(description = "Number of connected inactive nodes")
- public int getNumberOfInactiveNodes() {
- return getClient().getUnavailableServers().size();
- }
+ //TODO obtain count of available nodes vs unavailable ones and expose it
}
diff --git a/src/main/java/org/springframework/data/couchbase/monitor/ClusterInfo.java b/src/main/java/org/springframework/data/couchbase/monitor/ClusterInfo.java
index a9e5700e..282d0fc9 100644
--- a/src/main/java/org/springframework/data/couchbase/monitor/ClusterInfo.java
+++ b/src/main/java/org/springframework/data/couchbase/monitor/ClusterInfo.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2012-2015 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
+ * 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,
@@ -16,23 +16,36 @@
package org.springframework.data.couchbase.monitor;
-import com.couchbase.client.CouchbaseClient;
+import java.net.InetAddress;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+
+import com.couchbase.client.java.Bucket;
+import com.couchbase.client.java.bucket.BucketInfo;
+
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedMetric;
import org.springframework.jmx.export.annotation.ManagedResource;
-
-import java.util.HashMap;
+import org.springframework.web.client.RestTemplate;
/**
* Exposes basic cluster information.
*
* @author Michael Nitschinger
+ * @author Simon Baslé
*/
-@ManagedResource(description = "Cluster Information")
-public class ClusterInfo extends AbstractMonitor {
+@ManagedResource(description = "Cluster Information")
+public class ClusterInfo {
- public ClusterInfo(final CouchbaseClient client) {
- super(client);
+ private final RestTemplate template;
+ private final Bucket bucket;
+ private final BucketInfo info;
+
+ public ClusterInfo(final Bucket bucket) {
+ this.template = new RestTemplate();
+ this.bucket = bucket;
+ this.info = bucket.bucketManager().info();
}
@ManagedMetric(description = "Total RAM assigned")
@@ -80,27 +93,34 @@ public class ClusterInfo extends AbstractMonitor {
* converted to long.
*
* @param value the value to convert.
- *
* @return the converted value.
*/
private long convertPotentialLong(Object value) {
if (value instanceof Integer) {
return new Long((Integer) value);
- } else if (value instanceof Long) {
+ }
+ else if (value instanceof Long) {
return (Long) value;
- } else {
+ }
+ else {
throw new IllegalStateException("Cannot convert value to long: " + value);
}
}
+ protected String randomAvailableHostname() {
+ List available = info.nodeList();
+ Collections.shuffle(available);
+ return available.get(0).getHostName();
+ }
+
private HashMap fetchPoolInfo() {
- return getTemplate().getForObject("http://"
- + randomAvailableHostname() + ":8091/pools/default", HashMap.class);
+ return template.getForObject("http://"
+ + randomAvailableHostname() + ":8091/pools/default", HashMap.class);
}
private HashMap parseStorageTotals() {
HashMap stats = fetchPoolInfo();
- return (HashMap) stats.get("storageTotals");
+ return (HashMap) stats.get("storageTotals");
}
}
diff --git a/src/main/java/org/springframework/data/couchbase/monitor/package-info.java b/src/main/java/org/springframework/data/couchbase/monitor/package-info.java
new file mode 100644
index 00000000..d64a4c07
--- /dev/null
+++ b/src/main/java/org/springframework/data/couchbase/monitor/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * This package contains all classes related to monitoring the Couchbase cluster,
+ * statistics that will be exposed as JMX beans.
+ */
+package org.springframework.data.couchbase.monitor;
\ No newline at end of file
diff --git a/src/main/java/org/springframework/data/couchbase/repository/package-info.java b/src/main/java/org/springframework/data/couchbase/repository/package-info.java
new file mode 100644
index 00000000..b01e083a
--- /dev/null
+++ b/src/main/java/org/springframework/data/couchbase/repository/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * This package contains the Couchbase implementation to support the Spring Data repository abstraction.
+ *
+ * The goal of Spring Data repository abstraction is to significantly reduce the amount of boilerplate code required to
+ * implement data access layers for various persistence stores.
+ */
+package org.springframework.data.couchbase.repository;
\ No newline at end of file
diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/ViewBasedCouchbaseQuery.java b/src/main/java/org/springframework/data/couchbase/repository/query/ViewBasedCouchbaseQuery.java
index ee74bd8a..d37e8bfc 100644
--- a/src/main/java/org/springframework/data/couchbase/repository/query/ViewBasedCouchbaseQuery.java
+++ b/src/main/java/org/springframework/data/couchbase/repository/query/ViewBasedCouchbaseQuery.java
@@ -16,7 +16,8 @@
package org.springframework.data.couchbase.repository.query;
-import com.couchbase.client.protocol.views.Query;
+import com.couchbase.client.java.view.ViewQuery;
+
import org.springframework.data.couchbase.core.CouchbaseOperations;
import org.springframework.data.repository.query.QueryMethod;
import org.springframework.data.repository.query.RepositoryQuery;
@@ -39,21 +40,21 @@ public class ViewBasedCouchbaseQuery implements RepositoryQuery {
@Override
public Object execute(Object[] runtimeParams) {
- Query query = null;
+ ViewQuery query = null;
for (Object param : runtimeParams) {
- if (param instanceof Query) {
- query = (Query) param;
+ if (param instanceof ViewQuery) {
+ query = (ViewQuery) param;
} else {
throw new IllegalStateException("Unknown query param: " + param);
}
}
if (query == null) {
- query = new Query();
+ query = ViewQuery.from(designDocName(), viewName());
}
- query.setReduce(false);
+ query.reduce(false);
- return operations.findByView(designDocName(), viewName(), query, method.getEntityInformation().getJavaType());
+ return operations.findByView(query, method.getEntityInformation().getJavaType());
}
@Override
diff --git a/src/main/java/org/springframework/data/couchbase/repository/support/SimpleCouchbaseRepository.java b/src/main/java/org/springframework/data/couchbase/repository/support/SimpleCouchbaseRepository.java
index fea6205e..50e97488 100644
--- a/src/main/java/org/springframework/data/couchbase/repository/support/SimpleCouchbaseRepository.java
+++ b/src/main/java/org/springframework/data/couchbase/repository/support/SimpleCouchbaseRepository.java
@@ -16,20 +16,21 @@
package org.springframework.data.couchbase.repository.support;
-import com.couchbase.client.protocol.views.ComplexKey;
-import com.couchbase.client.protocol.views.Query;
-import com.couchbase.client.protocol.views.ViewResponse;
-import com.couchbase.client.protocol.views.ViewRow;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.couchbase.client.java.document.json.JsonArray;
+import com.couchbase.client.java.view.ViewQuery;
+import com.couchbase.client.java.view.ViewResult;
+import com.couchbase.client.java.view.ViewRow;
+
import org.springframework.data.couchbase.core.CouchbaseOperations;
import org.springframework.data.couchbase.core.view.View;
import org.springframework.data.couchbase.repository.CouchbaseRepository;
import org.springframework.data.couchbase.repository.query.CouchbaseEntityInformation;
import org.springframework.util.Assert;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* Repository base implementation for Couchbase.
*
@@ -130,30 +131,36 @@ public class SimpleCouchbaseRepository implements Co
@Override
public Iterable findAll() {
final ResolvedView resolvedView = determineView();
- return couchbaseOperations.findByView(resolvedView.getDesignDocument(), resolvedView.getViewName(), new Query().setReduce(false), entityInformation.getJavaType());
+ ViewQuery query = ViewQuery.from(resolvedView.getDesignDocument(), resolvedView.getViewName());
+ query.reduce(false);
+ return couchbaseOperations.findByView(query, entityInformation.getJavaType());
}
@Override
public Iterable findAll(final Iterable ids) {
- Query query = new Query();
- query.setReduce(false);
- query.setKeys(ComplexKey.of(ids));
-
final ResolvedView resolvedView = determineView();
- return couchbaseOperations.findByView(resolvedView.getDesignDocument(), resolvedView.getViewName(), query, entityInformation.getJavaType());
+ ViewQuery query = ViewQuery.from(resolvedView.getDesignDocument(), resolvedView.getViewName());
+ query.reduce(false);
+ JsonArray keys = JsonArray.create();
+ for (ID id : ids) {
+ keys.add(id);
+ }
+ query.keys(keys);
+
+ return couchbaseOperations.findByView(query, entityInformation.getJavaType());
}
@Override
public long count() {
- Query query = new Query();
- query.setReduce(true);
-
final ResolvedView resolvedView = determineView();
- ViewResponse response = couchbaseOperations.queryView(resolvedView.getDesignDocument(), resolvedView.getViewName(), query);
+ ViewQuery query = ViewQuery.from(resolvedView.getDesignDocument(), resolvedView.getViewName());
+ query.reduce(true);
+
+ ViewResult response = couchbaseOperations.queryView(query);
long count = 0;
for (ViewRow row : response) {
- count += Long.parseLong(row.getValue());
+ count += Long.parseLong(String.valueOf(row.value()));
}
return count;
@@ -161,13 +168,13 @@ public class SimpleCouchbaseRepository implements Co
@Override
public void deleteAll() {
- Query query = new Query();
- query.setReduce(false);
-
final ResolvedView resolvedView = determineView();
- ViewResponse response = couchbaseOperations.queryView(resolvedView.getDesignDocument(), resolvedView.getViewName(), query);
+ ViewQuery query = ViewQuery.from(resolvedView.getDesignDocument(), resolvedView.getViewName());
+ query.reduce(false);
+
+ ViewResult response = couchbaseOperations.queryView(query);
for (ViewRow row : response) {
- couchbaseOperations.remove(row.getId());
+ couchbaseOperations.remove(row.id());
}
}
diff --git a/src/main/resources/META-INF/spring.schemas b/src/main/resources/META-INF/spring.schemas
index 349e29ce..6b43469e 100644
--- a/src/main/resources/META-INF/spring.schemas
+++ b/src/main/resources/META-INF/spring.schemas
@@ -1,2 +1,4 @@
http\://www.springframework.org/schema/data/couchbase/spring-couchbase-1.0.xsd=org/springframework/data/couchbase/config/spring-couchbase-1.0.xsd
-http\://www.springframework.org/schema/data/couchbase/spring-couchbase.xsd=org/springframework/data/couchbase/config/spring-couchbase-1.0.xsd
\ No newline at end of file
+http\://www.springframework.org/schema/data/couchbase/spring-couchbase-2.0.xsd=org/springframework/data/couchbase/config/spring-couchbase-2.0.xsd
+http\://www.springframework.org/schema/data/couchbase/spring-couchbase-env-2.0.xsd=org/springframework/data/couchbase/config/spring-couchbase-env-2.0.xsd
+http\://www.springframework.org/schema/data/couchbase/spring-couchbase.xsd=org/springframework/data/couchbase/config/spring-couchbase-2.0.xsd
\ No newline at end of file
diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt
index 7806f98a..76739127 100644
--- a/src/main/resources/changelog.txt
+++ b/src/main/resources/changelog.txt
@@ -1,6 +1,22 @@
Spring Data Couchbase Changelog
===============================
+New Major Version: 2.0
+----------------------
+This version is a complete rewrite of the Spring Data Couchbase project, using the newer 2.x generation
+of the Couchbase Java SDK.
+
+Changes in version 2.0.0.M1 (2015-07-03)
+----------------------------------------
+ * DATACOUCH-135 - Migrate to Couchbase SDK 2.2.0-dp, with support for N1QL in template
+
+
+=================================================================================
+| Below are older release notes for the 1st generation of Spring Data Couchbase |
+| (based on the 1.x Couchbase Java SDK) |
+=================================================================================
+
+
Changes in version 1.1.6.RELEASE (2015-07-01)
---------------------------------------------
* DATACOUCH-133 - Fix typos in README.
@@ -224,4 +240,4 @@ Release Notes - Spring Data Couchbase - Version 1.0 M1 - 2013-09-11
* [DATACOUCH-4] - Add Apache 2 license headers
* [DATACOUCH-8] - Overhaul README with uptodate information
* [DATACOUCH-9] - Add View query support to the Template
- * [DATACOUCH-10] - Upgrade parent pom to 1.1.0.RELEASE
+ * [DATACOUCH-10] - Upgrade parent pom to 1.1.0.RELEASE
\ No newline at end of file
diff --git a/src/main/resources/notice.txt b/src/main/resources/notice.txt
index a728bdd0..942ed0ad 100644
--- a/src/main/resources/notice.txt
+++ b/src/main/resources/notice.txt
@@ -1,4 +1,4 @@
-Spring Data Couchbase 1.4 M1
+Spring Data Couchbase 2.0 BETA
Copyright (c) [2013-2015] Couchbase / Pivotal Software, Inc.
This product is licensed to you under the Apache License, Version 2.0 (the "License").
@@ -6,5 +6,5 @@ You may not use this product except in compliance with the License.
This product may include a number of subcomponents with
separate copyright notices and license terms. Your use of the source
-code for the these subcomponents is subject to the terms and
-conditions of the subcomponent's license, as noted in the LICENSE file.
+code for these subcomponents is subject to the terms and
+conditions of the subcomponent's license, as noted in the LICENSE file.
\ No newline at end of file
diff --git a/src/main/resources/org/springframework/data/couchbase/config/spring-couchbase-2.0.xsd b/src/main/resources/org/springframework/data/couchbase/config/spring-couchbase-2.0.xsd
new file mode 100644
index 00000000..669cb5f1
--- /dev/null
+++ b/src/main/resources/org/springframework/data/couchbase/config/spring-couchbase-2.0.xsd
@@ -0,0 +1,166 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The reference to a Bucket object.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/org/springframework/data/couchbase/config/spring-couchbase-env-2.0.xsd b/src/main/resources/org/springframework/data/couchbase/config/spring-couchbase-env-2.0.xsd
new file mode 100644
index 00000000..91e8f61f
--- /dev/null
+++ b/src/main/resources/org/springframework/data/couchbase/config/spring-couchbase-env-2.0.xsd
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/java/org/springframework/data/couchbase/BucketCreator.java b/src/test/java/org/springframework/data/couchbase/BucketCreator.java
deleted file mode 100644
index 151d1d9c..00000000
--- a/src/test/java/org/springframework/data/couchbase/BucketCreator.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package org.springframework.data.couchbase;
-
-import com.couchbase.client.ClusterManager;
-import com.couchbase.client.clustermanager.BucketType;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.impl.client.BasicCredentialsProvider;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.http.ResponseEntity;
-import org.springframework.http.client.ClientHttpRequestFactory;
-import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
-import org.springframework.web.client.HttpClientErrorException;
-import org.springframework.web.client.RestTemplate;
-
-import java.net.URI;
-import java.util.Arrays;
-
-public class BucketCreator implements InitializingBean {
-
- private final Logger logger = LoggerFactory.getLogger(BucketCreator.class);
-
- private final String hostUri;
- private final String adminUser;
- private final String adminPass;
-
- public BucketCreator(String host, String user, String pass) {
- hostUri = host;
- adminUser = user;
- adminPass = pass;
- }
-
- @Override
- public void afterPropertiesSet() throws Exception {
- DefaultHttpClient client = new DefaultHttpClient();
- BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
- credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(adminUser, adminPass));
- client.setCredentialsProvider(credentialsProvider);
- ClientHttpRequestFactory rf = new HttpComponentsClientHttpRequestFactory(client);
-
- RestTemplate template = new RestTemplate(rf);
-
- String fullUri = "http://" + hostUri + ":8091/pools/default/buckets/default";
-
- ResponseEntity entity = null;
- try {
- entity = template.getForEntity(fullUri, String.class);
- } catch (HttpClientErrorException ex) {
- logger.info("Got execpetion while looking for bucket: " + ex.getMessage());
- if (ex.getMessage().equals("404 Object Not Found")) {
- logger.info("Creating default bucket with admin credentials.");
- createBucket();
- return;
- } else {
- throw new RuntimeException("Could not see if bucket is already created.", ex);
- }
- }
-
- logger.info("Checking for bucket returned status code " + entity.getStatusCode());
- }
-
- private void createBucket() throws Exception {
- ClusterManager bucketManager =
- new ClusterManager(Arrays.asList(URI.create("http://" + hostUri + ":8091")), adminUser, adminPass);
- bucketManager.createDefaultBucket(BucketType.COUCHBASE, 128, 0, true);
-
- logger.info("Finished creating bucket, sleeping for warmup.");
- Thread.sleep(5000);
- bucketManager.shutdown();
- }
-
-}
diff --git a/src/test/java/org/springframework/data/couchbase/TestApplicationConfig.java b/src/test/java/org/springframework/data/couchbase/TestApplicationConfig.java
deleted file mode 100644
index 7ce4257c..00000000
--- a/src/test/java/org/springframework/data/couchbase/TestApplicationConfig.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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;
-
-import com.couchbase.client.CouchbaseClient;
-import com.couchbase.client.CouchbaseConnectionFactoryBuilder;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.DependsOn;
-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;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * @author Michael Nitschinger
- */
-@Configuration
-public class TestApplicationConfig extends AbstractCouchbaseConfiguration {
-
- @Autowired
- private Environment env;
-
- @Bean
- public String couchbaseAdminUser() {
- return env.getProperty("couchbase.adminUser", "Administrator");
- }
-
- @Bean
- public String couchbaseAdminPassword() {
- return env.getProperty("couchbase.adminUser", "password");
- }
-
- @Override
- protected List bootstrapHosts() {
- return Arrays.asList(env.getProperty("couchbase.host", "127.0.0.1"));
- }
-
- @Override
- protected String getBucketName() {
- return env.getProperty("couchbase.bucket", "default");
- }
-
- @Override
- protected String getBucketPassword() {
- return env.getProperty("couchbase.password", "");
- }
-
- @Bean
- public BucketCreator bucketCreator() throws Exception {
- return new BucketCreator(bootstrapHosts().get(0), couchbaseAdminUser(), couchbaseAdminPassword());
- }
-
- @Bean
- @Override
- @DependsOn("bucketCreator")
- public CouchbaseClient couchbaseClient() throws Exception {
- setLoggerProperty(couchbaseLogger());
-
- CouchbaseConnectionFactoryBuilder builder = new CouchbaseConnectionFactoryBuilder();
- builder.setOpTimeout(10000); // using a higher timeout for tests to reduce flakiness
-
- return new CouchbaseClient(builder.buildCouchbaseConnection(
- bootstrapUris(bootstrapHosts()),
- getBucketName(),
- getBucketPassword()
- ));
- }
-
- @Override
- public CouchbaseTemplate couchbaseTemplate() throws Exception {
- CouchbaseTemplate template = super.couchbaseTemplate();
- template.setWriteResultChecking(WriteResultChecking.LOG);
- return template;
- }
-}
diff --git a/src/test/java/org/springframework/data/couchbase/UnitTestApplicationConfig.java b/src/test/java/org/springframework/data/couchbase/UnitTestApplicationConfig.java
new file mode 100644
index 00000000..62be5f77
--- /dev/null
+++ b/src/test/java/org/springframework/data/couchbase/UnitTestApplicationConfig.java
@@ -0,0 +1,67 @@
+package org.springframework.data.couchbase;
+
+import java.util.Collections;
+import java.util.List;
+
+import com.couchbase.client.java.Bucket;
+import com.couchbase.client.java.Cluster;
+import com.couchbase.client.java.CouchbaseBucket;
+import com.couchbase.client.java.CouchbaseCluster;
+import com.couchbase.client.java.env.CouchbaseEnvironment;
+import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+
+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 UnitTestApplicationConfig extends AbstractCouchbaseConfiguration {
+
+ @Bean
+ public String couchbaseAdminUser() {
+ return "someLogin";
+ }
+
+ @Bean
+ public String couchbaseAdminPassword() {
+ return "somePassword";
+ }
+
+ @Override
+ protected List getBootstrapHosts() {
+ return Collections.singletonList("192.1.2.3");
+ }
+
+ @Override
+ protected String getBucketName() {
+ return "someBucket";
+ }
+
+ @Override
+ protected String getBucketPassword() {
+ return "someBucketPassword";
+ }
+
+ @Override
+ public Cluster couchbaseCluster() throws Exception {
+ return Mockito.mock(CouchbaseCluster.class);
+ }
+
+ @Override
+ public Bucket couchbaseClient() throws Exception {
+ return Mockito.mock(CouchbaseBucket.class);
+ }
+
+ @Override
+ public CouchbaseTemplate couchbaseTemplate() throws Exception {
+ CouchbaseTemplate template = super.couchbaseTemplate();
+ template.setWriteResultChecking(WriteResultChecking.LOG);
+ return template;
+ }
+}
diff --git a/src/test/java/org/springframework/data/couchbase/cache/CouchbaseCacheManagerTests.java b/src/test/java/org/springframework/data/couchbase/cache/CouchbaseCacheManagerTests.java
deleted file mode 100644
index 46f4e377..00000000
--- a/src/test/java/org/springframework/data/couchbase/cache/CouchbaseCacheManagerTests.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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.cache;
-
-import com.couchbase.client.CouchbaseClient;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.cache.Cache;
-import org.springframework.data.couchbase.TestApplicationConfig;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-import java.util.HashMap;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-/**
- * Verifies the correct functionality of the CouchbaseCacheManager.
- *
- * @author Michael Nitschinger
- */
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes = TestApplicationConfig.class)
-public class CouchbaseCacheManagerTests {
-
- /**
- * Contains a reference to the actual CouchbaseClient.
- */
- @Autowired
- private CouchbaseClient client;
-
- /**
- * Tests the main functionality of the manager: loading the caches.
- */
- @Test
- public void testCacheInit() {
- HashMap instances =
- new HashMap();
- instances.put("test", client);
-
- CouchbaseCacheManager manager = new CouchbaseCacheManager(instances);
- manager.afterPropertiesSet();
-
- assertEquals(instances, manager.getClients());
-
- Cache cache = manager.getCache("test");
-
- assertNotNull(cache);
-
- assertEquals(cache.getClass(), CouchbaseCache.class);
- assertEquals(((CouchbaseCache) cache).getName(), "test");
- assertEquals(((CouchbaseCache) cache).getTtl(), 0); // default TTL value
- assertEquals(((CouchbaseCache) cache).getNativeCache(), client);
- }
-
- /**
- * Test cache creation with custom TTL values.
- */
- @Test
- public void testCacheInitWithTtl() {
- HashMap instances = new HashMap();
- instances.put("cache1", client);
- instances.put("cache2", client);
-
- HashMap ttlConfiguration = new HashMap();
- ttlConfiguration.put("cache1", 100);
- ttlConfiguration.put("cache2", 200);
-
- CouchbaseCacheManager manager = new CouchbaseCacheManager(instances, ttlConfiguration);
- manager.afterPropertiesSet();
-
- assertEquals(instances, manager.getClients());
-
- Cache cache1 = manager.getCache("cache1");
- Cache cache2 = manager.getCache("cache2");
-
- assertNotNull(cache1);
- assertNotNull(cache2);
-
- assertEquals(cache1.getClass(), CouchbaseCache.class);
- assertEquals(cache2.getClass(), CouchbaseCache.class);
-
- assertEquals(((CouchbaseCache) cache1).getName(), "cache1");
- assertEquals(((CouchbaseCache) cache2).getName(), "cache2");
-
- assertEquals(((CouchbaseCache) cache1).getTtl(), 100);
- assertEquals(((CouchbaseCache) cache2).getTtl(), 200);
-
- assertEquals(((CouchbaseCache) cache1).getNativeCache(), client);
- assertEquals(((CouchbaseCache) cache2).getNativeCache(), client);
- }
-
-}
diff --git a/src/test/java/org/springframework/data/couchbase/cache/CouchbaseCacheTests.java b/src/test/java/org/springframework/data/couchbase/cache/CouchbaseCacheTests.java
deleted file mode 100644
index 62ef68a3..00000000
--- a/src/test/java/org/springframework/data/couchbase/cache/CouchbaseCacheTests.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * 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.cache;
-
-import com.couchbase.client.CouchbaseClient;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.cache.Cache.ValueWrapper;
-import org.springframework.data.couchbase.TestApplicationConfig;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-import java.io.Serializable;
-
-import static org.junit.Assert.*;
-
-/**
- * Tests the CouchbaseCache class and verifies its functionality.
- *
- * @author Michael Nitschinger
- * @author Konrad Król
- */
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes = TestApplicationConfig.class)
-public class CouchbaseCacheTests {
-
- /**
- * Contains a reference to the actual CouchbaseClient.
- */
- @Autowired
- private CouchbaseClient client;
-
- /**
- * Simple name of the cache bucket to create.
- */
- private String cacheName = "test";
-
- /**
- * Tests the basic Cache construction functionality.
- */
- @Test
- public void testConstruction() {
- CouchbaseCache cache = new CouchbaseCache(cacheName, client);
-
- assertEquals(cacheName, cache.getName());
- assertEquals(client, cache.getNativeCache());
- }
-
- /**
- * Verifies set() and get() of cache objects.
- */
- @Test
- public void testGetSet() {
- CouchbaseCache cache = new CouchbaseCache(cacheName, client);
-
- String key = "couchbase-cache-test";
- String value = "Hello World!";
- cache.put(key, value);
-
- String stored = (String) client.get(key);
- assertNotNull(stored);
- assertEquals(value, stored);
-
- ValueWrapper loaded = cache.get(key);
- assertEquals(value, loaded.get());
- }
-
- /**
- * Verifies set() with TTL value.
- */
- @Test
- public void testSetWithTtl() throws InterruptedException {
- CouchbaseCache cache = new CouchbaseCache(cacheName, client, 1); // cache for 1 second
-
- String key = "couchbase-cache-test";
- String value = "Hello World!";
- cache.put(key, value);
-
- // wait for TTL to expire (double time of TTL)
- Thread.sleep(2000);
-
- String stored = (String) client.get(key);
- assertNull(stored);
- }
-
- @Test
- public void testGetSetWithCast() {
- CouchbaseCache cache = new CouchbaseCache(cacheName, client);
-
- String key = "couchbase-cache-user";
- User user = new User();
- user.firstname = "Michael";
-
- cache.put(key, user);
-
- User loaded = cache.get(key, User.class);
- assertNotNull(loaded);
- assertEquals(user.firstname, loaded.firstname);
- }
-
- /**
- * Verifies the deletion of cache objects.
- *
- * @throws Exception
- */
- @Test
- public void testEvict() throws Exception {
- CouchbaseCache cache = new CouchbaseCache(cacheName, client);
-
- String key = "couchbase-cache-test";
- String value = "Hello World!";
-
- Boolean success = client.set(key, 0, value).get();
- assertTrue(success);
-
- cache.evict(key);
- Object result = client.get(key);
- assertNull(result);
- }
-
- /**
- * Putting into cache on the same key not null value, and then null value,
- * results in null object
- */
- @Test
- public void testSettingNullAndGetting() {
- CouchbaseCache cache = new CouchbaseCache(cacheName, client);
-
- String key = "couchbase-cache-test";
- String value = "Hello World!";
-
- cache.put(key, value);
- cache.put(key, null);
-
- assertNull(cache.get(key));
- }
-
- static class User implements Serializable {
- public String firstname;
- }
-
-}
diff --git a/src/test/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfigurationTests.java b/src/test/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfigurationTests.java
deleted file mode 100644
index 36fc876c..00000000
--- a/src/test/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfigurationTests.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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 com.couchbase.client.CouchbaseClient;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.context.annotation.Bean;
-import org.springframework.data.couchbase.TestApplicationConfig;
-import org.springframework.data.couchbase.core.mapping.Document;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Unit test for {@link AbstractCouchbaseConfiguration}
- *
- * @author Michael Nitschinger
- */
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes = TestApplicationConfig.class)
-public class AbstractCouchbaseConfigurationTests {
-
- /**
- * Contains a reference to the actual CouchbaseClient.
- */
- @Autowired
- private CouchbaseClient client;
-
- @Test
- public void usesConfigClassPackageAsBaseMappingPackage() throws Exception {
- AbstractCouchbaseConfiguration config = new SampleCouchbaseConfiguration();
- assertEquals(config.getMappingBasePackage(), SampleCouchbaseConfiguration.class.getPackage().getName());
- assertEquals(config.getInitialEntitySet().size(), 1);
- assertTrue(config.getInitialEntitySet().contains(Entity.class));
- }
-
- class SampleCouchbaseConfiguration extends AbstractCouchbaseConfiguration {
-
- @Override
- protected List bootstrapHosts() {
- return null;
- }
-
- @Override
- protected String getBucketName() {
- return null;
- }
-
- @Override
- protected String getBucketPassword() {
- return null;
- }
-
- @Bean
- @Override
- public CouchbaseClient couchbaseClient() throws Exception {
- return client;
- }
- }
-
- @Document
- static class Entity {
-
- }
-}
diff --git a/src/test/java/org/springframework/data/couchbase/config/CouchbaseBucketParserTest.java b/src/test/java/org/springframework/data/couchbase/config/CouchbaseBucketParserTest.java
new file mode 100644
index 00000000..932e1d29
--- /dev/null
+++ b/src/test/java/org/springframework/data/couchbase/config/CouchbaseBucketParserTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2012-2015 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.hamcrest.CoreMatchers.*;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+import java.util.List;
+
+import com.couchbase.client.java.env.CouchbaseEnvironment;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.ConstructorArgumentValues;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.BeanDefinitionReader;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.beans.factory.support.GenericBeanDefinition;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.core.io.ClassPathResource;
+
+public class CouchbaseBucketParserTest {
+
+
+ private static DefaultListableBeanFactory factory;
+
+ @BeforeClass
+ public static void setUp() {
+ factory = new DefaultListableBeanFactory();
+ BeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
+ int n = reader.loadBeanDefinitions(new ClassPathResource("configurations/couchbaseBucket-bean.xml"));
+ System.out.println(n);
+ }
+
+ @AfterClass
+ public static void tearDown() {
+ }
+
+ @Test
+ public void testDefaultBucketNoCluster() {
+ BeanDefinition def = factory.getBeanDefinition("bucketDefaultNoCluster");
+
+ assertThat(def, is(notNullValue()));
+ assertThat(def.getConstructorArgumentValues().getArgumentCount(), is(equalTo(1)));
+ assertThat(def.getPropertyValues().size(), is(equalTo(0)));
+
+ ConstructorArgumentValues.ValueHolder holder = def.getConstructorArgumentValues()
+ .getArgumentValue(0, Object.class);
+ assertThat(holder.getValue(), is(instanceOf(RuntimeBeanReference.class)));
+
+ RuntimeBeanReference clusterRef = (RuntimeBeanReference) holder.getValue();
+
+ assertThat(clusterRef.getBeanName(), is(equalTo(BeanNames.COUCHBASE_CLUSTER)));
+ }
+
+ @Test
+ public void testDefaultBucket() throws Exception {
+ BeanDefinition def = factory.getBeanDefinition("bucketDefault");
+
+ assertThat(def, is(notNullValue()));
+ assertThat(def.getConstructorArgumentValues().getArgumentCount(), is(equalTo(1)));
+ assertThat(def.getPropertyValues().size(), is(equalTo(0)));
+
+ ConstructorArgumentValues.ValueHolder holder = def.getConstructorArgumentValues()
+ .getArgumentValue(0, Object.class);
+ assertThat(holder.getValue(), is(instanceOf(RuntimeBeanReference.class)));
+
+ RuntimeBeanReference clusterRef = (RuntimeBeanReference) holder.getValue();
+
+ assertThat(clusterRef.getBeanName(), is(equalTo("clusterDefault")));
+ }
+
+ @Test
+ public void testBucketWithName() throws Exception {
+ BeanDefinition def = factory.getBeanDefinition("bucketWithName");
+
+ assertThat(def, is(notNullValue()));
+ assertThat(def.getConstructorArgumentValues().getArgumentCount(), is(equalTo(2)));
+ assertThat(def.getPropertyValues().size(), is(equalTo(0)));
+
+ ConstructorArgumentValues.ValueHolder holder = def.getConstructorArgumentValues()
+ .getArgumentValue(0, Object.class);
+ assertThat(holder.getValue(), is(instanceOf(RuntimeBeanReference.class)));
+
+ RuntimeBeanReference clusterRef = (RuntimeBeanReference) holder.getValue();
+ assertThat(clusterRef.getBeanName(), is(equalTo("clusterDefault")));
+
+ ConstructorArgumentValues.ValueHolder nameHolder = def.getConstructorArgumentValues()
+ .getArgumentValue(1, Object.class);
+ assertThat(nameHolder.getValue(), is(instanceOf(String.class)));
+ assertThat(nameHolder.getValue().toString(), is((equalTo("toto"))));
+ }
+
+ @Test
+ public void testBucketWithNameAndPassword() throws Exception {
+ BeanDefinition def = factory.getBeanDefinition("bucketWithNameAndPassword");
+
+ assertThat(def, is(notNullValue()));
+ assertThat(def.getConstructorArgumentValues().getArgumentCount(), is(equalTo(3)));
+ assertThat(def.getPropertyValues().size(), is(equalTo(0)));
+
+ ConstructorArgumentValues.ValueHolder holder = def.getConstructorArgumentValues()
+ .getArgumentValue(0, Object.class);
+ assertThat(holder.getValue(), is(instanceOf(RuntimeBeanReference.class)));
+
+ RuntimeBeanReference clusterRef = (RuntimeBeanReference) holder.getValue();
+ assertThat(clusterRef.getBeanName(), is(equalTo("clusterDefault")));
+
+ ConstructorArgumentValues.ValueHolder nameHolder = def.getConstructorArgumentValues()
+ .getArgumentValue(1, Object.class);
+ assertThat(nameHolder.getValue(), is(instanceOf(String.class)));
+ assertThat(nameHolder.getValue().toString(), is((equalTo("test"))));
+
+ ConstructorArgumentValues.ValueHolder passwordHolder = def.getConstructorArgumentValues()
+ .getArgumentValue(2, Object.class);
+ assertThat(passwordHolder.getValue(), is(instanceOf(String.class)));
+ assertThat(passwordHolder.getValue().toString(), is((equalTo("123"))));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/org/springframework/data/couchbase/config/CouchbaseClusterParserTest.java b/src/test/java/org/springframework/data/couchbase/config/CouchbaseClusterParserTest.java
new file mode 100644
index 00000000..1cfdcb16
--- /dev/null
+++ b/src/test/java/org/springframework/data/couchbase/config/CouchbaseClusterParserTest.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2012-2015 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.hamcrest.CoreMatchers.*;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+import java.util.List;
+
+import com.couchbase.client.java.env.CouchbaseEnvironment;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.ConstructorArgumentValues;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.BeanDefinitionReader;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.beans.factory.support.GenericBeanDefinition;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.core.io.ClassPathResource;
+
+public class CouchbaseClusterParserTest {
+
+
+ private static DefaultListableBeanFactory factory;
+
+ @BeforeClass
+ public static void setUp() {
+ factory = new DefaultListableBeanFactory();
+ BeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
+ int n = reader.loadBeanDefinitions(new ClassPathResource("configurations/couchbaseCluster-bean.xml"));
+ System.out.println(n);
+ }
+
+ @AfterClass
+ public static void tearDown() {
+ }
+
+ @Test
+ public void testClusterWithoutSpecificEnv() {
+ BeanDefinition def = factory.getBeanDefinition("clusterDefault");
+
+ assertThat(def, is(notNullValue()));
+ assertThat(def.getConstructorArgumentValues().getArgumentCount(), is(equalTo(1)));
+ assertThat(def.getPropertyValues().size(), is(equalTo(0)));
+ assertThat(def.getFactoryMethodName(), is(equalTo("create")));
+
+ ConstructorArgumentValues.ValueHolder holder = def.getConstructorArgumentValues()
+ .getArgumentValue(0, CouchbaseEnvironment.class);
+
+ assertThat(holder.getValue(), instanceOf(RuntimeBeanReference.class));
+ RuntimeBeanReference envRef = (RuntimeBeanReference) holder.getValue();
+
+ assertThat(envRef.getBeanName(), is(equalTo("couchbaseEnv")));
+ }
+
+ @Test
+ public void testClusterWithNodes() {
+ BeanDefinition def = factory.getBeanDefinition("clusterWithNodes");
+
+ assertThat(def, is(notNullValue()));
+ assertThat(def.getConstructorArgumentValues().getArgumentCount(), is(equalTo(2)));
+ assertThat(def.getPropertyValues().size(), is(equalTo(0)));
+ assertThat(def.getFactoryMethodName(), is(equalTo("create")));
+
+ ConstructorArgumentValues.ValueHolder holder = def.getConstructorArgumentValues()
+ .getArgumentValue(1, List.class);
+ assertThat(holder.getValue(), is(instanceOf(List.class)));
+ List nodes = (List) holder.getValue();
+
+ assertThat(nodes.size(), is(equalTo(2)));
+ assertThat((String) nodes.get(0), is(equalTo("192.1.2.3")));
+ assertThat((String) nodes.get(1), is(equalTo("192.4.5.6")));
+ }
+
+ @Test
+ public void testClusterWithEnvInline() {
+ BeanDefinition def = factory.getBeanDefinition("clusterWithEnvInline");
+
+ assertThat(def, is(notNullValue()));
+ assertThat(def.getConstructorArgumentValues().getArgumentCount(), is(equalTo(1)));
+ assertThat(def.getPropertyValues().size(), is(equalTo(0)));
+
+ ConstructorArgumentValues.ValueHolder holder = def.getConstructorArgumentValues()
+ .getArgumentValue(0, CouchbaseEnvironment.class);
+ GenericBeanDefinition envDef = (GenericBeanDefinition) holder.getValue();
+
+ assertThat(envDef.getBeanClassName(), is(equalTo(CouchbaseEnvironmentFactoryBean.class.getName())));
+ assertThat("unexpected attribute", envDef.getPropertyValues().contains("managementTimeout"));
+ }
+
+ @Test
+ public void testClusterWithEnvRef() {
+ BeanDefinition def = factory.getBeanDefinition("clusterWithEnvRef");
+
+ assertThat(def, is(notNullValue()));
+ assertThat(def.getConstructorArgumentValues().getArgumentCount(), is(equalTo(1)));
+ assertThat(def.getPropertyValues().size(), is(equalTo(0)));
+
+ ConstructorArgumentValues.ValueHolder holder = def.getConstructorArgumentValues()
+ .getArgumentValue(0, CouchbaseEnvironment.class);
+
+ assertThat(holder.getValue(), instanceOf(RuntimeBeanReference.class));
+ RuntimeBeanReference envRef = (RuntimeBeanReference) holder.getValue();
+
+ assertThat(envRef.getBeanName(), is(equalTo("someEnv")));
+ }
+ @Test
+ public void testClusterConfigurationPrecedence() {
+ BeanDefinition def = factory.getBeanDefinition("clusterWithAll");
+
+ assertThat(def, is(notNullValue()));
+ assertThat(def.getConstructorArgumentValues().getArgumentCount(), is(equalTo(2)));
+ assertThat(def.getPropertyValues().size(), is(equalTo(0)));
+ assertThat(def.getFactoryMethodName(), is(equalTo("create")));
+
+ assertThat(def.getConstructorArgumentValues().getIndexedArgumentValues().get(0).getValue(),
+ instanceOf(GenericBeanDefinition.class));
+ assertThat(def.getConstructorArgumentValues().getIndexedArgumentValues().get(1).getValue(),
+ instanceOf(List.class));
+
+ ConstructorArgumentValues.ValueHolder holderEnv = def.getConstructorArgumentValues()
+ .getArgumentValue(0, CouchbaseEnvironment.class);
+ GenericBeanDefinition envDef = (GenericBeanDefinition) holderEnv.getValue();
+
+ assertThat(envDef.getBeanClassName(), is(equalTo(CouchbaseEnvironmentFactoryBean.class.getName())));
+ assertThat("unexpected attribute", envDef.getPropertyValues().contains("autoreleaseAfter"));
+
+ ConstructorArgumentValues.ValueHolder holderNodes = def.getConstructorArgumentValues()
+ .getArgumentValue(1, List.class);
+ List nodes = (List) holderNodes.getValue();
+
+ assertThat(nodes.size(), is(equalTo(2)));
+ assertThat((String) nodes.get(0), is(equalTo("2.2.2.2")));
+ assertThat((String) nodes.get(1), is(equalTo("4.4.4.4")));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentParserTest.java b/src/test/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentParserTest.java
new file mode 100644
index 00000000..ad0766f2
--- /dev/null
+++ b/src/test/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentParserTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2012-2015 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.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+import com.couchbase.client.core.retry.BestEffortRetryStrategy;
+import com.couchbase.client.core.retry.FailFastRetryStrategy;
+import com.couchbase.client.java.env.CouchbaseEnvironment;
+import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import org.springframework.beans.factory.support.BeanDefinitionReader;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.context.support.GenericApplicationContext;
+import org.springframework.core.io.ClassPathResource;
+
+public class CouchbaseEnvironmentParserTest {
+
+ private static GenericApplicationContext context;
+
+ @BeforeClass
+ public static void setUp() {
+ DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
+ BeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
+ reader.loadBeanDefinitions(new ClassPathResource("configurations/couchbaseEnv-bean.xml"));
+ context = new GenericApplicationContext(factory);
+ context.refresh();
+ }
+
+ @Test
+ public void testParsingRetryStrategyFailFast() throws Exception {
+ CouchbaseEnvironment env = context.getBean("envWithFailFast", CouchbaseEnvironment.class);
+
+ assertThat(env.retryStrategy(), is(instanceOf(FailFastRetryStrategy.class)));
+ }
+
+ @Test
+ public void testParsingRetryStrategyBestEffort() throws Exception {
+ CouchbaseEnvironment env = context.getBean("envWithBestEffort", CouchbaseEnvironment.class);
+
+ assertThat(env.retryStrategy(), is(instanceOf(BestEffortRetryStrategy.class)));
+ }
+
+ @Test
+ public void testAllDefaultsOverridden() {
+ CouchbaseEnvironment env = context.getBean("envWithNoDefault", CouchbaseEnvironment.class);
+ CouchbaseEnvironment defaultEnv = DefaultCouchbaseEnvironment.create();
+
+ assertThat(env, is(instanceOf(DefaultCouchbaseEnvironment.class)));
+
+ assertThat(env.managementTimeout(), is(equalTo(1L)));
+ assertThat(env.queryTimeout(), is(equalTo(2L)));
+ assertThat(env.viewTimeout(), is(equalTo(3L)));
+ assertThat(env.kvTimeout(), is(equalTo(4L)));
+ assertThat(env.connectTimeout(), is(equalTo(5L)));
+ assertThat(env.disconnectTimeout(), is(equalTo(6L)));
+ assertThat(env.dnsSrvEnabled(), allOf(equalTo(true), not(defaultEnv.dnsSrvEnabled())));
+
+ //TODO activate test when dcp can be enabled on the environment (add it in the xml)
+// assertThat(env.dcpEnabled(), allOf(equalTo(true), not(defaultEnv.dcpEnabled())));
+ assertThat(env.sslEnabled(), allOf(equalTo(true), not(defaultEnv.sslEnabled())));
+ assertThat(env.sslKeystoreFile(), is(equalTo("test")));
+ assertThat(env.sslKeystorePassword(), is(equalTo("test")));
+ assertThat(env.queryEnabled(), allOf(equalTo(true), not(defaultEnv.queryEnabled())));
+ assertThat(env.queryPort(), is(equalTo(7)));
+ assertThat(env.bootstrapHttpEnabled(), allOf(equalTo(false), not(defaultEnv.bootstrapHttpEnabled())));
+ assertThat(env.bootstrapCarrierEnabled(), allOf(equalTo(false), not(defaultEnv.bootstrapCarrierEnabled())));
+ assertThat(env.bootstrapHttpDirectPort(), is(equalTo(8)));
+ assertThat(env.bootstrapHttpSslPort(), is(equalTo(9)));
+ assertThat(env.bootstrapCarrierDirectPort(), is(equalTo(10)));
+ assertThat(env.bootstrapCarrierSslPort(), is(equalTo(11)));
+ assertThat(env.ioPoolSize(), is(equalTo(12)));
+ assertThat(env.computationPoolSize(), is(equalTo(13)));
+ assertThat(env.responseBufferSize(), is(equalTo(14)));
+ assertThat(env.requestBufferSize(), is(equalTo(15)));
+ assertThat(env.kvEndpoints(), is(equalTo(16)));
+ assertThat(env.viewEndpoints(), is(equalTo(17)));
+ assertThat(env.queryEndpoints(), is(equalTo(18)));
+ assertThat(env.retryStrategy(), is(instanceOf(FailFastRetryStrategy.class)));
+ assertThat(env.maxRequestLifetime(), is(equalTo(19L)));
+ assertThat(env.keepAliveInterval(), is(equalTo(20L)));
+ assertThat(env.autoreleaseAfter(), is(equalTo(21L)));
+ assertThat(env.bufferPoolingEnabled(), allOf(equalTo(false), not(defaultEnv.bufferPoolingEnabled())));
+ }
+
+ @AfterClass
+ public static void tearDown() {
+ context.close();
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/org/springframework/data/couchbase/config/CouchbaseParserIntegrationTests.java b/src/test/java/org/springframework/data/couchbase/config/CouchbaseParserIntegrationTests.java
deleted file mode 100644
index 7b25521b..00000000
--- a/src/test/java/org/springframework/data/couchbase/config/CouchbaseParserIntegrationTests.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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 org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationContext;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-import static org.junit.Assert.*;
-
-/**
- * @author Michael Nitschinger
- */
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations = "classpath:namespace/couchbase-bean.xml")
-public class CouchbaseParserIntegrationTests {
- @Autowired
- ApplicationContext ctx;
-
- @Test
- public void readsCouchbaseAttributesCorrectly() {
- assertTrue(ctx.containsBean("couchbase"));
- assertTrue(ctx.containsBean("couchbase2"));
- assertTrue(ctx.containsBean("couchbase3"));
- }
-}
diff --git a/src/test/java/org/springframework/data/couchbase/config/CouchbaseTemplateParserIntegrationTests.java b/src/test/java/org/springframework/data/couchbase/config/CouchbaseTemplateParserIntegrationTests.java
deleted file mode 100644
index 426e0f26..00000000
--- a/src/test/java/org/springframework/data/couchbase/config/CouchbaseTemplateParserIntegrationTests.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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 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;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * @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("namespace/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("namespace/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("namespace/couchbase-multi-bucket-bean.xml"));
-
- factory.getBean("cb-template-first");
- factory.getBean("cb-template-second");
- }
-
-}
diff --git a/src/test/java/org/springframework/data/couchbase/core/Beer.java b/src/test/java/org/springframework/data/couchbase/core/Beer.java
index b6900de8..e801c296 100644
--- a/src/test/java/org/springframework/data/couchbase/core/Beer.java
+++ b/src/test/java/org/springframework/data/couchbase/core/Beer.java
@@ -61,9 +61,9 @@ public class Beer {
public boolean getActive() {
return active;
}
-
+
public String getId() {
- return id;
+ return id;
}
}
diff --git a/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateTests.java b/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateTests.java
deleted file mode 100644
index 0f3f5aad..00000000
--- a/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateTests.java
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * 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 com.couchbase.client.CouchbaseClient;
-import com.couchbase.client.protocol.views.Query;
-import com.couchbase.client.protocol.views.Stale;
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import net.spy.memcached.CASValue;
-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.TestApplicationConfig;
-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;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-/**
- * @author Michael Nitschinger
- */
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes = TestApplicationConfig.class)
-@TestExecutionListeners(CouchbaseTemplateViewListener.class)
-public class CouchbaseTemplateTests {
-
- @Autowired
- private CouchbaseClient client;
-
- @Autowired
- private CouchbaseTemplate template;
-
- private static final ObjectMapper MAPPER = new ObjectMapper();
-
- @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);
- String result = (String) client.get(id);
- assertNotNull(result);
- Map resultConv = MAPPER.readValue(result, new TypeReference>() {});
-
- 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";
- client.delete(id).get();
-
- SimplePerson doc = new SimplePerson(id, "Mr. A");
- template.insert(doc);
- String result = (String) client.get(id);
-
- Map resultConv = MAPPER.readValue(result, new TypeReference>() {});
- assertEquals("Mr. A", resultConv.get("name"));
-
- doc = new SimplePerson(id, "Mr. B");
- template.insert(doc);
- result = (String) client.get(id);
-
- resultConv = MAPPER.readValue(result, new TypeReference>() {});
- 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 names = new ArrayList();
- names.add("Michael");
- names.add("Thomas");
- names.add(null);
- List votes = new LinkedList();
- Map info1 = new HashMap();
- info1.put("foo", true);
- info1.put("bar", false);
- info1.put("nullValue", null);
- Map info2 = new HashMap();
-
- 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() {
- Query query = new Query();
- query.setStale(Stale.FALSE);
-
- final List beers = template.findByView("test_beers", "by_name", query, Beer.class);
- assertTrue(beers.size() > 0);
-
- for (Beer beer : beers) {
- assertNotNull(beer.getId());
- assertNotNull(beer.getName());
- assertNotNull(beer.getActive());
- }
- }
-
- @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 {
- client.delete("versionedClass:1").get();
-
- VersionedClass versionedClass = new VersionedClass("versionedClass:1", "foobar");
- assertEquals(0, versionedClass.getVersion());
- template.insert(versionedClass);
- CASValue rawStored = client.gets("versionedClass:1");
- assertEquals(rawStored.getCas(), versionedClass.getVersion());
- }
-
- @Test
- public void versionShouldNotUpdateOnSecondInsert() throws Exception {
- client.delete("versionedClass:2").get();
-
- 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 {
- client.delete("versionedClass:3").get();
-
- 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 {
- client.delete("versionedClass:4").get();
-
- VersionedClass versionedClass = new VersionedClass("versionedClass:4", "foobar");
- template.insert(versionedClass);
-
- assertTrue(client.set("versionedClass:4", "different").get());
-
- versionedClass.setField("foobar2");
- template.save(versionedClass);
- }
-
- @Test
- public void shouldUpdateDocumentOnMatchingVersion() throws Exception {
- client.delete("versionedClass:5").get();
-
- 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 {
- client.delete("versionedClass:6").get();
-
- VersionedClass versionedClass = new VersionedClass("versionedClass:6", "foobar");
- template.insert(versionedClass);
-
- assertTrue(client.set("versionedClass:6", "different").get());
-
- versionedClass.setField("foobar2");
- template.update(versionedClass);
- }
-
- @Test
- public void shouldLoadVersionPropertyOnFind() throws Exception {
- client.delete("versionedClass:7").get();
-
- 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 firstnames;
- @Field
- private final List votes;
-
- @Field
- private final Map info1;
- @Field
- private final Map info2;
-
- public ComplexPerson(String id, List firstnames,
- List votes, Map info1,
- Map info2) {
- this.id = id;
- this.firstnames = firstnames;
- this.votes = votes;
- this.info1 = info1;
- this.info2 = info2;
- }
-
- List getFirstnames() {
- return firstnames;
- }
-
- List getVotes() {
- return votes;
- }
-
- Map getInfo1() {
- return info1;
- }
-
- Map 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 integerClass;
-
- private String value;
-
- SimpleWithClass(final String id, final Class integerClass) {
- this.id = id;
- this.integerClass = integerClass;
- }
-
- String getId() {
- return id;
- }
-
- void setId(final String id) {
- this.id = id;
- }
-
- Class getIntegerClass() {
- return integerClass;
- }
-
- void setIntegerClass(final Class 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;
- }
- }
-
-}
diff --git a/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateViewListener.java b/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateViewListener.java
deleted file mode 100644
index 0ecaf8be..00000000
--- a/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateViewListener.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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 com.couchbase.client.CouchbaseClient;
-import com.couchbase.client.protocol.views.DesignDocument;
-import com.couchbase.client.protocol.views.ViewDesign;
-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 {
- CouchbaseClient client = (CouchbaseClient) testContext.getApplicationContext().getBean("couchbaseClient");
- populateTestData(client);
- createAndWaitForDesignDocs(client);
- }
-
- private void populateTestData(CouchbaseClient 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(CouchbaseClient client) {
- DesignDocument designDoc = new DesignDocument("test_beers");
- String mapFunction = "function (doc, meta) { if(doc._class == "
- + "\"org.springframework.data.couchbase.core.Beer\") { emit(doc.name, null); } }";
- designDoc.setView(new ViewDesign("by_name", mapFunction));
- client.createDesignDoc(designDoc);
- }
-
-}
diff --git a/src/test/java/org/springframework/data/couchbase/core/convert/translation/JacksonTranslationServiceTests.java b/src/test/java/org/springframework/data/couchbase/core/convert/translation/JacksonTranslationServiceTests.java
index f52d51b8..a53ea010 100644
--- a/src/test/java/org/springframework/data/couchbase/core/convert/translation/JacksonTranslationServiceTests.java
+++ b/src/test/java/org/springframework/data/couchbase/core/convert/translation/JacksonTranslationServiceTests.java
@@ -16,11 +16,13 @@
package org.springframework.data.couchbase.core.convert.translation;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
import org.junit.Before;
import org.junit.Test;
-import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
-import static org.junit.Assert.assertEquals;
+import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
/**
* Verifies the functionality of a {@link JacksonTranslationService}.
@@ -29,26 +31,39 @@ import static org.junit.Assert.assertEquals;
*/
public class JacksonTranslationServiceTests {
- private TranslationService service;
+ private TranslationService service;
- @Before
- public void setup() {
- service = new JacksonTranslationService();
- }
+ @Before
+ public void setup() {
+ service = new JacksonTranslationService();
+ ((JacksonTranslationService) service).afterPropertiesSet();
+ }
- @Test
- public void shouldEncodeNonASCII() {
- CouchbaseDocument doc = new CouchbaseDocument("key");
- doc.put("language", "русский");
- String expected = "{\"language\":\"русский\"}";
- assertEquals(expected, service.encode(doc));
- }
+ @Test
+ public void shouldEncodeNonASCII() {
+ CouchbaseDocument doc = new CouchbaseDocument("key");
+ doc.put("language", "русский");
+ String expected = "{\"language\":\"русский\"}";
+ assertEquals(expected, service.encode(doc));
+ }
- @Test
- public void shouldDecodeNonASCII() {
- String source = "{\"language\":\"русский\"}";
- CouchbaseDocument target = new CouchbaseDocument();
- service.decode(source, target);
- assertEquals("русский", target.get("language"));
- }
+ @Test
+ public void shouldDecodeNonASCII() {
+ String source = "{\"language\":\"русский\"}";
+ CouchbaseDocument target = new CouchbaseDocument();
+ service.decode(source, target);
+ assertEquals("русский", target.get("language"));
+ }
+
+ @Test
+ public void shouldDecodeAdHocFragment() {
+ String source = "{\"language\":\"french\"}";
+ LanguageFragment f = service.decodeFragment(source, LanguageFragment.class);
+ assertNotNull(f);
+ assertEquals("french", f.language);
+ }
+
+ private static class LanguageFragment {
+ public String language;
+ }
}
diff --git a/src/test/java/org/springframework/data/couchbase/core/mapping/BasicCouchbasePersistentPropertyTests.java b/src/test/java/org/springframework/data/couchbase/core/mapping/BasicCouchbasePersistentPropertyTests.java
index 9d9f9e6a..3c108e96 100644
--- a/src/test/java/org/springframework/data/couchbase/core/mapping/BasicCouchbasePersistentPropertyTests.java
+++ b/src/test/java/org/springframework/data/couchbase/core/mapping/BasicCouchbasePersistentPropertyTests.java
@@ -16,18 +16,19 @@
package org.springframework.data.couchbase.core.mapping;
+import static org.junit.Assert.assertEquals;
+
+import java.lang.reflect.Field;
+
import org.junit.Before;
import org.junit.Test;
+
import org.springframework.data.annotation.Id;
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.util.ReflectionUtils;
-import java.lang.reflect.Field;
-
-import static org.junit.Assert.assertEquals;
-
/**
* Verifies the correct behavior of properties on persistable objects.
*
@@ -46,7 +47,7 @@ public class BasicCouchbasePersistentPropertyTests {
@Before
public void setUp() {
entity = new BasicCouchbasePersistentEntity(
- ClassTypeInformation.from(Beer.class));
+ ClassTypeInformation.from(Beer.class));
}
/**
@@ -75,7 +76,7 @@ public class BasicCouchbasePersistentPropertyTests {
*/
private CouchbasePersistentProperty getPropertyFor(Field field) {
return new BasicCouchbasePersistentProperty(field, null, entity,
- new SimpleTypeHolder(), PropertyNameFieldNamingStrategy.INSTANCE);
+ new SimpleTypeHolder(), PropertyNameFieldNamingStrategy.INSTANCE);
}
/**
diff --git a/src/test/java/org/springframework/data/couchbase/core/mapping/CustomConvertersTests.java b/src/test/java/org/springframework/data/couchbase/core/mapping/CustomConvertersTests.java
index fb36e8b4..f0879aaa 100644
--- a/src/test/java/org/springframework/data/couchbase/core/mapping/CustomConvertersTests.java
+++ b/src/test/java/org/springframework/data/couchbase/core/mapping/CustomConvertersTests.java
@@ -16,34 +16,37 @@
package org.springframework.data.couchbase.core.mapping;
+import static org.junit.Assert.assertEquals;
+
+import java.text.Format;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
+
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.converter.Converter;
-
import org.springframework.data.annotation.Id;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
-import org.springframework.data.couchbase.TestApplicationConfig;
+import org.springframework.data.couchbase.UnitTestApplicationConfig;
import org.springframework.data.couchbase.core.convert.CustomConversions;
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import java.text.Format;
-import java.text.SimpleDateFormat;
-import java.util.*;
-
-import static org.junit.Assert.assertEquals;
-
/**
* Tests to verify custom mapping logic.
*
* @author Michael Nitschinger
*/
@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes = TestApplicationConfig.class)
+@ContextConfiguration(classes = UnitTestApplicationConfig.class)
public class CustomConvertersTests {
@Autowired
@@ -161,9 +164,9 @@ public class CustomConvertersTests {
@Override
public CouchbaseDocument convert(BlogPost source) {
return new CouchbaseDocument()
- .setId(source.id)
- .put("title", source.title)
- .put("slug", source.title.toLowerCase().replaceAll(" ", "_"));
+ .setId(source.id)
+ .put("title", source.title)
+ .put("slug", source.title.toLowerCase().replaceAll(" ", "_"));
}
}
diff --git a/src/test/java/org/springframework/data/couchbase/core/mapping/MappingCouchbaseConverterTests.java b/src/test/java/org/springframework/data/couchbase/core/mapping/MappingCouchbaseConverterTests.java
index 7e3b8286..ca3f92da 100644
--- a/src/test/java/org/springframework/data/couchbase/core/mapping/MappingCouchbaseConverterTests.java
+++ b/src/test/java/org/springframework/data/couchbase/core/mapping/MappingCouchbaseConverterTests.java
@@ -16,20 +16,7 @@
package org.springframework.data.couchbase.core.mapping;
-import org.joda.time.LocalDateTime;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.convert.converter.Converter;
-import org.springframework.data.annotation.Id;
-import org.springframework.data.couchbase.TestApplicationConfig;
-import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
-import org.springframework.data.mapping.model.MappingException;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.data.couchbase.core.convert.CustomConversions;
-import org.springframework.data.convert.ReadingConverter;
-import org.springframework.data.convert.WritingConverter;
+import static org.junit.Assert.*;
import java.math.BigDecimal;
import java.util.ArrayList;
@@ -46,15 +33,27 @@ import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+import org.joda.time.LocalDateTime;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.convert.ReadingConverter;
+import org.springframework.data.convert.WritingConverter;
+import org.springframework.data.couchbase.UnitTestApplicationConfig;
+import org.springframework.data.couchbase.core.convert.CustomConversions;
+import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
+import org.springframework.data.mapping.model.MappingException;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Michael Nitschinger
*/
@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes = TestApplicationConfig.class)
+@ContextConfiguration(classes = UnitTestApplicationConfig.class)
public class MappingCouchbaseConverterTests {
@Autowired
@@ -86,7 +85,7 @@ public class MappingCouchbaseConverterTests {
@Test(expected = MappingException.class)
public void needsIDOnEntity() {
converter.write(new EntityWithoutID("foo"),
- new CouchbaseDocument());
+ new CouchbaseDocument());
}
@Test
@@ -226,7 +225,7 @@ public class MappingCouchbaseConverterTests {
Map attr1 = new TreeMap();
Map attr2 = new LinkedHashMap();
Map> attr3 =
- new HashMap>();
+ new HashMap>();
attr0.put("foo", "bar");
attr1.put("bar", true);
@@ -374,7 +373,7 @@ public class MappingCouchbaseConverterTests {
ValueEntity readConverted = converter.read(ValueEntity.class, source);
assertEquals(addy.emailAddr, readConverted.email.emailAddr);
assertEquals(listOfEmails.get(0).emailAddr,
- readConverted.listOfEmails.get(0).emailAddr);
+ readConverted.listOfEmails.get(0).emailAddr);
}
@Test
@@ -486,6 +485,7 @@ public class MappingCouchbaseConverterTests {
static class EntityWithoutID {
private String attr0;
+
public EntityWithoutID(String a0) {
attr0 = a0;
}
@@ -499,6 +499,7 @@ public class MappingCouchbaseConverterTests {
static class StringEntity extends BaseEntity {
private String attr0;
+
public StringEntity(String attr0) {
this.attr0 = attr0;
}
@@ -506,6 +507,7 @@ public class MappingCouchbaseConverterTests {
static class NumberEntity extends BaseEntity {
private long attr0;
+
public NumberEntity(long attr0) {
this.attr0 = attr0;
}
@@ -513,6 +515,7 @@ public class MappingCouchbaseConverterTests {
static class BooleanEntity extends BaseEntity {
private boolean attr0;
+
public BooleanEntity(boolean attr0) {
this.attr0 = attr0;
}
@@ -523,6 +526,7 @@ public class MappingCouchbaseConverterTests {
private int attr1;
private double attr2;
private boolean attr3;
+
public MixedSimpleEntity(String attr0, int attr1, double attr2, boolean attr3) {
this.attr0 = attr0;
this.attr1 = attr1;
@@ -542,6 +546,7 @@ public class MappingCouchbaseConverterTests {
private Map attr1;
private Map attr2;
private Map> attr3;
+
public MapEntity(Map attr0, Map attr1, Map attr2, Map> attr3) {
this.attr0 = attr0;
this.attr1 = attr1;
@@ -554,6 +559,7 @@ public class MappingCouchbaseConverterTests {
private List attr0;
private List attr1;
private List> attr2;
+
ListEntity(List attr0, List attr1, List> attr2) {
this.attr0 = attr0;
this.attr1 = attr1;
@@ -565,6 +571,7 @@ public class MappingCouchbaseConverterTests {
private Set attr0;
private Set attr1;
private Set