diff --git a/spring-boot-actuator/pom.xml b/spring-boot-actuator/pom.xml
index 2f387986cec..b3020634f69 100644
--- a/spring-boot-actuator/pom.xml
+++ b/spring-boot-actuator/pom.xml
@@ -151,6 +151,11 @@
spring-data-cassandra
true
+
+ org.springframework.data
+ spring-data-couchbase
+ true
+
org.springframework.data
spring-data-mongodb
diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfiguration.java
index 5b638a515cb..38eb079ca64 100644
--- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfiguration.java
+++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfiguration.java
@@ -22,6 +22,7 @@ import java.util.Map;
import javax.jms.ConnectionFactory;
import javax.sql.DataSource;
+import com.couchbase.client.java.Bucket;
import com.datastax.driver.core.Cluster;
import org.apache.solr.client.solrj.SolrClient;
import org.elasticsearch.client.Client;
@@ -32,6 +33,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.ApplicationHealthIndicator;
import org.springframework.boot.actuate.health.CassandraHealthIndicator;
import org.springframework.boot.actuate.health.CompositeHealthIndicator;
+import org.springframework.boot.actuate.health.CouchbaseHealthIndicator;
import org.springframework.boot.actuate.health.DataSourceHealthIndicator;
import org.springframework.boot.actuate.health.DiskSpaceHealthIndicator;
import org.springframework.boot.actuate.health.DiskSpaceHealthIndicatorProperties;
@@ -54,6 +56,7 @@ import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfigurati
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration;
import org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration;
import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration;
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
@@ -71,6 +74,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.ResolvableType;
import org.springframework.data.cassandra.core.CassandraOperations;
+import org.springframework.data.couchbase.core.CouchbaseOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.jdbc.core.JdbcTemplate;
@@ -84,16 +88,18 @@ import org.springframework.mail.javamail.JavaMailSenderImpl;
* @author Stephane Nicoll
* @author Phillip Webb
* @author Tommy Ludwig
+ * @author Eddú Meléndez
* @since 1.1.0
*/
@Configuration
@AutoConfigureBefore({ EndpointAutoConfiguration.class })
@AutoConfigureAfter({ CassandraAutoConfiguration.class,
- CassandraDataAutoConfiguration.class, DataSourceAutoConfiguration.class,
- MongoAutoConfiguration.class, MongoDataAutoConfiguration.class,
- RedisAutoConfiguration.class, RabbitAutoConfiguration.class,
- SolrAutoConfiguration.class, MailSenderAutoConfiguration.class,
- JmsAutoConfiguration.class, ElasticsearchAutoConfiguration.class })
+ CassandraDataAutoConfiguration.class, CouchbaseAutoConfiguration.class,
+ DataSourceAutoConfiguration.class, MongoAutoConfiguration.class,
+ MongoDataAutoConfiguration.class, RedisAutoConfiguration.class,
+ RabbitAutoConfiguration.class, SolrAutoConfiguration.class,
+ MailSenderAutoConfiguration.class, JmsAutoConfiguration.class,
+ ElasticsearchAutoConfiguration.class })
@EnableConfigurationProperties({ HealthIndicatorAutoConfigurationProperties.class })
public class HealthIndicatorAutoConfiguration {
@@ -176,6 +182,24 @@ public class HealthIndicatorAutoConfiguration {
}
+ @Configuration
+ @ConditionalOnClass({ CouchbaseOperations.class, Bucket.class})
+ @ConditionalOnBean(CouchbaseOperations.class)
+ @ConditionalOnEnabledHealthIndicator("couchbase")
+ public static class CouchbaseHealthIndicatorConfiguration extends
+ CompositeHealthIndicatorConfiguration {
+
+ @Autowired
+ private Map couchbaseOperations;
+
+ @Bean
+ @ConditionalOnMissingBean(name = "couchbaseHealthIndicator")
+ public HealthIndicator couchbaseHealthIndicator() {
+ return createHealthIndicator(this.couchbaseOperations);
+ }
+
+ }
+
@Configuration
@ConditionalOnClass(JdbcTemplate.class)
@ConditionalOnBean(DataSource.class)
diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CouchbaseHealthIndicator.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CouchbaseHealthIndicator.java
new file mode 100644
index 00000000000..ae4e0f7c432
--- /dev/null
+++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CouchbaseHealthIndicator.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012-2016 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.boot.actuate.health;
+
+import java.util.List;
+
+import com.couchbase.client.java.util.features.Version;
+
+import org.springframework.data.couchbase.core.CouchbaseOperations;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+/**
+ * {@link HealthIndicator} for Couchbase.
+ *
+ * @author Eddú Meléndez
+ * @since 1.4.0
+ */
+public class CouchbaseHealthIndicator extends AbstractHealthIndicator {
+
+ private CouchbaseOperations couchbaseOperations;
+
+ public CouchbaseHealthIndicator(CouchbaseOperations couchbaseOperations) {
+ Assert.notNull(couchbaseOperations, "CouchbaseOperations must not be null");
+ this.couchbaseOperations = couchbaseOperations;
+ }
+
+ @Override
+ protected void doHealthCheck(Health.Builder builder) throws Exception {
+ List versions = this.couchbaseOperations.getCouchbaseClusterInfo().getAllVersions();
+ builder.up().withDetail("versions", StringUtils.collectionToCommaDelimitedString(versions));
+ }
+
+}
diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfigurationTests.java
index d5dbcd4d5b4..bb082b07f86 100644
--- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfigurationTests.java
+++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfigurationTests.java
@@ -25,6 +25,7 @@ import org.junit.Test;
import org.springframework.boot.actuate.health.ApplicationHealthIndicator;
import org.springframework.boot.actuate.health.CassandraHealthIndicator;
+import org.springframework.boot.actuate.health.CouchbaseHealthIndicator;
import org.springframework.boot.actuate.health.DataSourceHealthIndicator;
import org.springframework.boot.actuate.health.DiskSpaceHealthIndicator;
import org.springframework.boot.actuate.health.ElasticsearchHealthIndicator;
@@ -56,6 +57,7 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.cassandra.core.CassandraOperations;
+import org.springframework.data.couchbase.core.CouchbaseOperations;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -66,6 +68,7 @@ import static org.mockito.Mockito.mock;
* @author Christian Dupuis
* @author Stephane Nicoll
* @author Andy Wilkinson
+ * @author Eddú Meléndez
*/
public class HealthIndicatorAutoConfigurationTests {
@@ -436,6 +439,19 @@ public class HealthIndicatorAutoConfigurationTests {
.isEqualTo(CassandraHealthIndicator.class);
}
+ @Test
+ public void couchbaseHealthIndicator() throws Exception {
+ EnvironmentTestUtils.addEnvironment(this.context,
+ "management.health.diskspace.enabled:false");
+ this.context.register(CouchbaseConfiguration.class,
+ ManagementServerProperties.class, HealthIndicatorAutoConfiguration.class);
+ this.context.refresh();
+ Map beans = this.context
+ .getBeansOfType(HealthIndicator.class);
+ assertThat(beans.size()).isEqualTo(1);
+ assertThat(beans.values().iterator().next().getClass()).isEqualTo(CouchbaseHealthIndicator.class);
+ }
+
@Configuration
@EnableConfigurationProperties
protected static class DataSourceConfig {
@@ -476,4 +492,15 @@ public class HealthIndicatorAutoConfigurationTests {
}
+ @Configuration
+ protected static class CouchbaseConfiguration {
+
+ @Bean
+ public CouchbaseOperations couchbaseOperations() {
+ CouchbaseOperations operations = mock(CouchbaseOperations.class);
+ return operations;
+ }
+
+ }
+
}
diff --git a/spring-boot-autoconfigure/pom.xml b/spring-boot-autoconfigure/pom.xml
index 4500ac787c9..95a8622bef2 100755
--- a/spring-boot-autoconfigure/pom.xml
+++ b/spring-boot-autoconfigure/pom.xml
@@ -325,6 +325,17 @@
spring-batch-core
true
+
+ org.springframework.data
+ spring-data-couchbase
+ true
+
+
+ org.slf4j
+ jcl-over-slf4j
+
+
+
org.springframework.data
spring-data-jpa
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfiguration.java
new file mode 100644
index 00000000000..df6e889f1c0
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfiguration.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2012-2016 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.boot.autoconfigure.couchbase;
+
+import java.util.List;
+
+import javax.validation.Validator;
+
+import com.couchbase.client.java.CouchbaseBucket;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
+import org.springframework.data.couchbase.config.CouchbaseBucketFactoryBean;
+import org.springframework.data.couchbase.core.mapping.event.ValidatingCouchbaseEventListener;
+
+/**
+ * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
+ * Auto-Configuration} for Couchbase.
+ *
+ * @author Eddú Meléndez
+ * @author Stephane Nicoll
+ * @since 1.4.0
+ */
+@Configuration
+@ConditionalOnClass({CouchbaseBucket.class, CouchbaseBucketFactoryBean.class})
+@Conditional(CouchbaseAutoConfiguration.CouchbaseCondition.class)
+@EnableConfigurationProperties(CouchbaseProperties.class)
+public class CouchbaseAutoConfiguration {
+
+ @Bean
+ @ConditionalOnBean(Validator.class)
+ public ValidatingCouchbaseEventListener validationEventListener(Validator validator) {
+ return new ValidatingCouchbaseEventListener(validator);
+ }
+
+ @Configuration
+ @ConditionalOnMissingBean(AbstractCouchbaseConfiguration.class)
+ public static class CouchbaseConfiguration extends AbstractCouchbaseConfiguration {
+
+ @Autowired
+ private CouchbaseProperties properties;
+
+ @Override
+ protected List getBootstrapHosts() {
+ return this.properties.getBootstrapHosts();
+ }
+
+ @Override
+ protected String getBucketName() {
+ return this.properties.getBucket().getName();
+ }
+
+ @Override
+ protected String getBucketPassword() {
+ return this.properties.getBucket().getPassword();
+ }
+ }
+
+ /**
+ * Determine if Couchbase should be configured. This happens if either the user-configuration
+ * defines a couchbase configuration or if at least the bucket name is specified.
+ */
+ static class CouchbaseCondition extends AnyNestedCondition {
+
+ CouchbaseCondition() {
+ super(ConfigurationPhase.REGISTER_BEAN);
+ }
+
+ @ConditionalOnProperty(prefix = "spring.data.couchbase.bucket", name = "name")
+ static class BucketNameProperty {
+ }
+
+ @ConditionalOnBean(AbstractCouchbaseConfiguration.class)
+ static class CouchbaseConfiguration {
+ }
+
+ }
+
+}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseProperties.java
new file mode 100644
index 00000000000..a7b6f755077
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseProperties.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2012-2016 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.boot.autoconfigure.couchbase;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Configuration properties for Couchbase.
+ *
+ * @author Eddú Meléndez
+ * @author Stephane Nicoll
+ * @since 1.4.0
+ */
+@ConfigurationProperties(prefix = "spring.data.couchbase")
+public class CouchbaseProperties {
+
+ /**
+ * Couchbase nodes (host or IP address) to bootstrap from.
+ */
+ private List bootstrapHosts = new ArrayList(Collections.singletonList("localhost"));
+
+ private final Bucket bucket = new Bucket();
+
+ public List getBootstrapHosts() {
+ return this.bootstrapHosts;
+ }
+
+ public void setBootstrapHosts(List bootstrapHosts) {
+ this.bootstrapHosts = bootstrapHosts;
+ }
+
+ public Bucket getBucket() {
+ return this.bucket;
+ }
+
+ static class Bucket {
+
+ /**
+ * Name of the bucket to connect to.
+ */
+ private String name;
+
+ /**
+ * Password of the bucket.
+ */
+ private String password = "";
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getPassword() {
+ return this.password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+ }
+
+}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/package-info.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/package-info.java
new file mode 100644
index 00000000000..8d930f10d57
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2012-2016 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.
+ */
+
+/**
+ * Auto-configuration for Couchbase.
+ */
+package org.springframework.boot.autoconfigure.couchbase;
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseRepositoriesAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseRepositoriesAutoConfiguration.java
new file mode 100644
index 00000000000..f13a5d606c0
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseRepositoriesAutoConfiguration.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012-2016 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.boot.autoconfigure.data.couchbase;
+
+import com.couchbase.client.java.Bucket;
+
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.data.couchbase.repository.CouchbaseRepository;
+import org.springframework.data.couchbase.repository.support.CouchbaseRepositoryFactoryBean;
+
+/**
+ * {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Couchbase
+ * Repositories.
+ *
+ * @author Eddú Meléndez
+ * @since 1.4.0
+ */
+@Configuration
+@ConditionalOnClass({ Bucket.class, CouchbaseRepository.class })
+@ConditionalOnProperty(prefix = "spring.data.couchbase.repositories", name = "enabled", havingValue = "true", matchIfMissing = true)
+@ConditionalOnMissingBean(CouchbaseRepositoryFactoryBean.class)
+@Import(CouchbaseRepositoriesRegistrar.class)
+public class CouchbaseRepositoriesAutoConfiguration {
+
+}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseRepositoriesRegistrar.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseRepositoriesRegistrar.java
new file mode 100644
index 00000000000..bd52fcbf261
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseRepositoriesRegistrar.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012-2016 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.boot.autoconfigure.data.couchbase;
+
+import java.lang.annotation.Annotation;
+
+import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport;
+import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
+import org.springframework.data.couchbase.repository.config.CouchbaseRepositoryConfigurationExtension;
+import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories;
+import org.springframework.data.repository.config.RepositoryConfigurationExtension;
+
+/**
+ * {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data Couchbase
+ * Repositories.
+ *
+ * @author Eddú Meléndez
+ * @since 1.4.0
+ */
+public class CouchbaseRepositoriesRegistrar extends AbstractRepositoryConfigurationSourceSupport {
+
+ @Override
+ protected Class extends Annotation> getAnnotation() {
+ return EnableCouchbaseRepositories.class;
+ }
+
+ @Override
+ protected Class> getConfiguration() {
+ return EnableCouchbaseRepositoriesConfiguration.class;
+ }
+
+ @Override
+ protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() {
+ return new CouchbaseRepositoryConfigurationExtension();
+ }
+
+ @EnableCouchbaseRepositories
+ private static class EnableCouchbaseRepositoriesConfiguration {
+
+ }
+
+}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/package-info.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/package-info.java
new file mode 100644
index 00000000000..bba40726b58
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2012-2016 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.
+ */
+
+/**
+ * Auto-configuration for Spring Data Couchbase.
+ */
+package org.springframework.boot.autoconfigure.data.couchbase;
diff --git a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
index 3ca9810ebe0..da4b6b5eb7a 100644
--- a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
+++ b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
@@ -19,9 +19,11 @@ org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
+org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
+org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationTests.java
new file mode 100644
index 00000000000..35e23b434c6
--- /dev/null
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationTests.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2012-2016 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.boot.autoconfigure.couchbase;
+
+import javax.validation.Validator;
+
+import com.couchbase.client.java.Bucket;
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import org.springframework.beans.DirectFieldAccessor;
+import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
+import org.springframework.boot.test.EnvironmentTestUtils;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
+import org.springframework.data.couchbase.core.CouchbaseTemplate;
+import org.springframework.data.couchbase.core.mapping.event.ValidatingCouchbaseEventListener;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Tests for {@link CouchbaseAutoConfiguration}
+ *
+ * @author Eddú Meléndez
+ */
+public class CouchbaseAutoConfigurationTests {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private AnnotationConfigApplicationContext context;
+
+ @After
+ public void close() {
+ if (this.context != null) {
+ this.context.close();
+ }
+ }
+
+ @Test
+ public void bucketNameIsRequired() {
+ load(null);
+ assertThat(this.context.getBeansOfType(CouchbaseTemplate.class)).isEmpty();
+ assertThat(this.context.getBeansOfType(Bucket.class)).isEmpty();
+ assertThat(this.context.getBeansOfType(ValidatingCouchbaseEventListener.class)).isEmpty();
+ }
+
+ @Test
+ public void bucketNameIsNotRequiredIfCustomConfigurationIsSpecified() throws Exception {
+ load(CouchbaseTestConfiguration.class);
+
+ assertThat(this.context.getBeansOfType(AbstractCouchbaseConfiguration.class)).hasSize(1);
+ CouchbaseTestConfiguration configuration = this.context.getBean(CouchbaseTestConfiguration.class);
+ assertThat(this.context.getBean(CouchbaseTemplate.class)).isSameAs(configuration.couchbaseTemplate());
+ assertThat(this.context.getBean(Bucket.class)).isSameAs(configuration.couchbaseClient());
+ assertThat(this.context.getBeansOfType(ValidatingCouchbaseEventListener.class)).isEmpty();
+ }
+
+ @Test
+ public void validatorIsPresent() {
+ load(ValidatorConfiguration.class);
+
+ ValidatingCouchbaseEventListener listener = this.context
+ .getBean(ValidatingCouchbaseEventListener.class);
+ assertThat(new DirectFieldAccessor(listener).getPropertyValue("validator"))
+ .isEqualTo(this.context.getBean(Validator.class));
+ }
+
+ private void load(Class> config, String... environment) {
+ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
+ EnvironmentTestUtils.addEnvironment(context, environment);
+ if (config != null) {
+ context.register(config);
+ }
+ context.register(PropertyPlaceholderAutoConfiguration.class,
+ CouchbaseAutoConfiguration.class);
+ context.refresh();
+ this.context = context;
+ }
+
+ @Configuration
+ @Import(CouchbaseTestConfiguration.class)
+ static class ValidatorConfiguration {
+
+ @Bean
+ public Validator myValidator() {
+ return mock(Validator.class);
+ }
+
+ }
+
+}
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseTestConfiguration.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseTestConfiguration.java
new file mode 100644
index 00000000000..2d938584318
--- /dev/null
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseTestConfiguration.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2012-2016 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.boot.autoconfigure.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.cluster.ClusterInfo;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
+
+import static org.mockito.Mockito.mock;
+
+/**
+ * Test configuration for couchbase that mocks access.
+ *
+ * @author Stephane Nicoll
+ */
+@Configuration
+public class CouchbaseTestConfiguration extends AbstractCouchbaseConfiguration {
+
+ @Override
+ protected List getBootstrapHosts() {
+ return Collections.singletonList("localhost");
+ }
+
+ @Override
+ protected String getBucketName() {
+ return "my-bucket";
+ }
+
+ @Override
+ protected String getBucketPassword() {
+ return "my-password";
+ }
+
+ @Override
+ public Cluster couchbaseCluster() throws Exception {
+ return mock(CouchbaseCluster.class);
+ }
+
+ @Bean
+ public ClusterInfo couchbaseClusterInfo() {
+ return mock(ClusterInfo.class);
+ }
+
+ @Override
+ public Bucket couchbaseClient() throws Exception {
+ return mock(CouchbaseBucket.class);
+ }
+
+}
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/couchbase/CityCouchbaseRepository.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/couchbase/CityCouchbaseRepository.java
new file mode 100644
index 00000000000..5abd9020c95
--- /dev/null
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/couchbase/CityCouchbaseRepository.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2012-2016 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.boot.autoconfigure.data.alt.couchbase;
+
+import org.springframework.boot.autoconfigure.data.couchbase.city.City;
+import org.springframework.data.repository.Repository;
+
+/**
+ * @author Eddú Meléndez
+ */
+public interface CityCouchbaseRepository extends Repository {
+}
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseRepositoriesAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseRepositoriesAutoConfigurationTests.java
new file mode 100644
index 00000000000..8ab1d4e4a06
--- /dev/null
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseRepositoriesAutoConfigurationTests.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2012-2016 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.boot.autoconfigure.data.couchbase;
+
+import com.couchbase.client.java.Bucket;
+import org.junit.After;
+import org.junit.Test;
+
+import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
+import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
+import org.springframework.boot.autoconfigure.couchbase.CouchbaseTestConfiguration;
+import org.springframework.boot.autoconfigure.data.couchbase.city.City;
+import org.springframework.boot.autoconfigure.data.couchbase.city.CityRepository;
+import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author Eddú Meléndez
+ */
+public class CouchbaseRepositoriesAutoConfigurationTests {
+
+ private AnnotationConfigApplicationContext context;
+
+ @After
+ public void close() {
+ this.context.close();
+ }
+
+ @Test
+ public void testDefaultRepositoryConfiguration() throws Exception {
+ this.context = new AnnotationConfigApplicationContext();
+ this.context.register(TestConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class);
+ this.context.refresh();
+ assertThat(this.context.getBean(CityRepository.class)).isNotNull();
+ assertThat(this.context.getBean(Bucket.class)).isNotNull();
+ }
+
+ @Test
+ public void testNoRepositoryConfiguration() throws Exception {
+ this.context = new AnnotationConfigApplicationContext();
+ this.context.register(EmptyConfiguration.class, TestConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class);
+ this.context.refresh();
+ assertThat(this.context.getBean(Bucket.class)).isNotNull();
+ }
+
+ @Configuration
+ @TestAutoConfigurationPackage(City.class)
+ @Import({ CouchbaseRepositoriesRegistrar.class, CouchbaseTestConfiguration.class })
+ static class TestConfiguration {
+
+ }
+
+ @Configuration
+ @TestAutoConfigurationPackage(EmptyDataPackage.class)
+ protected static class EmptyConfiguration {
+
+ }
+
+}
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/city/City.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/city/City.java
new file mode 100644
index 00000000000..0b0659a1143
--- /dev/null
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/city/City.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2012-2016 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.boot.autoconfigure.data.couchbase.city;
+
+import com.couchbase.client.java.repository.annotation.Field;
+import com.couchbase.client.java.repository.annotation.Id;
+
+import org.springframework.data.couchbase.core.mapping.Document;
+
+@Document
+public class City {
+
+ @Id
+ private String id;
+
+ @Field
+ private String name;
+
+}
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/city/CityRepository.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/city/CityRepository.java
new file mode 100644
index 00000000000..d3d36ef701f
--- /dev/null
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/city/CityRepository.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2012-2016 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.boot.autoconfigure.data.couchbase.city;
+
+import org.springframework.data.repository.Repository;
+
+public interface CityRepository extends Repository {
+
+}
diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml
index aba773bd98e..0b8947cf887 100644
--- a/spring-boot-dependencies/pom.xml
+++ b/spring-boot-dependencies/pom.xml
@@ -271,6 +271,11 @@
spring-boot-starter-data-cassandra
1.4.0.BUILD-SNAPSHOT
+
+ org.springframework.boot
+ spring-boot-starter-data-couchbase
+ 1.4.0.BUILD-SNAPSHOT
+
org.springframework.boot
spring-boot-starter-data-elasticsearch
@@ -2239,4 +2244,4 @@
integration-test
-
\ No newline at end of file
+
diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc
index 9284eb8d007..49ddc578785 100644
--- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc
+++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc
@@ -488,6 +488,11 @@ content into your application; rather pick only the properties that you need.
spring.data.cassandra.ssl=false # Enable SSL support.
spring.data.cassandra.username= # Login user of the server.
+ # COUCHBASE ({sc-spring-boot-autoconfigure}/couchbase/CouchbaseProperties.{sc-ext}[CouchbaseProperties])
+ spring.data.couchbase.bootstrap-hosts=localhost # Couchbase nodes (host or IP address) to bootstrap from.
+ spring.data.couchbase.bucket.name= # Name of the bucket to connect to.
+ spring.data.couchbase.bucket.password= # Password of the bucket.
+
# ELASTICSEARCH ({sc-spring-boot-autoconfigure}/elasticsearch/ElasticsearchProperties.{sc-ext}[ElasticsearchProperties])
spring.data.elasticsearch.cluster-name=elasticsearch # Elasticsearch cluster name.
spring.data.elasticsearch.cluster-nodes= # Comma-separated list of cluster node addresses. If not specified, starts a client node.
diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
index a574c2fa9c6..08ac5d37ac6 100644
--- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
+++ b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
@@ -3122,6 +3122,66 @@ TIP: For complete details of Spring Data Cassandra, refer to their
http://docs.spring.io/spring-data/cassandra/docs/[reference documentation].
+[[boot-features-couchbase]]
+=== Couchbase
+http://www.couchbase.com/[Couchbase] is an open-source, distributed multi-model NoSQL
+document-oriented database that is optimized for interactive applications. Spring Boot
+offers auto-configuration for Couchbase and abstractions on top of it provided by
+https://github.com/spring-projects/spring-data-couchbase[Spring Data Couchbase].
+There is a `spring-boot-starter-data-couchbase` '`Starter POM`' for collecting the
+dependencies in a convenient way.
+
+
+
+[[boot-features-connecting-to-couchbase]]
+==== Connecting to Couchbase
+You can inject an auto-configured `CouchbaseTemplate` instance as you would with any
+other Spring Bean. The `spring.data.couchbase.*` properties can be used to customize the
+connection. Generally you will provide the bootstrap hosts, bucket name and password:
+
+[source,properties,indent=0]
+----
+ spring.data.couchbase.bootstrap-hosts=my-host-1,192.168.1.123
+ spring.data.couchbase.bucket.name=my-bucket
+ spring.data.couchbase.bucket.password=secret
+----
+
+[TIP]
+====
+You need to provide _at least_ the bucket name, in which case the bootstrap host is
+localhost and the password is an empty String. Alternatively, you can define your
+own `org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration` `@Bean`
+configuration to take control over the whole configuration.
+====
+
+[source,java,indent=0]
+----
+ @Component
+ public class MyBean {
+
+ private final CouchbaseTemplate template;
+
+ @Autowired
+ public MyBean(CouchbaseTemplate template) {
+ this.template = template;
+ }
+
+ // ...
+
+ }
+----
+
+If you add a `@Bean` of your own of type `CassandraTemplate` it will replace the
+default.
+
+
+
+[[boot-features-spring-data-couchbase-repositories]]
+==== Spring Data Couchbase repositories
+Spring Data includes repository support for Couchbase. For complete details of Spring
+Data Couchbase, refer to their
+http://docs.spring.io/spring-data/couchbase/docs/current/reference/html/[reference documentation].
+
[[boot-features-caching]]
== Caching
diff --git a/spring-boot-samples/README.adoc b/spring-boot-samples/README.adoc
index 469eedb13e5..551b8252836 100644
--- a/spring-boot-samples/README.adoc
+++ b/spring-boot-samples/README.adoc
@@ -60,6 +60,8 @@
-- Example showing message-oriented application using HornetQ
* link:spring-boot-sample-batch[spring-boot-sample-batch]
-- Define and run a Batch job in a few lines of code
+* link:spring-boot-sample-data-couchbase[spring-boot-sample-data-couchbase]
+ -- Spring Data Couchbase repositories
* link:spring-boot-sample-data-jpa[spring-boot-sample-data-jpa]
-- Spring Data JPA + Hibernate + HSQLDB
* link:spring-boot-sample-data-mongodb[spring-boot-sample-data-mongodb]
diff --git a/spring-boot-samples/pom.xml b/spring-boot-samples/pom.xml
index 4e7446eb03f..3fb2f76fa2b 100644
--- a/spring-boot-samples/pom.xml
+++ b/spring-boot-samples/pom.xml
@@ -33,6 +33,7 @@
spring-boot-sample-batch
spring-boot-sample-cache
spring-boot-sample-data-cassandra
+ spring-boot-sample-data-couchbase
spring-boot-sample-data-elasticsearch
spring-boot-sample-data-gemfire
spring-boot-sample-data-jpa
diff --git a/spring-boot-samples/spring-boot-sample-data-couchbase/README.adoc b/spring-boot-samples/spring-boot-sample-data-couchbase/README.adoc
new file mode 100644
index 00000000000..1a0058bd9c5
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-data-couchbase/README.adoc
@@ -0,0 +1,22 @@
+= Spring Boot Couchbase Sample
+
+This sample demonstrates how you can store a simple document using Spring Data Couchbase.
+
+The sample expects couchbase to run on your machine with a bucket named `mybucket` and
+`couchbase` for the password. You can customize these settings in `application.properties`.
+
+Before you use the sample, you need _at least_ to create an `all` view for the `User`: go
+to the Couchbase server’s admin console and visit the Views screen, then click `Create
+Development View` and name it `all` with `user` as document name. On that view, you need
+to change the code to:
+
+```java
+function (doc, meta) {
+ if (doc._class == "sample.data.couchbase.User") {
+ emit(meta.id, null);
+ }
+}
+```
+
+and the _reduce_ function to `_count`. After you've saved your changes go back to `Views`
+and click on `Publish` so that the `all` view move to the `Production Views` tab.
\ No newline at end of file
diff --git a/spring-boot-samples/spring-boot-sample-data-couchbase/pom.xml b/spring-boot-samples/spring-boot-sample-data-couchbase/pom.xml
new file mode 100644
index 00000000000..32c98431e9e
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-data-couchbase/pom.xml
@@ -0,0 +1,54 @@
+
+
+ 4.0.0
+
+ spring-boot-samples
+ org.springframework.boot
+ 1.4.0.BUILD-SNAPSHOT
+
+ spring-boot-sample-data-couchbase
+ Spring Boot Data Couchbase Sample
+ Spring Boot Data Couchbase Sample
+ http://projects.spring.io/spring-boot/
+
+ Pivotal Software, Inc.
+ http://www.spring.io
+
+
+ ${basedir}/../..
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-data-couchbase
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-actuator
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/spring-boot-samples/spring-boot-sample-data-couchbase/src/main/java/sample/data/couchbase/SampleCouchbaseApplication.java b/spring-boot-samples/spring-boot-sample-data-couchbase/src/main/java/sample/data/couchbase/SampleCouchbaseApplication.java
new file mode 100644
index 00000000000..4ba3ab45493
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-data-couchbase/src/main/java/sample/data/couchbase/SampleCouchbaseApplication.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2012-2016 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 sample.data.couchbase;
+
+import java.util.UUID;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SampleCouchbaseApplication implements CommandLineRunner {
+
+ @Autowired
+ private UserRepository userRepository;
+
+ public static void main(String[] args) {
+ SpringApplication.run(SampleCouchbaseApplication.class);
+ }
+
+ @Override
+ public void run(String... args) throws Exception {
+ saveUsers();
+
+ System.out.println(this.userRepository.findAll());
+ }
+
+ private void saveUsers() {
+ User user = new User();
+ user.setId(UUID.randomUUID().toString());
+ user.setFirstName("Alice");
+ user.setLastName("Smith");
+
+ this.userRepository.save(user);
+ }
+
+}
diff --git a/spring-boot-samples/spring-boot-sample-data-couchbase/src/main/java/sample/data/couchbase/User.java b/spring-boot-samples/spring-boot-sample-data-couchbase/src/main/java/sample/data/couchbase/User.java
new file mode 100644
index 00000000000..88a7a659d51
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-data-couchbase/src/main/java/sample/data/couchbase/User.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2012-2016 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 sample.data.couchbase;
+
+
+import com.couchbase.client.java.repository.annotation.Field;
+import com.couchbase.client.java.repository.annotation.Id;
+import org.springframework.data.couchbase.core.mapping.Document;
+
+@Document
+public class User {
+
+ @Id
+ private String id;
+
+ @Field
+ private String firstName;
+
+ @Field
+ private String lastName;
+
+ public String getId() {
+ return this.id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getFirstName() {
+ return this.firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return this.lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ @Override
+ public String toString() {
+ return "User{" +
+ "id='" + this.id + '\'' +
+ ", firstName='" + this.firstName + '\'' +
+ ", lastName='" + this.lastName + '\'' +
+ '}';
+ }
+}
diff --git a/spring-boot-samples/spring-boot-sample-data-couchbase/src/main/java/sample/data/couchbase/UserRepository.java b/spring-boot-samples/spring-boot-sample-data-couchbase/src/main/java/sample/data/couchbase/UserRepository.java
new file mode 100644
index 00000000000..1e2deab5bc0
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-data-couchbase/src/main/java/sample/data/couchbase/UserRepository.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2012-2016 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 sample.data.couchbase;
+
+import org.springframework.data.couchbase.repository.CouchbaseRepository;
+
+public interface UserRepository extends CouchbaseRepository {
+
+}
diff --git a/spring-boot-samples/spring-boot-sample-data-couchbase/src/test/java/sample/data/couchbase/SampleCouchbaseApplicationTests.java b/spring-boot-samples/spring-boot-sample-data-couchbase/src/test/java/sample/data/couchbase/SampleCouchbaseApplicationTests.java
new file mode 100644
index 00000000000..79e920d2589
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-data-couchbase/src/test/java/sample/data/couchbase/SampleCouchbaseApplicationTests.java
@@ -0,0 +1,47 @@
+package sample.data.couchbase;
+
+import java.net.ConnectException;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.test.OutputCapture;
+import org.springframework.core.NestedCheckedException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class SampleCouchbaseApplicationTests {
+
+ @Rule
+ public OutputCapture outputCapture = new OutputCapture();
+
+ @Test
+ public void testDefaultSettings() throws Exception {
+ try {
+ new SpringApplicationBuilder(SampleCouchbaseApplication.class)
+ .run();
+ }
+ catch (RuntimeException ex) {
+ if (serverNotRunning(ex)) {
+ return;
+ }
+ }
+ String output = this.outputCapture.toString();
+ assertThat(output).contains("firstName='Alice', lastName='Smith'");
+ }
+
+ private boolean serverNotRunning(RuntimeException ex) {
+ @SuppressWarnings("serial")
+ NestedCheckedException nested = new NestedCheckedException("failed", ex) {
+ };
+ if (nested.contains(ConnectException.class)) {
+ Throwable root = nested.getRootCause();
+ if (root.getMessage().contains("Connection refused")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/spring-boot-samples/spring-boot-sample-data-couchbase/src/test/resources/application.properties b/spring-boot-samples/spring-boot-sample-data-couchbase/src/test/resources/application.properties
new file mode 100644
index 00000000000..774aeb9a18d
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-data-couchbase/src/test/resources/application.properties
@@ -0,0 +1,2 @@
+spring.data.couchbase.bucket.name=mybucket
+spring.data.couchbase.bucket.password=couchbase
\ No newline at end of file
diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml
index c7552423324..e5667e3c3a5 100644
--- a/spring-boot-starters/pom.xml
+++ b/spring-boot-starters/pom.xml
@@ -28,6 +28,7 @@
spring-boot-starter-cache
spring-boot-starter-cloud-connectors
spring-boot-starter-data-cassandra
+ spring-boot-starter-data-couchbase
spring-boot-starter-data-elasticsearch
spring-boot-starter-data-gemfire
spring-boot-starter-data-jpa
diff --git a/spring-boot-starters/spring-boot-starter-data-couchbase/pom.xml b/spring-boot-starters/spring-boot-starter-data-couchbase/pom.xml
new file mode 100644
index 00000000000..938e7e5e234
--- /dev/null
+++ b/spring-boot-starters/spring-boot-starter-data-couchbase/pom.xml
@@ -0,0 +1,32 @@
+
+
+ 4.0.0
+
+ spring-boot-starters
+ org.springframework.boot
+ 1.4.0.BUILD-SNAPSHOT
+
+ spring-boot-starter-data-couchbase
+ Spring Boot Data Couchbase Starter
+ Spring Boot Data Couchbase Starter
+ http://projects.spring.io/spring-boot/
+
+ Pivotal Software, Inc.
+ http://www.spring.io
+
+
+ ${basedir}/../..
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.data
+ spring-data-couchbase
+
+
+
diff --git a/spring-boot-starters/spring-boot-starter-data-couchbase/src/main/resources/META-INF/spring.provides b/spring-boot-starters/spring-boot-starter-data-couchbase/src/main/resources/META-INF/spring.provides
new file mode 100644
index 00000000000..7eb2d6ff979
--- /dev/null
+++ b/spring-boot-starters/spring-boot-starter-data-couchbase/src/main/resources/META-INF/spring.provides
@@ -0,0 +1 @@
+provides: spring-data-couchbase