diff --git a/spring-boot-project/spring-boot-autoconfigure/pom.xml b/spring-boot-project/spring-boot-autoconfigure/pom.xml
index 70f9e1349a..cd7633bb0e 100755
--- a/spring-boot-project/spring-boot-autoconfigure/pom.xml
+++ b/spring-boot-project/spring-boot-autoconfigure/pom.xml
@@ -957,6 +957,11 @@
cassandra
test
+
+ org.testcontainers
+ couchbase
+ test
+
org.testcontainers
elasticsearch
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
index dca5184964..cee5ec6580 100644
--- 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2019 the original author or authors.
+ * Copyright 2012-2020 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.
@@ -37,6 +37,7 @@ import org.springframework.context.annotation.Primary;
* Support class to configure Couchbase based on {@link CouchbaseProperties}.
*
* @author Stephane Nicoll
+ * @author Brian Clozel
* @since 2.1.0
*/
@Configuration
@@ -76,6 +77,9 @@ public class CouchbaseConfiguration {
@Primary
@DependsOn("couchbaseClient")
public ClusterInfo couchbaseClusterInfo() {
+ if (isRoleBasedAccessControlEnabled()) {
+ return couchbaseCluster().clusterManager().info();
+ }
return couchbaseCluster()
.clusterManager(this.properties.getBucket().getName(), this.properties.getBucket().getPassword())
.info();
@@ -103,7 +107,14 @@ public class CouchbaseConfiguration {
protected DefaultCouchbaseEnvironment.Builder initializeEnvironmentBuilder(CouchbaseProperties properties) {
CouchbaseProperties.Endpoints endpoints = properties.getEnv().getEndpoints();
CouchbaseProperties.Timeouts timeouts = properties.getEnv().getTimeouts();
+ CouchbaseProperties.Bootstrap bootstrap = properties.getEnv().getBootstrap();
DefaultCouchbaseEnvironment.Builder builder = DefaultCouchbaseEnvironment.builder();
+ if (bootstrap.getHttpDirectPort() != null) {
+ builder.bootstrapHttpDirectPort(bootstrap.getHttpDirectPort());
+ }
+ if (bootstrap.getHttpSslPort() != null) {
+ builder.bootstrapHttpSslPort(bootstrap.getHttpSslPort());
+ }
if (timeouts.getConnect() != null) {
builder = builder.connectTimeout(timeouts.getConnect().toMillis());
}
diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseProperties.java
index e7080ec5af..21d548eea1 100644
--- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseProperties.java
+++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2019 the original author or authors.
+ * Copyright 2012-2020 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.
@@ -28,6 +28,7 @@ import org.springframework.util.StringUtils;
* @author EddĂș MelĂ©ndez
* @author Stephane Nicoll
* @author Yulin Qin
+ * @author Brian Clozel
* @since 1.4.0
*/
@ConfigurationProperties(prefix = "spring.couchbase")
@@ -116,12 +117,18 @@ public class CouchbaseProperties {
public static class Env {
+ private final Bootstrap bootstrap = new Bootstrap();
+
private final Endpoints endpoints = new Endpoints();
private final Ssl ssl = new Ssl();
private final Timeouts timeouts = new Timeouts();
+ public Bootstrap getBootstrap() {
+ return this.bootstrap;
+ }
+
public Endpoints getEndpoints() {
return this.endpoints;
}
@@ -314,4 +321,34 @@ public class CouchbaseProperties {
}
+ public static class Bootstrap {
+
+ /**
+ * Port for the HTTP bootstrap.
+ */
+ private Integer httpDirectPort;
+
+ /**
+ * Port for the HTTPS bootstrap.
+ */
+ private Integer httpSslPort;
+
+ public Integer getHttpDirectPort() {
+ return this.httpDirectPort;
+ }
+
+ public void setHttpDirectPort(Integer httpDirectPort) {
+ this.httpDirectPort = httpDirectPort;
+ }
+
+ public Integer getHttpSslPort() {
+ return this.httpSslPort;
+ }
+
+ public void setHttpSslPort(Integer httpSslPort) {
+ this.httpSslPort = httpSslPort;
+ }
+
+ }
+
}
diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationIntegrationTests.java
index d11bc5eda0..9a2549e3a0 100644
--- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationIntegrationTests.java
+++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationIntegrationTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2019 the original author or authors.
+ * Copyright 2012-2020 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.
@@ -16,17 +16,24 @@
package org.springframework.boot.autoconfigure.couchbase;
+import java.time.Duration;
+
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.CouchbaseBucket;
+import com.couchbase.client.java.bucket.BucketType;
import com.couchbase.client.java.cluster.ClusterInfo;
+import com.couchbase.client.java.cluster.DefaultBucketSettings;
import com.couchbase.client.java.env.CouchbaseEnvironment;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
+import org.testcontainers.couchbase.CouchbaseContainer;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
-import org.springframework.boot.autoconfigure.AutoConfigurations;
-import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
-import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.boot.test.util.TestPropertyValues;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -37,29 +44,53 @@ import static org.mockito.Mockito.mock;
* Integration tests for {@link CouchbaseAutoConfiguration}.
*
* @author Stephane Nicoll
+ * @author Brian Clozel
*/
-@ExtendWith(LocalCouchbaseServer.class)
+@Testcontainers(disabledWithoutDocker = true)
class CouchbaseAutoConfigurationIntegrationTests {
- private ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration(
- AutoConfigurations.of(PropertyPlaceholderAutoConfiguration.class, CouchbaseAutoConfiguration.class));
+ @Container
+ static final CouchbaseContainer couchbase = new CouchbaseContainer().withClusterAdmin("spring", "password")
+ .withNewBucket(DefaultBucketSettings.builder().enableFlush(true).name("default").password("secret")
+ .quota(100).replicas(0).type(BucketType.COUCHBASE).build())
+ .withStartupAttempts(5).withStartupTimeout(Duration.ofMinutes(2));
+
+ private AnnotationConfigApplicationContext context;
+
+ @BeforeEach
+ void setUp() {
+ this.context = new AnnotationConfigApplicationContext();
+ this.context.register(CouchbaseAutoConfiguration.class);
+ TestPropertyValues.of("spring.couchbase.bootstrap-hosts=localhost",
+ "spring.couchbase.env.bootstrap.http-direct-port:" + couchbase.getMappedPort(8091),
+ "spring.couchbase.username:spring", "spring.couchbase.password:password",
+ "spring.couchbase.bucket.name:default").applyTo(this.context.getEnvironment());
+ }
+
+ @AfterEach
+ void close() {
+ if (this.context != null) {
+ this.context.close();
+ }
+ }
@Test
void defaultConfiguration() {
- this.contextRunner.withPropertyValues("spring.couchbase.bootstrapHosts=localhost")
- .run((context) -> assertThat(context).hasSingleBean(Cluster.class).hasSingleBean(ClusterInfo.class)
- .hasSingleBean(CouchbaseEnvironment.class).hasSingleBean(Bucket.class));
+ this.context.refresh();
+ assertThat(this.context.getBeansOfType(Cluster.class)).hasSize(1);
+ assertThat(this.context.getBeansOfType(ClusterInfo.class)).hasSize(1);
+ assertThat(this.context.getBeansOfType(CouchbaseEnvironment.class)).hasSize(1);
+ assertThat(this.context.getBeansOfType(Bucket.class)).hasSize(1);
}
@Test
void customConfiguration() {
- this.contextRunner.withUserConfiguration(CustomConfiguration.class)
- .withPropertyValues("spring.couchbase.bootstrapHosts=localhost").run((context) -> {
- assertThat(context.getBeansOfType(Cluster.class)).hasSize(2);
- assertThat(context.getBeansOfType(ClusterInfo.class)).hasSize(1);
- assertThat(context.getBeansOfType(CouchbaseEnvironment.class)).hasSize(1);
- assertThat(context.getBeansOfType(Bucket.class)).hasSize(2);
- });
+ this.context.register(CustomConfiguration.class);
+ this.context.refresh();
+ assertThat(this.context.getBeansOfType(Cluster.class)).hasSize(2);
+ assertThat(this.context.getBeansOfType(ClusterInfo.class)).hasSize(1);
+ assertThat(this.context.getBeansOfType(CouchbaseEnvironment.class)).hasSize(1);
+ assertThat(this.context.getBeansOfType(Bucket.class)).hasSize(2);
}
@Configuration(proxyBeanMethods = false)
diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/LocalCouchbaseServer.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/LocalCouchbaseServer.java
deleted file mode 100644
index 80103bb32c..0000000000
--- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/LocalCouchbaseServer.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2012-2019 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
- *
- * https://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.concurrent.TimeUnit;
-
-import com.couchbase.client.java.Bucket;
-import com.couchbase.client.java.Cluster;
-import com.couchbase.client.java.CouchbaseCluster;
-import com.couchbase.client.java.env.CouchbaseEnvironment;
-import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
-import org.junit.jupiter.api.extension.ConditionEvaluationResult;
-import org.junit.jupiter.api.extension.ExecutionCondition;
-import org.junit.jupiter.api.extension.Extension;
-import org.junit.jupiter.api.extension.ExtensionContext;
-import org.junit.jupiter.api.extension.TestExecutionExceptionHandler;
-
-import org.springframework.beans.factory.BeanCreationException;
-
-/**
- * {@link Extension} for working with an optional Couchbase server. Expects a default
- * {@link Bucket} with no password to be available on localhost.
- *
- * @author Stephane Nicoll
- * @author Andy Wilkinson
- */
-class LocalCouchbaseServer implements ExecutionCondition, TestExecutionExceptionHandler {
-
- @Override
- public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
- try {
- CouchbaseEnvironment environment = DefaultCouchbaseEnvironment.create();
- Cluster cluster = CouchbaseCluster.create(environment, "localhost");
- testConnection(cluster);
- cluster.disconnect();
- environment.shutdownAsync();
- return ConditionEvaluationResult.enabled("Local Couchbase server available");
- }
- catch (Exception ex) {
- return ConditionEvaluationResult.disabled("Local Couchbase server not available");
- }
- }
-
- private static void testConnection(Cluster cluster) {
- Bucket bucket = cluster.openBucket(2, TimeUnit.SECONDS);
- bucket.close();
- }
-
- @Override
- public void handleTestExecutionException(ExtensionContext context, Throwable ex) throws Throwable {
- if ((ex instanceof BeanCreationException)
- && "couchbaseClient".equals(((BeanCreationException) ex).getBeanName())) {
- return;
- }
- throw ex;
- }
-
-}