Commit fa84b179 authored by Stephane Nicoll's avatar Stephane Nicoll

Allow to customize the Couchbase environment

Closes gh-5403
parent caf11e44
......@@ -64,7 +64,7 @@ public class CouchbaseAutoConfiguration {
@Bean
@Primary
public CouchbaseEnvironment couchbaseEnvironment() throws Exception {
return DefaultCouchbaseEnvironment.create();
return createEnvironment(this.properties);
}
@Bean
......@@ -88,6 +88,35 @@ public class CouchbaseAutoConfiguration {
this.properties.getBucket().getPassword());
}
/**
* Create a {@link CouchbaseEnvironment} based on the specified settings.
* @param properties the couchbase properties to use
* @return a {@link CouchbaseEnvironment}
*/
protected CouchbaseEnvironment createEnvironment(CouchbaseProperties properties) {
CouchbaseProperties.Endpoints endpoints = properties.getEnv().getEndpoints();
CouchbaseProperties.Timeouts timeouts = properties.getEnv().getTimeouts();
DefaultCouchbaseEnvironment.Builder builder = DefaultCouchbaseEnvironment.builder()
.connectTimeout(timeouts.getConnect())
.kvEndpoints(endpoints.getKeyValue())
.kvTimeout(timeouts.getKeyValue())
.queryEndpoints(endpoints.getQuery())
.queryTimeout(timeouts.getQuery())
.viewEndpoints(endpoints.getView())
.viewTimeout(timeouts.getView());
CouchbaseProperties.Ssl ssl = properties.getEnv().getSsl();
if (ssl.getEnabled()) {
builder.sslEnabled(true);
if (ssl.getKeyStore() != null) {
builder.sslKeystoreFile(ssl.getKeyStore());
}
if (ssl.getKeyStorePassword() != null) {
builder.sslKeystorePassword(ssl.getKeyStorePassword());
}
}
return builder.build();
}
}
/**
......
......@@ -19,6 +19,8 @@ package org.springframework.boot.autoconfigure.couchbase;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.util.StringUtils;
/**
* Configuration properties for Couchbase.
......@@ -37,6 +39,8 @@ public class CouchbaseProperties {
private final Bucket bucket = new Bucket();
private final Env env = new Env();
public List<String> getBootstrapHosts() {
return this.bootstrapHosts;
}
......@@ -49,7 +53,12 @@ public class CouchbaseProperties {
return this.bucket;
}
static class Bucket {
public Env getEnv() {
return this.env;
}
public static class Bucket {
/**
* Name of the bucket to connect to.
......@@ -79,4 +88,172 @@ public class CouchbaseProperties {
}
public static class Env {
@NestedConfigurationProperty
private final Endpoints endpoints = new Endpoints();
@NestedConfigurationProperty
private final Ssl ssl = new Ssl();
@NestedConfigurationProperty
private final Timeouts timeouts = new Timeouts();
public Endpoints getEndpoints() {
return this.endpoints;
}
public Ssl getSsl() {
return this.ssl;
}
public Timeouts getTimeouts() {
return this.timeouts;
}
}
public static class Endpoints {
/**
* Number of sockets per node against the Key/value service.
*/
private int keyValue = 1;
/**
* Number of sockets per node against the Query (N1QL) service.
*/
private int query = 1;
/**
* Number of sockets per node against the view service.
*/
private int view = 1;
public int getKeyValue() {
return this.keyValue;
}
public void setKeyValue(int keyValue) {
this.keyValue = keyValue;
}
public int getQuery() {
return this.query;
}
public void setQuery(int query) {
this.query = query;
}
public int getView() {
return this.view;
}
public void setView(int view) {
this.view = view;
}
}
public static class Ssl {
/**
* Enable SSL support. Enabled automatically if a "keyStore" is provided unless
* specified otherwise.
*/
private Boolean enabled;
/**
* Path to the JVM key store that holds the certificates.
*/
private String keyStore;
/**
* Password used to access the key store.
*/
private String keyStorePassword;
public Boolean getEnabled() {
return (this.enabled != null ? this.enabled : StringUtils.hasText(this.keyStore));
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public String getKeyStore() {
return this.keyStore;
}
public void setKeyStore(String keyStore) {
this.keyStore = keyStore;
}
public String getKeyStorePassword() {
return this.keyStorePassword;
}
public void setKeyStorePassword(String keyStorePassword) {
this.keyStorePassword = keyStorePassword;
}
}
public static class Timeouts {
/**
* Bucket connections timeout in milliseconds.
*/
private long connect = 5000;
/**
* Blocking operations performed on a specific key timeout in milliseconds.
*/
private long keyValue = 2500;
/**
* N1QL query operations timeout in milliseconds.
*/
private long query = 7500;
/**
* Regular and geospatial view operations timeout in milliseconds.
*/
private long view = 7500;
public long getConnect() {
return this.connect;
}
public void setConnect(long connect) {
this.connect = connect;
}
public long getKeyValue() {
return this.keyValue;
}
public void setKeyValue(long keyValue) {
this.keyValue = keyValue;
}
public long getQuery() {
return this.query;
}
public void setQuery(long query) {
this.query = query;
}
public long getView() {
return this.view;
}
public void setView(long view) {
this.view = view;
}
}
}
......@@ -20,6 +20,7 @@ import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.cluster.ClusterInfo;
import com.couchbase.client.java.env.CouchbaseEnvironment;
import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
......@@ -58,7 +59,6 @@ public class CouchbaseAutoConfigurationTests extends AbstractCouchbaseAutoConfig
assertThat(this.context.getBeansOfType(CouchbaseTestConfigurer.class))
.hasSize(1);
assertNoCouchbaseBeans();
}
private void assertNoCouchbaseBeans() {
......@@ -69,4 +69,56 @@ public class CouchbaseAutoConfigurationTests extends AbstractCouchbaseAutoConfig
assertThat(this.context.getBeansOfType(Bucket.class)).isEmpty();
}
@Test
public void customizeEnvEndpoints() throws Exception {
DefaultCouchbaseEnvironment env = customizeEnv(
"spring.couchbase.env.endpoints.keyValue=4",
"spring.couchbase.env.endpoints.query=5",
"spring.couchbase.env.endpoints.view=6");
assertThat(env.kvEndpoints()).isEqualTo(4);
assertThat(env.queryEndpoints()).isEqualTo(5);
assertThat(env.viewEndpoints()).isEqualTo(6);
}
@Test
public void customizeEnvTimeouts() throws Exception {
DefaultCouchbaseEnvironment env = customizeEnv(
"spring.couchbase.env.timeouts.connect=100",
"spring.couchbase.env.timeouts.keyValue=200",
"spring.couchbase.env.timeouts.query=300",
"spring.couchbase.env.timeouts.view=400");
assertThat(env.connectTimeout()).isEqualTo(100);
assertThat(env.kvTimeout()).isEqualTo(200);
assertThat(env.queryTimeout()).isEqualTo(300);
assertThat(env.viewTimeout()).isEqualTo(400);
}
@Test
public void enableSslNoEnabledFlag() throws Exception {
DefaultCouchbaseEnvironment env = customizeEnv(
"spring.couchbase.env.ssl.keyStore=foo",
"spring.couchbase.env.ssl.keyStorePassword=secret");
assertThat(env.sslEnabled()).isTrue();
assertThat(env.sslKeystoreFile()).isEqualTo("foo");
assertThat(env.sslKeystorePassword()).isEqualTo("secret");
}
@Test
public void disableSslEvenWithKeyStore() throws Exception {
DefaultCouchbaseEnvironment env = customizeEnv(
"spring.couchbase.env.ssl.enabled=false",
"spring.couchbase.env.ssl.keyStore=foo",
"spring.couchbase.env.ssl.keyStorePassword=secret");
assertThat(env.sslEnabled()).isFalse();
assertThat(env.sslKeystoreFile()).isNull();
assertThat(env.sslKeystorePassword()).isNull();
}
private DefaultCouchbaseEnvironment customizeEnv(String... environment) throws Exception {
load(CouchbaseTestConfigurer.class, environment);
CouchbaseProperties properties = this.context.getBean(CouchbaseProperties.class);
return (DefaultCouchbaseEnvironment) new CouchbaseAutoConfiguration.CouchbaseConfiguration(properties)
.couchbaseEnvironment();
}
}
......@@ -478,6 +478,16 @@ content into your application; rather pick only the properties that you need.
spring.couchbase.bootstrap-hosts= # Couchbase nodes (host or IP address) to bootstrap from.
spring.couchbase.bucket.name=default # Name of the bucket to connect to.
spring.couchbase.bucket.password= # Password of the bucket.
spring.couchbase.env.endpoints.key-value=1 # Number of sockets per node against the Key/value service.
spring.couchbase.env.endpoints.query=1 # Number of sockets per node against the Query (N1QL) service.
spring.couchbase.env.endpoints.view=1 # Number of sockets per node against the view service.
spring.couchbase.env.ssl.enabled= # Enable SSL support. Enabled automatically if a "keyStore" is provided unless specified otherwise.
spring.couchbase.env.ssl.key-store= # Path to the JVM key store that holds the certificates.
spring.couchbase.env.ssl.key-store-password= # Password used to access the key store.
spring.couchbase.env.timeouts.connect=5000 # Bucket connections timeout in milliseconds.
spring.couchbase.env.timeouts.key-value=2500 # Blocking operations performed on a specific key timeout in milliseconds.
spring.couchbase.env.timeouts.query=7500 # N1QL query operations timeout in milliseconds.
spring.couchbase.env.timeouts.view=7500 # Regular and geospatial view operations timeout in milliseconds.
# DAO ({sc-spring-boot-autoconfigure}/dao/PersistenceExceptionTranslationAutoConfiguration.{sc-ext}[PersistenceExceptionTranslationAutoConfiguration])
spring.dao.exceptiontranslation.enabled=true # Enable the PersistenceExceptionTranslationPostProcessor.
......
......@@ -3217,6 +3217,20 @@ own `org.springframework.data.couchbase.config.CouchbaseConfigurer` `@Bean` to t
control over the whole configuration.
====
It is also possible to customize some of the `CouchbaseEnvironment` settings. For instance
the following configuration changes the timeout to use to open a new `Bucket` and enable
SSL support:
[source,properties,indent=0]
----
spring.couchbase.env.timeouts.connect=3000
spring.couchbase.env.ssl.key-store=/location/of/keystore.jks
spring.couchbase.env.ssl.key-store-password=secret
----
Check the `spring.couchbase.env.*` properties for more details.
[[boot-features-spring-data-couchbase-repositories]]
==== Spring Data Couchbase repositories
Spring Data includes repository support for Couchbase. For complete details of Spring
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment