DATACOUCH-362 - Use dynamic proxying

Dynamic proxying for couchbase environment instead of an explicit no shutdown
proxy.

Original pull request: #157.

DATACOUCH-363 - Upgrade to 2.5.5

Java client upgrade. Remove the dcpEnabled property from
CouchbaseEnvironment factory bean and parser.

Original pull request: #157.
This commit is contained in:
Subhashni Balakrishnan
2018-02-08 16:23:40 -08:00
parent 7502f20e6d
commit 63a70fa8c1
12 changed files with 143 additions and 408 deletions

View File

@@ -18,8 +18,8 @@
</parent>
<properties>
<couchbase>2.4.6</couchbase>
<couchbase.osgi>2.4.6</couchbase.osgi>
<couchbase>2.5.5</couchbase>
<couchbase.osgi>2.5.5</couchbase.osgi>
<springdata.commons>2.0.6.BUILD-SNAPSHOT</springdata.commons>
<java-module-name>spring.data.couchbase</java-module-name>
</properties>

View File

@@ -0,0 +1,55 @@
package org.springframework.data.couchbase;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
import org.springframework.data.couchbase.config.CouchbaseConfigurer;
/**
* Configuration for testing no shutdown
*
* @author Subhashni Balakrishnan
*/
public class IntegrationTestNoShutdownApplicationConfig extends AbstractCouchbaseConfiguration {
@Autowired
private Environment springEnv;
@Bean
public String couchbaseAdminUser() {
return springEnv.getProperty("couchbase.adminUser", "Administrator");
}
@Bean
public String couchbaseAdminPassword() {
return springEnv.getProperty("couchbase.adminUser", "password");
}
@Override
protected List<String> getBootstrapHosts() {
return Collections.singletonList(springEnv.getProperty("couchbase.host", "127.0.0.1"));
}
@Override
protected String getBucketName() {
return springEnv.getProperty("couchbase.bucket", "default");
}
@Override
protected String getBucketPassword() {
return springEnv.getProperty("couchbase.password", "");
}
@Override
protected boolean isEnvironmentManagedBySpring() {
return false;
}
@Override
protected CouchbaseConfigurer couchbaseConfigurer() {
return this;
}
}

View File

@@ -0,0 +1,26 @@
package org.springframework.data.couchbase.config;
import com.couchbase.client.java.env.CouchbaseEnvironment;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.couchbase.IntegrationTestNoShutdownApplicationConfig;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* Simple test to make sure that environment is not shutdown if not life cycle managed by Spring.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = IntegrationTestNoShutdownApplicationConfig.class)
public class CouchbaseEnvironmentNoShutdownProxyTest {
@Autowired
public CouchbaseEnvironment environment;
@Test
public void testEnvironmentShutDown() {
Assert.assertEquals("Should return false", false, environment.shutdown());
}
}

View File

@@ -16,6 +16,7 @@
package org.springframework.data.couchbase.config;
import java.lang.reflect.Proxy;
import java.util.List;
import com.couchbase.client.java.Bucket;
@@ -90,11 +91,14 @@ public abstract class AbstractCouchbaseConfiguration
@Override
@Bean(destroyMethod = "shutdown", name = BeanNames.COUCHBASE_ENV)
public CouchbaseEnvironment couchbaseEnvironment() {
CouchbaseEnvironment env = getEnvironment();
if (isEnvironmentManagedBySpring()) {
return env;
return getEnvironment();
} else {
CouchbaseEnvironment proxy = (CouchbaseEnvironment) Proxy.newProxyInstance(CouchbaseEnvironment.class.getClassLoader(),
new Class[]{CouchbaseEnvironment.class},
new CouchbaseEnvironmentNoShutdownInvocationHandler(getEnvironment()));
return proxy;
}
return new CouchbaseEnvironmentNoShutdownProxy(env);
}
/**

View File

@@ -25,6 +25,7 @@ import com.couchbase.client.java.cluster.ClusterInfo;
import com.couchbase.client.java.env.CouchbaseEnvironment;
import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
import java.lang.reflect.Proxy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -88,11 +89,14 @@ public abstract class AbstractReactiveCouchbaseConfiguration
@Override
@Bean(destroyMethod = "shutdown", name = BeanNames.COUCHBASE_ENV)
public CouchbaseEnvironment couchbaseEnvironment() {
CouchbaseEnvironment env = getEnvironment();
if (isEnvironmentManagedBySpring()) {
return env;
return getEnvironment();
} else {
CouchbaseEnvironment proxy = (CouchbaseEnvironment) java.lang.reflect.Proxy.newProxyInstance(CouchbaseEnvironment.class.getClassLoader(),
new Class[]{CouchbaseEnvironment.class},
new CouchbaseEnvironmentNoShutdownInvocationHandler(getEnvironment()));
return proxy;
}
return new CouchbaseEnvironmentNoShutdownProxy(env);
}
/**

View File

@@ -119,10 +119,6 @@ import org.springframework.beans.factory.config.AbstractFactoryBean;
this.couchbaseEnvBuilder.dnsSrvEnabled(dnsSrvEnabled);
}
public void setDcpEnabled(boolean dcpEnabled) {
this.couchbaseEnvBuilder.dcpEnabled(dcpEnabled);
}
public void setSslEnabled(boolean sslEnabled) {
this.couchbaseEnvBuilder.sslEnabled(sslEnabled);
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2012-2017 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.data.couchbase.config;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import com.couchbase.client.java.env.CouchbaseEnvironment;
/**
* A dynamic proxy around a {@link CouchbaseEnvironment} that prevents its {@link CouchbaseEnvironment#shutdown()} method
* to be invoked. Useful when the delegate is not to be lifecycle-managed by Spring.
*
* @author Simon Baslé
* @author Jonathan Edwards
* @author Subhashni Balakrishnan
*/
public class CouchbaseEnvironmentNoShutdownInvocationHandler implements InvocationHandler {
private final CouchbaseEnvironment environment;
public CouchbaseEnvironmentNoShutdownInvocationHandler(CouchbaseEnvironment environment) {
this.environment = environment;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().contentEquals("shutdown")) {
return false;
}
return method.invoke(this.environment, args);
}
}

View File

