DATACASS-55: WIP: all working ok

This commit is contained in:
Matthew Adams
2014-01-07 12:20:37 -06:00
parent 891b3ff339
commit a503963c71
15 changed files with 450 additions and 150 deletions

View File

@@ -55,62 +55,50 @@ import com.datastax.driver.core.policies.RetryPolicy;
public class CassandraClusterFactoryBean implements FactoryBean<Cluster>, InitializingBean, DisposableBean,
PersistenceExceptionTranslator {
protected static final Logger log = LoggerFactory.getLogger(CassandraClusterFactoryBean.class);
public static final String DEFAULT_CONTACT_POINTS = "localhost";
public static final boolean DEFAULT_METRICS_ENABLED = true;
public static final int DEFAULT_PORT = 9042;
private static final int DEFAULT_PORT = 9042;
protected static final Logger log = LoggerFactory.getLogger(CassandraClusterFactoryBean.class);
private Cluster cluster;
private String contactPoints;
private int port = DEFAULT_PORT;
/**
* Comma-delimited string of servers.
*/
private String contactPoints = DEFAULT_CONTACT_POINTS;
private int port = CassandraClusterFactoryBean.DEFAULT_PORT;
private CompressionType compressionType;
private PoolingOptionsConfig localPoolingOptions;
private PoolingOptionsConfig remotePoolingOptions;
private SocketOptionsConfig socketOptions;
private AuthProvider authProvider;
private LoadBalancingPolicy loadBalancingPolicy;
private ReconnectionPolicy reconnectionPolicy;
private RetryPolicy retryPolicy;
private boolean metricsEnabled = true;
private final PersistenceExceptionTranslator exceptionTranslator = new CassandraExceptionTranslator();
private boolean metricsEnabled = DEFAULT_METRICS_ENABLED;
private List<CreateKeyspaceSpecification> keyspaceCreations = new ArrayList<CreateKeyspaceSpecification>();
private List<DropKeyspaceSpecification> keyspaceDrops = new ArrayList<DropKeyspaceSpecification>();
private List<String> startupScripts = new ArrayList<String>();
private List<String> shutdownScripts = new ArrayList<String>();
private final PersistenceExceptionTranslator exceptionTranslator = new CassandraExceptionTranslator();
@Override
public Cluster getObject() throws Exception {
return cluster;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
@Override
public Class<? extends Cluster> getObjectType() {
return Cluster.class;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
*/
@Override
public boolean isSingleton() {
return true;
}
/*
* (non-Javadoc)
* @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException)
*/
@Override
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
return exceptionTranslator.translateExceptionIfPossible(ex);
@@ -163,44 +151,56 @@ public class CassandraClusterFactoryBean implements FactoryBean<Cluster>, Initia
builder.withoutMetrics();
}
Cluster cluster = builder.build();
// initialize property
this.cluster = cluster;
cluster = builder.build();
executeSpecsAndScripts(keyspaceCreations, startupScripts);
}
protected void executeSpecsAndScripts(@SuppressWarnings("rawtypes") List specs, List<String> scripts) {
Session system = null;
CassandraTemplate template = null;
try {
system = specs.size() > 0 ? cluster.connect() : null;
CassandraTemplate template = system == null ? null : new CassandraTemplate(system);
if (specs != null) {
system = specs.size() == 0 ? null : cluster.connect();
template = system == null ? null : new CassandraTemplate(system);
Iterator<?> i = specs.iterator();
while (i.hasNext()) {
KeyspaceNameSpecification<?> spec = (KeyspaceNameSpecification<?>) i.next();
String cql = (spec instanceof CreateKeyspaceSpecification) ? new CreateKeyspaceCqlGenerator(
(CreateKeyspaceSpecification) spec).toCql()
: new DropKeyspaceCqlGenerator((DropKeyspaceSpecification) spec).toCql();
Iterator<?> i = specs.iterator();
while (i.hasNext()) {
KeyspaceNameSpecification<?> spec = (KeyspaceNameSpecification<?>) i.next();
String cql = (spec instanceof CreateKeyspaceSpecification) ? new CreateKeyspaceCqlGenerator(
(CreateKeyspaceSpecification) spec).toCql() : new DropKeyspaceCqlGenerator(
(DropKeyspaceSpecification) spec).toCql();
if (log.isDebugEnabled()) {
log.info("executing CQL [{}]", cql);
if (log.isInfoEnabled()) {
log.info("executing CQL [{}]", cql);
}
template.execute(cql);
}
template.execute(cql);
}
for (String script : startupScripts) {
if (scripts != null) {
if (log.isDebugEnabled()) {
log.info("executing raw CQL [{}]", script);
if (system == null) {
system = scripts.size() == 0 ? null : cluster.connect();
}
template.execute(script);
}
if (template == null) {
template = system == null ? null : new CassandraTemplate(system);
}
for (String script : scripts) {
if (log.isInfoEnabled()) {
log.info("executing raw CQL [{}]", script);
}
template.execute(script);
}
}
} finally {
if (system != null) {
system.shutdown();
}
@@ -211,10 +211,12 @@ public class CassandraClusterFactoryBean implements FactoryBean<Cluster>, Initia
public void destroy() throws Exception {
executeSpecsAndScripts(keyspaceDrops, shutdownScripts);
cluster.shutdown();
}
/**
* Sets a comma-delimited string of the contact points (hosts) to connect to.
*/
public void setContactPoints(String contactPoints) {
this.contactPoints = contactPoints;
}

View File

@@ -15,14 +15,19 @@
*/
package org.springframework.cassandra.config;
import java.util.ArrayList;
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;
import org.springframework.cassandra.core.CassandraTemplate;
import org.springframework.cassandra.support.CassandraExceptionTranslator;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import com.datastax.driver.core.Cluster;
@@ -41,69 +46,101 @@ public class CassandraSessionFactoryBean implements FactoryBean<Session>, Initia
private static final Logger log = LoggerFactory.getLogger(CassandraSessionFactoryBean.class);
public static final String DEFAULT_REPLICATION_STRATEGY = "SimpleStrategy";
public static final int DEFAULT_REPLICATION_FACTOR = 1;
private Cluster cluster;
private Session session;
private String keyspaceName;
private List<String> startupScripts = new ArrayList<String>();
private List<String> shutdownScripts = new ArrayList<String>();
private final PersistenceExceptionTranslator exceptionTranslator = new CassandraExceptionTranslator();
@Override
public Session getObject() {
return session;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
@Override
public Class<? extends Session> getObjectType() {
return Session.class;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
*/
@Override
public boolean isSingleton() {
return true;
}
/*
* (non-Javadoc)
* @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException)
*/
@Override
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
return exceptionTranslator.translateExceptionIfPossible(ex);
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() throws Exception {
if (cluster == null) {
throw new IllegalArgumentException("at least one cluster is required");
}
this.session = StringUtils.hasText(this.keyspaceName) ? cluster.connect(keyspaceName) : cluster.connect();
session = StringUtils.hasText(keyspaceName) ? cluster.connect(keyspaceName) : cluster.connect();
executeScripts(startupScripts);
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.DisposableBean#destroy()
/**
* Executes given scripts. Session must be connected when this method is called.
*/
public void destroy() throws Exception {
this.session.shutdown();
protected void executeScripts(List<String> scripts) {
if (scripts == null) {
return;
}
CassandraTemplate template = new CassandraTemplate(session);
for (String script : scripts) {
if (log.isInfoEnabled()) {
log.info("executing raw CQL [{}]", script);
}
template.execute(script);
}
}
@Override
public void destroy() throws Exception {
executeScripts(shutdownScripts);
session.shutdown();
}
/**
* Sets the keyspace name to connect to. Using <code>null</code>, empty string, or only whitespace will cause the
* system keyspace to be used.
*/
public void setKeyspaceName(String keyspaceName) {
this.keyspaceName = keyspaceName;
}
/**
* Sets the cluster to use. Must not be null.
*/
public void setCluster(Cluster cluster) {
if (cluster == null) {
throw new IllegalArgumentException("cluster must not be null");
}
this.cluster = cluster;
}
/**
* Sets CQL scripts to be executed immediately after the session is connected.
*/
public void setStartupScripts(List<String> scripts) {
this.startupScripts = scripts;
}
/**
* Sets CQL scripts to be executed immediately before the session is shutdown.
*/
public void setShutdownScripts(List<String> scripts) {
this.shutdownScripts = scripts;
}
}

View File

@@ -18,6 +18,11 @@ package org.springframework.cassandra.config;
import java.util.HashMap;
import java.util.Map;
import org.springframework.cassandra.core.keyspace.DefaultOption;
import org.springframework.cassandra.core.keyspace.KeyspaceOption;
import org.springframework.cassandra.core.keyspace.Option;
import org.springframework.cassandra.core.util.MapBuilder;
/**
* Keyspace attributes.
*
@@ -33,6 +38,54 @@ public class KeyspaceAttributes {
public static final long DEFAULT_REPLICATION_FACTOR = 1;
public static final boolean DEFAULT_DURABLE_WRITES = true;
/**
* Returns a map of {@link Option}s suitable as the value of a {@link KeyspaceOption#REPLICATION} option with
* replication strategy class "SimpleStrategy" and with a replication factor of one.
*/
public static Map<Option, Object> newSimpleReplication() {
return newSimpleReplication(DEFAULT_REPLICATION_FACTOR);
}
/**
* Returns a map of {@link Option}s suitable as the value of a {@link KeyspaceOption#REPLICATION} option with
* replication strategy class "SimpleStrategy" and with a replication factor equal to that given.
*/
public static Map<Option, Object> newSimpleReplication(long replicationFactor) {
return MapBuilder.map(Option.class, Object.class)
.entry(new DefaultOption("class", String.class, true, false, true), SIMPLE_REPLICATION_STRATEGY)
.entry(new DefaultOption("replication_factor", Long.class, true, false, false), replicationFactor).build();
}
/**
* Returns a map of {@link Option}s suitable as the value of a {@link KeyspaceOption#REPLICATION} option with
* replication strategy class "NetworkTopologyStrategy" and with data centers each with their corresponding
* replication factors.
*/
public static Map<Option, Object> newNetworkReplication(DataCenterReplication... dataCenterReplications) {
MapBuilder<Option, Object> builder = MapBuilder.map(Option.class, Object.class).entry(
new DefaultOption("class", String.class, true, false, true), NETWORK_TOPOLOGY_REPLICATION_STRATEGY);
for (DataCenterReplication dcr : dataCenterReplications) {
builder.entry(new DefaultOption(dcr.dataCenter, Long.class, true, false, false), dcr.replicationFactor);
}
return builder.build();
}
/**
* Simple data structure to be used when setting the replication factor for a given data center.
*/
public static class DataCenterReplication {
public String dataCenter;
public long replicationFactor;
public DataCenterReplication(String dataCenter, long replicationFactor) {
this.dataCenter = dataCenter;
this.replicationFactor = replicationFactor;
}
}
private String replicationStrategy = DEFAULT_REPLICATION_STRATEGY;
private long replicationFactor = DEFAULT_REPLICATION_FACTOR;
private boolean durableWrites = DEFAULT_DURABLE_WRITES;

View File

@@ -0,0 +1,134 @@
package org.springframework.cassandra.config.java;
import java.util.Collections;
import java.util.List;
import org.springframework.cassandra.config.CassandraClusterFactoryBean;
import org.springframework.cassandra.config.CassandraSessionFactoryBean;
import org.springframework.cassandra.config.CompressionType;
import org.springframework.cassandra.config.PoolingOptionsConfig;
import org.springframework.cassandra.config.SocketOptionsConfig;
import org.springframework.cassandra.core.CassandraOperations;
import org.springframework.cassandra.core.CassandraTemplate;
import org.springframework.cassandra.core.keyspace.CreateKeyspaceSpecification;
import org.springframework.cassandra.core.keyspace.DropKeyspaceSpecification;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.datastax.driver.core.AuthProvider;
import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.policies.LoadBalancingPolicy;
import com.datastax.driver.core.policies.ReconnectionPolicy;
import com.datastax.driver.core.policies.RetryPolicy;
/**
* Base class for Spring Cassandra configuration that can handle creating namespaces, execute arbitrary CQL on startup &
* shutdown, and optionally drop namespaces.
*
* @author Matthew T. Adams
*/
@Configuration
public abstract class AbstractCassandraFactoryBeanConfiguration {
protected abstract String getKeyspaceName();
@Bean
public CassandraClusterFactoryBean cluster() throws Exception {
CassandraClusterFactoryBean bean = new CassandraClusterFactoryBean();
bean.setAuthProvider(getAuthProvider());
bean.setCompressionType(getCompressionType());
bean.setContactPoints(getContactPoints());
bean.setKeyspaceCreations(getKeyspaceCreations());
bean.setKeyspaceDrops(getKeyspaceDrops());
bean.setLoadBalancingPolicy(getLoadBalancingPolicy());
bean.setLocalPoolingOptions(getLocalPoolingOptions());
bean.setMetricsEnabled(getMetricsEnabled());
bean.setPort(getPort());
bean.setReconnectionPolicy(getReconnectionPolicy());
bean.setRemotePoolingOptions(getRemotePoolingOptions());
bean.setRetryPolicy(getRetryPolicy());
bean.setShutdownScripts(getShutdownScripts());
bean.setSocketOptions(getSocketOptions());
bean.setStartupScripts(getStartupScripts());
return bean;
}
@Bean
public CassandraSessionFactoryBean session() throws Exception {
Cluster cluster = cluster().getObject();
CassandraSessionFactoryBean bean = new CassandraSessionFactoryBean();
bean.setCluster(cluster);
bean.setKeyspaceName(getKeyspaceName());
return bean;
}
@Bean
public CassandraOperations template() throws Exception {
return new CassandraTemplate(session().getObject());
}
protected List<String> getStartupScripts() {
return Collections.emptyList();
}
protected SocketOptionsConfig getSocketOptions() {
return null;
}
protected List<String> getShutdownScripts() {
return Collections.emptyList();
}
protected ReconnectionPolicy getReconnectionPolicy() {
return null;
}
protected RetryPolicy getRetryPolicy() {
return null;
}
protected PoolingOptionsConfig getRemotePoolingOptions() {
return null;
}
protected int getPort() {
return CassandraClusterFactoryBean.DEFAULT_PORT;
}
protected boolean getMetricsEnabled() {
return CassandraClusterFactoryBean.DEFAULT_METRICS_ENABLED;
}
protected PoolingOptionsConfig getLocalPoolingOptions() {
return null;
}
protected LoadBalancingPolicy getLoadBalancingPolicy() {
return null;
}
protected List<DropKeyspaceSpecification> getKeyspaceDrops() {
return Collections.emptyList();
}
protected List<CreateKeyspaceSpecification> getKeyspaceCreations() {
return Collections.emptyList();
}
protected String getContactPoints() {
return CassandraClusterFactoryBean.DEFAULT_CONTACT_POINTS;
}
protected CompressionType getCompressionType() {
return null;
}
protected AuthProvider getAuthProvider() {
return null;
}
}

View File

@@ -15,6 +15,9 @@
*/
package org.springframework.cassandra.config.xml;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@@ -23,6 +26,7 @@ import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.cassandra.config.CassandraSessionFactoryBean;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
/**
* Parser for &lt;session&gt; definitions.
@@ -38,10 +42,6 @@ public class CassandraSessionParser extends AbstractSimpleBeanDefinitionParser {
return CassandraSessionFactoryBean.class;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.factory.xml.ParserContext)
*/
@Override
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
throws BeanDefinitionStoreException {
@@ -64,5 +64,30 @@ public class CassandraSessionParser extends AbstractSimpleBeanDefinitionParser {
clusterRef = BeanNames.CASSANDRA_CLUSTER;
}
builder.addPropertyReference("cluster", clusterRef);
parseChildElements(element, builder);
}
protected void parseChildElements(Element element, BeanDefinitionBuilder builder) {
List<String> scripts = parseScripts(element, "startup-cql");
builder.addPropertyValue("startupScripts", scripts);
scripts = parseScripts(element, "shutdown-cql");
builder.addPropertyValue("shutdownScripts", scripts);
}
protected List<String> parseScripts(Element element, String elementName) {
NodeList nodes = element.getElementsByTagName("startup-cql");
int length = nodes.getLength();
List<String> scripts = new ArrayList<String>(length);
for (int i = 0; i < length; i++) {
Element script = (Element) nodes.item(i);
scripts.add(script.getTextContent());
}
return scripts;
}
}

View File

@@ -22,7 +22,7 @@ import java.util.Set;
/**
* Builder for maps, which also conveniently implements {@link Map} via delegation for convenience so you don't have to
* actually {@link #build()} it (or forget to).
* actually {@link #build()} it.
*
* @author Matthew T. Adams
* @param <K> The key type of the map.
@@ -83,58 +83,72 @@ public class MapBuilder<K, V> implements Map<K, V> {
return new LinkedHashMap<K, V>(map);
}
@Override
public int size() {
return map.size();
}
@Override
public boolean isEmpty() {
return map.isEmpty();
}
@Override
public boolean containsKey(Object key) {
return map.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
return map.containsValue(value);
}
@Override
public V get(Object key) {
return map.get(key);
}
@Override
public V put(K key, V value) {
return map.put(key, value);
}
@Override
public V remove(Object key) {
return map.remove(key);
}
@Override
public void putAll(Map<? extends K, ? extends V> m) {
map.putAll(m);
}
@Override
public void clear() {
map.clear();
}
@Override
public Set<K> keySet() {
return map.keySet();
}
@Override
public Collection<V> values() {
return map.values();
}
@Override
public Set<java.util.Map.Entry<K, V>> entrySet() {
return map.entrySet();
}
@Override
public boolean equals(Object o) {
return map.equals(o);
}
@Override
public int hashCode() {
return map.hashCode();
}

View File

@@ -337,6 +337,27 @@ Sets the SO_SNDBUF socket option.
</xsd:complexType>
<xsd:complexType name="sessionType">
<xsd:sequence>
<xsd:element name="startup-cql" type="xsd:string"
minOccurs="0" maxOccurs="unbounded">
<!-- TODO: cql could come from a resource via a resource attribute... -->
<xsd:annotation>
<xsd:documentation><![CDATA[
Arbitrary CQL script to be executed against the session's keyspace during bean initialization. Multiple elements will be executed in document order.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="shutdown-cql" type="xsd:string"
minOccurs="0" maxOccurs="unbounded">
<!-- TODO: cql could come from a resource via a resource attribute... -->
<xsd:annotation>
<xsd:documentation><![CDATA[
Arbitrary CQL script to be executed against the session's keyspace during bean destruction. Multiple elements will be executed in document order.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:ID" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[

View File

@@ -14,7 +14,7 @@ import com.datastax.driver.core.Session;
public abstract class AbstractIntegrationTest extends AbstractEmbeddedCassandraIntegrationTest {
@Inject
public Session session;
protected Session session;
@Before
public void assertSession() {

View File

@@ -1,8 +1,5 @@
package org.springframework.cassandra.test.integration.config.java;
import org.springframework.cassandra.config.KeyspaceAttributes;
import org.springframework.cassandra.config.PoolingOptionsConfig;
import org.springframework.cassandra.config.SocketOptionsConfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
@@ -38,20 +35,4 @@ public abstract class AbstractKeyspaceCreatingConfiguration extends AbstractInte
+ " WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };");
system.shutdown();
}
protected KeyspaceAttributes getKeyspaceAttributes() {
return null;
}
protected PoolingOptionsConfig getLocalPoolingOptionsConfig() {
return null;
}
protected PoolingOptionsConfig getRemotePoolingOptionsConfig() {
return null;
}
protected SocketOptionsConfig getSocketOptionsConfig() {
return null;
}
}

View File

@@ -1,14 +0,0 @@
package org.springframework.cassandra.test.integration.config.java;
import org.springframework.context.annotation.Configuration;
@Configuration
public class KeyspaceCreatingConfig extends AbstractKeyspaceCreatingConfiguration {
public static final String KEYSPACE = "kcc";
@Override
protected String getKeyspaceName() {
return KEYSPACE;
}
}

View File

@@ -1,14 +0,0 @@
package org.springframework.cassandra.test.integration.config.java;
import org.junit.Test;
import org.springframework.cassandra.test.integration.config.IntegrationTestUtils;
import org.springframework.test.context.ContextConfiguration;
@ContextConfiguration(classes = KeyspaceCreatingConfig.class)
public class KeyspaceCreatingConfigTest extends AbstractIntegrationTest {
@Test
public void test() {
IntegrationTestUtils.assertKeyspaceExists(KeyspaceCreatingConfig.KEYSPACE, session);
}
}

View File

@@ -0,0 +1,32 @@
package org.springframework.cassandra.test.integration.config.java;
import java.util.ArrayList;
import java.util.List;
import org.springframework.cassandra.config.KeyspaceAttributes;
import org.springframework.cassandra.config.java.AbstractCassandraFactoryBeanConfiguration;
import org.springframework.cassandra.core.keyspace.CreateKeyspaceSpecification;
import org.springframework.cassandra.core.keyspace.KeyspaceOption;
import org.springframework.context.annotation.Configuration;
@Configuration
public class KeyspaceCreatingJavaConfig extends AbstractCassandraFactoryBeanConfiguration {
public static final String KEYSPACE_NAME = "foo";
@Override
protected String getKeyspaceName() {
return KEYSPACE_NAME;
}
@Override
protected List<CreateKeyspaceSpecification> getKeyspaceCreations() {
ArrayList<CreateKeyspaceSpecification> list = new ArrayList<CreateKeyspaceSpecification>();
CreateKeyspaceSpecification specification = CreateKeyspaceSpecification.createKeyspace().name(getKeyspaceName());
specification.with(KeyspaceOption.REPLICATION, KeyspaceAttributes.newSimpleReplication(1L));
list.add(specification);
return list;
}
}

View File

@@ -0,0 +1,31 @@
package org.springframework.cassandra.test.integration.config.java;
import javax.inject.Inject;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.cassandra.test.integration.config.IntegrationTestUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.datastax.driver.core.Session;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = KeyspaceCreatingJavaConfig.class)
public class KeyspaceCreatingJavaConfigTest extends AbstractIntegrationTest {
@Inject
protected Session session;
@Override
protected String keyspace() {
return null;
}
@Test
public void test() {
Assert.assertNotNull(session);
IntegrationTestUtils.assertKeyspaceExists(KeyspaceCreatingJavaConfig.KEYSPACE_NAME, session);
}
}

View File

@@ -6,6 +6,7 @@ import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.springframework.cassandra.config.KeyspaceAttributes;
import org.springframework.cassandra.core.cql.generator.CreateKeyspaceCqlGenerator;
import org.springframework.cassandra.core.keyspace.CreateKeyspaceSpecification;
import org.springframework.cassandra.core.keyspace.DefaultOption;
@@ -23,9 +24,10 @@ public class CreateKeyspaceCqlGeneratorTests {
private static void assertReplicationMap(Map<Option, Object> replicationMap, String cql) {
assertTrue(cql.contains(" WITH replication = { "));
for (Map.Entry<Option, Object> entry : replicationMap.entrySet() ) {
String keyValuePair = "'" + entry.getKey().getName() + "' : '" + entry.getValue().toString() + "'";
for (Map.Entry<Option, Object> entry : replicationMap.entrySet()) {
String keyValuePair = "'" + entry.getKey().getName() + "' : " + (entry.getKey().quotesValue() ? "'" : "")
+ entry.getValue().toString() + (entry.getKey().quotesValue() ? "'" : "");
assertTrue(cql.contains(keyValuePair));
}
}
@@ -41,6 +43,7 @@ public class CreateKeyspaceCqlGeneratorTests {
public static abstract class CreateKeyspaceTest extends
KeyspaceOperationCqlGeneratorTest<CreateKeyspaceSpecification, CreateKeyspaceCqlGenerator> {
@Override
public CreateKeyspaceCqlGenerator generator() {
return new CreateKeyspaceCqlGenerator(specification);
}
@@ -50,20 +53,15 @@ public class CreateKeyspaceCqlGeneratorTests {
public String name = "mykeyspace";
public Boolean durableWrites = true;
public Map<Option, Object> replicationMap = new HashMap<Option, Object>();
public Map<Option, Object> replicationMap = KeyspaceAttributes.newSimpleReplication();
@Override
public CreateKeyspaceSpecification specification() {
keyspace = name;
replicationMap.put( new DefaultOption( "class", String.class, false, false, true ), "SimpleStrategy" );
replicationMap.put( new DefaultOption( "replication_factor", Long.class, false, false, true ), 1 );
return (CreateKeyspaceSpecification) CreateKeyspaceSpecification.createKeyspace()
.name(keyspace)
.with(KeyspaceOption.REPLICATION, replicationMap)
.with(KeyspaceOption.DURABLE_WRITES, durableWrites);
return CreateKeyspaceSpecification.createKeyspace().name(keyspace)
.with(KeyspaceOption.REPLICATION, replicationMap).with(KeyspaceOption.DURABLE_WRITES, durableWrites);
}
@Test
@@ -80,21 +78,19 @@ public class CreateKeyspaceCqlGeneratorTests {
public String name = "mykeyspace";
public Boolean durableWrites = false;
public Map<Option, Object> replicationMap = new HashMap<Option, Object>();
@Override
public CreateKeyspaceSpecification specification() {
keyspace = name;
replicationMap.put( new DefaultOption( "class", String.class, false, false, true ), "NetworkTopologyStrategy" );
replicationMap.put( new DefaultOption( "dc1", Long.class, false, false, true ), 2 );
replicationMap.put( new DefaultOption( "dc2", Long.class, false, false, true ), 3 );
return (CreateKeyspaceSpecification) CreateKeyspaceSpecification.createKeyspace()
.name(keyspace)
.with(KeyspaceOption.REPLICATION, replicationMap)
.with(KeyspaceOption.DURABLE_WRITES, durableWrites);
replicationMap.put(new DefaultOption("class", String.class, false, false, true), "NetworkTopologyStrategy");
replicationMap.put(new DefaultOption("dc1", Long.class, false, false, true), 2);
replicationMap.put(new DefaultOption("dc2", Long.class, false, false, true), 3);
return CreateKeyspaceSpecification.createKeyspace().name(keyspace)
.with(KeyspaceOption.REPLICATION, replicationMap).with(KeyspaceOption.DURABLE_WRITES, durableWrites);
}
@Test

View File

@@ -9,8 +9,10 @@
</encoder>
</appender>
<logger name="org.springframework.context" level="info" />
<logger name="org.springframework.cassandra" level="info" />
<logger name="org.springframework.data.cassandra" level="info" />
<logger name="org.springframework.data.cassandra" level="info" />
<logger name="com.datastax" level="info" />
<root level="warn">
<appender-ref ref="console" />