all tests passing now with the exception of UserRepositoryIntegrationTests
This commit is contained in:
@@ -28,6 +28,7 @@ import org.springframework.cassandra.core.CqlTemplate;
|
||||
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;
|
||||
@@ -76,9 +77,7 @@ public class CassandraSessionFactoryBean implements FactoryBean<Session>, Initia
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
||||
if (cluster == null) {
|
||||
throw new IllegalArgumentException("at least one cluster is required");
|
||||
}
|
||||
Assert.notNull(cluster);
|
||||
|
||||
session = StringUtils.hasText(keyspaceName) ? cluster.connect(keyspaceName) : cluster.connect();
|
||||
executeScripts(startupScripts);
|
||||
|
||||
@@ -50,7 +50,7 @@ public class KeyspaceActionSpecificationFactoryBean implements FactoryBean<Set<K
|
||||
private String name;
|
||||
private List<String> networkTopologyDataCenters = new LinkedList<String>();
|
||||
private List<String> networkTopologyReplicationFactors = new LinkedList<String>();
|
||||
private String replicationStrategy;
|
||||
private ReplicationStrategy replicationStrategy;
|
||||
private long replicationFactor;
|
||||
private boolean durableWrites = false;
|
||||
private boolean ifNotExists = false;
|
||||
@@ -97,18 +97,15 @@ public class KeyspaceActionSpecificationFactoryBean implements FactoryBean<Set<K
|
||||
create.name(name).ifNotExists(ifNotExists).with(KeyspaceOption.DURABLE_WRITES, durableWrites);
|
||||
|
||||
Map<Option, Object> replicationStrategyMap = new HashMap<Option, Object>();
|
||||
replicationStrategyMap.put(new DefaultOption("class", String.class, true, false, true), ReplicationStrategy
|
||||
.valueOf(replicationStrategy).getValue());
|
||||
replicationStrategyMap.put(new DefaultOption("class", String.class, true, false, true),
|
||||
replicationStrategy.getValue());
|
||||
|
||||
/*
|
||||
* Just set replication factor for SimpleStrategy
|
||||
*/
|
||||
if (replicationStrategy.equals(ReplicationStrategy.SIMPLE_STRATEGY.name())) {
|
||||
if (replicationStrategy == ReplicationStrategy.SIMPLE_STRATEGY) {
|
||||
replicationStrategyMap.put(new DefaultOption("replication_factor", Long.class, true, false, false),
|
||||
replicationFactor);
|
||||
}
|
||||
|
||||
if (replicationStrategy.equals(ReplicationStrategy.NETWORK_TOPOLOGY_STRATEGY.name())) {
|
||||
if (replicationStrategy == ReplicationStrategy.NETWORK_TOPOLOGY_STRATEGY) {
|
||||
int i = 0;
|
||||
for (String datacenter : networkTopologyDataCenters) {
|
||||
replicationStrategyMap.put(new DefaultOption(datacenter, Long.class, true, false, false),
|
||||
@@ -207,14 +204,14 @@ public class KeyspaceActionSpecificationFactoryBean implements FactoryBean<Set<K
|
||||
/**
|
||||
* @return Returns the replicationStrategy.
|
||||
*/
|
||||
public String getReplicationStrategy() {
|
||||
public ReplicationStrategy getReplicationStrategy() {
|
||||
return replicationStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param replicationStrategy The replicationStrategy to set.
|
||||
*/
|
||||
public void setReplicationStrategy(String replicationStrategy) {
|
||||
public void setReplicationStrategy(ReplicationStrategy replicationStrategy) {
|
||||
this.replicationStrategy = replicationStrategy;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.util.Map;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.DefaultOption;
|
||||
import org.springframework.cassandra.core.keyspace.KeyspaceOption;
|
||||
import org.springframework.cassandra.core.keyspace.KeyspaceOption.ReplicationStrategy;
|
||||
import org.springframework.cassandra.core.keyspace.Option;
|
||||
import org.springframework.cassandra.core.util.MapBuilder;
|
||||
|
||||
@@ -31,10 +32,7 @@ import org.springframework.cassandra.core.util.MapBuilder;
|
||||
*/
|
||||
public class KeyspaceAttributes {
|
||||
|
||||
public static final String SIMPLE_REPLICATION_STRATEGY = "SimpleStrategy";
|
||||
public static final String NETWORK_TOPOLOGY_REPLICATION_STRATEGY = "NetworkTopologyStrategy";
|
||||
|
||||
public static final String DEFAULT_REPLICATION_STRATEGY = SIMPLE_REPLICATION_STRATEGY;
|
||||
public static final ReplicationStrategy DEFAULT_REPLICATION_STRATEGY = ReplicationStrategy.SIMPLE_STRATEGY;
|
||||
public static final long DEFAULT_REPLICATION_FACTOR = 1;
|
||||
public static final boolean DEFAULT_DURABLE_WRITES = true;
|
||||
|
||||
@@ -51,8 +49,10 @@ public class KeyspaceAttributes {
|
||||
* 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)
|
||||
return MapBuilder
|
||||
.map(Option.class, Object.class)
|
||||
.entry(new DefaultOption("class", String.class, true, false, true),
|
||||
ReplicationStrategy.SIMPLE_STRATEGY.getValue())
|
||||
.entry(new DefaultOption("replication_factor", Long.class, true, false, false), replicationFactor).build();
|
||||
}
|
||||
|
||||
@@ -64,7 +64,8 @@ public class KeyspaceAttributes {
|
||||
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);
|
||||
new DefaultOption("class", String.class, true, false, true),
|
||||
ReplicationStrategy.NETWORK_TOPOLOGY_STRATEGY.getValue());
|
||||
|
||||
for (DataCenterReplication dcr : dataCenterReplications) {
|
||||
builder.entry(new DefaultOption(dcr.dataCenter, Long.class, true, false, false), dcr.replicationFactor);
|
||||
@@ -86,16 +87,16 @@ public class KeyspaceAttributes {
|
||||
}
|
||||
}
|
||||
|
||||
private String replicationStrategy = DEFAULT_REPLICATION_STRATEGY;
|
||||
private ReplicationStrategy replicationStrategy = DEFAULT_REPLICATION_STRATEGY;
|
||||
private long replicationFactor = DEFAULT_REPLICATION_FACTOR;
|
||||
private boolean durableWrites = DEFAULT_DURABLE_WRITES;
|
||||
private Map<String, Long> replicasPerNodeByDataCenter = new HashMap<String, Long>();
|
||||
|
||||
public String getReplicationStrategy() {
|
||||
public ReplicationStrategy getReplicationStrategy() {
|
||||
return replicationStrategy;
|
||||
}
|
||||
|
||||
public void setReplicationStrategy(String replicationStrategy) {
|
||||
public void setReplicationStrategy(ReplicationStrategy replicationStrategy) {
|
||||
this.replicationStrategy = replicationStrategy;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,10 @@
|
||||
*/
|
||||
package org.springframework.cassandra.config.xml;
|
||||
|
||||
import static org.springframework.data.config.ParsingUtils.getSourceBeanDefinition;
|
||||
import static org.springframework.cassandra.config.xml.ParsingUtils.addOptionalPropertyReference;
|
||||
import static org.springframework.cassandra.config.xml.ParsingUtils.addOptionalPropertyValue;
|
||||
import static org.springframework.cassandra.config.xml.ParsingUtils.addRequiredPropertyValue;
|
||||
import static org.springframework.cassandra.config.xml.ParsingUtils.getSourceBeanDefinition;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -35,8 +38,6 @@ import org.springframework.cassandra.config.MultiLevelSetFlattenerFactoryBean;
|
||||
import org.springframework.cassandra.config.PoolingOptionsFactoryBean;
|
||||
import org.springframework.cassandra.config.SocketOptionsFactoryBean;
|
||||
import org.springframework.cassandra.core.keyspace.KeyspaceActionSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.KeyspaceOption.ReplicationStrategy;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Element;
|
||||
@@ -58,7 +59,7 @@ public class CassandraClusterParser extends AbstractBeanDefinitionParser {
|
||||
throws BeanDefinitionStoreException {
|
||||
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : BeanNames.CASSANDRA_CLUSTER;
|
||||
return StringUtils.hasText(id) ? id : DefaultBeanNames.CLUSTER;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -91,91 +92,29 @@ public class CassandraClusterParser extends AbstractBeanDefinitionParser {
|
||||
*/
|
||||
protected void doParse(Element element, ParserContext context, BeanDefinitionBuilder builder) {
|
||||
|
||||
String contactPoints = element.getAttribute("contactPoints");
|
||||
if (StringUtils.hasText(contactPoints)) {
|
||||
builder.addPropertyValue("contactPoints", contactPoints);
|
||||
}
|
||||
addOptionalPropertyValue(builder, "contactPoints", element, "contact-points", null);
|
||||
addOptionalPropertyValue(builder, "port", element, "port", null);
|
||||
addOptionalPropertyValue(builder, "compressionType", element, "compression", null);
|
||||
addOptionalPropertyValue(builder, "username", element, "username", null);
|
||||
addOptionalPropertyValue(builder, "password", element, "password", null);
|
||||
addOptionalPropertyValue(builder, "deferredInitialization", element, "deferred-initialization", null);
|
||||
addOptionalPropertyValue(builder, "metricsEnabled", element, "metrics-enabled", null);
|
||||
addOptionalPropertyValue(builder, "jmxReportingEnabled", element, "jmx-reporting-enabled", null);
|
||||
addOptionalPropertyValue(builder, "sslEnabled", element, "ssl-enabled", null);
|
||||
|
||||
String port = element.getAttribute("port");
|
||||
if (StringUtils.hasText(port)) {
|
||||
builder.addPropertyValue("port", port);
|
||||
}
|
||||
|
||||
String compression = element.getAttribute("compression");
|
||||
if (StringUtils.hasText(compression)) {
|
||||
builder.addPropertyValue("compressionType", compression);
|
||||
}
|
||||
|
||||
String username = element.getAttribute("username");
|
||||
if (StringUtils.hasText(username)) {
|
||||
builder.addPropertyValue("username", username);
|
||||
}
|
||||
|
||||
String password = element.getAttribute("password");
|
||||
if (StringUtils.hasText(password)) {
|
||||
builder.addPropertyValue("password", password);
|
||||
}
|
||||
|
||||
String deferredInitialization = element.getAttribute("deferredInitialization");
|
||||
if (StringUtils.hasText(deferredInitialization)) {
|
||||
builder.addPropertyValue("deferredInitialization", deferredInitialization);
|
||||
}
|
||||
|
||||
String metricsEnabled = element.getAttribute("metricsEnabled");
|
||||
if (StringUtils.hasText(metricsEnabled)) {
|
||||
builder.addPropertyValue("metricsEnabled", metricsEnabled);
|
||||
}
|
||||
|
||||
String jmxReportingEnabled = element.getAttribute("jmxReportingEnabled");
|
||||
if (StringUtils.hasText(jmxReportingEnabled)) {
|
||||
builder.addPropertyValue("jmxReportingEnabled", jmxReportingEnabled);
|
||||
}
|
||||
|
||||
String sslEnabled = element.getAttribute("sslEnabled");
|
||||
if (StringUtils.hasText(sslEnabled)) {
|
||||
builder.addPropertyValue("sslEnabled", sslEnabled);
|
||||
}
|
||||
|
||||
String authProvider = element.getAttribute("auth-info-provider-ref");
|
||||
if (StringUtils.hasText(authProvider)) {
|
||||
builder.addPropertyReference("authProvider", authProvider);
|
||||
}
|
||||
|
||||
String loadBalancingPolicy = element.getAttribute("load-balancing-policy-ref");
|
||||
if (StringUtils.hasText(loadBalancingPolicy)) {
|
||||
builder.addPropertyReference("loadBalancingPolicy", loadBalancingPolicy);
|
||||
}
|
||||
|
||||
String reconnectionPolicy = element.getAttribute("reconnection-policy-ref");
|
||||
if (StringUtils.hasText(reconnectionPolicy)) {
|
||||
builder.addPropertyReference("reconnectionPolicy", reconnectionPolicy);
|
||||
}
|
||||
|
||||
String retryPolicy = element.getAttribute("retry-policy-ref");
|
||||
if (StringUtils.hasText(retryPolicy)) {
|
||||
builder.addPropertyReference("retryPolicy", retryPolicy);
|
||||
}
|
||||
|
||||
String sslOptions = element.getAttribute("ssl-options-ref");
|
||||
if (StringUtils.hasText(sslOptions)) {
|
||||
builder.addPropertyReference("sslOptions", sslOptions);
|
||||
}
|
||||
|
||||
String hostStateListener = element.getAttribute("host-state-listener-ref");
|
||||
if (StringUtils.hasText(hostStateListener)) {
|
||||
builder.addPropertyReference("hostStateListener", hostStateListener);
|
||||
}
|
||||
|
||||
String latencyTracker = element.getAttribute("latency-tracker-ref");
|
||||
if (StringUtils.hasText(latencyTracker)) {
|
||||
builder.addPropertyReference("latencyTracker", latencyTracker);
|
||||
}
|
||||
addOptionalPropertyReference(builder, "authProvider", element, "auth-info-provider-ref", null);
|
||||
addOptionalPropertyReference(builder, "loadBalancingPolicy", element, "load-balancing-policy-ref", null);
|
||||
addOptionalPropertyReference(builder, "reconnectionPolicy", element, "reconnection-policy-ref", null);
|
||||
addOptionalPropertyReference(builder, "retryPolicy", element, "retry-policy-ref", null);
|
||||
addOptionalPropertyReference(builder, "sslOptions", element, "ssl-options-ref", null);
|
||||
addOptionalPropertyReference(builder, "hostStateListener", element, "host-state-listener-ref", null);
|
||||
addOptionalPropertyReference(builder, "latencyTracker", element, "latency-tracker-ref", null);
|
||||
|
||||
parseChildElements(element, context, builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the Child Elemement of {@link BeanNames.CASSANDRA_CLUSTER}
|
||||
* Parse the Child Element of {@link DefaultBeanNames.CLUSTER}
|
||||
*
|
||||
* @param element The Element being parsed
|
||||
* @param context The Parser Context
|
||||
@@ -223,7 +162,7 @@ public class CassandraClusterParser extends AbstractBeanDefinitionParser {
|
||||
}
|
||||
|
||||
/*
|
||||
* If the PoolingOptionsBuilder was initilized during parsing, process it now.
|
||||
* If the PoolingOptionsBuilder was initialized during parsing, process it now.
|
||||
*/
|
||||
if (poolingOptionsBuilder != null) {
|
||||
builder.addPropertyValue("poolingOptions", getSourceBeanDefinition(poolingOptionsBuilder, context, element));
|
||||
@@ -236,7 +175,7 @@ public class CassandraClusterParser extends AbstractBeanDefinitionParser {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the Single Factory Bean that will flatten all List<List<KeyspaceActionSpecificationFactoryBean>>
|
||||
* Create the Single Factory Bean that will flatten all Set<Set<KeyspaceActionSpecificationFactoryBean>>
|
||||
*
|
||||
* @param element The Element being parsed
|
||||
* @param context The Parser Context
|
||||
@@ -262,20 +201,13 @@ public class CassandraClusterParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
ManagedList<String> networkTopologyDataCenters = new ManagedList<String>();
|
||||
ManagedList<String> networkTopologyReplicationFactors = new ManagedList<String>();
|
||||
String strategyClass = null;
|
||||
String replicationFactor = null;
|
||||
|
||||
if (element != null) {
|
||||
|
||||
strategyClass = element.getAttribute("class");
|
||||
if (!StringUtils.hasText(strategyClass)) {
|
||||
strategyClass = KeyspaceAttributes.DEFAULT_REPLICATION_STRATEGY;
|
||||
}
|
||||
|
||||
replicationFactor = element.getAttribute("replication-factor");
|
||||
if (!StringUtils.hasText(replicationFactor)) {
|
||||
replicationFactor = KeyspaceAttributes.DEFAULT_REPLICATION_FACTOR + "";
|
||||
}
|
||||
addOptionalPropertyValue(builder, "replicationStrategy", element, "class",
|
||||
KeyspaceAttributes.DEFAULT_REPLICATION_STRATEGY.name());
|
||||
addOptionalPropertyValue(builder, "replicationFactor", element, "replication-factor", ""
|
||||
+ KeyspaceAttributes.DEFAULT_REPLICATION_FACTOR);
|
||||
|
||||
/*
|
||||
* DataCenters only apply to NetworkTolopogyStrategy
|
||||
@@ -285,16 +217,10 @@ public class CassandraClusterParser extends AbstractBeanDefinitionParser {
|
||||
networkTopologyDataCenters.add(dataCenter.getAttribute("name"));
|
||||
networkTopologyReplicationFactors.add(dataCenter.getAttribute("replication-factor"));
|
||||
}
|
||||
} else {
|
||||
strategyClass = ReplicationStrategy.SIMPLE_STRATEGY.name();
|
||||
replicationFactor = KeyspaceAttributes.DEFAULT_REPLICATION_FACTOR + "";
|
||||
}
|
||||
|
||||
builder.addPropertyValue("replicationStrategy", strategyClass);
|
||||
builder.addPropertyValue("replicationFactor", replicationFactor);
|
||||
builder.addPropertyValue("networkTopologyDataCenters", networkTopologyDataCenters);
|
||||
builder.addPropertyValue("networkTopologyReplicationFactors", networkTopologyReplicationFactors);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -323,16 +249,16 @@ public class CassandraClusterParser extends AbstractBeanDefinitionParser {
|
||||
}
|
||||
|
||||
if (hostDistance.equals(HostDistance.LOCAL)) {
|
||||
ParsingUtils.setPropertyValue(builder, element, "min-simultaneous-requests", "localMinSimultaneousRequests");
|
||||
ParsingUtils.setPropertyValue(builder, element, "max-simultaneous-requests", "localMaxSimultaneousRequests");
|
||||
ParsingUtils.setPropertyValue(builder, element, "core-connections", "localCoreConnections");
|
||||
ParsingUtils.setPropertyValue(builder, element, "max-connections", "localMaxConnections");
|
||||
addOptionalPropertyValue(builder, "localMinSimultaneousRequests", element, "min-simultaneous-requests", null);
|
||||
addOptionalPropertyValue(builder, "localMaxSimultaneousRequests", element, "max-simultaneous-requests", null);
|
||||
addOptionalPropertyValue(builder, "localCoreConnections", element, "core-connections", null);
|
||||
addOptionalPropertyValue(builder, "localMaxConnections", element, "max-connections", null);
|
||||
}
|
||||
if (hostDistance.equals(HostDistance.REMOTE)) {
|
||||
ParsingUtils.setPropertyValue(builder, element, "min-simultaneous-requests", "remoteMinSimultaneousRequests");
|
||||
ParsingUtils.setPropertyValue(builder, element, "max-simultaneous-requests", "remoteMaxSimultaneousRequests");
|
||||
ParsingUtils.setPropertyValue(builder, element, "core-connections", "remoteCoreConnections");
|
||||
ParsingUtils.setPropertyValue(builder, element, "max-connections", "remoteMaxConnections");
|
||||
addOptionalPropertyValue(builder, "remoteMinSimultaneousRequests", element, "min-simultaneous-requests", null);
|
||||
addOptionalPropertyValue(builder, "remoteMaxSimultaneousRequests", element, "max-simultaneous-requests", null);
|
||||
addOptionalPropertyValue(builder, "remoteCoreConnections", element, "core-connections", null);
|
||||
addOptionalPropertyValue(builder, "remoteMaxConnections", element, "max-connections", null);
|
||||
}
|
||||
|
||||
return builder;
|
||||
@@ -349,14 +275,14 @@ public class CassandraClusterParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(SocketOptionsFactoryBean.class);
|
||||
|
||||
ParsingUtils.setPropertyValue(builder, element, "connect-timeout-mls", "connectTimeoutMillis");
|
||||
ParsingUtils.setPropertyValue(builder, element, "keep-alive", "keepAlive");
|
||||
ParsingUtils.setPropertyValue(builder, element, "read-timeout-mls", "readTimeoutMillis");
|
||||
ParsingUtils.setPropertyValue(builder, element, "reuse-address", "reuseAddress");
|
||||
ParsingUtils.setPropertyValue(builder, element, "so-linger", "soLinger");
|
||||
ParsingUtils.setPropertyValue(builder, element, "tcp-no-delay", "tcpNoDelay");
|
||||
ParsingUtils.setPropertyValue(builder, element, "receive-buffer-size", "receiveBufferSize");
|
||||
ParsingUtils.setPropertyValue(builder, element, "send-buffer-size", "sendBufferSize");
|
||||
addOptionalPropertyValue(builder, "connectTimeoutMillis", element, "connect-timeout-mls", null);
|
||||
addOptionalPropertyValue(builder, "keepAlive", element, "keep-alive", null);
|
||||
addOptionalPropertyValue(builder, "readTimeoutMillis", element, "read-timeout-mls", null);
|
||||
addOptionalPropertyValue(builder, "reuseAddress", element, "reuse-address", null);
|
||||
addOptionalPropertyValue(builder, "soLinger", element, "so-linger", null);
|
||||
addOptionalPropertyValue(builder, "tcpNoDelay", element, "tcp-no-delay", null);
|
||||
addOptionalPropertyValue(builder, "receiveBufferSize", element, "receive-buffer-size", null);
|
||||
addOptionalPropertyValue(builder, "sendBufferSize", element, "send-buffer-size", null);
|
||||
|
||||
return getSourceBeanDefinition(builder, context, element);
|
||||
}
|
||||
@@ -370,21 +296,22 @@ public class CassandraClusterParser extends AbstractBeanDefinitionParser {
|
||||
*/
|
||||
private BeanDefinition getKeyspaceSpecificationBeanDefinition(Element element, ParserContext context) {
|
||||
|
||||
String action = element.getAttribute("action");
|
||||
|
||||
Assert.notNull(action, "Keyspace Action must not be null!");
|
||||
|
||||
BeanDefinitionBuilder keyspaceBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(KeyspaceActionSpecificationFactoryBean.class);
|
||||
|
||||
ParsingUtils.setPropertyValue(keyspaceBuilder, element, "name", "name");
|
||||
ParsingUtils.setPropertyValue(keyspaceBuilder, element, "action", "action");
|
||||
ParsingUtils.setPropertyValue(keyspaceBuilder, element, "durableWrites", "durableWrites");
|
||||
// add required replication defaults
|
||||
addRequiredPropertyValue(keyspaceBuilder, "replicationStrategy",
|
||||
KeyspaceAttributes.DEFAULT_REPLICATION_STRATEGY.name());
|
||||
addRequiredPropertyValue(keyspaceBuilder, "replicationFactor", "" + KeyspaceAttributes.DEFAULT_REPLICATION_FACTOR);
|
||||
|
||||
// now start parsing
|
||||
addRequiredPropertyValue(keyspaceBuilder, "name", element, "name");
|
||||
addRequiredPropertyValue(keyspaceBuilder, "action", element, "action");
|
||||
addOptionalPropertyValue(keyspaceBuilder, "durableWrites", element, "durable-writes", "false");
|
||||
|
||||
Element replicationElement = DomUtils.getChildElementByTagName(element, "replication");
|
||||
parseReplication(replicationElement, keyspaceBuilder);
|
||||
|
||||
return getSourceBeanDefinition(keyspaceBuilder, context, element);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,12 +18,11 @@ package org.springframework.cassandra.config.xml;
|
||||
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||
|
||||
/**
|
||||
* Namespace handler for <cassandra> elements.
|
||||
* Namespace handler for spring-cassandra.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
|
||||
public class CassandraNamespaceHandler extends NamespaceHandlerSupport {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
*/
|
||||
package org.springframework.cassandra.config.xml;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import static org.springframework.cassandra.config.xml.ParsingUtils.addOptionalPropertyReference;
|
||||
import static org.springframework.cassandra.config.xml.ParsingUtils.addRequiredPropertyReference;
|
||||
import static org.springframework.cassandra.config.xml.ParsingUtils.addRequiredPropertyValue;
|
||||
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
@@ -26,8 +27,9 @@ import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.cassandra.config.CassandraSessionFactoryBean;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
|
||||
/**
|
||||
* Parser for <session> definitions.
|
||||
@@ -35,7 +37,6 @@ import org.w3c.dom.NodeList;
|
||||
* @author David Webb
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
|
||||
public class CassandraSessionParser extends AbstractSimpleBeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
@@ -48,53 +49,76 @@ public class CassandraSessionParser extends AbstractSimpleBeanDefinitionParser {
|
||||
throws BeanDefinitionStoreException {
|
||||
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : BeanNames.CASSANDRA_SESSION;
|
||||
return StringUtils.hasText(id) ? id : DefaultBeanNames.SESSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given element. This method is intended to be overridden by subclasses so that any elements not known to
|
||||
* this class can be properly parsed. The default implementation throws {@link IllegalStateException}.
|
||||
*/
|
||||
protected void parseUnhandledElement(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
throw new IllegalStateException(String.format("encountered unhandled element [%s]", element.getLocalName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given session element attribute. This method is intended to be overridden by subclasses so that any
|
||||
* attributes not known to this class can be properly parsed. The default implementation throws
|
||||
* {@link IllegalStateException}.
|
||||
*/
|
||||
protected void parseUnhandledSessionElementAttribute(Attr attribute, ParserContext parserContext,
|
||||
BeanDefinitionBuilder builder) {
|
||||
throw new IllegalStateException(String.format("encountered unhandled session element attribute [%s]",
|
||||
attribute.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
parseKeyspaceName(element, builder);
|
||||
parseClusterRef(element, builder);
|
||||
parseScripts(element, builder, "startup-cql", "startupScripts");
|
||||
parseScripts(element, builder, "shutdown-cql", "shutdownScripts");
|
||||
setDefaultProperties(builder);
|
||||
|
||||
parseSessionAttributes(element, parserContext, builder);
|
||||
parseSessionChildElements(element, parserContext, builder);
|
||||
}
|
||||
|
||||
protected void parseScripts(Element element, BeanDefinitionBuilder builder, String elementName, String propertyName) {
|
||||
|
||||
List<String> scripts = parseScripts(element, elementName);
|
||||
builder.addPropertyValue(propertyName, scripts);
|
||||
protected void setDefaultProperties(BeanDefinitionBuilder builder) {
|
||||
addRequiredPropertyReference(builder, "cluster", DefaultBeanNames.CLUSTER);
|
||||
}
|
||||
|
||||
protected void parseClusterRef(Element element, BeanDefinitionBuilder builder) {
|
||||
protected void parseSessionAttributes(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
String clusterRef = element.getAttribute("cluster-ref");
|
||||
if (!StringUtils.hasText(clusterRef)) {
|
||||
clusterRef = BeanNames.CASSANDRA_CLUSTER;
|
||||
}
|
||||
builder.addPropertyReference("cluster", clusterRef);
|
||||
}
|
||||
|
||||
protected void parseKeyspaceName(Element element, BeanDefinitionBuilder builder) {
|
||||
|
||||
String keyspaceName = element.getAttribute("keyspace-name");
|
||||
if (!StringUtils.hasText(keyspaceName)) {
|
||||
keyspaceName = null;
|
||||
}
|
||||
builder.addPropertyValue("keyspaceName", keyspaceName);
|
||||
}
|
||||
|
||||
protected List<String> parseScripts(Element element, String elementName) {
|
||||
|
||||
NodeList nodes = element.getElementsByTagName(elementName);
|
||||
int length = nodes.getLength();
|
||||
List<String> scripts = new ArrayList<String>(length);
|
||||
NamedNodeMap attributes = element.getAttributes();
|
||||
int length = attributes.getLength();
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
Element script = (Element) nodes.item(i);
|
||||
scripts.add(DomUtils.getTextValue(script));
|
||||
}
|
||||
|
||||
return scripts;
|
||||
Attr attribute = (Attr) attributes.item(i);
|
||||
if ("id".equals(attribute.getName())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String name = attribute.getName();
|
||||
|
||||
if ("keyspace-name".equals(name)) {
|
||||
addRequiredPropertyValue(builder, "keyspaceName", attribute);
|
||||
} else if ("cluster-ref".equals(name)) {
|
||||
addOptionalPropertyReference(builder, "cluster", attribute, DefaultBeanNames.CLUSTER);
|
||||
} else {
|
||||
parseUnhandledSessionElementAttribute(attribute, parserContext, builder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void parseSessionChildElements(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
for (Element child : DomUtils.getChildElements(element)) {
|
||||
|
||||
if ("startup-cql".equals(child.getLocalName())) {
|
||||
builder.addPropertyValue("startupScripts", DomUtils.getTextValue(child));
|
||||
} else if ("shutdown-cql".equals(child.getLocalName())) {
|
||||
builder.addPropertyValue("shutdownScripts", DomUtils.getTextValue(child));
|
||||
} else {
|
||||
parseUnhandledElement(child, parserContext, builder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.cassandra.config.xml;
|
||||
|
||||
import static org.springframework.cassandra.config.xml.ParsingUtils.*;
|
||||
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
@@ -30,7 +32,6 @@ import org.w3c.dom.Element;
|
||||
* @author David Webb
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
|
||||
public class CassandraTemplateParser extends AbstractSimpleBeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
@@ -43,16 +44,11 @@ public class CassandraTemplateParser extends AbstractSimpleBeanDefinitionParser
|
||||
throws BeanDefinitionStoreException {
|
||||
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : BeanNames.CASSANDRA_TEMPLATE;
|
||||
return StringUtils.hasText(id) ? id : DefaultBeanNames.TEMPLATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
String sessionRef = element.getAttribute("session-ref");
|
||||
if (!StringUtils.hasText(sessionRef)) {
|
||||
sessionRef = BeanNames.CASSANDRA_SESSION;
|
||||
}
|
||||
builder.addPropertyReference("session", sessionRef);
|
||||
addOptionalPropertyReference(builder, "session", element, "session-ref", DefaultBeanNames.SESSION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,13 +20,9 @@ package org.springframework.cassandra.config.xml;
|
||||
* @author David Webb
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public final class BeanNames {
|
||||
public interface DefaultBeanNames {
|
||||
|
||||
private BeanNames() {
|
||||
}
|
||||
|
||||
public static final String CASSANDRA_CLUSTER = "cassandra-cluster";
|
||||
public static final String CASSANDRA_KEYSPACE = "cassandra-keyspace";
|
||||
public static final String CASSANDRA_SESSION = "cassandra-session";
|
||||
public static final String CASSANDRA_TEMPLATE = "cassandra-template";
|
||||
public static final String CLUSTER = "cassandra-cluster";
|
||||
public static final String SESSION = "cassandra-session";
|
||||
public static final String TEMPLATE = "cql-template";
|
||||
}
|
||||
@@ -1,33 +1,295 @@
|
||||
package org.springframework.cassandra.config.xml;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
public class ParsingUtils {
|
||||
|
||||
/**
|
||||
* Configures a property value for the given property name reading the attribute of the given name from the given
|
||||
* {@link Element} if the attribute is configured.
|
||||
*
|
||||
* @param builder must not be {@literal null}.
|
||||
* @param element must not be {@literal null}.
|
||||
* @param attrName must not be {@literal null} or empty.
|
||||
* @param propertyName must not be {@literal null} or empty.
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void setPropertyValue(BeanDefinitionBuilder builder, Element element, String attrName,
|
||||
String propertyName) {
|
||||
public static void addOptionalPropertyValue(BeanDefinitionBuilder builder, String propertyName, Element element,
|
||||
String attrName, String defaultValue) {
|
||||
|
||||
addProperty(builder, propertyName, element.getAttribute(attrName), defaultValue, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addOptionalPropertyReference(BeanDefinitionBuilder builder, String propertyName, Element element,
|
||||
String attrName, String defaultValue) {
|
||||
|
||||
addProperty(builder, propertyName, element.getAttribute(attrName), defaultValue, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addRequiredPropertyValue(BeanDefinitionBuilder builder, String propertyName, Element element,
|
||||
String attrName) {
|
||||
|
||||
addProperty(builder, propertyName, element.getAttribute(attrName), null, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addRequiredPropertyReference(BeanDefinitionBuilder builder, String propertyName, Element element,
|
||||
String attrName) {
|
||||
|
||||
addProperty(builder, propertyName, element.getAttribute(attrName), null, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addPropertyValue(BeanDefinitionBuilder builder, String propertyName, Element element,
|
||||
String attrName, String defaultValue, boolean required) {
|
||||
|
||||
addProperty(builder, propertyName, element.getAttribute(attrName), defaultValue, required, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addPropertyReference(BeanDefinitionBuilder builder, String propertyName, Element element,
|
||||
String attrName, String defaultValue, boolean required) {
|
||||
|
||||
addProperty(builder, propertyName, element.getAttribute(attrName), defaultValue, required, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addProperty(BeanDefinitionBuilder builder, String propertyName, Element element, String attrName,
|
||||
String defaultValue, boolean required, boolean reference) {
|
||||
|
||||
Assert.notNull(builder, "BeanDefinitionBuilder must not be null!");
|
||||
Assert.notNull(element, "Element must not be null!");
|
||||
Assert.hasText(attrName, "Attribute name must not be null!");
|
||||
|
||||
addProperty(builder, propertyName, element.getAttribute(attrName), defaultValue, required, reference);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addOptionalPropertyValue(BeanDefinitionBuilder builder, String propertyName, Attr attr,
|
||||
String defaultValue) {
|
||||
|
||||
addProperty(builder, propertyName, attr, defaultValue, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addOptionalPropertyReference(BeanDefinitionBuilder builder, String propertyName, Attr attr,
|
||||
String defaultValue) {
|
||||
|
||||
addProperty(builder, propertyName, attr, defaultValue, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addRequiredPropertyValue(BeanDefinitionBuilder builder, String propertyName, Attr attr) {
|
||||
|
||||
addProperty(builder, propertyName, attr, null, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addRequiredPropertyReference(BeanDefinitionBuilder builder, String propertyName, Attr attr) {
|
||||
|
||||
addProperty(builder, propertyName, attr, null, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addPropertyValue(BeanDefinitionBuilder builder, String propertyName, Attr attr,
|
||||
String defaultValue, boolean required) {
|
||||
|
||||
addProperty(builder, propertyName, attr, defaultValue, required, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addPropertyReference(BeanDefinitionBuilder builder, String propertyName, Attr attr,
|
||||
String defaultValue, boolean required) {
|
||||
|
||||
addProperty(builder, propertyName, attr, defaultValue, required, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addProperty(BeanDefinitionBuilder builder, String propertyName, Attr attr, String defaultValue,
|
||||
boolean required, boolean reference) {
|
||||
|
||||
Assert.notNull(attr, "Attr must not be null!");
|
||||
|
||||
addProperty(builder, propertyName, attr.getValue(), defaultValue, required, reference);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addRequiredPropertyValue(BeanDefinitionBuilder builder, String propertyName, String value) {
|
||||
|
||||
addProperty(builder, propertyName, value, null, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addRequiredPropertyReference(BeanDefinitionBuilder builder, String propertyName, String value) {
|
||||
|
||||
addProperty(builder, propertyName, value, null, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addOptionalPropertyValue(BeanDefinitionBuilder builder, String propertyName, String value,
|
||||
String defaultValue) {
|
||||
|
||||
addProperty(builder, propertyName, value, defaultValue, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addOptionalPropertyReference(BeanDefinitionBuilder builder, String propertyName, String value,
|
||||
String defaultValue) {
|
||||
|
||||
addProperty(builder, propertyName, value, defaultValue, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addPropertyValue(BeanDefinitionBuilder builder, String propertyName, String value,
|
||||
String defaultValue, boolean required) {
|
||||
|
||||
addProperty(builder, propertyName, value, defaultValue, required, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that ultimately delegates to
|
||||
* {@link #addProperty(BeanDefinitionBuilder, String, Element, String, String, boolean, boolean)}.
|
||||
*/
|
||||
public static void addPropertyReference(BeanDefinitionBuilder builder, String propertyName, String value,
|
||||
String defaultValue, boolean required) {
|
||||
|
||||
addProperty(builder, propertyName, value, defaultValue, required, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the named property as a value or reference to the given {@link BeanDefinitionBuilder}, with an optional
|
||||
* default value.
|
||||
* <p/>
|
||||
* Note: If <code>required</code> is <code>false</code>, <code>value</code> is null or empty, and
|
||||
* <code>defaultValue</code> is null or empty, then no property is added and this method silently returns.
|
||||
*
|
||||
* @param builder The {@link BeanDefinitionBuilder}; must not be null.
|
||||
* @param propertyName The name of the property being added; must not be null or empty.
|
||||
* @param value The value of the property being added; may be null.
|
||||
* @param defaultValue The default value of the property being set.
|
||||
* @param required If <code>true</code>, then the <code>value</code> parameter must not be null or empty. If
|
||||
* <code>false</code>, the <code>value</code> parameter may be null, in which case the
|
||||
* <code>defaultValue</code> is used. If <code>required</code> is <code>false</code>, <code>value</code> is
|
||||
* null or empty, and <code>defaultValue</code> is null or empty, then no property is added and this method
|
||||
* silently returns.
|
||||
* @param reference If <code>true</code>, this method will add the property as a reference, else as a value.
|
||||
*
|
||||
* @see BeanDefinitionBuilder#addPropertyReference(String, String)
|
||||
* @see BeanDefinitionBuilder#addPropertyValue(String, Object)
|
||||
*/
|
||||
public static void addProperty(BeanDefinitionBuilder builder, String propertyName, String value, String defaultValue,
|
||||
boolean required, boolean reference) {
|
||||
|
||||
Assert.notNull(builder, "BeanDefinitionBuilder must not be null!");
|
||||
Assert.hasText(propertyName, "Property name must not be null!");
|
||||
|
||||
String attr = element.getAttribute(attrName);
|
||||
if (!StringUtils.hasText(value)) {
|
||||
if (required) {
|
||||
throw new IllegalStateException(String.format("value required for property %s [%s] on class [%s]",
|
||||
reference ? "reference" : "", propertyName, builder.getBeanDefinition().getClass().getName()));
|
||||
}
|
||||
// else optional; use default
|
||||
if (defaultValue != null) {
|
||||
value = defaultValue;
|
||||
} else { // no default value given; quietly ignore & return
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(attr)) {
|
||||
builder.addPropertyValue(propertyName, attr);
|
||||
if (reference) {
|
||||
builder.addPropertyReference(propertyName, value);
|
||||
} else {
|
||||
builder.addPropertyValue(propertyName, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link BeanDefinition} built by the given {@link BeanDefinitionBuilder} enriched with source
|
||||
* information derived from the given {@link Element}.
|
||||
*
|
||||
* @param builder must not be {@literal null}.
|
||||
* @param context must not be {@literal null}.
|
||||
* @param element must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static AbstractBeanDefinition getSourceBeanDefinition(BeanDefinitionBuilder builder, ParserContext context,
|
||||
Element element) {
|
||||
|
||||
Assert.notNull(element, "Element must not be null!");
|
||||
Assert.notNull(context, "ParserContext must not be null!");
|
||||
|
||||
return getSourceBeanDefinition(builder, context.extractSource(element));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link AbstractBeanDefinition} built by the given builder with the given extracted source applied.
|
||||
*
|
||||
* @param builder must not be {@literal null}.
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
public static AbstractBeanDefinition getSourceBeanDefinition(BeanDefinitionBuilder builder, Object source) {
|
||||
|
||||
Assert.notNull(builder, "Builder must not be null!");
|
||||
|
||||
AbstractBeanDefinition definition = builder.getRawBeanDefinition();
|
||||
definition.setSource(source);
|
||||
return definition;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.cassandra.support;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.Session;
|
||||
|
||||
@@ -53,6 +54,7 @@ public class CassandraAccessor implements InitializingBean {
|
||||
/**
|
||||
* Ensure that the Cassandra Session has been set
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
if (getSession() == null) {
|
||||
throw new IllegalArgumentException("Property 'session' is required");
|
||||
@@ -70,7 +72,7 @@ public class CassandraAccessor implements InitializingBean {
|
||||
* @param session The session to set.
|
||||
*/
|
||||
public void setSession(Session session) {
|
||||
Assert.notNull(session);
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ Defines the configuration elements for Spring Cassandra support.
|
||||
<xsd:element name="session" type="sessionType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation
|
||||
source="org.springframework.cassandra.config.xml.SessionFactoryBean"><![CDATA[
|
||||
source="org.springframework.cassandra.config.xml.CassandraSessionFactoryBean"><![CDATA[
|
||||
Defines a Cassandra session.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
@@ -32,12 +32,12 @@ Defines a Cassandra session.
|
||||
<xsd:element name="template" type="templateType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation
|
||||
source="org.springframework.cassandra.config.xml.TemplateFactoryBean"><![CDATA[
|
||||
Defines a CassandraTemplate.
|
||||
source="org.springframework.cassandra.config.xml.CassandraTemplateFactoryBean"><![CDATA[
|
||||
Defines a CqlTemplate.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="org.springframework.cassandra.CassandraTemplate" />
|
||||
<tool:exports type="org.springframework.cassandra.CqlTemplate" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -59,16 +59,22 @@ Defines a Cassandra cluster.
|
||||
|
||||
<xsd:complexType name="clusterType">
|
||||
<xsd:sequence>
|
||||
|
||||
<xsd:element name="local-pooling-options"
|
||||
type="poolingOptionsType" maxOccurs="1" minOccurs="0">
|
||||
<xsd:element name="local-pooling-options" type="poolingOptionsType"
|
||||
maxOccurs="1" minOccurs="0">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Local pooling options.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="remote-pooling-options" type="poolingOptionsType"
|
||||
minOccurs="0" maxOccurs="1">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Remote pooling options.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="remote-pooling-options" type="poolingOptionsType" minOccurs="0" maxOccurs="1"></xsd:element>
|
||||
<xsd:element name="socket-options" type="socketOptionsType"
|
||||
maxOccurs="1" minOccurs="0">
|
||||
<xsd:annotation>
|
||||
@@ -111,7 +117,7 @@ The name of the Cassandra Cluster definition; default is "cassandra-cluster".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="contactPoints" type="xsd:string"
|
||||
<xsd:attribute name="contact-points" type="xsd:string"
|
||||
use="optional" default="localhost">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
@@ -135,7 +141,6 @@ The protocol compression option. Default is "NONE".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
|
||||
<xsd:attribute name="username" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
@@ -151,35 +156,39 @@ When Authentication is enabled, the password to use when connecting to the Clust
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="metricsEnabled" type="xsd:string" default="true">
|
||||
<xsd:attribute name="metrics-enabled" type="xsd:string"
|
||||
default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Determine whether or not to collect metrics. Defaults to true.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="jmxReportingEnabled" type="xsd:string" default="true">
|
||||
<xsd:attribute name="jmx-reporting-enabled" type="xsd:string"
|
||||
default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Determine whether or not to enable JMX Reporting. Defaults to true.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="deferredInitialization" type="xsd:string" default="false">
|
||||
<xsd:attribute name="deferred-initialization" type="xsd:string"
|
||||
default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Determine if we defer initalizing the cluster until a connection is requested. Defaults to false.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="sslEnabled" type="xsd:string" default="false">
|
||||
<xsd:attribute name="ssl-enabled" type="xsd:string"
|
||||
default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Determine if SSL is used for Cassandra communication. Defaults to false.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="auth-info-provider-ref" use="optional">
|
||||
<xsd:attribute name="auth-info-provider-ref" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
AuthInfoProvider implementation.
|
||||
@@ -196,7 +205,7 @@ AuthInfoProvider implementation.
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="load-balancing-policy-ref" use="optional">
|
||||
<xsd:attribute name="load-balancing-policy-ref" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
LoadBalancingPolicy implementation.
|
||||
@@ -260,8 +269,7 @@ Custom SSL Options. sslEnabled must be true for sslOptions to be used.
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to
|
||||
type="com.datastax.driver.core.SSLOptions" />
|
||||
<tool:assignable-to type="com.datastax.driver.core.SSLOptions" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -278,8 +286,7 @@ Custom Host State Listener for the Cassandra Cluster.
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to
|
||||
type="com.datastax.driver.core.Host.StateListener" />
|
||||
<tool:assignable-to type="com.datastax.driver.core.Host.StateListener" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -296,8 +303,7 @@ Custom Latency Tracker for the Cassandra Cluster.
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to
|
||||
type="com.datastax.driver.core.LatencyTracker" />
|
||||
<tool:assignable-to type="com.datastax.driver.core.LatencyTracker" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -467,7 +473,7 @@ The name of a Cassandra Keyspace. No default; for the system keyspace, use the
|
||||
<xsd:attribute name="id" type="xsd:ID" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the template; default is "cassandra-template".
|
||||
The name of the template; default is "cql-template".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
@@ -537,7 +543,7 @@ Provides the ability to specify replication factors by data center.
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="class" type="xsd:string" use="optional"
|
||||
default="SimpleStrategy">
|
||||
default="SIMPLE_STRATEGY">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the replication class; default is "SIMPLE_STRATEGY".
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
<bean id="latencyTracker" class="org.springframework.cassandra.test.integration.config.xml.TestLatencyTracker"/>
|
||||
|
||||
<cassandra:cluster id="cassandra-cluster"
|
||||
contactPoints="${cluster.contactPoints}" port="${cluster.port}"
|
||||
contact-points="${cluster.contactPoints}" port="${cluster.port}"
|
||||
compression="${cluster.compression}" auth-info-provider-ref="authProvider"
|
||||
load-balancing-policy-ref="loadBalancingPolicy" username="${auth.username}" password="${auth.password}"
|
||||
deferredInitialization="${cluster.deferredInit}" metricsEnabled="${cluster.metricsEnabled}"
|
||||
jmxReportingEnabled="${cluster.jmxReportingEnabled}"
|
||||
deferred-initialization="${cluster.deferredInit}" metrics-enabled="${cluster.metricsEnabled}"
|
||||
jmx-reporting-enabled="${cluster.jmxReportingEnabled}"
|
||||
reconnection-policy-ref="reconnectionPolicy"
|
||||
retry-policy-ref="retryPolicy"
|
||||
host-state-listener-ref="hostStateListener"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
location="classpath:org.springframework.cassandra.test.integration.support.BuildProperties.properties" />
|
||||
|
||||
<cassandra:cluster id="cassandra-cluster"
|
||||
contactPoints="localhost" port="${build.cassandra.native_transport_port}">
|
||||
contact-points="localhost" port="${build.cassandra.native_transport_port}">
|
||||
<cassandra:local-pooling-options
|
||||
min-simultaneous-requests="25" max-simultaneous-requests="100"
|
||||
core-connections="2" max-connections="8" />
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.springframework.data.cassandra.config;
|
||||
|
||||
import org.springframework.cassandra.config.CassandraClusterFactoryBean;
|
||||
|
||||
/**
|
||||
* Spring Data Cassandra extension of CassandraClusterFactoryBean. This class exists only in the name of symmetry, based
|
||||
* on the other CassandraData*FactoryBean classes.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraDataClusterFactoryBean extends CassandraClusterFactoryBean {
|
||||
}
|
||||
@@ -8,7 +8,10 @@ import org.springframework.data.cassandra.core.CassandraAdminTemplate;
|
||||
import org.springframework.data.cassandra.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.datastax.driver.core.KeyspaceMetadata;
|
||||
import com.datastax.driver.core.Metadata;
|
||||
import com.datastax.driver.core.TableMetadata;
|
||||
|
||||
public class CassandraDataSessionFactoryBean extends CassandraSessionFactoryBean {
|
||||
@@ -17,17 +20,56 @@ public class CassandraDataSessionFactoryBean extends CassandraSessionFactoryBean
|
||||
protected CassandraAdminTemplate admin;
|
||||
protected CassandraConverter converter;
|
||||
protected CassandraMappingContext mappingContext;
|
||||
protected Mapping mapping;
|
||||
protected ClassLoader entityClassLoader = getClass().getClassLoader();
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
super.afterPropertiesSet();
|
||||
|
||||
Assert.notNull(converter);
|
||||
|
||||
if (mapping == null) {
|
||||
mapping = new Mapping();
|
||||
}
|
||||
|
||||
admin = new CassandraAdminTemplate(session);
|
||||
admin.setCassandraConverter(converter);
|
||||
|
||||
processMappingOverrides();
|
||||
performSchemaAction();
|
||||
}
|
||||
|
||||
protected void processMappingOverrides() throws ClassNotFoundException {
|
||||
|
||||
if (mapping == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (EntityMapping entityMapping : mapping.getEntityMappings()) {
|
||||
|
||||
if (entityMapping == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String entityClassName = entityMapping.getEntityClassName();
|
||||
Class<?> entityClass = Class.forName(entityClassName, false, entityClassLoader);
|
||||
|
||||
CassandraPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
|
||||
|
||||
if (entity == null) {
|
||||
throw new IllegalStateException(String.format("unknown persistent entity class name [%s]", entityClassName));
|
||||
}
|
||||
|
||||
String tableName = entityMapping.getTableName();
|
||||
if (!StringUtils.hasText(tableName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
entity.setTableName(tableName);
|
||||
}
|
||||
}
|
||||
|
||||
protected void performSchemaAction() {
|
||||
|
||||
boolean dropTables = false;
|
||||
@@ -51,7 +93,18 @@ public class CassandraDataSessionFactoryBean extends CassandraSessionFactoryBean
|
||||
|
||||
protected void createTables(boolean dropTables, boolean dropUnused) {
|
||||
|
||||
for (TableMetadata table : session.getCluster().getMetadata().getKeyspace(keyspaceName).getTables()) {
|
||||
Metadata md = session.getCluster().getMetadata();
|
||||
KeyspaceMetadata kmd = md.getKeyspace(keyspaceName);
|
||||
|
||||
if (kmd == null) { // try lower-cased keyspace name
|
||||
kmd = md.getKeyspace(keyspaceName.toLowerCase());
|
||||
}
|
||||
|
||||
if (kmd == null) {
|
||||
throw new IllegalStateException(String.format("keyspace [%s] does not exist", keyspaceName));
|
||||
}
|
||||
|
||||
for (TableMetadata table : kmd.getTables()) {
|
||||
if (dropTables) {
|
||||
if (dropUnused || mappingContext.usesTable(table)) {
|
||||
admin.dropTable(table.getName());
|
||||
@@ -62,7 +115,7 @@ public class CassandraDataSessionFactoryBean extends CassandraSessionFactoryBean
|
||||
Collection<? extends CassandraPersistentEntity<?>> entities = converter.getMappingContext().getPersistentEntities();
|
||||
|
||||
for (CassandraPersistentEntity<?> entity : entities) {
|
||||
admin.createTable(false, entity.getTableName(), entity.getType(), null /* TODO */);
|
||||
admin.createTable(false, entity.getTableName(), entity.getType(), null); // TODO: allow spec of table options
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,4 +137,22 @@ public class CassandraDataSessionFactoryBean extends CassandraSessionFactoryBean
|
||||
this.converter = converter;
|
||||
this.mappingContext = converter.getCassandraMappingContext();
|
||||
}
|
||||
|
||||
public Mapping getMapping() {
|
||||
return mapping;
|
||||
}
|
||||
|
||||
public void setMapping(Mapping mapping) {
|
||||
Assert.notNull(mapping);
|
||||
this.mapping = mapping;
|
||||
}
|
||||
|
||||
public ClassLoader getEntityClassLoader() {
|
||||
return entityClassLoader;
|
||||
}
|
||||
|
||||
public void setEntityClassLoader(ClassLoader entityClassLoader) {
|
||||
Assert.notNull(entityClassLoader);
|
||||
this.entityClassLoader = entityClassLoader;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.springframework.data.cassandra.config;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.data.cassandra.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.core.CassandraOperations;
|
||||
import org.springframework.data.cassandra.core.CassandraTemplate;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.Session;
|
||||
|
||||
public class CassandraDataTemplateFactoryBean implements FactoryBean<CassandraOperations>, InitializingBean {
|
||||
|
||||
protected Session session;
|
||||
protected CassandraConverter converter;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(session);
|
||||
Assert.notNull(converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CassandraOperations getObject() throws Exception {
|
||||
return new CassandraTemplate(session, converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return CassandraOperations.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setSession(Session session) {
|
||||
Assert.notNull(session);
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
public void setConverter(CassandraConverter converter) {
|
||||
Assert.notNull(converter);
|
||||
this.converter = converter;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.springframework.data.cassandra.config;
|
||||
|
||||
import org.springframework.cassandra.config.xml.DefaultBeanNames;
|
||||
|
||||
public interface DefaultDataBeanNames extends DefaultBeanNames {
|
||||
|
||||
public static final String DATA_TEMPLATE = "cassandra-template";
|
||||
public static final String CONVERTER = "cassandra-converter";
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package org.springframework.data.cassandra.config;
|
||||
|
||||
/**
|
||||
* Mapping information for an individual entity class.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class EntityMapping {
|
||||
|
||||
protected String entityClassName;
|
||||
protected String tableName;
|
||||
|
||||
public EntityMapping(String entityClassName, String tableName) {
|
||||
setEntityClassName(entityClassName);
|
||||
setTableName(tableName);
|
||||
}
|
||||
|
||||
public String getEntityClassName() {
|
||||
return entityClassName;
|
||||
}
|
||||
|
||||
public void setEntityClassName(String entityClassName) {
|
||||
this.entityClassName = entityClassName;
|
||||
}
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
if (that == null) {
|
||||
return false;
|
||||
}
|
||||
if (this == that) {
|
||||
return true;
|
||||
}
|
||||
if (!(that instanceof EntityMapping)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EntityMapping thatMapping = (EntityMapping) that;
|
||||
|
||||
return this.entityClassName.equals(thatMapping.entityClassName) && this.tableName.equals(thatMapping.tableName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return entityClassName.hashCode() ^ tableName.hashCode();
|
||||
}
|
||||
}
|
||||
@@ -15,17 +15,25 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.config;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class KeyspaceAttributes extends org.springframework.cassandra.config.KeyspaceAttributes {
|
||||
public class Mapping {
|
||||
|
||||
private Collection<TableAttributes> tables;
|
||||
private Set<EntityMapping> entityMappings = new HashSet<EntityMapping>();
|
||||
|
||||
public Collection<TableAttributes> getTables() {
|
||||
return tables;
|
||||
public Set<EntityMapping> getEntityMappings() {
|
||||
return Collections.unmodifiableSet(entityMappings);
|
||||
}
|
||||
|
||||
public void setTables(Collection<TableAttributes> tables) {
|
||||
this.tables = tables;
|
||||
public void setEntityMappings(Set<EntityMapping> mappings) {
|
||||
|
||||
if (mappings == null) {
|
||||
entityMappings.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
this.entityMappings = new HashSet<EntityMapping>(mappings);
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2013 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.cassandra.config;
|
||||
|
||||
/**
|
||||
* Table attributes are used for manipulation around table at the startup (create/update/validate).
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
public class TableAttributes {
|
||||
|
||||
private String entity;
|
||||
private String name;
|
||||
|
||||
public String getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public void setEntity(String entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TableAttributes [entity=" + entity + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.springframework.data.cassandra.config.xml;
|
||||
|
||||
import org.springframework.cassandra.config.xml.CassandraClusterParser;
|
||||
|
||||
/**
|
||||
* Spring Data Cassandra XML namespace parser for the <cluster> element.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraDataClusterParser extends CassandraClusterParser {
|
||||
}
|
||||
@@ -15,16 +15,21 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.config.xml;
|
||||
|
||||
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||
|
||||
/**
|
||||
* Namespace handler for <cassandra>.
|
||||
* Namespace handler for spring-data-cassandra.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
|
||||
public class CassandraNamespaceHandler extends org.springframework.cassandra.config.xml.CassandraNamespaceHandler {
|
||||
public class CassandraDataNamespaceHandler extends NamespaceHandlerSupport {
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
|
||||
registerBeanDefinitionParser("cluster", new CassandraDataClusterParser());
|
||||
registerBeanDefinitionParser("session", new CassandraDataSessionParser());
|
||||
registerBeanDefinitionParser("template", new CassandraDataTemplateParser());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package org.springframework.data.cassandra.config.xml;
|
||||
|
||||
import static org.springframework.cassandra.config.xml.ParsingUtils.*;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.cassandra.config.xml.CassandraSessionParser;
|
||||
import org.springframework.data.cassandra.config.DefaultDataBeanNames;
|
||||
import org.springframework.data.cassandra.config.CassandraDataSessionFactoryBean;
|
||||
import org.springframework.data.cassandra.config.EntityMapping;
|
||||
import org.springframework.data.cassandra.config.Mapping;
|
||||
import org.springframework.data.cassandra.config.SchemaAction;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Spring Data Cassandra XML namespace parser for the <session> element.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraDataSessionParser extends CassandraSessionParser {
|
||||
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return CassandraDataSessionFactoryBean.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void parseUnhandledSessionElementAttribute(Attr attribute, ParserContext parserContext,
|
||||
BeanDefinitionBuilder builder) {
|
||||
|
||||
String name = attribute.getName();
|
||||
|
||||
if ("cassandra-converter-ref".equals(name)) {
|
||||
addOptionalPropertyReference(builder, "converter", attribute, DefaultDataBeanNames.CONVERTER);
|
||||
} else if ("schema-action".equals(name)) {
|
||||
addOptionalPropertyValue(builder, "schemaAction", attribute, SchemaAction.NONE.name());
|
||||
} else {
|
||||
super.parseUnhandledSessionElementAttribute(attribute, parserContext, builder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void parseUnhandledElement(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
if ("mapping".equals(element.getLocalName())) {
|
||||
parseMapping(element, parserContext, builder);
|
||||
} else {
|
||||
super.parseUnhandledElement(element, parserContext, builder);
|
||||
}
|
||||
}
|
||||
|
||||
protected void parseMapping(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
// TODO: parse <mapping> attributes here, if there ever are any
|
||||
|
||||
Set<EntityMapping> mappings = new HashSet<EntityMapping>();
|
||||
|
||||
for (Element child : DomUtils.getChildElementsByTagName(element, "entity")) {
|
||||
|
||||
EntityMapping entityMapping = parseEntity(child);
|
||||
|
||||
if (entityMapping != null) {
|
||||
mappings.add(entityMapping);
|
||||
}
|
||||
}
|
||||
|
||||
Mapping mapping = new Mapping();
|
||||
mapping.setEntityMappings(mappings);
|
||||
|
||||
builder.addPropertyValue("mapping", mapping);
|
||||
}
|
||||
|
||||
protected EntityMapping parseEntity(Element entity) {
|
||||
|
||||
String className = entity.getAttribute("class");
|
||||
if (!StringUtils.hasText(className)) {
|
||||
throw new IllegalStateException("class attribute must not be empty");
|
||||
}
|
||||
|
||||
Element table = DomUtils.getChildElementByTagName(entity, "table");
|
||||
if (table == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String tableName = table.getAttribute("name");
|
||||
if (!StringUtils.hasText(tableName)) {
|
||||
tableName = null;
|
||||
}
|
||||
|
||||
// TODO: parse future entity mappings here, like table options
|
||||
|
||||
return new EntityMapping(className, tableName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.springframework.data.cassandra.config.xml;
|
||||
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.cassandra.config.xml.CassandraTemplateParser;
|
||||
import org.springframework.data.cassandra.config.DefaultDataBeanNames;
|
||||
import org.springframework.data.cassandra.config.CassandraDataTemplateFactoryBean;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Spring Data Cassandra XML namespace parser for the <template> element.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraDataTemplateParser extends CassandraTemplateParser {
|
||||
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return CassandraDataTemplateFactoryBean.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||
throws BeanDefinitionStoreException {
|
||||
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : DefaultDataBeanNames.DATA_TEMPLATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
super.doParse(element, parserContext, builder);
|
||||
|
||||
parseConverterAttribute(element, parserContext, builder);
|
||||
}
|
||||
|
||||
protected void parseConverterAttribute(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
String converterRef = element.getAttribute("cassandra-converter-ref");
|
||||
if (!StringUtils.hasText(converterRef)) {
|
||||
converterRef = DefaultDataBeanNames.CONVERTER;
|
||||
}
|
||||
builder.addPropertyReference("converter", converterRef);
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,6 @@ public class CassandraAdminTemplate extends CassandraAccessor implements Cassand
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(CassandraAdminTemplate.class);
|
||||
|
||||
private Session session;
|
||||
private CassandraConverter converter;
|
||||
private CassandraMappingContext mappingContext;
|
||||
|
||||
@@ -197,7 +196,7 @@ public class CassandraAdminTemplate extends CassandraAccessor implements Cassand
|
||||
Assert.notNull(callback);
|
||||
|
||||
try {
|
||||
return callback.doInSession(session);
|
||||
return callback.doInSession(getSession());
|
||||
} catch (RuntimeException x) {
|
||||
throw tryToConvert(x);
|
||||
}
|
||||
|
||||
@@ -46,11 +46,12 @@ import com.datastax.driver.core.querybuilder.QueryBuilder;
|
||||
import com.datastax.driver.core.querybuilder.Select;
|
||||
|
||||
/**
|
||||
* The Cassandra Data Template is a convenience API for all Cassandra Operations using POJOs. This is the "Spring Data"
|
||||
* flavor of the template. For low level Cassandra Operations use the {@link CqlTemplate}
|
||||
* The Cassandra Data Template is a convenience API for all Cassandra Operations using POJOs. For low level Cassandra
|
||||
* Operations use the {@link CqlTemplate}
|
||||
*
|
||||
* @author Alex Shvid
|
||||
* @author David Webb
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraTemplate extends CqlTemplate implements CassandraOperations {
|
||||
|
||||
@@ -107,7 +108,11 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
|
||||
*
|
||||
* @param session must not be {@literal null}.
|
||||
* @param converter must not be {@literal null}.
|
||||
*
|
||||
* @deprecated use {@link #CassandraTemplate(Session, CassandraConverter)} because session should already be connected
|
||||
* to keyspace
|
||||
*/
|
||||
@Deprecated
|
||||
public CassandraTemplate(Session session, CassandraConverter converter, String keyspace) {
|
||||
setSession(session);
|
||||
this.keyspace = keyspace;
|
||||
@@ -937,6 +942,7 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
|
||||
* @param callback
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected <T> T doExecute(SessionCallback<T> callback) {
|
||||
|
||||
Assert.notNull(callback);
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ParserContext;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -42,7 +43,7 @@ import org.springframework.util.StringUtils;
|
||||
public class BasicCassandraPersistentEntity<T> extends BasicPersistentEntity<T, CassandraPersistentProperty> implements
|
||||
CassandraPersistentEntity<T>, ApplicationContextAware {
|
||||
|
||||
private String table;
|
||||
private String tableName;
|
||||
private final SpelExpressionParser spelParser;
|
||||
private final StandardEvaluationContext spelContext;
|
||||
private final Class<T> type;
|
||||
@@ -68,7 +69,7 @@ public class BasicCassandraPersistentEntity<T> extends BasicPersistentEntity<T,
|
||||
protected void determineTableName() {
|
||||
Table anno = type.getAnnotation(Table.class);
|
||||
|
||||
this.table = anno != null && StringUtils.hasText(anno.value()) ? anno.value() : CassandraNamingUtils
|
||||
this.tableName = anno != null && StringUtils.hasText(anno.value()) ? anno.value() : CassandraNamingUtils
|
||||
.getPreferredTableName(type);
|
||||
}
|
||||
|
||||
@@ -92,7 +93,13 @@ public class BasicCassandraPersistentEntity<T> extends BasicPersistentEntity<T,
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
Expression expression = spelParser.parseExpression(table, ParserContext.TEMPLATE_EXPRESSION);
|
||||
Expression expression = spelParser.parseExpression(tableName, ParserContext.TEMPLATE_EXPRESSION);
|
||||
return expression.getValue(spelContext, String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTableName(String tableName) {
|
||||
Assert.hasText(tableName);
|
||||
this.tableName = tableName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,4 +30,11 @@ public interface CassandraPersistentEntity<T> extends MutablePersistentEntity<T,
|
||||
* Returns the table name to which the entity shall be persisted.
|
||||
*/
|
||||
String getTableName();
|
||||
|
||||
/**
|
||||
* Sets the table name to which the entity shall be persisted.
|
||||
*
|
||||
* @param tableName The table name; must contain a valid Cassandra table name.
|
||||
*/
|
||||
void setTableName(String tableName);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ import org.w3c.dom.Element;
|
||||
*/
|
||||
public class CassandraRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport {
|
||||
|
||||
private static final String CASSANDRA_TEMPLATE_REF = "cassandra-template-ref";
|
||||
private static final String CASSANDRA_TEMPLATE_REF = "cql-template-ref";
|
||||
private static final String CREATE_QUERY_INDEXES = "create-query-indexes";
|
||||
|
||||
/*
|
||||
|
||||
@@ -1 +1 @@
|
||||
http\://www.springframework.org/schema/data/cassandra=org.springframework.data.cassandra.config.xml.CassandraNamespaceHandler
|
||||
http\://www.springframework.org/schema/data/cassandra=org.springframework.data.cassandra.config.xml.CassandraDataNamespaceHandler
|
||||
|
||||
@@ -18,7 +18,7 @@ Defines the configuration elements for Spring Cassandra support.
|
||||
<xsd:element name="session" type="sessionType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation
|
||||
source="org.springframework.cassandra.config.xml.SessionFactoryBean"><![CDATA[
|
||||
source="org.springframework.data.cassandra.config.xml.CassandraDataSessionFactoryBean"><![CDATA[
|
||||
Defines a Cassandra session.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
@@ -32,12 +32,13 @@ Defines a Cassandra session.
|
||||
<xsd:element name="template" type="templateType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation
|
||||
source="org.springframework.cassandra.config.xml.TemplateFactoryBean"><![CDATA[
|
||||
source="org.springframework.data.cassandra.config.xml.CassandraDataTemplateFactoryBean"><![CDATA[
|
||||
Defines a CassandraTemplate.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="org.springframework.cassandra.CassandraTemplate" />
|
||||
<tool:exports
|
||||
type="org.springframework.data.cassandra.CassandraTemplate" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -68,7 +69,7 @@ Local pooling options.
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="remote-pooling-options" type="poolingOptionsType"
|
||||
maxOccurs="1" minOccurs="0">
|
||||
minOccurs="0" maxOccurs="1">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Remote pooling options.
|
||||
@@ -133,32 +134,62 @@ The native CQL port to connect to. Default is 9042.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="compression" default="NONE" use="optional">
|
||||
<xsd:attribute name="compression" default="NONE" use="optional"
|
||||
type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The protocol compression option. Default is "NONE".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="NONE">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
No compression.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:enumeration>
|
||||
<xsd:enumeration value="SNAPPY">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
SNAPPY compression algorithm.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:enumeration>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="auth-info-provider" use="optional">
|
||||
<xsd:attribute name="username" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
When Authentication is enabled, the username to use when connecting to the Cluster.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="password" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
When Authentication is enabled, the password to use when connecting to the Cluster.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="metricsEnabled" type="xsd:string"
|
||||
default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Determine whether or not to collect metrics. Defaults to true.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="jmxReportingEnabled" type="xsd:string"
|
||||
default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Determine whether or not to enable JMX Reporting. Defaults to true.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="deferredInitialization" type="xsd:string"
|
||||
default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Determine if we defer initalizing the cluster until a connection is requested. Defaults to false.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="sslEnabled" type="xsd:string"
|
||||
default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Determine if SSL is used for Cassandra communication. Defaults to false.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="auth-info-provider-ref" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
AuthInfoProvider implementation.
|
||||
@@ -175,7 +206,7 @@ AuthInfoProvider implementation.
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="load-balancing-policy" use="optional">
|
||||
<xsd:attribute name="load-balancing-policy-ref" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
LoadBalancingPolicy implementation.
|
||||
@@ -193,7 +224,7 @@ LoadBalancingPolicy implementation.
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="reconnection-policy" use="optional">
|
||||
<xsd:attribute name="reconnection-policy-ref" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
ReconnectionPolicy implementation.
|
||||
@@ -211,7 +242,7 @@ ReconnectionPolicy implementation.
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="retry-policy" use="optional">
|
||||
<xsd:attribute name="retry-policy-ref" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
RetryPolicy implementation.
|
||||
@@ -229,8 +260,58 @@ RetryPolicy implementation.
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="ssl-options-ref" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Custom SSL Options. sslEnabled must be true for sslOptions to be used.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="com.datastax.driver.core.SSLOptions" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="host-state-listener-ref" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Custom Host State Listener for the Cassandra Cluster.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="com.datastax.driver.core.Host.StateListener" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="latency-tracker-ref" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Custom Latency Tracker for the Cassandra Cluster.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="com.datastax.driver.core.LatencyTracker" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="clusterRef" final="union">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
@@ -253,18 +334,6 @@ RetryPolicy implementation.
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="cassandraConverterRef" final="union">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to
|
||||
type="org.springframework.data.cassandra.convert.CassandraConverter" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:complexType name="poolingOptionsType">
|
||||
<xsd:attribute name="min-simultaneous-requests" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
@@ -297,7 +366,7 @@ More connections are created up to a configurable maximum number of connections.
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="socketOptionsType">
|
||||
<xsd:attribute name="connect-timeout-mls" type="xsd:string">
|
||||
<xsd:attribute name="connect-timeout-millis" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Sets connection timeout for client socket in milliseconds.
|
||||
@@ -311,6 +380,13 @@ Sets the SO_KEEPALIVE socket option.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="read-timeout-millis" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Sets read timeout for client socket in milliseconds.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="reuse-address" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
@@ -350,10 +426,6 @@ Sets the SO_SNDBUF socket option.
|
||||
|
||||
<xsd:complexType name="sessionType">
|
||||
<xsd:sequence>
|
||||
<!-- TODO: support custom table mappings
|
||||
|
||||
<xsd:element name="mapping" minOccurs="0" maxOccurs="1" type="mappingType"/>
|
||||
-->
|
||||
<xsd:element name="startup-cql" type="xsd:string"
|
||||
minOccurs="0" maxOccurs="unbounded">
|
||||
<!-- TODO: cql could come from a resource via a resource attribute... -->
|
||||
@@ -372,6 +444,7 @@ Arbitrary CQL script to be executed against the session's keyspace during bean d
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="mapping" type="mappingType" minOccurs="0" maxOccurs="1" />
|
||||
</xsd:sequence>
|
||||
|
||||
<xsd:attribute name="id" type="xsd:ID" use="optional">
|
||||
@@ -396,14 +469,6 @@ The name of a Cassandra Keyspace. No default; for the system keyspace, use the
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="schema-actions" type="xsd:string"
|
||||
use="optional" default="NONE">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The schema action to take on the Cassandra Keyspace. See the SchemaAction enum.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="cassandra-converter-ref" type="cassandraConverterRef"
|
||||
use="optional">
|
||||
<xsd:annotation>
|
||||
@@ -412,6 +477,14 @@ The reference to a CassandraConverter; default is "cassandra-converter".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="schema-action" type="xsd:string"
|
||||
use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The schema action to perform; default is NONE.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="templateType">
|
||||
@@ -462,32 +535,14 @@ The name of this keyspace. Required.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="action" use="required">
|
||||
<xsd:attribute name="action" use="required" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The keyspace action to take at startup and possibly shutdown.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="CREATE">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Action value that causes keyspace creation during bean initialization.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:enumeration>
|
||||
<xsd:enumeration value="CREATE-DROP">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Action value that causes keyspace creation during bean initialization and keyspace dropping during bean destruction.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:enumeration>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="durable-writes" type="xsd:boolean"
|
||||
<xsd:attribute name="durable-writes" type="xsd:string"
|
||||
use="optional" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
@@ -517,11 +572,11 @@ Provides the ability to specify replication factors by data center.
|
||||
default="SimpleStrategy">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the replication class; default is "SimpleStrategy".
|
||||
The name of the replication class; default is "SIMPLE_STRATEGY".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="replication-factor" type="xsd:integer"
|
||||
<xsd:attribute name="replication-factor" type="xsd:string"
|
||||
use="optional" default="1">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
@@ -530,7 +585,6 @@ The replication factor; default is 1.
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="datacenterType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
@@ -544,7 +598,7 @@ The name of the data center.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="replication-factor" type="xsd:integer"
|
||||
<xsd:attribute name="replication-factor" type="xsd:string"
|
||||
use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
@@ -554,30 +608,49 @@ The replication factor for the data center.
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<!-- TODO: support custom table mappings
|
||||
<xsd:simpleType name="cassandraConverterRef" final="union">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to
|
||||
type="org.springframework.data.cassandra.convert.CassandraConverter" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:complexType name="mappingType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="table" type="tableType" minOccurs="0"
|
||||
maxOccurs="1"></xsd:element>
|
||||
<xsd:element name="entity" type="entityType" minOccurs="0"
|
||||
maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="tableType">
|
||||
<xsd:attribute name="entity" type="xsd:string">
|
||||
<xsd:complexType name="entityType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="table" type="tableType" minOccurs="0"
|
||||
maxOccurs="1">
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="class" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Entity class name.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="table-name" type="xsd:string" use="optional">
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="tableType">
|
||||
<xsd:attribute name="name" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Table name override.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
|
||||
<!-- TODO: allow specification of C* table options here -->
|
||||
</xsd:complexType>
|
||||
-->
|
||||
</xsd:schema>
|
||||
</xsd:schema>
|
||||
|
||||
@@ -32,9 +32,13 @@ import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.cassandra.core.CassandraOperations;
|
||||
import org.springframework.data.cassandra.test.integration.table.User;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
@@ -44,8 +48,8 @@ import com.google.common.collect.Lists;
|
||||
* @author Alex Shvid
|
||||
*
|
||||
*/
|
||||
// @ContextConfiguration
|
||||
// @RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class UserRepositoryIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
@@ -100,7 +104,7 @@ public class UserRepositoryIntegrationTests {
|
||||
all = dataOperations.insert(Arrays.asList(tom, bob, alice, scott));
|
||||
}
|
||||
|
||||
// @Test
|
||||
@Test
|
||||
public void findsUserById() throws Exception {
|
||||
|
||||
User user = repository.findOne(bob.getUsername());
|
||||
@@ -109,7 +113,7 @@ public class UserRepositoryIntegrationTests {
|
||||
|
||||
}
|
||||
|
||||
// @Test
|
||||
@Test
|
||||
public void findsAll() throws Exception {
|
||||
List<User> result = Lists.newArrayList(repository.findAll());
|
||||
assertThat(result.size(), is(all.size()));
|
||||
@@ -117,7 +121,7 @@ public class UserRepositoryIntegrationTests {
|
||||
|
||||
}
|
||||
|
||||
// @Test
|
||||
@Test
|
||||
public void findsAllWithGivenIds() {
|
||||
|
||||
Iterable<User> result = repository.findAll(Arrays.asList(bob.getUsername(), tom.getUsername()));
|
||||
@@ -125,7 +129,7 @@ public class UserRepositoryIntegrationTests {
|
||||
assertThat(result, not(hasItems(alice, scott)));
|
||||
}
|
||||
|
||||
// @Test
|
||||
@Test
|
||||
public void deletesUserCorrectly() throws Exception {
|
||||
|
||||
repository.delete(tom);
|
||||
@@ -136,7 +140,7 @@ public class UserRepositoryIntegrationTests {
|
||||
assertThat(result, not(hasItem(tom)));
|
||||
}
|
||||
|
||||
// @Test
|
||||
@Test
|
||||
public void deletesUserByIdCorrectly() {
|
||||
|
||||
repository.delete(tom.getUsername().toString());
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<cass:remote-pooling-options
|
||||
min-simultaneous-requests="25" max-simultaneous-requests="100"
|
||||
core-connections="1" max-connections="2" />
|
||||
<cass:socket-options connect-timeout-mls="5000"
|
||||
<cass:socket-options connect-timeout-millis="5000"
|
||||
keep-alive="true" reuse-address="true" so-linger="60" tcp-no-delay="true"
|
||||
receive-buffer-size="65536" send-buffer-size="65536" />
|
||||
<cass:keyspace name="${cassandra.keyspace}" action="CREATE"
|
||||
@@ -38,7 +38,7 @@
|
||||
</bean>
|
||||
|
||||
<cass:session id="cassandra-session" keyspace-name="${cassandra.keyspace}"
|
||||
schema-actions="NONE" cluster-ref="cassandra-cluster"
|
||||
schema-action="NONE" cluster-ref="cassandra-cluster"
|
||||
cassandra-converter-ref="cassandra-converter">
|
||||
</cass:session>
|
||||
|
||||
|
||||
@@ -2,18 +2,16 @@
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cassandra="http://www.springframework.org/schema/data/cassandra"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/data/cassandra http://www.springframework.org/schema/data/cassandra/spring-cassandra-1.0.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/data/cassandra http://www.springframework.org/schema/data/cassandra/spring-cassandra-1.0.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
|
||||
|
||||
<context:property-placeholder
|
||||
location="classpath:/org/springframework/data/cassandra/test/integration/repository/cassandra.properties" />
|
||||
|
||||
<cassandra:cluster id="cassandra-cluster"
|
||||
contactPoints="${cassandra.contactPoints}" port="${cassandra.native_transport_port}"
|
||||
compression="SNAPPY">
|
||||
contactPoints="${cassandra.contactPoints}" port="${cassandra.native_transport_port}">
|
||||
<cassandra:local-pooling-options
|
||||
min-simultaneous-requests="25" max-simultaneous-requests="100"
|
||||
core-connections="2" max-connections="8" />
|
||||
@@ -21,12 +19,14 @@
|
||||
min-simultaneous-requests="25" max-simultaneous-requests="100"
|
||||
core-connections="1" max-connections="2" />
|
||||
<cassandra:socket-options
|
||||
connect-timeout-mls="5000" keep-alive="true" reuse-address="true"
|
||||
connect-timeout-millis="5000" keep-alive="true" reuse-address="true"
|
||||
so-linger="60" tcp-no-delay="true" receive-buffer-size="65536"
|
||||
send-buffer-size="65536" />
|
||||
|
||||
<cassandra:keyspace name="${cassandra-keyspace}" action="CREATE" durable-writes="true">
|
||||
<cassandra:replication class="SimpleStrategy" replication-factor="1"/>
|
||||
|
||||
<cassandra:keyspace name="${cassandra.keyspace}"
|
||||
action="CREATE" durable-writes="true">
|
||||
<cassandra:replication class="SIMPLE_STRATEGY"
|
||||
replication-factor="1" />
|
||||
</cassandra:keyspace>
|
||||
</cassandra:cluster>
|
||||
|
||||
@@ -34,17 +34,27 @@
|
||||
class="org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext" />
|
||||
|
||||
<bean id="cassandra-converter"
|
||||
class=" org.springframework.data.cassandra.convert.MappingCassandraConverter">
|
||||
class="org.springframework.data.cassandra.convert.MappingCassandraConverter">
|
||||
<constructor-arg ref="cassandra-mapping" />
|
||||
</bean>
|
||||
|
||||
<cassandra:session id="cassandra-session" keyspace-name="cassandra-keyspace"/>
|
||||
|
||||
<cassandra:session id="cassandra-session"
|
||||
cluster-ref="cassandra-cluster" keyspace-name="${cassandra.keyspace}"
|
||||
cassandra-converter-ref="cassandra-converter" schema-action="CREATE">
|
||||
<cassandra:mapping>
|
||||
<cassandra:entity
|
||||
class="org.springframework.data.cassandra.test.integration.table.User">
|
||||
<cassandra:table name="users_x" />
|
||||
</cassandra:entity>
|
||||
</cassandra:mapping>
|
||||
</cassandra:session>
|
||||
|
||||
<bean id="cassandraTemplate" class="org.springframework.cassandra.core.CqlTemplate">
|
||||
<constructor-arg ref="cassandra-session" />
|
||||
</bean>
|
||||
|
||||
<bean id="cassandraDataTemplate" class="org.springframework.data.cassandra.core.CassandraTemplate">
|
||||
<bean id="cassandraDataTemplate"
|
||||
class="org.springframework.data.cassandra.core.CassandraTemplate">
|
||||
<constructor-arg ref="cassandra-session" />
|
||||
<constructor-arg ref="cassandra-converter" />
|
||||
<constructor-arg value="${cassandra.keyspace}" />
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
cassandra.contactPoints=localhost
|
||||
cassandra.native_transport_port=@build.cassandra.native_transport_port@
|
||||
cassandra.keyspace=TestKS123
|
||||
cassandra.keyspace=UserRepositoryIntegrationTests
|
||||
|
||||
Reference in New Issue
Block a user