@@ -1,391 +0,0 @@
/*
* Copyright 2012-2017 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.data.couchbase.config;
import java.security.KeyStore;
import java.util.concurrent.TimeUnit;
import com.couchbase.client.core.env.*;
import com.couchbase.client.core.event.EventBus;
import com.couchbase.client.core.metrics.MetricsCollector;
import com.couchbase.client.core.metrics.NetworkLatencyMetricsCollector;
import com.couchbase.client.core.node.MemcachedHashingStrategy;
import com.couchbase.client.core.retry.RetryStrategy;
import com.couchbase.client.core.time.Delay;
import com.couchbase.client.deps.io.netty.channel.EventLoopGroup;
import com.couchbase.client.java.env.CouchbaseEnvironment;
import rx.Observable;
import rx.Scheduler;
/**
* A proxy around a {@link CouchbaseEnvironment} that prevents its {@link #shutdown()} method
* to be invoked. Useful when the delegate is not to be lifecycle-managed by Spring.
*
* @author Simon Baslé
* @author Jonathan Edwards
* @author Subhashni Balakrishnan
*/
public class CouchbaseEnvironmentNoShutdownProxy implements CouchbaseEnvironment {
private final CouchbaseEnvironment delegate;
public CouchbaseEnvironmentNoShutdownProxy(CouchbaseEnvironment delegate) {
this.delegate = delegate;
}
@Override
public boolean shutdown() {
return false;
}
//===== DELEGATION METHODS =====
@Override
public Observable<Boolean> shutdownAsync() {
return delegate.shutdownAsync();
}
@Override
public EventLoopGroup ioPool() {
return delegate.ioPool();
}
@Override
public EventLoopGroup kvIoPool() {
return delegate.kvIoPool();
}
@Override
public Scheduler scheduler() {
return delegate.scheduler();
}
@Override
public boolean dcpEnabled() {
return delegate.dcpEnabled();
}
@Override
public boolean sslEnabled() {
return delegate.sslEnabled();
}
@Override
public String sslKeystoreFile() {
return delegate.sslKeystoreFile();
}
@Override
public String sslKeystorePassword() {
return delegate.sslKeystorePassword();
}
@Override
public boolean bootstrapHttpEnabled() {
return delegate.bootstrapHttpEnabled();
}
@Override
public boolean bootstrapCarrierEnabled() {
return delegate.bootstrapCarrierEnabled();
}
@Override
public int bootstrapHttpDirectPort() {
return delegate.bootstrapHttpDirectPort();
}
@Override
public int bootstrapHttpSslPort() {
return delegate.bootstrapHttpSslPort();
}
@Override
public int bootstrapCarrierDirectPort() {
return delegate.bootstrapCarrierDirectPort();
}
@Override
public int bootstrapCarrierSslPort() {
return delegate.bootstrapCarrierSslPort();
}
@Override
public int ioPoolSize() {
return delegate.ioPoolSize();
}
@Override
public int computationPoolSize() {
return delegate.computationPoolSize();
}
@Override
public Delay observeIntervalDelay() {
return delegate.observeIntervalDelay();
}
@Override
public Delay reconnectDelay() {
return delegate.reconnectDelay();
}
@Override
public Delay retryDelay() {
return delegate.retryDelay();
}
@Override
public int requestBufferSize() {
return delegate.requestBufferSize();
}
@Override
public int responseBufferSize() {
return delegate.responseBufferSize();
}
@Override
public int dcpConnectionBufferSize() {
return delegate.dcpConnectionBufferSize();
}
@Override
public double dcpConnectionBufferAckThreshold() {
return delegate.dcpConnectionBufferAckThreshold();
}
@Override
public int kvEndpoints() {
return delegate.kvEndpoints();
}
@Override
public int viewEndpoints() {
return delegate.viewEndpoints();
}
@Override
public int queryEndpoints() {
return delegate.queryEndpoints();
}
@Override
public String userAgent() {
return delegate.userAgent();
}
@Override
public String packageNameAndVersion() {
return delegate.packageNameAndVersion();
}
@Override
public RetryStrategy retryStrategy() {
return delegate.retryStrategy();
}
@Override
public long maxRequestLifetime() {
return delegate.maxRequestLifetime();
}
@Override
public long autoreleaseAfter() {
return delegate.autoreleaseAfter();
}
@Override
public long keepAliveInterval() {
return delegate.keepAliveInterval();
}
@Override
public EventBus eventBus() {
return delegate.eventBus();
}
@Override
public boolean bufferPoolingEnabled() {
return delegate.bufferPoolingEnabled();
}
@Override
public long managementTimeout() {
return delegate.managementTimeout();
}
@Override
public long queryTimeout() {
return delegate.queryTimeout();
}
@Override
public long viewTimeout() {
return delegate.viewTimeout();
}
@Override
public long kvTimeout() {
return delegate.kvTimeout();
}
@Override
public long connectTimeout() {
return delegate.connectTimeout();
}
@Override
public long disconnectTimeout() {
return delegate.disconnectTimeout();
}
@Override
public boolean dnsSrvEnabled() {
return delegate.dnsSrvEnabled();
}
@Override
public NetworkLatencyMetricsCollector networkLatencyMetricsCollector() {
return delegate.networkLatencyMetricsCollector();
}
@Override
public int socketConnectTimeout() {
return delegate.socketConnectTimeout();
}
@Override
public MetricsCollector runtimeMetricsCollector() {
return delegate.runtimeMetricsCollector();
}
@Override
public boolean mutationTokensEnabled() {
return delegate.mutationTokensEnabled();
}
@Override
public boolean tcpNodelayEnabled() {
return delegate.tcpNodelayEnabled();
}
@Override
public boolean callbacksOnIoPool() {
return delegate.callbacksOnIoPool();
}
@Override
public String coreBuild() {
return delegate.coreBuild();
}
@Override
public String coreVersion() {
return delegate.coreVersion();
}
@Override
public String dcpConnectionName() {
return delegate.dcpConnectionName();
}
@Override
public int searchEndpoints() {
return delegate.searchEndpoints();
}
@Override
public String clientBuild() {
return delegate.clientBuild();
}
@Override
public String clientVersion() {
return delegate.clientVersion();
}
@Override
public long searchTimeout() {
return delegate.searchTimeout();
}
@Override
public WaitStrategyFactory requestBufferWaitStrategy() {
return delegate.requestBufferWaitStrategy();
}
@Override
public EventLoopGroup viewIoPool() {
return delegate.viewIoPool();
}
@Override
public EventLoopGroup searchIoPool() {
return delegate.searchIoPool();
}
@Override
public EventLoopGroup queryIoPool() {
return delegate.queryIoPool();
}
@Override
public KeyStore sslKeystore() {
return delegate.sslKeystore();
}
@Override
public boolean shutdown(long timeout, TimeUnit timeUnit) {
return delegate.shutdown(timeout, timeUnit);
}
@Override
public MemcachedHashingStrategy memcachedHashingStrategy() {
return delegate.memcachedHashingStrategy();
}
@Override
public long analyticsTimeout() {
return delegate.analyticsTimeout();
}
@Override
public long configPollInterval() {
return delegate.configPollInterval();
}
@Override
public KeyValueServiceConfig kvServiceConfig() {
return delegate.kvServiceConfig();
}
@Override
public QueryServiceConfig queryServiceConfig() {
return delegate.queryServiceConfig();
}
@Override
public SearchServiceConfig searchServiceConfig() {
return delegate.searchServiceConfig();
}
@Override
public ViewServiceConfig viewServiceConfig() {
return delegate.viewServiceConfig();
}
}

