DATACASS-475 - Simplify logic in afterPropertiesSet for Cassandra CQL Cluster and Session FactoryBeans.

This commit is contained in:
John Blum
2017-07-07 12:58:16 -07:00
parent 1d4db2cc92
commit 54528c6910
4 changed files with 137 additions and 154 deletions

View File

@@ -47,6 +47,51 @@ public class CassandraSessionFactoryBean extends CassandraCqlSessionFactoryBean
private SchemaAction schemaAction = SchemaAction.NONE;
/*
* (non-Javadoc)
* @see org.springframework.cassandra.config.CassandraCqlSessionFactoryBean#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() throws Exception {
Assert.state(converter != null, "Converter was not properly initialized");
super.afterPropertiesSet();
admin = new CassandraAdminTemplate(getObject(), converter);
performSchemaAction();
}
/**
* Perform the configure {@link SchemaAction} using {@link CassandraMappingContext} metadata.
*/
protected void performSchemaAction() {
boolean create = false;
boolean drop = DEFAULT_DROP_TABLES;
boolean dropUnused = DEFAULT_DROP_UNUSED_TABLES;
boolean ifNotExists = DEFAULT_CREATE_IF_NOT_EXISTS;
switch (schemaAction) {
case RECREATE_DROP_UNUSED:
dropUnused = true;
case RECREATE:
drop = true;
case CREATE_IF_NOT_EXISTS:
ifNotExists = SchemaAction.CREATE_IF_NOT_EXISTS.equals(schemaAction);
case CREATE:
create = true;
case NONE:
default:
// do nothing
}
if (create) {
createTables(drop, dropUnused, ifNotExists);
}
}
/**
* Set the {@link CassandraConverter} to use. Schema actions will derive table and user type information from the
* {@link CassandraMappingContext} inside {@code converter}.
@@ -92,50 +137,6 @@ public class CassandraSessionFactoryBean extends CassandraCqlSessionFactoryBean
return schemaAction;
}
/* (non-Javadoc)
* @see org.springframework.cassandra.config.CassandraCqlSessionFactoryBean#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() throws Exception {
Assert.state(converter != null, "Converter was not properly initialized");
super.afterPropertiesSet();
admin = new CassandraAdminTemplate(getObject(), converter);
performSchemaAction();
}
/**
* Perform the configure {@link SchemaAction} using {@link CassandraMappingContext} metadata.
*/
protected void performSchemaAction() {
boolean create = false;
boolean drop = DEFAULT_DROP_TABLES;
boolean dropUnused = DEFAULT_DROP_UNUSED_TABLES;
boolean ifNotExists = DEFAULT_CREATE_IF_NOT_EXISTS;
switch (schemaAction) {
case RECREATE_DROP_UNUSED:
dropUnused = true;
case RECREATE:
drop = true;
case CREATE_IF_NOT_EXISTS:
ifNotExists = SchemaAction.CREATE_IF_NOT_EXISTS.equals(schemaAction);
case CREATE:
create = true;
case NONE:
default:
// do nothing
}
if (create) {
createTables(drop, dropUnused, ifNotExists);
}
}
/**
* Perform schema actions.
*

View File

@@ -18,10 +18,9 @@ package org.springframework.data.cql.config;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
@@ -39,9 +38,23 @@ import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import com.datastax.driver.core.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.datastax.driver.core.AuthProvider;
import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.Cluster.Builder;
import com.datastax.driver.core.Host;
import com.datastax.driver.core.LatencyTracker;
import com.datastax.driver.core.NettyOptions;
import com.datastax.driver.core.PoolingOptions;
import com.datastax.driver.core.ProtocolOptions.Compression;
import com.datastax.driver.core.ProtocolVersion;
import com.datastax.driver.core.QueryOptions;
import com.datastax.driver.core.SSLOptions;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.SocketOptions;
import com.datastax.driver.core.TimestampGenerator;
import com.datastax.driver.core.policies.AddressTranslator;
import com.datastax.driver.core.policies.LoadBalancingPolicy;
import com.datastax.driver.core.policies.ReconnectionPolicy;
@@ -129,89 +142,55 @@ public class CassandraCqlClusterFactoryBean
@Override
public void afterPropertiesSet() throws Exception {
Assert.isTrue(StringUtils.hasText(contactPoints), "At least one server is required");
Assert.hasText(contactPoints, "At least one server is required");
Cluster.Builder clusterBuilder = newClusterBuilder();
clusterBuilder.addContactPoints(StringUtils.commaDelimitedListToStringArray(contactPoints)).withPort(port);
clusterBuilder.withMaxSchemaAgreementWaitSeconds(maxSchemaAgreementWaitSeconds);
if (compressionType != null) {
clusterBuilder.withCompression(convertCompressionType(compressionType));
}
Optional.ofNullable(compressionType).map(CassandraCqlClusterFactoryBean::convertCompressionType)
.ifPresent(clusterBuilder::withCompression);
if (poolingOptions != null) {
clusterBuilder.withPoolingOptions(poolingOptions);
}
if (socketOptions != null) {
clusterBuilder.withSocketOptions(socketOptions);
}
if (queryOptions != null) {
clusterBuilder.withQueryOptions(queryOptions);
}
Optional.ofNullable(addressTranslator).ifPresent(clusterBuilder::withAddressTranslator);
Optional.ofNullable(loadBalancingPolicy).ifPresent(clusterBuilder::withLoadBalancingPolicy);
Optional.ofNullable(nettyOptions).ifPresent(clusterBuilder::withNettyOptions);
Optional.ofNullable(poolingOptions).ifPresent(clusterBuilder::withPoolingOptions);
Optional.ofNullable(protocolVersion).ifPresent(clusterBuilder::withProtocolVersion);
Optional.ofNullable(queryOptions).ifPresent(clusterBuilder::withQueryOptions);
Optional.ofNullable(reconnectionPolicy).ifPresent(clusterBuilder::withReconnectionPolicy);
Optional.ofNullable(retryPolicy).ifPresent(clusterBuilder::withRetryPolicy);
Optional.ofNullable(socketOptions).ifPresent(clusterBuilder::withSocketOptions);
Optional.ofNullable(speculativeExecutionPolicy).ifPresent(clusterBuilder::withSpeculativeExecutionPolicy);
Optional.ofNullable(timestampGenerator).ifPresent(clusterBuilder::withTimestampGenerator);
if (authProvider != null) {
clusterBuilder.withAuthProvider(authProvider);
} else if (username != null) {
}
else if (username != null) {
clusterBuilder.withCredentials(username, password);
}
if (nettyOptions != null) {
clusterBuilder.withNettyOptions(nettyOptions);
}
if (loadBalancingPolicy != null) {
clusterBuilder.withLoadBalancingPolicy(loadBalancingPolicy);
}
if (reconnectionPolicy != null) {
clusterBuilder.withReconnectionPolicy(reconnectionPolicy);
}
if (retryPolicy != null) {
clusterBuilder.withRetryPolicy(retryPolicy);
}
if (!metricsEnabled) {
clusterBuilder.withoutMetrics();
}
if (!jmxReportingEnabled) {
clusterBuilder.withoutJMXReporting();
}
if (!metricsEnabled) {
clusterBuilder.withoutMetrics();
}
if (sslEnabled) {
if (sslOptions == null) {
clusterBuilder.withSSL();
} else {
if (sslOptions != null) {
clusterBuilder.withSSL(sslOptions);
}
else {
clusterBuilder.withSSL();
}
}
if (protocolVersion != null) {
clusterBuilder.withProtocolVersion(protocolVersion);
}
Optional.ofNullable(resolveClusterName()).filter(StringUtils::hasText)
.ifPresent(clusterBuilder::withClusterName);
if (addressTranslator != null) {
clusterBuilder.withAddressTranslator(addressTranslator);
}
String clusterName = resolveClusterName();
if (StringUtils.hasText(clusterName)) {
clusterBuilder.withClusterName(clusterName);
}
clusterBuilder.withMaxSchemaAgreementWaitSeconds(maxSchemaAgreementWaitSeconds);
if (speculativeExecutionPolicy != null) {
clusterBuilder.withSpeculativeExecutionPolicy(speculativeExecutionPolicy);
}
if (timestampGenerator != null) {
clusterBuilder.withTimestampGenerator(timestampGenerator);
}
if (clusterBuilderConfigurer != null) {
clusterBuilderConfigurer.configure(clusterBuilder);
@@ -219,16 +198,10 @@ public class CassandraCqlClusterFactoryBean
cluster = clusterBuilder.build();
if (hostStateListener != null) {
cluster.register(hostStateListener);
}
if (latencyTracker != null) {
cluster.register(latencyTracker);
}
Optional.ofNullable(hostStateListener).ifPresent(cluster::register);
Optional.ofNullable(latencyTracker).ifPresent(cluster::register);
generateSpecificationsFromFactoryBeans();
executeSpecsAndScripts(keyspaceCreations, startupScripts);
}
@@ -240,6 +213,7 @@ public class CassandraCqlClusterFactoryBean
return Cluster.builder();
}
/* (non-Javadoc) */
private String resolveClusterName() {
return (StringUtils.hasText(clusterName) ? clusterName : beanName);
}
@@ -297,6 +271,7 @@ public class CassandraCqlClusterFactoryBean
private void generateSpecificationsFromFactoryBeans() {
keyspaceSpecifications.forEach(keyspaceActionSpecification -> {
if (keyspaceActionSpecification instanceof CreateKeyspaceSpecification) {
keyspaceCreations.add((CreateKeyspaceSpecification) keyspaceActionSpecification);
}
@@ -321,7 +296,8 @@ public class CassandraCqlClusterFactoryBean
.forEach(keyspaceActionSpecification -> template.execute(toCql(keyspaceActionSpecification)));
scripts.forEach(template::execute);
} finally {
}
finally {
if (session != null) {
session.close();
}

View File

@@ -20,8 +20,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
@@ -34,6 +32,9 @@ import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.Session;
@@ -69,7 +70,25 @@ public class CassandraCqlSessionFactoryBean
private String keyspaceName;
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() throws Exception {
this.session = connect(getKeyspaceName());
executeScripts(getStartupScripts());
}
/* (non-Javadoc) */
Session connect(String keyspaceName) {
return (StringUtils.hasText(keyspaceName) ? getCluster().connect(keyspaceName) : getCluster().connect());
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
@Override
@@ -77,7 +96,8 @@ public class CassandraCqlSessionFactoryBean
return this.session;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
@Override
@@ -85,7 +105,8 @@ public class CassandraCqlSessionFactoryBean
return (this.session != null ? this.session.getClass() : Session.class);
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
*/
@Override
@@ -93,27 +114,11 @@ public class CassandraCqlSessionFactoryBean
return true;
}
/* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() throws Exception {
this.session = connect(getKeyspaceName());
executeScripts(getStartupScripts());
}
Session connect(String keyspaceName) {
return (StringUtils.hasText(keyspaceName) ? getCluster().connect(keyspaceName) : getCluster().connect());
}
/* (non-Javadoc)
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
@Override
public void destroy() throws Exception {
executeScripts(getShutdownScripts());
getSession().close();
}
@@ -160,6 +165,7 @@ public class CassandraCqlSessionFactoryBean
public boolean isConnected() {
Session session = getObject();
return !(session == null || session.isClosed());
}
@@ -172,7 +178,6 @@ public class CassandraCqlSessionFactoryBean
* @see #getCluster()
*/
public void setCluster(Cluster cluster) {
Assert.notNull(cluster, "Cluster must not be null");
this.cluster = cluster;
}
@@ -186,7 +191,6 @@ public class CassandraCqlSessionFactoryBean
* @see #setCluster(Cluster)
*/
protected Cluster getCluster() {
Assert.state(this.cluster != null, "Cluster was not properly initialized");
return this.cluster;
}
@@ -222,7 +226,9 @@ public class CassandraCqlSessionFactoryBean
protected Session getSession() {
Session session = getObject();
Assert.state(session != null, "Session was not properly initialized");
return session;
}

View File

@@ -271,42 +271,42 @@ public class CassandraCqlClusterFactoryBeanUnitTests {
@Test // DATACASS-317
public void shouldSetClusterNameWithBeanNameProperty() throws Exception {
final Cluster.Builder mockClusterBuilder = mock(Cluster.Builder.class);
Cluster.Builder mockClusterBuilder = mock(Cluster.Builder.class);
Cluster mockCluster = mock(Cluster.class);
when(mockClusterBuilder.addContactPoints(anyString())).thenReturn(mockClusterBuilder);
when(mockClusterBuilder.build()).thenReturn(mockCluster);
CassandraCqlClusterFactoryBean bean = new CassandraCqlClusterFactoryBean() {
@Override
Cluster.Builder newClusterBuilder() {
return mockClusterBuilder;
}
};
CassandraCqlClusterFactoryBean bean = spy(new CassandraCqlClusterFactoryBean());
when(bean.newClusterBuilder()).thenReturn(mockClusterBuilder);
bean.setBeanName("ABC");
bean.setClusterName(" ");
bean.afterPropertiesSet();
verify(bean, times(1)).newClusterBuilder();
verify(mockClusterBuilder, times(1)).withClusterName(eq("ABC"));
}
@Test // DATACASS-317
public void shouldSetClusterNameWithClusterNameProperty() throws Exception {
final Cluster.Builder mockClusterBuilder = mock(Cluster.Builder.class);
Cluster.Builder mockClusterBuilder = mock(Cluster.Builder.class);
Cluster mockCluster = mock(Cluster.class);
when(mockClusterBuilder.addContactPoints(anyString())).thenReturn(mockClusterBuilder);
when(mockClusterBuilder.build()).thenReturn(mockCluster);
CassandraCqlClusterFactoryBean bean = new CassandraCqlClusterFactoryBean() {
@Override
Cluster.Builder newClusterBuilder() {
return mockClusterBuilder;
}
};
CassandraCqlClusterFactoryBean bean = spy(new CassandraCqlClusterFactoryBean());
when(bean.newClusterBuilder()).thenReturn(mockClusterBuilder);
bean.setBeanName("ABC");
bean.setClusterName("XYZ");
bean.afterPropertiesSet();
verify(bean,times(1)).newClusterBuilder();
verify(mockClusterBuilder, times(1)).withClusterName(eq("XYZ"));
}