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 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