DATACASS-325 - Add ClusterBuilderConfigurer configuration API.
We allow users to provide a ClusterBuilderConfigurer that can be applied to the Cluster Builder. ClusterBuilderConfigurer is a callback interface to handle extended configuration when the DataStax API changes. It allows configuration of options after all provided properties were set. Original pull request: #79. Related pull request: #80.
This commit is contained in:
@@ -101,6 +101,8 @@ public class CassandraCqlClusterFactoryBean implements FactoryBean<Cluster>, Ini
|
||||
|
||||
private Cluster cluster;
|
||||
|
||||
private ClusterBuilderConfigurer clusterBuilderConfigurer;
|
||||
|
||||
private CompressionType compressionType;
|
||||
|
||||
private Host.StateListener hostStateListener;
|
||||
@@ -237,6 +239,10 @@ public class CassandraCqlClusterFactoryBean implements FactoryBean<Cluster>, Ini
|
||||
clusterBuilder.withTimestampGenerator(timestampGenerator);
|
||||
}
|
||||
|
||||
if (clusterBuilderConfigurer != null) {
|
||||
clusterBuilderConfigurer.configure(clusterBuilder);
|
||||
}
|
||||
|
||||
cluster = clusterBuilder.build();
|
||||
|
||||
if (hostStateListener != null) {
|
||||
@@ -607,6 +613,18 @@ public class CassandraCqlClusterFactoryBean implements FactoryBean<Cluster>, Ini
|
||||
this.addressTranslator = addressTranslator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link ClusterBuilderConfigurer} used to apply additional configuration logic
|
||||
* to the {@link com.datastax.driver.core.Cluster.Builder}.
|
||||
*
|
||||
* @param clusterBuilderConfigurer {@link ClusterBuilderConfigurer} used to configure the
|
||||
* {@link com.datastax.driver.core.Cluster.Builder}.
|
||||
* @see org.springframework.cassandra.config.ClusterBuilderConfigurer
|
||||
*/
|
||||
public void setClusterBuilderConfigurer(ClusterBuilderConfigurer clusterBuilderConfigurer) {
|
||||
this.clusterBuilderConfigurer = clusterBuilderConfigurer;
|
||||
}
|
||||
|
||||
/**
|
||||
* An optional name for the create cluster.
|
||||
* \
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2013-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.cassandra.config;
|
||||
|
||||
import com.datastax.driver.core.Cluster;
|
||||
|
||||
/**
|
||||
* Configuration callback class to allow a user to apply additional configuration logic
|
||||
* to the {@link Cluster.Builder}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see com.datastax.driver.core.Cluster
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public interface ClusterBuilderConfigurer {
|
||||
|
||||
/**
|
||||
* Apply addition configuration to the {@link com.datastax.driver.core.Cluster.Builder}.
|
||||
*
|
||||
* @param clusterBuilder {@link Cluster.Builder} to configure.
|
||||
* @return the argument to the {@code clusterBuilder} parameter.
|
||||
* @see com.datastax.driver.core.Cluster.Builder
|
||||
*/
|
||||
Cluster.Builder configure(Cluster.Builder clusterBuilder);
|
||||
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cassandra.config.CassandraCqlClusterFactoryBean;
|
||||
import org.springframework.cassandra.config.ClusterBuilderConfigurer;
|
||||
import org.springframework.cassandra.config.CompressionType;
|
||||
import org.springframework.cassandra.core.keyspace.CreateKeyspaceSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.DropKeyspaceSpecification;
|
||||
@@ -45,6 +46,7 @@ import com.datastax.driver.core.policies.SpeculativeExecutionPolicy;
|
||||
* @author Matthew T. Adams
|
||||
* @author Jorge Davison
|
||||
* @author Mark Paluch
|
||||
* @author John Blum
|
||||
*/
|
||||
@Configuration
|
||||
public abstract class AbstractClusterConfiguration {
|
||||
@@ -56,6 +58,7 @@ public abstract class AbstractClusterConfiguration {
|
||||
|
||||
bean.setAddressTranslator(getAddressTranslator());
|
||||
bean.setAuthProvider(getAuthProvider());
|
||||
bean.setClusterBuilderConfigurer(getClusterBuilderConfigurer());
|
||||
bean.setClusterName(getClusterName());
|
||||
bean.setCompressionType(getCompressionType());
|
||||
bean.setContactPoints(getContactPoints());
|
||||
@@ -100,6 +103,16 @@ public abstract class AbstractClusterConfiguration {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ClusterBuilderConfigurer}.
|
||||
*
|
||||
* @return the {@link ClusterBuilderConfigurer}; may be {@literal null}.
|
||||
* @since 1.5
|
||||
*/
|
||||
protected ClusterBuilderConfigurer getClusterBuilderConfigurer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cluster name.
|
||||
*
|
||||
|
||||
@@ -91,6 +91,7 @@ public class CassandraCqlClusterParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
addOptionalPropertyReference(builder, "addressTranslator", element, "address-translator-ref");
|
||||
addOptionalPropertyReference(builder, "authProvider", element, "auth-info-provider-ref");
|
||||
addOptionalPropertyReference(builder, "clusterBuilderConfigurer", element, "cluster-builder-configurer-ref");
|
||||
addOptionalPropertyReference(builder, "hostStateListener", element, "host-state-listener-ref");
|
||||
addOptionalPropertyReference(builder, "latencyTracker", element, "latency-tracker-ref");
|
||||
addOptionalPropertyReference(builder, "loadBalancingPolicy", element, "load-balancing-policy-ref");
|
||||
|
||||
@@ -139,6 +139,24 @@ AuthInfoProvider implementation.
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="cluster-builder-configurer-ref" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Sets the ClusterBuilderConfigurer used to apply additional configuration logic
|
||||
to the com.datastax.driver.core.Cluster.Builder.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.cassandra.config.ClusterBuilderConfigurer"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="cluster-name" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.cassandra.config;
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.Mockito.isA;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Matchers;
|
||||
@@ -309,6 +310,18 @@ public class CassandraCqlClusterFactoryBeanUnitTests {
|
||||
assertThat(getConfiguration(bean).getMetricsOptions().isJMXReportingEnabled(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCallClusterBuilderConfigurer() throws Exception {
|
||||
|
||||
ClusterBuilderConfigurer mockClusterBuilderConfigurer = mock(ClusterBuilderConfigurer.class);
|
||||
CassandraCqlClusterFactoryBean bean = new CassandraCqlClusterFactoryBean();
|
||||
|
||||
bean.setClusterBuilderConfigurer(mockClusterBuilderConfigurer);
|
||||
bean.afterPropertiesSet();
|
||||
|
||||
verify(mockClusterBuilderConfigurer, times(1)).configure(isA(Cluster.Builder.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see <a href="https://jira.spring.io/browse/DATACASS-316">DATACASS-316</a>
|
||||
*/
|
||||
|
||||
@@ -18,12 +18,15 @@ package org.springframework.cassandra.config.java;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.mockito.Mockito.isA;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cassandra.config.CassandraCqlClusterFactoryBean;
|
||||
import org.springframework.cassandra.config.ClusterBuilderConfigurer;
|
||||
import org.springframework.cassandra.config.CompressionType;
|
||||
import org.springframework.cassandra.core.keyspace.CreateKeyspaceSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.DropKeyspaceSpecification;
|
||||
@@ -52,8 +55,9 @@ import com.datastax.driver.core.policies.SpeculativeExecutionPolicy;
|
||||
* Unit tests for {@link AbstractClusterConfiguration}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author John Blum
|
||||
* @soundtrack Max Graham Feat Neev Kennedy - So Caught Up (Dns Project Remix)
|
||||
* @see DATACASS-226
|
||||
* @see <a href="https://jira.spring.io/browse/DATACASS-226"></a>
|
||||
*/
|
||||
public class AbstractClusterConfigurationUnitTests {
|
||||
|
||||
@@ -344,6 +348,24 @@ public class AbstractClusterConfigurationUnitTests {
|
||||
is(equalTo(mockAddressTranslator)));
|
||||
}
|
||||
|
||||
/**
|
||||
* <a href="https://jira.spring.io/browse/DATACASS-325">DATACASS-325</a>
|
||||
*/
|
||||
@Test
|
||||
public void shouldSetAndApplyClusterBuilderConfigurer() throws Exception {
|
||||
final ClusterBuilderConfigurer mockClusterBuilderConfigurer = mock(ClusterBuilderConfigurer.class);
|
||||
|
||||
AbstractClusterConfiguration clusterConfiguration = new AbstractClusterConfiguration() {
|
||||
@Override protected ClusterBuilderConfigurer getClusterBuilderConfigurer() {
|
||||
return mockClusterBuilderConfigurer;
|
||||
}
|
||||
};
|
||||
|
||||
assertThat(getCluster(clusterConfiguration), is(notNullValue(Cluster.class)));
|
||||
|
||||
verify(mockClusterBuilderConfigurer, times(1)).configure(isA(Cluster.Builder.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* <a href="https://jira.spring.io/browse/DATACASS-120">DATACASS-120</a>
|
||||
* <a href="https://jira.spring.io/browse/DATACASS-317">DATACASS-317</a>
|
||||
|
||||
@@ -88,6 +88,7 @@ public class CassandraCqlClusterParserUnitTests {
|
||||
when(mockContainingBeanDefinition.getScope()).thenReturn("Singleton");
|
||||
when(mockElement.getAttribute("address-translator-ref")).thenReturn("testAddressTranslator");
|
||||
when(mockElement.getAttribute("auth-info-provider-ref")).thenReturn("testAuthInfoProvider");
|
||||
when(mockElement.getAttribute("cluster-builder-configurer-ref")).thenReturn("testClusterBuilderConfigurer");
|
||||
when(mockElement.getAttribute("host-state-listener-ref")).thenReturn("testHostStateListener");
|
||||
when(mockElement.getAttribute("latency-tracker-ref")).thenReturn("testLatencyTracker");
|
||||
when(mockElement.getAttribute("load-balancing-policy-ref")).thenReturn("testLoadBalancingPolicy");
|
||||
@@ -124,6 +125,7 @@ public class CassandraCqlClusterParserUnitTests {
|
||||
assertThat(beanDefinition.isLazyInit(), is(false));
|
||||
assertThat(getPropertyValueAsString(beanDefinition, "addressTranslator"), is(equalTo("testAddressTranslator")));
|
||||
assertThat(getPropertyValueAsString(beanDefinition, "authProvider"), is(equalTo("testAuthInfoProvider")));
|
||||
assertThat(getPropertyValueAsString(beanDefinition, "clusterBuilderConfigurer"), is(equalTo("testClusterBuilderConfigurer")));
|
||||
assertThat(getPropertyValueAsString(beanDefinition, "hostStateListener"), is(equalTo("testHostStateListener")));
|
||||
assertThat(getPropertyValueAsString(beanDefinition, "latencyTracker"), is(equalTo("testLatencyTracker")));
|
||||
assertThat(getPropertyValueAsString(beanDefinition, "loadBalancingPolicy"), is(equalTo("testLoadBalancingPolicy")));
|
||||
@@ -146,6 +148,7 @@ public class CassandraCqlClusterParserUnitTests {
|
||||
verify(mockContainingBeanDefinition).getScope();
|
||||
verify(mockElement).getAttribute(eq("address-translator-ref"));
|
||||
verify(mockElement).getAttribute(eq("auth-info-provider-ref"));
|
||||
verify(mockElement).getAttribute(eq("cluster-builder-configurer-ref"));
|
||||
verify(mockElement).getAttribute(eq("host-state-listener-ref"));
|
||||
verify(mockElement).getAttribute(eq("latency-tracker-ref"));
|
||||
verify(mockElement).getAttribute(eq("load-balancing-policy-ref"));
|
||||
|
||||
@@ -19,11 +19,13 @@ import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.springframework.cassandra.config.ClusterBuilderConfigurer;
|
||||
import org.springframework.cassandra.test.integration.AbstractEmbeddedCassandraIntegrationTest;
|
||||
import org.springframework.cassandra.test.integration.KeyspaceRule;
|
||||
import org.springframework.cassandra.test.integration.config.IntegrationTestUtils;
|
||||
@@ -59,6 +61,7 @@ public class XmlConfigIntegrationTests extends AbstractEmbeddedCassandraIntegrat
|
||||
|
||||
private AddressTranslator addressTranslator;
|
||||
private Cluster cluster;
|
||||
private ClusterBuilderConfigurer clusterBuilderConfigurer;
|
||||
private Executor executor;
|
||||
private Session session;
|
||||
private SpeculativeExecutionPolicy speculativeExecutionPolicy;
|
||||
@@ -71,6 +74,7 @@ public class XmlConfigIntegrationTests extends AbstractEmbeddedCassandraIntegrat
|
||||
|
||||
this.addressTranslator = applicationContext.getBean(AddressTranslator.class);
|
||||
this.cluster = applicationContext.getBean(Cluster.class);
|
||||
this.clusterBuilderConfigurer = applicationContext.getBean(ClusterBuilderConfigurer.class);
|
||||
this.executor = applicationContext.getBean(Executor.class);
|
||||
this.session = applicationContext.getBean(Session.class);
|
||||
this.speculativeExecutionPolicy = applicationContext.getBean(SpeculativeExecutionPolicy.class);
|
||||
@@ -101,6 +105,12 @@ public class XmlConfigIntegrationTests extends AbstractEmbeddedCassandraIntegrat
|
||||
assertThat(cluster.getConfiguration().getPolicies().getTimestampGenerator(), is(equalTo(timestampGenerator)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clusterBuilderConfigurerWasCalled() {
|
||||
assertThat(clusterBuilderConfigurer, is(instanceOf(TestClusterBuilderConfigurer.class)));
|
||||
assertThat(((TestClusterBuilderConfigurer) clusterBuilderConfigurer).configureCalled.get(), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see <a href="https://jira.spring.io/browse/DATACASS-298">DATACASS-298</a>
|
||||
*/
|
||||
@@ -142,4 +152,15 @@ public class XmlConfigIntegrationTests extends AbstractEmbeddedCassandraIntegrat
|
||||
assertThat(socketOptions.getSoLinger(), is(equalTo(60)));
|
||||
assertThat(socketOptions.getTcpNoDelay(), is(true));
|
||||
}
|
||||
|
||||
public static class TestClusterBuilderConfigurer implements ClusterBuilderConfigurer {
|
||||
|
||||
AtomicBoolean configureCalled = new AtomicBoolean(false);
|
||||
|
||||
@Override
|
||||
public Cluster.Builder configure(Cluster.Builder clusterBuilder) {
|
||||
configureCalled.set(true);
|
||||
return clusterBuilder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
<bean name="testAddressTranslator" class="com.datastax.driver.core.policies.IdentityTranslator"/>
|
||||
|
||||
<bean name="testClusterBuilderConfigurer" class="org.springframework.cassandra.test.integration.config.xml.XmlConfigIntegrationTests.TestClusterBuilderConfigurer"/>
|
||||
|
||||
<bean name="testSpeculativeExecutionPolicy" class="com.datastax.driver.core.policies.NoSpeculativeExecutionPolicy"/>
|
||||
|
||||
<bean name="testTimestampGenerator" class="com.datastax.driver.core.AtomicMonotonicTimestampGenerator"/>
|
||||
@@ -24,6 +26,7 @@
|
||||
<cassandra:cluster
|
||||
cluster-name="skynet" contact-points="localhost" port="${build.cassandra.native_transport_port}"
|
||||
address-translator-ref="testAddressTranslator"
|
||||
cluster-builder-configurer-ref="testClusterBuilderConfigurer"
|
||||
heartbeat-interval-seconds="60"
|
||||
initialization-executor-ref="testExecutor"
|
||||
idle-timeout-seconds="300"
|
||||
|
||||
@@ -148,6 +148,24 @@ AuthInfoProvider implementation.
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="cluster-builder-configurer-ref" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Sets the ClusterBuilderConfigurer used to apply additional configuration logic
|
||||
to the com.datastax.driver.core.Cluster.Builder.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.cassandra.config.ClusterBuilderConfigurer"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="cluster-name" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
|
||||
Reference in New Issue
Block a user