From b090280b0c37a26d72c3fcc37a26efc5c46113b8 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Wed, 25 Apr 2018 13:35:49 +0200 Subject: [PATCH] Improve Couchbase auto-configuration This commit improves the couchbase auto-configuration so that it is easier to customize the way the connection to the couchbase server is initiated. See gh-11146 --- .../couchbase/CouchbaseAutoConfiguration.java | 120 +------------ .../couchbase/CouchbaseConfiguration.java | 157 ++++++++++++++++++ ...uchbaseConfigurerAdapterConfiguration.java | 4 +- .../CouchbaseAutoConfigurationTests.java | 4 - 4 files changed, 162 insertions(+), 123 deletions(-) create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseConfiguration.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfiguration.java index 45107c1ac7..142f9e98dc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfiguration.java @@ -16,31 +16,18 @@ package org.springframework.boot.autoconfigure.couchbase; -import java.util.function.BiFunction; - -import com.couchbase.client.core.env.KeyValueServiceConfig; -import com.couchbase.client.core.env.QueryServiceConfig; -import com.couchbase.client.core.env.ViewServiceConfig; -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 com.couchbase.client.java.env.DefaultCouchbaseEnvironment; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 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.couchbase.CouchbaseProperties.Endpoints; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseProperties.Endpoints.CouchbaseService; 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.context.annotation.DependsOn; -import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.Import; /** * {@link EnableAutoConfiguration Auto-configuration} for Couchbase. @@ -58,109 +45,8 @@ public class CouchbaseAutoConfiguration { @Configuration @ConditionalOnMissingBean(value = CouchbaseConfiguration.class, type = "org.springframework.data.couchbase.config.CouchbaseConfigurer") - public static class CouchbaseConfiguration { - - private final CouchbaseProperties properties; - - public CouchbaseConfiguration(CouchbaseProperties properties) { - this.properties = properties; - } - - @Bean - @Primary - public DefaultCouchbaseEnvironment couchbaseEnvironment() throws Exception { - return initializeEnvironmentBuilder(this.properties).build(); - } - - @Bean - @Primary - public Cluster couchbaseCluster() throws Exception { - return CouchbaseCluster.create(couchbaseEnvironment(), - this.properties.getBootstrapHosts()); - } - - @Bean - @Primary - @DependsOn("couchbaseClient") - public ClusterInfo couchbaseClusterInfo() throws Exception { - return couchbaseCluster() - .clusterManager(this.properties.getBucket().getName(), - this.properties.getBucket().getPassword()) - .info(); - } - - @Bean - @Primary - public Bucket couchbaseClient() throws Exception { - return couchbaseCluster().openBucket(this.properties.getBucket().getName(), - this.properties.getBucket().getPassword()); - } - - /** - * Initialize an environment builder based on the specified settings. - * @param properties the couchbase properties to use - * @return the {@link DefaultCouchbaseEnvironment} builder. - */ - protected DefaultCouchbaseEnvironment.Builder initializeEnvironmentBuilder( - CouchbaseProperties properties) { - CouchbaseProperties.Endpoints endpoints = properties.getEnv().getEndpoints(); - CouchbaseProperties.Timeouts timeouts = properties.getEnv().getTimeouts(); - DefaultCouchbaseEnvironment.Builder builder = DefaultCouchbaseEnvironment - .builder(); - if (timeouts.getConnect() != null) { - builder = builder.connectTimeout(timeouts.getConnect().toMillis()); - } - builder = builder.keyValueServiceConfig( - KeyValueServiceConfig.create(endpoints.getKeyValue())); - if (timeouts.getKeyValue() != null) { - builder = builder.kvTimeout(timeouts.getKeyValue().toMillis()); - } - if (timeouts.getQuery() != null) { - builder = builder.queryTimeout(timeouts.getQuery().toMillis()); - builder = builder.queryServiceConfig(getQueryServiceConfig(endpoints)); - builder = builder.viewServiceConfig(getViewServiceConfig(endpoints)); - } - if (timeouts.getSocketConnect() != null) { - builder = builder.socketConnectTimeout( - (int) timeouts.getSocketConnect().toMillis()); - } - if (timeouts.getView() != null) { - builder = builder.viewTimeout(timeouts.getView().toMillis()); - } - CouchbaseProperties.Ssl ssl = properties.getEnv().getSsl(); - if (ssl.getEnabled()) { - builder = builder.sslEnabled(true); - if (ssl.getKeyStore() != null) { - builder = builder.sslKeystoreFile(ssl.getKeyStore()); - } - if (ssl.getKeyStorePassword() != null) { - builder = builder.sslKeystorePassword(ssl.getKeyStorePassword()); - } - } - return builder; - } - - @SuppressWarnings("deprecation") - private QueryServiceConfig getQueryServiceConfig(Endpoints endpoints) { - return getServiceConfig(endpoints.getQueryservice(), endpoints.getQuery(), - QueryServiceConfig::create); - } - - @SuppressWarnings("deprecation") - private ViewServiceConfig getViewServiceConfig(Endpoints endpoints) { - return getServiceConfig(endpoints.getViewservice(), endpoints.getView(), - ViewServiceConfig::create); - } - - private T getServiceConfig(CouchbaseService service, Integer fallback, - BiFunction factory) { - if (service.getMinEndpoints() != 1 || service.getMaxEndpoints() != 1) { - return factory.apply(service.getMinEndpoints(), - service.getMaxEndpoints()); - } - int endpoints = (fallback != null ? fallback : 1); - return factory.apply(endpoints, endpoints); - } + @Import(CouchbaseConfiguration.class) + static class DefaultCouchbaseConfiguration { } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseConfiguration.java new file mode 100644 index 0000000000..ac5c688ef1 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseConfiguration.java @@ -0,0 +1,157 @@ +/* + * Copyright 2012-2018 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 java.util.function.BiFunction; + +import com.couchbase.client.core.env.KeyValueServiceConfig; +import com.couchbase.client.core.env.QueryServiceConfig; +import com.couchbase.client.core.env.ViewServiceConfig; +import com.couchbase.client.java.Bucket; +import com.couchbase.client.java.Cluster; +import com.couchbase.client.java.CouchbaseCluster; +import com.couchbase.client.java.cluster.ClusterInfo; +import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; + +import org.springframework.boot.autoconfigure.couchbase.CouchbaseProperties.Endpoints; +import org.springframework.boot.autoconfigure.couchbase.CouchbaseProperties.Endpoints.CouchbaseService; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; +import org.springframework.context.annotation.Primary; + +/** + * Support class to configure Couchbase based on {@link CouchbaseProperties}. + * + * @author Stephane Nicoll + * @since 2.1.0 + */ +@Configuration +public class CouchbaseConfiguration { + + private final CouchbaseProperties properties; + + public CouchbaseConfiguration(CouchbaseProperties properties) { + this.properties = properties; + } + + @Bean + @Primary + public DefaultCouchbaseEnvironment couchbaseEnvironment() { + return initializeEnvironmentBuilder(this.properties).build(); + } + + @Bean + @Primary + public Cluster couchbaseCluster() { + return CouchbaseCluster.create(couchbaseEnvironment(), + determineBootstrapHosts()); + } + + /** + * Determine the Couchbase nodes to bootstrap from. + * @return the Couchbase nodes to bootstrap from + */ + protected List determineBootstrapHosts() { + return this.properties.getBootstrapHosts(); + } + + @Bean + @Primary + @DependsOn("couchbaseClient") + public ClusterInfo couchbaseClusterInfo() { + return couchbaseCluster() + .clusterManager(this.properties.getBucket().getName(), + this.properties.getBucket().getPassword()) + .info(); + } + + @Bean + @Primary + public Bucket couchbaseClient() { + return couchbaseCluster().openBucket(this.properties.getBucket().getName(), + this.properties.getBucket().getPassword()); + } + + /** + * Initialize an environment builder based on the specified settings. + * @param properties the couchbase properties to use + * @return the {@link DefaultCouchbaseEnvironment} builder. + */ + protected DefaultCouchbaseEnvironment.Builder initializeEnvironmentBuilder( + CouchbaseProperties properties) { + CouchbaseProperties.Endpoints endpoints = properties.getEnv().getEndpoints(); + CouchbaseProperties.Timeouts timeouts = properties.getEnv().getTimeouts(); + DefaultCouchbaseEnvironment.Builder builder = DefaultCouchbaseEnvironment + .builder(); + if (timeouts.getConnect() != null) { + builder = builder.connectTimeout(timeouts.getConnect().toMillis()); + } + builder = builder.keyValueServiceConfig( + KeyValueServiceConfig.create(endpoints.getKeyValue())); + if (timeouts.getKeyValue() != null) { + builder = builder.kvTimeout(timeouts.getKeyValue().toMillis()); + } + if (timeouts.getQuery() != null) { + builder = builder.queryTimeout(timeouts.getQuery().toMillis()); + builder = builder.queryServiceConfig(getQueryServiceConfig(endpoints)); + builder = builder.viewServiceConfig(getViewServiceConfig(endpoints)); + } + if (timeouts.getSocketConnect() != null) { + builder = builder.socketConnectTimeout( + (int) timeouts.getSocketConnect().toMillis()); + } + if (timeouts.getView() != null) { + builder = builder.viewTimeout(timeouts.getView().toMillis()); + } + CouchbaseProperties.Ssl ssl = properties.getEnv().getSsl(); + if (ssl.getEnabled()) { + builder = builder.sslEnabled(true); + if (ssl.getKeyStore() != null) { + builder = builder.sslKeystoreFile(ssl.getKeyStore()); + } + if (ssl.getKeyStorePassword() != null) { + builder = builder.sslKeystorePassword(ssl.getKeyStorePassword()); + } + } + return builder; + } + + @SuppressWarnings("deprecation") + private QueryServiceConfig getQueryServiceConfig(Endpoints endpoints) { + return getServiceConfig(endpoints.getQueryservice(), endpoints.getQuery(), + QueryServiceConfig::create); + } + + @SuppressWarnings("deprecation") + private ViewServiceConfig getViewServiceConfig(Endpoints endpoints) { + return getServiceConfig(endpoints.getViewservice(), endpoints.getView(), + ViewServiceConfig::create); + } + + private T getServiceConfig(CouchbaseService service, Integer fallback, + BiFunction factory) { + if (service.getMinEndpoints() != 1 || service.getMaxEndpoints() != 1) { + return factory.apply(service.getMinEndpoints(), + service.getMaxEndpoints()); + } + int endpoints = (fallback != null ? fallback : 1); + return factory.apply(endpoints, endpoints); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseConfigurerAdapterConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseConfigurerAdapterConfiguration.java index bf2bf03029..5f8d7d7d63 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseConfigurerAdapterConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseConfigurerAdapterConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -19,7 +19,7 @@ package org.springframework.boot.autoconfigure.data.couchbase; 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.CouchbaseConfiguration; +import org.springframework.boot.autoconfigure.couchbase.CouchbaseConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.couchbase.config.CouchbaseConfigurer; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationTests.java index 4f5255f7c9..411131ea69 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationTests.java @@ -28,12 +28,9 @@ import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration.CouchbaseConfiguration; -import org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -203,7 +200,6 @@ public class CouchbaseAutoConfigurationTests { } @Configuration - @Import(CouchbaseDataAutoConfiguration.class) static class CustomCouchbaseConfiguration extends CouchbaseConfiguration { CustomCouchbaseConfiguration(CouchbaseProperties properties) {