DATACASS-219 - Polish.

Refactored code based on @Mark Paluch's code review here (https://github.com/spring-projects/spring-data-cassandra/pull/55).

(cherry picked from commit 27019f3218)
Signed-off-by: John Blum <jblum@pivotal.io>
This commit is contained in:
John Blum
2016-05-11 11:47:50 -07:00
parent 71889b78b4
commit bd4078621f
9 changed files with 111 additions and 95 deletions

View File

@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cassandra.config;
import java.util.ArrayList;
@@ -32,6 +33,7 @@ import org.springframework.cassandra.core.cql.generator.DropKeyspaceCqlGenerator
import org.springframework.cassandra.core.keyspace.CreateKeyspaceSpecification;
import org.springframework.cassandra.core.keyspace.DropKeyspaceSpecification;
import org.springframework.cassandra.core.keyspace.KeyspaceActionSpecification;
import org.springframework.cassandra.core.util.CollectionUtils;
import org.springframework.cassandra.support.CassandraExceptionTranslator;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
@@ -57,6 +59,13 @@ import com.datastax.driver.core.policies.RetryPolicy;
* @author Matthew T. Adams
* @author David Webb
* @author Mark Paluch
* @author Kirk Clemens
* @author Jorge Davison
* @author John Blum
* @see org.springframework.beans.factory.InitializingBean
* @see org.springframework.beans.factory.DisposableBean
* @see org.springframework.beans.factory.FactoryBean
* @see com.datastax.driver.core.Cluster
*/
public class CassandraCqlClusterFactoryBean implements FactoryBean<Cluster>, InitializingBean, DisposableBean,
PersistenceExceptionTranslator {
@@ -214,12 +223,12 @@ public class CassandraCqlClusterFactoryBean implements FactoryBean<Cluster>, Ini
protected void executeSpecsAndScripts(@SuppressWarnings("rawtypes") List specs, List<String> scripts) {
Session system = null;
CqlTemplate template = null;
try {
if (specs != null) {
system = specs.size() == 0 ? null : cluster.connect();
template = system == null ? null : new CqlTemplate(system);
if (!CollectionUtils.isEmpty(specs)) {
system = cluster.connect();
CqlTemplate template = new CqlTemplate(system);
Iterator<?> i = specs.iterator();
while (i.hasNext()) {
@@ -232,18 +241,12 @@ public class CassandraCqlClusterFactoryBean implements FactoryBean<Cluster>, Ini
}
}
if (scripts != null) {
if (!CollectionUtils.isEmpty(scripts)) {
system = (system != null ? system : cluster.connect());
if (system == null) {
system = scripts.size() == 0 ? null : cluster.connect();
}
if (template == null) {
template = system == null ? null : new CqlTemplate(system);
}
CqlTemplate template = new CqlTemplate(system);
for (String script : scripts) {
if (log.isDebugEnabled()) {
log.debug("executing raw CQL [{}]", script);
}
@@ -252,7 +255,6 @@ public class CassandraCqlClusterFactoryBean implements FactoryBean<Cluster>, Ini
}
}
} finally {
if (system != null) {
system.close();
}
@@ -273,54 +275,98 @@ public class CassandraCqlClusterFactoryBean implements FactoryBean<Cluster>, Ini
this.contactPoints = contactPoints;
}
/**
* Set the port for the contact points. Default is {@code 9042}, see {@link #DEFAULT_PORT}.
*/
public void setPort(int port) {
this.port = port;
}
/**
* Set the {@link CompressionType}. Default is uncompressed.
*/
public void setCompressionType(CompressionType compressionType) {
this.compressionType = compressionType;
}
/**
* Set the {@link PoolingOptions}.
*/
public void setPoolingOptions(PoolingOptions poolingOptions) {
this.poolingOptions = poolingOptions;
}
/**
* Set the {@link SocketOptions} containing low-level socket options.
*/
public void setSocketOptions(SocketOptions socketOptions) {
this.socketOptions = socketOptions;
}
/**
* Set the {@link AuthProvider}. Default is unauthenticated.
*/
public void setAuthProvider(AuthProvider authProvider) {
this.authProvider = authProvider;
}
/**
* Set the {@link LoadBalancingPolicy}.
*/
public void setLoadBalancingPolicy(LoadBalancingPolicy loadBalancingPolicy) {
this.loadBalancingPolicy = loadBalancingPolicy;
}
/**
* Set the {@link ReconnectionPolicy}.
*/
public void setReconnectionPolicy(ReconnectionPolicy reconnectionPolicy) {
this.reconnectionPolicy = reconnectionPolicy;
}
/**
* Set the {@link RetryPolicy}.
*/
public void setRetryPolicy(RetryPolicy retryPolicy) {
this.retryPolicy = retryPolicy;
}
/**
* Set whether metrics are enabled. Default is {@literal true}, see {@link #DEFAULT_METRICS_ENABLED}.
*/
public void setMetricsEnabled(boolean metricsEnabled) {
this.metricsEnabled = metricsEnabled;
}
/**
* Set a {@link List} of {@link CreateKeyspaceSpecification create keyspace specifications} that are executed when
* this factory is {@link #afterPropertiesSet() initialized}. {@link CreateKeyspaceSpecification Create keyspace
* specifications} are executed on a system session with no keyspace set, before executing
* {@link #setStartupScripts(List)}.
*/
public void setKeyspaceCreations(List<CreateKeyspaceSpecification> specifications) {
this.keyspaceCreations = specifications;
}
/**
* Return a {@link List} of {@link CreateKeyspaceSpecification create keyspace specifications}.
*/
public List<CreateKeyspaceSpecification> getKeyspaceCreations() {
return keyspaceCreations;
}
/**
* Set a {@link List} of {@link DropKeyspaceSpecification drop keyspace specifications} that are executed when this
* factory is {@link #destroy() destroyed}. {@link DropKeyspaceSpecification Drop keyspace specifications} are
* executed on a system session with no keyspace set, before executing {@link #setShutdownScripts(List)}.
*/
public void setKeyspaceDrops(List<DropKeyspaceSpecification> specifications) {
this.keyspaceDrops = specifications;
}
/**
* Reurn the {@link List} of {@link DropKeyspaceSpecification drop keyspace specifications}.
*/
public List<DropKeyspaceSpecification> getKeyspaceDrops() {
return keyspaceDrops;
}

View File

@@ -40,7 +40,7 @@ import com.datastax.driver.core.Session;
/**
* Factory for creating and configuring a Cassandra {@link Session}, which is a thread-safe singleton.
* As such, it is sufficient to have one {@link Session} per application and keyspace.
*
*
* @author Alex Shvid
* @author Matthew T. Adams
* @author John Blum

View File

@@ -16,24 +16,11 @@
package org.springframework.cassandra.config;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.sameInstance;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.*;
import java.util.ArrayList;
import java.util.Arrays;
@@ -58,14 +45,8 @@ import com.datastax.driver.core.Session;
* and functionality of the {@link CassandraCqlSessionFactoryBean} class.
*
* @author John Blum
* @see org.junit.Rule
* @see org.junit.Test
* @see org.junit.rules.ExpectedException
* @see org.junit.runner.RunWith
* @see org.mockito.Mock
* @see org.mockito.Mockito
* @see org.mockito.runners.MockitoJUnitRunner
* @see org.springframework.cassandra.config.CassandraCqlSessionFactoryBean
* @see <a href="https://jira.spring.io/browse/DATACASS-219>DATACASS-219</a>
* @since 1.5.0
*/
@RunWith(MockitoJUnitRunner.class)
@@ -293,8 +274,7 @@ public class CassandraCqlSessionFactoryBeanUnitTests {
try {
exception.expect(UnsupportedOperationException.class);
actualStartupScripts.add("/path/to/yetAnother.cql");
}
finally {
} finally {
assertThat(actualStartupScripts.size(), is(equalTo(1)));
}
}
@@ -340,10 +320,8 @@ public class CassandraCqlSessionFactoryBeanUnitTests {
try {
exception.expect(UnsupportedOperationException.class);
actualShutdownScripts.add("/path/to/blowUpCluster.cql");
}
finally {
} finally {
assertThat(actualShutdownScripts.size(), is(equalTo(1)));
}
}
}

View File

@@ -16,11 +16,8 @@
package org.springframework.cassandra.core.util;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.sameInstance;
import static org.junit.Assert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Collection;
@@ -34,7 +31,6 @@ import org.junit.Test;
* of the {@link CollectionUtils} class.
*
* @author John Blum
* @see org.junit.Test
* @see org.springframework.cassandra.core.util.CollectionUtils
* @since 1.5.0
*/

View File

@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.cassandra.config;
import org.springframework.cassandra.config.CassandraCqlClusterFactoryBean;
@@ -20,7 +21,9 @@ import org.springframework.cassandra.config.CassandraCqlClusterFactoryBean;
/**
* Spring Data Cassandra extension of CassandraCqlClusterFactoryBean. This class exists only in the name of symmetry,
* based on the other CassandraData*FactoryBean classes.
*
*
* @author Matthew T. Adams
*/
public class CassandraClusterFactoryBean extends CassandraCqlClusterFactoryBean {}
public class CassandraClusterFactoryBean extends CassandraCqlClusterFactoryBean {
}

View File

@@ -16,7 +16,7 @@
package org.springframework.data.cassandra.config;
import static org.springframework.cassandra.core.cql.CqlIdentifier.cqlId;
import static org.springframework.cassandra.core.cql.CqlIdentifier.*;
import java.util.Collection;
@@ -59,7 +59,7 @@ public class CassandraSessionFactoryBean extends CassandraCqlSessionFactoryBean
public void afterPropertiesSet() throws Exception {
super.afterPropertiesSet();
Assert.state(converter != null, "Converter must not be null");
Assert.state(converter != null, "Converter was not properly initialized");
admin = newCassandraAdminOperations(getObject(), converter);

View File

@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.cassandra.config.xml;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
@@ -21,7 +22,7 @@ import org.springframework.data.repository.config.RepositoryBeanDefinitionParser
/**
* Namespace handler for spring-data-cassandra.
*
*
* @author Alex Shvid
* @author Matthew T. Adams
*/

View File

@@ -13,10 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.cassandra.mapping;
import static org.springframework.cassandra.core.cql.CqlIdentifier.cqlId;
import static org.springframework.cassandra.core.keyspace.CreateTableSpecification.createTable;
import static org.springframework.cassandra.core.cql.CqlIdentifier.*;
import static org.springframework.cassandra.core.keyspace.CreateTableSpecification.*;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
@@ -51,20 +52,23 @@ import com.datastax.driver.core.TableMetadata;
* @author Alex Shvid
* @author Matthew T. Adams
*/
public class BasicCassandraMappingContext extends
AbstractMappingContext<CassandraPersistentEntity<?>, CassandraPersistentProperty> implements
CassandraMappingContext, ApplicationContextAware {
public class BasicCassandraMappingContext extends AbstractMappingContext<CassandraPersistentEntity<?>, CassandraPersistentProperty>
implements CassandraMappingContext, ApplicationContextAware {
protected ApplicationContext context;
protected Mapping mapping = new Mapping();
protected ClassLoader beanClassLoader;
protected CassandraPersistentEntityMetadataVerifier verifier = new BasicCassandraPersistentEntityMetadataVerifier();
protected Mapping mapping = new Mapping();
// useful caches
protected Map<Class<?>, CassandraPersistentEntity<?>> entitiesByType = new HashMap<Class<?>, CassandraPersistentEntity<?>>();
protected Map<CqlIdentifier, Set<CassandraPersistentEntity<?>>> entitySetsByTableName = new HashMap<CqlIdentifier, Set<CassandraPersistentEntity<?>>>();
protected Set<CassandraPersistentEntity<?>> nonPrimaryKeyEntities = new HashSet<CassandraPersistentEntity<?>>();
protected Set<CassandraPersistentEntity<?>> primaryKeyEntities = new HashSet<CassandraPersistentEntity<?>>();
protected Map<Class<?>, CassandraPersistentEntity<?>> entitiesByType = new HashMap<Class<?>, CassandraPersistentEntity<?>>();
/**
* Creates a new {@link BasicCassandraMappingContext}.
@@ -75,9 +79,7 @@ public class BasicCassandraMappingContext extends
@Override
public void initialize() {
super.initialize();
processMappingOverrides();
}
@@ -129,9 +131,11 @@ public class BasicCassandraMappingContext extends
// now do some caching of the entity
Set<CassandraPersistentEntity<?>> entities = entitySetsByTableName.get(entity.getTableName());
if (entities == null) {
entities = new HashSet<CassandraPersistentEntity<?>>();
}
entities.add(entity);
entitySetsByTableName.put(entity.getTableName(), entities);
@@ -180,13 +184,13 @@ public class BasicCassandraMappingContext extends
if (pkProp.isPartitionKeyColumn()) {
spec.partitionKeyColumn(pkProp.getColumnName(), pkProp.getDataType());
} else { // it's a cluster column
spec.clusteredKeyColumn(pkProp.getColumnName(), pkProp.getDataType(), pkProp.getPrimaryKeyOrdering());
spec.clusteredKeyColumn(pkProp.getColumnName(), pkProp.getDataType(),
pkProp.getPrimaryKeyOrdering());
}
}
});
} else {
if (prop.isIdProperty() || prop.isPartitionKeyColumn()) {
spec.partitionKeyColumn(prop.getColumnName(), prop.getDataType());
} else if (prop.isClusterKeyColumn()) {
@@ -226,20 +230,25 @@ public class BasicCassandraMappingContext extends
}
String entityClassName = entityMapping.getEntityClassName();
Class<?> entityClass;
try {
entityClass = ClassUtils.forName(entityClassName, beanClassLoader);
} catch (ClassNotFoundException e) {
throw new IllegalStateException(String.format("unknown persistent entity name [%s]", entityClassName), e);
throw new IllegalStateException(String.format("unknown persistent entity name [%s]",
entityClassName), e);
}
CassandraPersistentEntity<?> entity = getPersistentEntity(entityClass);
if (entity == null) {
throw new IllegalStateException(String.format("unknown persistent entity class name [%s]", entityClassName));
throw new IllegalStateException(String.format("unknown persistent entity class name [%s]",
entityClassName));
}
String tableName = entityMapping.getTableName();
if (StringUtils.hasText(tableName)) {
entity.setTableName(cqlId(tableName, Boolean.valueOf(entityMapping.getForceQuote())));
}
@@ -258,13 +267,16 @@ public class BasicCassandraMappingContext extends
protected void processMappingOverride(CassandraPersistentEntity<?> entity, PropertyMapping mapping) {
CassandraPersistentProperty property = entity.getPersistentProperty(mapping.getPropertyName());
if (property == null) {
throw new IllegalArgumentException(String.format("entity class [%s] has no persistent property named [%s]",
entity.getType().getName(), mapping.getPropertyName()));
entity.getType().getName(), mapping.getPropertyName()));
}
boolean forceQuote = false;
String value = mapping.getForceQuote();
if (StringUtils.hasText(value)) {
property.setForceQuote(forceQuote = Boolean.valueOf(value));
}
@@ -274,7 +286,6 @@ public class BasicCassandraMappingContext extends
if (StringUtils.hasText(value)) {
property.setColumnName(cqlId(value, forceQuote));
}
}
public void setBeanClassLoader(ClassLoader beanClassLoader) {
@@ -285,6 +296,7 @@ public class BasicCassandraMappingContext extends
public CassandraPersistentEntity<?> getExistingPersistentEntity(Class<?> type) {
CassandraPersistentEntity<?> entity = entitiesByType.get(type);
if (entity != null) {
return entity;
}

View File

@@ -16,28 +16,14 @@
package org.springframework.data.cassandra.config;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import static org.springframework.data.cassandra.config.CassandraSessionFactoryBean.DEFAULT_CREATE_IF_NOT_EXISTS;
import static org.springframework.data.cassandra.config.CassandraSessionFactoryBean.DEFAULT_DROP_TABLES;
import static org.springframework.data.cassandra.config.CassandraSessionFactoryBean.DEFAULT_DROP_UNUSED_TABLES;
import static org.mockito.Mockito.*;
import static org.springframework.data.cassandra.config.CassandraSessionFactoryBean.*;
import java.util.Collections;
import java.util.Map;
@@ -68,14 +54,8 @@ import com.datastax.driver.core.TableMetadata;
* of the {@link CassandraSessionFactoryBean} class.
*
* @author John Blum
* @see org.junit.Rule
* @see org.junit.Test
* @see org.junit.rules.ExpectedException
* @see org.junit.runner.RunWith
* @see org.mockito.Mock
* @see org.mockito.Mockito
* @see org.mockito.runners.MockitoJUnitRunner
* @see org.springframework.data.cassandra.config.CassandraSessionFactoryBean
* @see <a href="https://jira.spring.io/browse/DATACASS-219>DATACASS-219</a>
* @since 1.5.0
*/
@RunWith(MockitoJUnitRunner.class)
@@ -136,7 +116,7 @@ public class CassandraSessionFactoryBeanUnitTests {
public void afterPropertiesSetThrowsIllegalStateExceptionWhenConverterIsNull() throws Exception {
exception.expect(IllegalStateException.class);
exception.expectCause(is(nullValue(Throwable.class)));
exception.expectMessage("Converter must not be null");
exception.expectMessage("Converter was not properly initialized");
factoryBean.setCluster(mockCluster);
factoryBean.afterPropertiesSet();