View File

@@ -40,7 +40,6 @@ import org.springframework.util.StringUtils;
* <li>{@link DefaultCouchbaseEnvironment.Builder#disconnectTimeout(long) disconnectTimeout}</li>
* <li>{@link DefaultCouchbaseEnvironment.Builder#dnsSrvEnabled(boolean) dnsSrvEnabled}</li>
*
* <li>{@link DefaultCouchbaseEnvironment.Builder#dcpEnabled(boolean) dcpEnabled}</li>
* <li>{@link DefaultCouchbaseEnvironment.Builder#sslEnabled(boolean) sslEnabled}</li>
* <li>{@link DefaultCouchbaseEnvironment.Builder#sslKeystoreFile(String) sslKeystoreFile}</li>
* <li>{@link DefaultCouchbaseEnvironment.Builder#sslKeystorePassword(String) sslKeystorePassword}</li>
@@ -113,7 +112,6 @@ public class CouchbaseEnvironmentParser extends AbstractSingleBeanDefinitionPars
setPropertyValue(envDefinitionBuilder, envElement, "disconnectTimeout", "disconnectTimeout");
setPropertyValue(envDefinitionBuilder, envElement, "dnsSrvEnabled", "dnsSrvEnabled");
setPropertyValue(envDefinitionBuilder, envElement, "dcpEnabled", "dcpEnabled");
setPropertyValue(envDefinitionBuilder, envElement, "sslEnabled", "sslEnabled");
setPropertyValue(envDefinitionBuilder, envElement, "sslKeystoreFile", "sslKeystoreFile");
setPropertyValue(envDefinitionBuilder, envElement, "sslKeystorePassword", "sslKeystorePassword");

View File

@@ -29,7 +29,6 @@
<xsd:attribute name="disconnectTimeout" type="xsd:long"/>
<xsd:attribute name="dnsSrvEnabled" type="xsd:boolean"/>
<xsd:attribute name="dcpEnabled" type="xsd:boolean"/>
<xsd:attribute name="sslEnabled" type="xsd:boolean"/>
<xsd:attribute name="sslKeystoreFile" type="xsd:string"/>
<xsd:attribute name="sslKeystorePassword" type="xsd:string"/>

View File

@@ -75,7 +75,6 @@ public class CouchbaseEnvironmentParserTest {
assertThat(env.disconnectTimeout(), is(equalTo(6L)));
assertThat(env.dnsSrvEnabled(), allOf(equalTo(true), not(defaultEnv.dnsSrvEnabled())));
assertThat(env.dcpEnabled(), allOf(equalTo(true), not(defaultEnv.dcpEnabled())));
assertThat(env.sslEnabled(), allOf(equalTo(true), not(defaultEnv.sslEnabled())));
assertThat(env.sslKeystoreFile(), is(equalTo("test")));
assertThat(env.sslKeystorePassword(), is(equalTo("test")));

View File

@@ -19,7 +19,6 @@
disconnectTimeout="6"
dnsSrvEnabled="true"
dcpEnabled="true"
sslEnabled="true"
sslKeystoreFile="test"
sslKeystorePassword="test"