diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/BeanNames.java b/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/BeanNames.java index aa5dabf59..07f3537dd 100644 --- a/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/BeanNames.java +++ b/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/BeanNames.java @@ -18,6 +18,7 @@ package org.springframework.cassandra.config.xml; /** * @author Alex Shvid * @author David Webb + * @author Matthew T. Adams */ public final class BeanNames { @@ -27,5 +28,5 @@ public final class 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"; } diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraClusterParser.java b/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraClusterParser.java index fc3201e0e..4158dedca 100644 --- a/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraClusterParser.java +++ b/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraClusterParser.java @@ -74,15 +74,14 @@ public class CassandraClusterParser extends AbstractSimpleBeanDefinitionParser { builder.addPropertyValue("compressionType", CompressionType.valueOf(compression)); } - postProcess(builder, element); + parseChildElements(builder, element); } - @Override - protected void postProcess(BeanDefinitionBuilder builder, Element element) { - List subElements = DomUtils.getChildElements(element); + protected void parseChildElements(BeanDefinitionBuilder builder, Element element) { + List elements = DomUtils.getChildElements(element); // parse nested elements - for (Element subElement : subElements) { + for (Element subElement : elements) { String name = subElement.getLocalName(); if ("local-pooling-options".equals(name)) { @@ -99,11 +98,10 @@ public class CassandraClusterParser extends AbstractSimpleBeanDefinitionParser { private BeanDefinition parsePoolingOptions(Element element) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(PoolingOptionsConfig.class); - // TODO - // ParsingUtils.setPropertyValue(builder, element, "min-simultaneous-requests", "minSimultaneousRequests"); - // ParsingUtils.setPropertyValue(builder, element, "max-simultaneous-requests", "maxSimultaneousRequests"); - // ParsingUtils.setPropertyValue(builder, element, "core-connections", "coreConnections"); - // ParsingUtils.setPropertyValue(builder, element, "max-connections", "maxConnections"); + ParsingUtils.setPropertyValue(builder, element, "min-simultaneous-requests", "minSimultaneousRequests"); + ParsingUtils.setPropertyValue(builder, element, "max-simultaneous-requests", "maxSimultaneousRequests"); + ParsingUtils.setPropertyValue(builder, element, "core-connections", "coreConnections"); + ParsingUtils.setPropertyValue(builder, element, "max-connections", "maxConnections"); return builder.getBeanDefinition(); } @@ -111,14 +109,13 @@ public class CassandraClusterParser extends AbstractSimpleBeanDefinitionParser { private BeanDefinition parseSocketOptions(Element element) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(SocketOptionsConfig.class); - // TODO - // ParsingUtils.setPropertyValue(builder, element, "connect-timeout-mls", "connectTimeoutMls"); - // ParsingUtils.setPropertyValue(builder, element, "keep-alive", "keepAlive"); - // 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"); + ParsingUtils.setPropertyValue(builder, element, "connect-timeout-mls", "connectTimeoutMls"); + ParsingUtils.setPropertyValue(builder, element, "keep-alive", "keepAlive"); + 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"); return builder.getBeanDefinition(); } diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraKeyspaceParser.java b/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraKeyspaceParser.java index 37ee4988f..d98be4d2f 100644 --- a/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraKeyspaceParser.java +++ b/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraKeyspaceParser.java @@ -31,9 +31,10 @@ import org.springframework.util.xml.DomUtils; import org.w3c.dom.Element; /** - * Parser for <keyspace;gt; definitions. + * Parser for <keyspace> definitions. * * @author Alex Shvid + * @author Matthew T. Adams */ public class CassandraKeyspaceParser extends AbstractSimpleBeanDefinitionParser { @@ -95,11 +96,10 @@ public class CassandraKeyspaceParser extends AbstractSimpleBeanDefinitionParser private BeanDefinition parseKeyspaceAttributes(Element element) { BeanDefinitionBuilder defBuilder = BeanDefinitionBuilder.genericBeanDefinition(KeyspaceAttributes.class); - // TODO - // ParsingUtils.setPropertyValue(defBuilder, element, "auto", "auto"); - // ParsingUtils.setPropertyValue(defBuilder, element, "replication-strategy", "replicationStrategy"); - // ParsingUtils.setPropertyValue(defBuilder, element, "replication-factor", "replicationFactor"); - // ParsingUtils.setPropertyValue(defBuilder, element, "durable-writes", "durableWrites"); + ParsingUtils.setPropertyValue(defBuilder, element, "auto", "auto"); + ParsingUtils.setPropertyValue(defBuilder, element, "replication-strategy", "replicationStrategy"); + ParsingUtils.setPropertyValue(defBuilder, element, "replication-factor", "replicationFactor"); + ParsingUtils.setPropertyValue(defBuilder, element, "durable-writes", "durableWrites"); List subElements = DomUtils.getChildElements(element); ManagedList tables = new ManagedList(subElements.size()); @@ -122,9 +122,8 @@ public class CassandraKeyspaceParser extends AbstractSimpleBeanDefinitionParser private BeanDefinition parseTable(Element element) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(TableAttributes.class); - // TODO - // ParsingUtils.setPropertyValue(builder, element, "entity", "entity"); - // ParsingUtils.setPropertyValue(builder, element, "name", "name"); + ParsingUtils.setPropertyValue(builder, element, "entity", "entity"); + ParsingUtils.setPropertyValue(builder, element, "name", "name"); return builder.getBeanDefinition(); } diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraNamespaceHandler.java b/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraNamespaceHandler.java index 0a2ad6518..4563c3081 100644 --- a/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraNamespaceHandler.java +++ b/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraNamespaceHandler.java @@ -18,9 +18,10 @@ package org.springframework.cassandra.config.xml; import org.springframework.beans.factory.xml.NamespaceHandlerSupport; /** - * Namespace handler for <cassandra;gt;. + * Namespace handler for <cassandra> elements. * * @author Alex Shvid + * @author Matthew T. Adams */ public class CassandraNamespaceHandler extends NamespaceHandlerSupport { @@ -28,9 +29,8 @@ public class CassandraNamespaceHandler extends NamespaceHandlerSupport { public void init() { registerBeanDefinitionParser("cluster", new CassandraClusterParser()); - registerBeanDefinitionParser("keyspace", new CassandraKeyspaceParser()); + // registerBeanDefinitionParser("keyspace", new CassandraKeyspaceParser()); registerBeanDefinitionParser("session", new CassandraSessionParser()); - + registerBeanDefinitionParser("template", new CassandraTemplateParser()); } - } diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraSessionFactoryBean.java b/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraSessionFactoryBean.java index 0be9a5feb..01396dee3 100644 --- a/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraSessionFactoryBean.java +++ b/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraSessionFactoryBean.java @@ -15,54 +15,41 @@ */ package org.springframework.cassandra.config.xml; -import java.util.Map; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; -import org.springframework.cassandra.config.KeyspaceAttributes; import org.springframework.cassandra.support.CassandraExceptionTranslator; import org.springframework.dao.DataAccessException; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.util.StringUtils; import com.datastax.driver.core.Cluster; -import com.datastax.driver.core.KeyspaceMetadata; import com.datastax.driver.core.Session; /** - * Convenient factory for configuring a Cassandra Session. Session is a thread safe singleton and created per a - * keyspace. So, it is enough to have one session per application. + * Factory for configuring a Cassandra {@link Session}, which is a thread-safe singleton. As such, it is sufficient to + * have one {@link Session} per application and keyspace. * * @author Alex Shvid * @author Matthew T. Adams */ public class CassandraSessionFactoryBean implements FactoryBean, InitializingBean, DisposableBean, - BeanClassLoaderAware, PersistenceExceptionTranslator { + PersistenceExceptionTranslator { private static final Logger log = LoggerFactory.getLogger(CassandraSessionFactoryBean.class); public static final String DEFAULT_REPLICATION_STRATEGY = "SimpleStrategy"; public static final int DEFAULT_REPLICATION_FACTOR = 1; - private ClassLoader beanClassLoader; - private Cluster cluster; private Session session; - private String keyspace; - - private KeyspaceAttributes keyspaceAttributes; + private String keyspaceName; private final PersistenceExceptionTranslator exceptionTranslator = new CassandraExceptionTranslator(); - public void setBeanClassLoader(ClassLoader classLoader) { - this.beanClassLoader = classLoader; - } - public Session getObject() { return session; } @@ -101,7 +88,7 @@ public class CassandraSessionFactoryBean implements FactoryBean, Initia throw new IllegalArgumentException("at least one cluster is required"); } - this.session = StringUtils.hasText(this.keyspace) ? cluster.connect(keyspace) : cluster.connect(); + this.session = StringUtils.hasText(this.keyspaceName) ? cluster.connect(keyspaceName) : cluster.connect(); } /* @@ -109,49 +96,14 @@ public class CassandraSessionFactoryBean implements FactoryBean, Initia * @see org.springframework.beans.factory.DisposableBean#destroy() */ public void destroy() throws Exception { - this.session.shutdown(); } - public void setKeyspace(String keyspace) { - this.keyspace = keyspace; + public void setKeyspaceName(String keyspaceName) { + this.keyspaceName = keyspaceName; } public void setCluster(Cluster cluster) { this.cluster = cluster; } - - public void setKeyspaceAttributes(KeyspaceAttributes keyspaceAttributes) { - this.keyspaceAttributes = keyspaceAttributes; - } - - private static String compareKeyspaceAttributes(KeyspaceAttributes keyspaceAttributes, - KeyspaceMetadata keyspaceMetadata) { - if (keyspaceAttributes.isDurableWrites() != keyspaceMetadata.isDurableWrites()) { - return "durableWrites"; - } - Map replication = keyspaceMetadata.getReplication(); - String replicationFactorStr = replication.get("replication_factor"); - if (replicationFactorStr == null) { - return "replication_factor"; - } - try { - int replicationFactor = Integer.parseInt(replicationFactorStr); - if (keyspaceAttributes.getReplicationFactor() != replicationFactor) { - return "replication_factor"; - } - } catch (NumberFormatException e) { - return "replication_factor"; - } - - String attributesStrategy = keyspaceAttributes.getReplicationStrategy(); - if (attributesStrategy.indexOf('.') == -1) { - attributesStrategy = "org.apache.cassandra.locator." + attributesStrategy; - } - String replicationStrategy = replication.get("class"); - if (!attributesStrategy.equals(replicationStrategy)) { - return "replication_class"; - } - return null; - } } diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraSessionParser.java b/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraSessionParser.java index 357ce17a6..94ee88a22 100644 --- a/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraSessionParser.java +++ b/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraSessionParser.java @@ -20,21 +20,21 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.cassandra.core.SessionFactoryBean; import org.springframework.util.StringUtils; import org.w3c.dom.Element; /** - * Parser for <session;gt; definitions. + * Parser for <session> definitions. * * @author David Webb + * @author Matthew T. Adams */ public class CassandraSessionParser extends AbstractSimpleBeanDefinitionParser { @Override protected Class getBeanClass(Element element) { - return SessionFactoryBean.class; + return CassandraSessionFactoryBean.class; } /* @@ -52,18 +52,16 @@ public class CassandraSessionParser extends AbstractSimpleBeanDefinitionParser { @Override protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { - String keyspaceRef = element.getAttribute("cassandra-keyspace-ref"); - if (!StringUtils.hasText(keyspaceRef)) { - keyspaceRef = BeanNames.CASSANDRA_KEYSPACE; + String keyspaceName = element.getAttribute("keyspace-name"); + if (!StringUtils.hasText(keyspaceName)) { + keyspaceName = null; } - builder.addPropertyReference("keyspace", keyspaceRef); + builder.addPropertyValue("keyspaceName", keyspaceName); - postProcess(builder, element); + String clusterRef = element.getAttribute("cluster-ref"); + if (!StringUtils.hasText(clusterRef)) { + clusterRef = BeanNames.CASSANDRA_CLUSTER; + } + builder.addPropertyReference("cluster", clusterRef); } - - @Override - protected void postProcess(BeanDefinitionBuilder builder, Element element) { - - } - } diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraTemplateFactoryBean.java b/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraTemplateFactoryBean.java new file mode 100644 index 000000000..414561b7e --- /dev/null +++ b/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraTemplateFactoryBean.java @@ -0,0 +1,63 @@ +/* + * 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.cassandra.config.xml; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.cassandra.core.CassandraTemplate; + +import com.datastax.driver.core.Session; + +/** + * Factory for configuring a {@link CassandraTemplate}. + * + * @author Matthew T. Adams + */ + +public class CassandraTemplateFactoryBean implements FactoryBean, InitializingBean { + + private static final Logger log = LoggerFactory.getLogger(CassandraTemplateFactoryBean.class); + + private CassandraTemplate template; + private Session session; + + public CassandraTemplate getObject() { + return template; + } + + public Class getObjectType() { + return CassandraTemplate.class; + } + + public boolean isSingleton() { + return true; + } + + public void afterPropertiesSet() throws Exception { + + if (session == null) { + throw new IllegalStateException("session is required"); + } + + this.template = new CassandraTemplate(session); + } + + public void setSession(Session session) { + this.session = session; + } +} diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraTemplateParser.java b/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraTemplateParser.java new file mode 100644 index 000000000..2fa5d35ad --- /dev/null +++ b/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/CassandraTemplateParser.java @@ -0,0 +1,57 @@ +/* + * Copyright 2011-2012 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cassandra.config.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.AbstractSimpleBeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * Parser for <template> definitions. + * + * @author David Webb + * @author Matthew T. Adams + */ + +public class CassandraTemplateParser extends AbstractSimpleBeanDefinitionParser { + + @Override + protected Class getBeanClass(Element element) { + return CassandraTemplateFactoryBean.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 : BeanNames.CASSANDRA_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); + } +} diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/ParsingUtils.java b/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/ParsingUtils.java new file mode 100644 index 000000000..826c26e3c --- /dev/null +++ b/spring-cassandra/src/main/java/org/springframework/cassandra/config/xml/ParsingUtils.java @@ -0,0 +1,33 @@ +package org.springframework.cassandra.config.xml; + +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; +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. + */ + public static void setPropertyValue(BeanDefinitionBuilder builder, Element element, String attrName, + String propertyName) { + + 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!"); + Assert.hasText(propertyName, "Property name must not be null!"); + + String attr = element.getAttribute(attrName); + + if (StringUtils.hasText(attr)) { + builder.addPropertyValue(propertyName, attr); + } + } +} diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/SessionFactoryBean.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/SessionFactoryBean.java deleted file mode 100644 index f753a322f..000000000 --- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/SessionFactoryBean.java +++ /dev/null @@ -1,87 +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.cassandra.core; - -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.cassandra.core.Keyspace; - -import com.datastax.driver.core.Session; - -/** - * @author David Webb - * - */ -public class SessionFactoryBean implements FactoryBean, InitializingBean { - - private Keyspace keyspace; - - public SessionFactoryBean() { - } - - public SessionFactoryBean(Keyspace keyspace) { - setKeyspace(keyspace); - } - - /* (non-Javadoc) - * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() throws Exception { - if (keyspace == null) { - throw new IllegalStateException("Keyspace required."); - } - } - - /** - * @return Returns the keyspace. - */ - public Keyspace getKeyspace() { - return keyspace; - } - - /** - * @param keyspace The keyspace to set. - */ - public void setKeyspace(Keyspace keyspace) { - this.keyspace = keyspace; - } - - /* (non-Javadoc) - * @see org.springframework.beans.factory.FactoryBean#getObject() - */ - @Override - public Session getObject() { - return keyspace.getSession(); - } - - /* (non-Javadoc) - * @see org.springframework.beans.factory.FactoryBean#getObjectType() - */ - @Override - public Class getObjectType() { - return Session.class; - } - - /* (non-Javadoc) - * @see org.springframework.beans.factory.FactoryBean#isSingleton() - */ - @Override - public boolean isSingleton() { - return true; - } - -} diff --git a/spring-cassandra/src/main/resources/META-INF/spring.handlers.todo b/spring-cassandra/src/main/resources/META-INF/spring.handlers similarity index 100% rename from spring-cassandra/src/main/resources/META-INF/spring.handlers.todo rename to spring-cassandra/src/main/resources/META-INF/spring.handlers diff --git a/spring-cassandra/src/main/resources/META-INF/spring.schemas.todo b/spring-cassandra/src/main/resources/META-INF/spring.schemas similarity index 100% rename from spring-cassandra/src/main/resources/META-INF/spring.schemas.todo rename to spring-cassandra/src/main/resources/META-INF/spring.schemas diff --git a/spring-cassandra/src/main/resources/META-INF/spring.tooling.todo b/spring-cassandra/src/main/resources/META-INF/spring.tooling similarity index 100% rename from spring-cassandra/src/main/resources/META-INF/spring.tooling.todo rename to spring-cassandra/src/main/resources/META-INF/spring.tooling diff --git a/spring-cassandra/src/main/resources/org/springframework/cassandra/config/spring-cassandra-1.0.xsd b/spring-cassandra/src/main/resources/org/springframework/cassandra/config/spring-cassandra-1.0.xsd index 98c1f9eff..7f4c437e4 100644 --- a/spring-cassandra/src/main/resources/org/springframework/cassandra/config/spring-cassandra-1.0.xsd +++ b/spring-cassandra/src/main/resources/org/springframework/cassandra/config/spring-cassandra-1.0.xsd @@ -12,14 +12,14 @@ + ]]> @@ -29,11 +29,25 @@ Defines a Cassandra Session instance used for accessing Cassandra Keyspace'. + + + + + + + + + + + @@ -43,6 +57,20 @@ Defines a Cassandra Cluster instance used for accessing Cassandra'. + + + + + + + + + + + - + - + @@ -174,20 +204,6 @@ RetryPolicy implementation. - - - - - - - - - - - - + + ]]> - - - - - - - - - - - - +The name of the Cassandra keyspace. + ]]> @@ -239,12 +237,11 @@ The reference to a CassandraConverter instance. Default is null. - + - + @@ -335,55 +332,12 @@ Sets the SO_SNDBUF socket option. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + ]]> + ]]> - - - - - - - - - - - - - +Whether to support durable writes in the Cassandra keyspace. Default value is 'true'. + ]]> @@ -425,29 +362,44 @@ Table name override. +The name of the Session definition; default is 'cassandra-session'. + ]]> - + + + + + - +The name of a Cassandra Keyspace. No default; for the system keyspace, use the empty string. + ]]> + + + + + + + + + + + + + - - - - - - - - - - \ No newline at end of file diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/AbstractEmbeddedCassandraIntegrationTest.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/AbstractEmbeddedCassandraIntegrationTest.java index 2d89db056..4b5127af6 100644 --- a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/AbstractEmbeddedCassandraIntegrationTest.java +++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/AbstractEmbeddedCassandraIntegrationTest.java @@ -7,8 +7,6 @@ import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.thrift.transport.TTransportException; import org.cassandraunit.utils.EmbeddedCassandraServerHelper; import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; import com.datastax.driver.core.Cluster; import com.datastax.driver.core.KeyspaceMetadata; @@ -20,12 +18,20 @@ public abstract class AbstractEmbeddedCassandraIntegrationTest { protected final static String CASSANDRA_HOST = "localhost"; protected final static int CASSANDRA_NATIVE_PORT = 9042; - @BeforeClass - public static void beforeClass() throws ConfigurationException, TTransportException, IOException, + public static void startCassandra() throws ConfigurationException, TTransportException, IOException, InterruptedException { EmbeddedCassandraServerHelper.startEmbeddedCassandra(CASSANDRA_CONFIG); } + public AbstractEmbeddedCassandraIntegrationTest() { + try { + startCassandra(); + } catch (Exception e) { + throw new RuntimeException(e); + } + connect(); + } + /** * Whether to clear the cluster before the next test. */ @@ -47,6 +53,10 @@ public abstract class AbstractEmbeddedCassandraIntegrationTest { */ protected Session session; + protected String keyspace() { + return keyspace; + } + /** * Returns whether we're currently connected to the cluster. */ @@ -58,23 +68,22 @@ public abstract class AbstractEmbeddedCassandraIntegrationTest { return Cluster.builder().addContactPoint(CASSANDRA_HOST).withPort(CASSANDRA_NATIVE_PORT).build(); } - @Before - public void before() { + public void connect() { if (connect && !connected()) { cluster = cluster(); - if (keyspace == null) { + if (keyspace() == null) { session = cluster.connect(); } else { - KeyspaceMetadata kmd = cluster.getMetadata().getKeyspace(keyspace); + KeyspaceMetadata kmd = cluster.getMetadata().getKeyspace(keyspace()); if (kmd == null) { // then create keyspace session = cluster.connect(); - session.execute("CREATE KEYSPACE " + keyspace + session.execute("CREATE KEYSPACE " + keyspace() + " WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};"); - session.execute("USE " + keyspace + ";"); + session.execute("USE " + keyspace() + ";"); } else {// else keyspace already exists - session = cluster.connect(keyspace); + session = cluster.connect(keyspace()); } } } diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/AbstractIntegrationTest.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/AbstractIntegrationTest.java deleted file mode 100644 index e5bd39dff..000000000 --- a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/AbstractIntegrationTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.springframework.cassandra.test.integration.config; - -import java.io.IOException; - -import javax.inject.Inject; - -import org.apache.cassandra.exceptions.ConfigurationException; -import org.apache.thrift.transport.TTransportException; -import org.cassandraunit.utils.EmbeddedCassandraServerHelper; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.runner.RunWith; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import com.datastax.driver.core.Session; - -@RunWith(SpringJUnit4ClassRunner.class) -public abstract class AbstractIntegrationTest { - - @BeforeClass - public static void startCassandra() throws ConfigurationException, TTransportException, IOException { - EmbeddedCassandraServerHelper.startEmbeddedCassandra("spring-cassandra.yaml"); - } - - @Inject - public Session session; - - @Before - public void assertSession() { - IntegrationTestUtils.assertSession(session); - } -} diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/IntegrationTestUtils.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/IntegrationTestUtils.java index a638a665c..bac0245c1 100644 --- a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/IntegrationTestUtils.java +++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/IntegrationTestUtils.java @@ -11,6 +11,6 @@ public class IntegrationTestUtils { } public static void assertKeyspaceExists(String keyspace, Session session) { - assertNotNull(session.getCluster().getMetadata().getKeyspace(KeyspaceCreatingConfig.KEYSPACE)); + assertNotNull(session.getCluster().getMetadata().getKeyspace(keyspace)); } } diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/AbstractIntegrationTest.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/AbstractIntegrationTest.java new file mode 100644 index 000000000..0ac2b001c --- /dev/null +++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/AbstractIntegrationTest.java @@ -0,0 +1,23 @@ +package org.springframework.cassandra.test.integration.config.java; + +import javax.inject.Inject; + +import org.junit.Before; +import org.junit.runner.RunWith; +import org.springframework.cassandra.test.integration.AbstractEmbeddedCassandraIntegrationTest; +import org.springframework.cassandra.test.integration.config.IntegrationTestUtils; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.datastax.driver.core.Session; + +@RunWith(SpringJUnit4ClassRunner.class) +public abstract class AbstractIntegrationTest extends AbstractEmbeddedCassandraIntegrationTest { + + @Inject + public Session session; + + @Before + public void assertSession() { + IntegrationTestUtils.assertSession(session); + } +} diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/AbstractIntegrationTestConfiguration.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/AbstractIntegrationTestConfiguration.java similarity index 88% rename from spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/AbstractIntegrationTestConfiguration.java rename to spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/AbstractIntegrationTestConfiguration.java index 6c92065a7..d2b5fb7f5 100644 --- a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/AbstractIntegrationTestConfiguration.java +++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/AbstractIntegrationTestConfiguration.java @@ -1,4 +1,4 @@ -package org.springframework.cassandra.test.integration.config; +package org.springframework.cassandra.test.integration.config.java; import org.springframework.cassandra.config.java.AbstractCassandraConfiguration; import org.springframework.context.annotation.Configuration; diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/AbstractKeyspaceCreatingConfiguration.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/AbstractKeyspaceCreatingConfiguration.java similarity index 95% rename from spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/AbstractKeyspaceCreatingConfiguration.java rename to spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/AbstractKeyspaceCreatingConfiguration.java index e23408760..f0ceefb33 100644 --- a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/AbstractKeyspaceCreatingConfiguration.java +++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/AbstractKeyspaceCreatingConfiguration.java @@ -1,4 +1,4 @@ -package org.springframework.cassandra.test.integration.config; +package org.springframework.cassandra.test.integration.config.java; import org.springframework.cassandra.config.KeyspaceAttributes; import org.springframework.cassandra.config.PoolingOptionsConfig; diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/Config.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/Config.java similarity index 75% rename from spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/Config.java rename to spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/Config.java index a4e977e3c..8a1abf636 100644 --- a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/Config.java +++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/Config.java @@ -1,4 +1,4 @@ -package org.springframework.cassandra.test.integration.config; +package org.springframework.cassandra.test.integration.config.java; import org.springframework.context.annotation.Configuration; diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/ConfigTest.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/ConfigTest.java similarity index 85% rename from spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/ConfigTest.java rename to spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/ConfigTest.java index e91bad306..d00de3a59 100644 --- a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/ConfigTest.java +++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/ConfigTest.java @@ -1,4 +1,4 @@ -package org.springframework.cassandra.test.integration.config; +package org.springframework.cassandra.test.integration.config.java; import org.junit.Test; import org.springframework.test.context.ContextConfiguration; diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/KeyspaceCreatingConfig.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/KeyspaceCreatingConfig.java similarity index 80% rename from spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/KeyspaceCreatingConfig.java rename to spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/KeyspaceCreatingConfig.java index 16a02d275..13d75dc69 100644 --- a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/KeyspaceCreatingConfig.java +++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/KeyspaceCreatingConfig.java @@ -1,4 +1,4 @@ -package org.springframework.cassandra.test.integration.config; +package org.springframework.cassandra.test.integration.config.java; import org.springframework.context.annotation.Configuration; diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/KeyspaceCreatingConfigTest.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/KeyspaceCreatingConfigTest.java similarity index 69% rename from spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/KeyspaceCreatingConfigTest.java rename to spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/KeyspaceCreatingConfigTest.java index eec886594..26cf12b70 100644 --- a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/KeyspaceCreatingConfigTest.java +++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/java/KeyspaceCreatingConfigTest.java @@ -1,6 +1,7 @@ -package org.springframework.cassandra.test.integration.config; +package org.springframework.cassandra.test.integration.config.java; import org.junit.Test; +import org.springframework.cassandra.test.integration.config.IntegrationTestUtils; import org.springframework.test.context.ContextConfiguration; @ContextConfiguration(classes = KeyspaceCreatingConfig.class) diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/xml/MinimalXmlConfigTest.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/xml/MinimalXmlConfigTest.java new file mode 100644 index 000000000..760c00192 --- /dev/null +++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/xml/MinimalXmlConfigTest.java @@ -0,0 +1,38 @@ +package org.springframework.cassandra.test.integration.config.xml; + +import static org.junit.Assert.*; + +import javax.inject.Inject; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.cassandra.core.CassandraOperations; +import org.springframework.cassandra.test.integration.AbstractEmbeddedCassandraIntegrationTest; +import org.springframework.cassandra.test.integration.config.IntegrationTestUtils; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.datastax.driver.core.Session; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +public class MinimalXmlConfigTest extends AbstractEmbeddedCassandraIntegrationTest { + + protected String keyspace() { + return "minimalxmlconfigtest"; + } + + @Inject + Session s; + + @Inject + CassandraOperations ops; + + @Test + public void test() { + IntegrationTestUtils.assertSession(s); + IntegrationTestUtils.assertKeyspaceExists(keyspace(), s); + + assertNotNull(ops); + } +} diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/xml/XmlConfigTest.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/xml/XmlConfigTest.java new file mode 100644 index 000000000..b8eb27ea8 --- /dev/null +++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/config/xml/XmlConfigTest.java @@ -0,0 +1,30 @@ +package org.springframework.cassandra.test.integration.config.xml; + +import javax.inject.Inject; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.cassandra.test.integration.AbstractEmbeddedCassandraIntegrationTest; +import org.springframework.cassandra.test.integration.config.IntegrationTestUtils; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.datastax.driver.core.Session; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +public class XmlConfigTest extends AbstractEmbeddedCassandraIntegrationTest { + + protected String keyspace() { + return "xmlconfigtest"; + } + + @Inject + Session s; + + @Test + public void test() { + IntegrationTestUtils.assertSession(s); + IntegrationTestUtils.assertKeyspaceExists(keyspace(), s); + } +} diff --git a/spring-cassandra/src/test/resources/org/springframework/cassandra/test/integration/config/xml/MinimalXmlConfigTest-context.xml b/spring-cassandra/src/test/resources/org/springframework/cassandra/test/integration/config/xml/MinimalXmlConfigTest-context.xml new file mode 100644 index 000000000..e0939fdc3 --- /dev/null +++ b/spring-cassandra/src/test/resources/org/springframework/cassandra/test/integration/config/xml/MinimalXmlConfigTest-context.xml @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/spring-cassandra/src/test/resources/org/springframework/cassandra/test/integration/config/xml/XmlConfigTest-context.xml b/spring-cassandra/src/test/resources/org/springframework/cassandra/test/integration/config/xml/XmlConfigTest-context.xml new file mode 100644 index 000000000..39e2ff612 --- /dev/null +++ b/spring-cassandra/src/test/resources/org/springframework/cassandra/test/integration/config/xml/XmlConfigTest-context.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + diff --git a/spring-cassandra/src/test/resources/org/springframework/data/cassandra/test/integration/config/cassandra.properties b/spring-cassandra/src/test/resources/org/springframework/cassandra/test/integration/config/xml/xmlconfigtest.properties similarity index 62% rename from spring-cassandra/src/test/resources/org/springframework/data/cassandra/test/integration/config/cassandra.properties rename to spring-cassandra/src/test/resources/org/springframework/cassandra/test/integration/config/xml/xmlconfigtest.properties index 6a0dd3197..2d7a6eb68 100644 --- a/spring-cassandra/src/test/resources/org/springframework/data/cassandra/test/integration/config/cassandra.properties +++ b/spring-cassandra/src/test/resources/org/springframework/cassandra/test/integration/config/xml/xmlconfigtest.properties @@ -1,7 +1,3 @@ cassandra.contactPoints=localhost cassandra.port=9042 -cassandra.keyspace=TestKS123 - - - - +cassandra.keyspace=xmlconfigtest diff --git a/spring-cassandra/src/test/resources/org/springframework/data/cassandra/test/integration/config/CassandraNamespaceTests-context.xml b/spring-cassandra/src/test/resources/org/springframework/data/cassandra/test/integration/config/CassandraNamespaceTests-context.xml deleted file mode 100644 index 4050ec523..000000000 --- a/spring-cassandra/src/test/resources/org/springframework/data/cassandra/test/integration/config/CassandraNamespaceTests-context.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraClusterFactoryBean.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraClusterFactoryBean.java similarity index 100% rename from spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraClusterFactoryBean.java rename to spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraClusterFactoryBean.java diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CompressionType.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CompressionType.java deleted file mode 100644 index c74c36676..000000000 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CompressionType.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2010-2012 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; - -/** - * Simple enumeration for the various compression types. - * - * @author Alex Shvid - */ -public enum CompressionType { - NONE, SNAPPY; -} diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/PoolingOptionsConfig.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/PoolingOptionsConfig.java deleted file mode 100644 index 4ba96539e..000000000 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/PoolingOptionsConfig.java +++ /dev/null @@ -1,62 +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; - -/** - * Pooling options POJO. Can be remote or local. - * - * @author Alex Shvid - */ -public class PoolingOptionsConfig { - - private Integer minSimultaneousRequests; - private Integer maxSimultaneousRequests; - private Integer coreConnections; - private Integer maxConnections; - - public Integer getMinSimultaneousRequests() { - return minSimultaneousRequests; - } - - public void setMinSimultaneousRequests(Integer minSimultaneousRequests) { - this.minSimultaneousRequests = minSimultaneousRequests; - } - - public Integer getMaxSimultaneousRequests() { - return maxSimultaneousRequests; - } - - public void setMaxSimultaneousRequests(Integer maxSimultaneousRequests) { - this.maxSimultaneousRequests = maxSimultaneousRequests; - } - - public Integer getCoreConnections() { - return coreConnections; - } - - public void setCoreConnections(Integer coreConnections) { - this.coreConnections = coreConnections; - } - - public Integer getMaxConnections() { - return maxConnections; - } - - public void setMaxConnections(Integer maxConnections) { - this.maxConnections = maxConnections; - } - -} diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SocketOptionsConfig.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SocketOptionsConfig.java deleted file mode 100644 index 1e72c7742..000000000 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SocketOptionsConfig.java +++ /dev/null @@ -1,89 +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; - -/** - * Socket options POJO. Uses to configure Netty. - * - * @author Alex Shvid - */ -public class SocketOptionsConfig { - - private Integer connectTimeoutMls; - private Boolean keepAlive; - private Boolean reuseAddress; - private Integer soLinger; - private Boolean tcpNoDelay; - private Integer receiveBufferSize; - private Integer sendBufferSize; - - public Integer getConnectTimeoutMls() { - return connectTimeoutMls; - } - - public void setConnectTimeoutMls(Integer connectTimeoutMls) { - this.connectTimeoutMls = connectTimeoutMls; - } - - public Boolean getKeepAlive() { - return keepAlive; - } - - public void setKeepAlive(Boolean keepAlive) { - this.keepAlive = keepAlive; - } - - public Boolean getReuseAddress() { - return reuseAddress; - } - - public void setReuseAddress(Boolean reuseAddress) { - this.reuseAddress = reuseAddress; - } - - public Integer getSoLinger() { - return soLinger; - } - - public void setSoLinger(Integer soLinger) { - this.soLinger = soLinger; - } - - public Boolean getTcpNoDelay() { - return tcpNoDelay; - } - - public void setTcpNoDelay(Boolean tcpNoDelay) { - this.tcpNoDelay = tcpNoDelay; - } - - public Integer getReceiveBufferSize() { - return receiveBufferSize; - } - - public void setReceiveBufferSize(Integer receiveBufferSize) { - this.receiveBufferSize = receiveBufferSize; - } - - public Integer getSendBufferSize() { - return sendBufferSize; - } - - public void setSendBufferSize(Integer sendBufferSize) { - this.sendBufferSize = sendBufferSize; - } - -} diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraKeyspaceFactoryBean.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraKeyspaceFactoryBean.java deleted file mode 100644 index 06d7bb784..000000000 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraKeyspaceFactoryBean.java +++ /dev/null @@ -1,341 +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.core; - -import java.util.List; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.cassandra.support.CassandraExceptionTranslator; -import org.springframework.dao.DataAccessException; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.dao.support.PersistenceExceptionTranslator; -import org.springframework.data.cassandra.config.KeyspaceAttributes; -import org.springframework.data.cassandra.config.TableAttributes; -import org.springframework.data.cassandra.convert.CassandraConverter; -import org.springframework.data.cassandra.convert.MappingCassandraConverter; -import org.springframework.data.cassandra.mapping.CassandraMappingContext; -import org.springframework.data.cassandra.mapping.CassandraPersistentEntity; -import org.springframework.data.cassandra.mapping.CassandraPersistentProperty; -import org.springframework.data.cassandra.util.CqlUtils; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.util.ClassUtils; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; - -import com.datastax.driver.core.Cluster; -import com.datastax.driver.core.KeyspaceMetadata; -import com.datastax.driver.core.Session; -import com.datastax.driver.core.TableMetadata; -import com.datastax.driver.core.exceptions.NoHostAvailableException; - -/** - * Convenient factory for configuring a Cassandra Session. Session is a thread safe singleton and created per a - * keyspace. So, it is enough to have one session per application. - * - * @author Alex Shvid - */ - -public class CassandraKeyspaceFactoryBean implements FactoryBean, InitializingBean, DisposableBean, - BeanClassLoaderAware, PersistenceExceptionTranslator { - - private static final Logger log = LoggerFactory.getLogger(CassandraKeyspaceFactoryBean.class); - - public static final String DEFAULT_REPLICATION_STRATEGY = "SimpleStrategy"; - public static final int DEFAULT_REPLICATION_FACTOR = 1; - - private ClassLoader beanClassLoader; - - private Cluster cluster; - private Session session; - private String keyspace; - - private CassandraConverter converter; - private MappingContext, CassandraPersistentProperty> mappingContext; - - private SpringDataKeyspace keyspaceBean; - - private KeyspaceAttributes keyspaceAttributes; - - private final PersistenceExceptionTranslator exceptionTranslator = new CassandraExceptionTranslator(); - - public void setBeanClassLoader(ClassLoader classLoader) { - this.beanClassLoader = classLoader; - } - - public SpringDataKeyspace getObject() { - return keyspaceBean; - } - - /* - * (non-Javadoc) - * @see org.springframework.beans.factory.FactoryBean#getObjectType() - */ - public Class getObjectType() { - return Session.class; - } - - /* - * (non-Javadoc) - * @see org.springframework.beans.factory.FactoryBean#isSingleton() - */ - public boolean isSingleton() { - return true; - } - - /* - * (non-Javadoc) - * @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException) - */ - public DataAccessException translateExceptionIfPossible(RuntimeException ex) { - return exceptionTranslator.translateExceptionIfPossible(ex); - } - - /* - * (non-Javadoc) - * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() - */ - public void afterPropertiesSet() throws Exception { - - if (this.converter == null) { - this.converter = getDefaultCassandraConverter(); - } - this.mappingContext = this.converter.getMappingContext(); - - if (cluster == null) { - throw new IllegalArgumentException("at least one cluster is required"); - } - - Session session = null; - session = cluster.connect(); - - if (StringUtils.hasText(keyspace)) { - - KeyspaceMetadata keyspaceMetadata = cluster.getMetadata().getKeyspace(keyspace.toLowerCase()); - boolean keyspaceExists = keyspaceMetadata != null; - boolean keyspaceCreated = false; - - if (keyspaceExists) { - log.info("keyspace exists " + keyspaceMetadata.asCQLQuery()); - } - - if (keyspaceAttributes == null) { - keyspaceAttributes = new KeyspaceAttributes(); - } - - // drop the old keyspace if needed - if (keyspaceExists && (keyspaceAttributes.isCreate() || keyspaceAttributes.isCreateDrop())) { - log.info("Drop keyspace " + keyspace + " on afterPropertiesSet"); - session.execute("DROP KEYSPACE " + keyspace + ";"); - keyspaceExists = false; - } - - // create the new keyspace if needed - if (!keyspaceExists - && (keyspaceAttributes.isCreate() || keyspaceAttributes.isCreateDrop() || keyspaceAttributes.isUpdate())) { - - String query = String - .format( - "CREATE KEYSPACE %1$s WITH replication = { 'class' : '%2$s', 'replication_factor' : %3$d } AND DURABLE_WRITES = %4$b", - keyspace, keyspaceAttributes.getReplicationStrategy(), keyspaceAttributes.getReplicationFactor(), - keyspaceAttributes.isDurableWrites()); - - log.info("Create keyspace " + keyspace + " on afterPropertiesSet " + query); - - session.execute(query); - keyspaceCreated = true; - } - - // update keyspace if needed - if (keyspaceAttributes.isUpdate() && !keyspaceCreated) { - - if (compareKeyspaceAttributes(keyspaceAttributes, keyspaceMetadata) != null) { - - String query = String - .format( - "ALTER KEYSPACE %1$s WITH replication = { 'class' : '%2$s', 'replication_factor' : %3$d } AND DURABLE_WRITES = %4$b", - keyspace, keyspaceAttributes.getReplicationStrategy(), keyspaceAttributes.getReplicationFactor(), - keyspaceAttributes.isDurableWrites()); - - log.info("Update keyspace " + keyspace + " on afterPropertiesSet " + query); - session.execute(query); - } - - } - - // validate keyspace if needed - if (keyspaceAttributes.isValidate()) { - - if (!keyspaceExists) { - throw new InvalidDataAccessApiUsageException("keyspace '" + keyspace + "' not found in the Cassandra"); - } - - String errorField = compareKeyspaceAttributes(keyspaceAttributes, keyspaceMetadata); - if (errorField != null) { - throw new InvalidDataAccessApiUsageException(errorField + " attribute is not much in the keyspace '" - + keyspace + "'"); - } - - } - - session.execute("USE " + keyspace); - - if (!CollectionUtils.isEmpty(keyspaceAttributes.getTables())) { - - for (TableAttributes tableAttributes : keyspaceAttributes.getTables()) { - - String entityClassName = tableAttributes.getEntity(); - Class entityClass = ClassUtils.forName(entityClassName, this.beanClassLoader); - CassandraPersistentEntity entity = determineEntity(entityClass); - String useTableName = tableAttributes.getName() != null ? tableAttributes.getName() : entity.getTable(); - - if (keyspaceCreated) { - createNewTable(session, useTableName, entity); - } else if (keyspaceAttributes.isUpdate()) { - TableMetadata table = keyspaceMetadata.getTable(useTableName.toLowerCase()); - if (table == null) { - createNewTable(session, useTableName, entity); - } else { - // alter table columns - for (String cql : CqlUtils.alterTable(useTableName, entity, table)) { - log.info("Execute on keyspace " + keyspace + " CQL " + cql); - session.execute(cql); - } - } - } else if (keyspaceAttributes.isValidate()) { - TableMetadata table = keyspaceMetadata.getTable(useTableName.toLowerCase()); - if (table == null) { - throw new InvalidDataAccessApiUsageException("not found table " + useTableName + " for entity " - + entityClassName); - } - // validate columns - List alter = CqlUtils.alterTable(useTableName, entity, table); - if (!alter.isEmpty()) { - throw new InvalidDataAccessApiUsageException("invalid table " + useTableName + " for entity " - + entityClassName + ". modify it by " + alter); - } - } - - // System.out.println("tableAttributes, entityClass=" + entityClass + ", table = " + entity.getTable()); - - } - } - - } - - // initialize property - this.session = session; - - this.keyspaceBean = new SpringDataKeyspace(keyspace, session, converter); - } - - private void createNewTable(Session session, String useTableName, CassandraPersistentEntity entity) - throws NoHostAvailableException { - String cql = CqlUtils.createTable(useTableName, entity, converter); - log.info("Execute on keyspace " + keyspace + " CQL " + cql); - session.execute(cql); - for (String indexCQL : CqlUtils.createIndexes(useTableName, entity)) { - log.info("Execute on keyspace " + keyspace + " CQL " + indexCQL); - session.execute(indexCQL); - } - } - - /* - * (non-Javadoc) - * @see org.springframework.beans.factory.DisposableBean#destroy() - */ - public void destroy() throws Exception { - - if (StringUtils.hasText(keyspace) && keyspaceAttributes != null && keyspaceAttributes.isCreateDrop()) { - log.info("Drop keyspace " + keyspace + " on destroy"); - session.execute("USE system"); - session.execute("DROP KEYSPACE " + keyspace); - } - this.session.shutdown(); - } - - public void setKeyspace(String keyspace) { - this.keyspace = keyspace; - } - - public void setCluster(Cluster cluster) { - this.cluster = cluster; - } - - public void setKeyspaceAttributes(KeyspaceAttributes keyspaceAttributes) { - this.keyspaceAttributes = keyspaceAttributes; - } - - public void setConverter(CassandraConverter converter) { - this.converter = converter; - } - - private static String compareKeyspaceAttributes(KeyspaceAttributes keyspaceAttributes, - KeyspaceMetadata keyspaceMetadata) { - if (keyspaceAttributes.isDurableWrites() != keyspaceMetadata.isDurableWrites()) { - return "durableWrites"; - } - Map replication = keyspaceMetadata.getReplication(); - String replicationFactorStr = replication.get("replication_factor"); - if (replicationFactorStr == null) { - return "replication_factor"; - } - try { - int replicationFactor = Integer.parseInt(replicationFactorStr); - if (keyspaceAttributes.getReplicationFactor() != replicationFactor) { - return "replication_factor"; - } - } catch (NumberFormatException e) { - return "replication_factor"; - } - - String attributesStrategy = keyspaceAttributes.getReplicationStrategy(); - if (attributesStrategy.indexOf('.') == -1) { - attributesStrategy = "org.apache.cassandra.locator." + attributesStrategy; - } - String replicationStrategy = replication.get("class"); - if (!attributesStrategy.equals(replicationStrategy)) { - return "replication_class"; - } - return null; - } - - CassandraPersistentEntity determineEntity(Class entityClass) { - - if (entityClass == null) { - throw new InvalidDataAccessApiUsageException( - "No class parameter provided, entity table name can't be determined!"); - } - - CassandraPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); - if (entity == null) { - throw new InvalidDataAccessApiUsageException("No Persitent Entity information found for the class " - + entityClass.getName()); - } - return entity; - } - - private static final CassandraConverter getDefaultCassandraConverter() { - MappingCassandraConverter converter = new MappingCassandraConverter(new CassandraMappingContext()); - converter.afterPropertiesSet(); - return converter; - } -}