diff --git a/pom.xml b/pom.xml index 08270dfb1..02877e232 100644 --- a/pom.xml +++ b/pom.xml @@ -21,25 +21,6 @@ Spring Data Cassandra http://projects.spring.io/spring-data-cassandra/ - - multi - spring-data-cassandra - 1.13.0.BUILD-SNAPSHOT - 3.0.0.1 - 1.0 - 2.16 - 0.3.1 - 3.0.0 - 3.0.0-rc1 - - embedded - localhost - 19042 - 19160 - 17000 - 17001 - - madams @@ -83,6 +64,22 @@ spring-data-cassandra-distribution + + localhost + embedded + 19042 + 19160 + 17001 + 17000 + 3.0.0 + 3.0.1 + spring-data-cassandra + 1.0 + 2.16 + multi + 1.13.0.BUILD-SNAPSHOT + + spring-libs-snapshot @@ -99,38 +96,24 @@ + + com.datastax.cassandra - cassandra-driver-dse - ${cassandra-driver-dse.version} + cassandra-driver-core + ${cassandra-driver.version} - slf4j-log4j12 - org.slf4j - - - log4j - log4j - - - guava - com.google.guava - - - netty-handler io.netty + netty-handler + + + com.google.guava + guava - - - org.slf4j - jul-to-slf4j - ${slf4j} - test - - javax.enterprise @@ -140,6 +123,24 @@ true + + + org.apache.cassandra + cassandra-all + ${cassandra.version} + test + + + ch.qos.logback + logback-core + + + guava + com.google.guava + + + + org.xerial.snappy snappy-java @@ -194,7 +195,7 @@ com.datastax.cassandra - cassandra-driver-dse + cassandra-driver-core diff --git a/spring-cql/pom.xml b/spring-cql/pom.xml index 97eb9341f..d37c3e33d 100644 --- a/spring-cql/pom.xml +++ b/spring-cql/pom.xml @@ -50,7 +50,7 @@ com.datastax.cassandra - cassandra-driver-dse + cassandra-driver-core javax.enterprise @@ -76,18 +76,6 @@ org.apache.cassandra cassandra-all - ${cassandra.version} - test - - - ch.qos.logback - logback-core - - - guava - com.google.guava - - com.google.guava diff --git a/spring-cql/src/main/java/org/springframework/cassandra/config/CassandraCqlClusterFactoryBean.java b/spring-cql/src/main/java/org/springframework/cassandra/config/CassandraCqlClusterFactoryBean.java index aae08bdce..901e2192a 100644 --- a/spring-cql/src/main/java/org/springframework/cassandra/config/CassandraCqlClusterFactoryBean.java +++ b/spring-cql/src/main/java/org/springframework/cassandra/config/CassandraCqlClusterFactoryBean.java @@ -42,6 +42,7 @@ import com.datastax.driver.core.AuthProvider; import com.datastax.driver.core.Cluster; import com.datastax.driver.core.Host; import com.datastax.driver.core.LatencyTracker; +import com.datastax.driver.core.NettyOptions; import com.datastax.driver.core.PoolingOptions; import com.datastax.driver.core.ProtocolOptions.Compression; import com.datastax.driver.core.ProtocolVersion; @@ -93,6 +94,7 @@ public class CassandraCqlClusterFactoryBean private AuthProvider authProvider; private String username; private String password; + private NettyOptions nettyOptions; private ProtocolVersion protocolVersion; // Policies @@ -189,6 +191,10 @@ public class CassandraCqlClusterFactoryBean } } + if (nettyOptions != null) { + builder.withNettyOptions(nettyOptions); + } + if (loadBalancingPolicy != null) { builder.withLoadBalancingPolicy(loadBalancingPolicy); } @@ -275,8 +281,8 @@ public class CassandraCqlClusterFactoryBean for (Object spec : specs) { String cql = (spec instanceof CreateKeyspaceSpecification) - ? new CreateKeyspaceCqlGenerator((CreateKeyspaceSpecification) spec).toCql() - : new DropKeyspaceCqlGenerator((DropKeyspaceSpecification) spec).toCql(); + ? new CreateKeyspaceCqlGenerator((CreateKeyspaceSpecification) spec).toCql() + : new DropKeyspaceCqlGenerator((DropKeyspaceSpecification) spec).toCql(); if (log.isDebugEnabled()) { log.debug("executing raw CQL [{}]", cql); @@ -329,7 +335,7 @@ public class CassandraCqlClusterFactoryBean } /** - * Set the {@link PoolingOptions}. + * Set the {@link PoolingOptions} to configure the connection pooling behavior. */ public void setPoolingOptions(PoolingOptions poolingOptions) { this.poolingOptions = poolingOptions; @@ -352,7 +358,7 @@ public class CassandraCqlClusterFactoryBean } /** - * Set the {@link QueryOptions}. + * Set the {@link QueryOptions} to tune to defaults for individual queries. */ public void setQueryOptions(QueryOptions queryOptions) { this.queryOptions = queryOptions; @@ -366,21 +372,31 @@ public class CassandraCqlClusterFactoryBean } /** - * Set the {@link LoadBalancingPolicy}. + * Set the {@link NettyOptions} used by a client to customize the driver's underlying Netty layer. + * + * @param nettyOptions + * @since 1.5 + */ + public void setNettyOptions(NettyOptions nettyOptions) { + this.nettyOptions = nettyOptions; + } + + /** + * Set the {@link LoadBalancingPolicy} that decides which Cassandra hosts to contact for each new query. */ public void setLoadBalancingPolicy(LoadBalancingPolicy loadBalancingPolicy) { this.loadBalancingPolicy = loadBalancingPolicy; } /** - * Set the {@link ReconnectionPolicy}. + * Set the {@link ReconnectionPolicy} that decides how often the reconnection to a dead node is attempted. */ public void setReconnectionPolicy(ReconnectionPolicy reconnectionPolicy) { this.reconnectionPolicy = reconnectionPolicy; } /** - * Set the {@link RetryPolicy}. + * Set the {@link RetryPolicy} that defines a default behavior to adopt when a request fails. */ public void setRetryPolicy(RetryPolicy retryPolicy) { this.retryPolicy = retryPolicy; diff --git a/spring-cql/src/main/java/org/springframework/cassandra/config/PoolingOptionsFactoryBean.java b/spring-cql/src/main/java/org/springframework/cassandra/config/PoolingOptionsFactoryBean.java index a2dde2f44..e332e92fe 100644 --- a/spring-cql/src/main/java/org/springframework/cassandra/config/PoolingOptionsFactoryBean.java +++ b/spring-cql/src/main/java/org/springframework/cassandra/config/PoolingOptionsFactoryBean.java @@ -1,12 +1,12 @@ /* - * Copyright 2013-2014 the original author or authors. - * + * Copyright 2013-2016 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. @@ -24,9 +24,10 @@ import com.datastax.driver.core.PoolingOptions; /** * Pooling Options Factory Bean. - * + * * @author Matthew T. Adams * @author David Webb + * @author Mark Paluch */ public class PoolingOptionsFactoryBean implements FactoryBean, InitializingBean, DisposableBean { @@ -79,7 +80,7 @@ public class PoolingOptionsFactoryBean implements FactoryBean, I } if (localMaxSimultaneousRequests != null) { - poolingOptions.setNewConnectionThreshold(HostDistance.LOCAL, localMaxSimultaneousRequests); + poolingOptions.setMaxRequestsPerConnection(HostDistance.LOCAL, localMaxSimultaneousRequests); } if (remoteMaxConnections != null) { @@ -103,7 +104,7 @@ public class PoolingOptionsFactoryBean implements FactoryBean, I } if (remoteMaxSimultaneousRequests != null) { - poolingOptions.setNewConnectionThreshold(HostDistance.REMOTE, + poolingOptions.setMaxRequestsPerConnection(HostDistance.REMOTE, remoteMaxSimultaneousRequests); } diff --git a/spring-cql/src/main/java/org/springframework/cassandra/config/java/AbstractClusterConfiguration.java b/spring-cql/src/main/java/org/springframework/cassandra/config/java/AbstractClusterConfiguration.java index b5c5c7663..a7d895119 100644 --- a/spring-cql/src/main/java/org/springframework/cassandra/config/java/AbstractClusterConfiguration.java +++ b/spring-cql/src/main/java/org/springframework/cassandra/config/java/AbstractClusterConfiguration.java @@ -26,6 +26,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.datastax.driver.core.AuthProvider; +import com.datastax.driver.core.NettyOptions; import com.datastax.driver.core.PoolingOptions; import com.datastax.driver.core.ProtocolVersion; import com.datastax.driver.core.QueryOptions; @@ -61,6 +62,7 @@ public abstract class AbstractClusterConfiguration { bean.setReconnectionPolicy(getReconnectionPolicy()); bean.setRetryPolicy(getRetryPolicy()); bean.setMetricsEnabled(getMetricsEnabled()); + bean.setNettyOptions(getNettyOptions()); bean.setPoolingOptions(getPoolingOptions()); bean.setQueryOptions(getQueryOptions()); @@ -158,6 +160,16 @@ public abstract class AbstractClusterConfiguration { return CassandraCqlClusterFactoryBean.DEFAULT_METRICS_ENABLED; } + /** + * Returns the {@link NettyOptions}. Defaults to {@link NettyOptions#DEFAULT_INSTANCE}. + * + * @return + * @since 1.5 + */ + protected NettyOptions getNettyOptions() { + return NettyOptions.DEFAULT_INSTANCE; + } + /** * Returns the {@link PoolingOptions}. * diff --git a/spring-cql/src/main/java/org/springframework/cassandra/config/java/AbstractCqlTemplateConfiguration.java b/spring-cql/src/main/java/org/springframework/cassandra/config/java/AbstractCqlTemplateConfiguration.java index 433fd06b9..1b26b22f7 100644 --- a/spring-cql/src/main/java/org/springframework/cassandra/config/java/AbstractCqlTemplateConfiguration.java +++ b/spring-cql/src/main/java/org/springframework/cassandra/config/java/AbstractCqlTemplateConfiguration.java @@ -1,8 +1,34 @@ +/* + * Copyright 2016 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.java; import org.springframework.cassandra.core.CqlTemplate; import org.springframework.context.annotation.Bean; +/** + * Abstract configuration class to create a {@link CqlTemplate} and inheriting {@link com.datastax.driver.core.Session} + * and {@link com.datastax.driver.core.Cluster} creation. This class is usually extended by user configuration classes. + * + * @author Matthew T. Adams + * @see org.springframework.cassandra.config.java.AbstractClusterConfiguration + * @see org.springframework.cassandra.config.java.AbstractSessionConfiguration + * @see com.datastax.driver.core.Session + * @see com.datastax.driver.core.Cluster + * @see CqlTemplate + */ public abstract class AbstractCqlTemplateConfiguration extends AbstractSessionConfiguration { @Bean diff --git a/spring-cql/src/main/java/org/springframework/cassandra/core/CqlTemplate.java b/spring-cql/src/main/java/org/springframework/cassandra/core/CqlTemplate.java index ea9441b7e..1cd145a67 100644 --- a/spring-cql/src/main/java/org/springframework/cassandra/core/CqlTemplate.java +++ b/spring-cql/src/main/java/org/springframework/cassandra/core/CqlTemplate.java @@ -89,6 +89,7 @@ import com.datastax.driver.core.querybuilder.Update; * @author David Webb * @author Matthew Adams * @author Ryan Scheidter + * @author Antoine Toulme */ public class CqlTemplate extends CassandraAccessor implements CqlOperations { diff --git a/spring-cql/src/main/java/org/springframework/cassandra/core/converter/RowToListConverter.java b/spring-cql/src/main/java/org/springframework/cassandra/core/converter/RowToListConverter.java index e572e063f..f3ca6fe40 100644 --- a/spring-cql/src/main/java/org/springframework/cassandra/core/converter/RowToListConverter.java +++ b/spring-cql/src/main/java/org/springframework/cassandra/core/converter/RowToListConverter.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.cassandra.core.converter; import java.util.ArrayList; @@ -34,6 +33,7 @@ import com.datastax.driver.core.Row; * @author Matthew T. Adams * @author Stefan Birkner * @author Mark Paluch + * @author Antoine Toulme */ @ReadingConverter public class RowToListConverter implements Converter> { @@ -47,13 +47,16 @@ public class RowToListConverter implements Converter> { return null; } + CodecRegistry codecRegistry = CodecRegistry.DEFAULT_INSTANCE; ColumnDefinitions cols = row.getColumnDefinitions(); List list = new ArrayList(cols.size()); for (Definition def : cols.asList()) { String name = def.getName(); - list.add(row.isNull(name) ? null : CodecRegistry.DEFAULT_INSTANCE.codecFor(def.getType()).deserialize( - row.getBytesUnsafe(name), ProtocolVersion.NEWEST_SUPPORTED)); + + list.add(row.isNull(name) ? null + : codecRegistry.codecFor(def.getType()).deserialize(row.getBytesUnsafe(name), + ProtocolVersion.NEWEST_SUPPORTED)); } return list; diff --git a/spring-cql/src/main/java/org/springframework/cassandra/core/converter/RowToMapConverter.java b/spring-cql/src/main/java/org/springframework/cassandra/core/converter/RowToMapConverter.java index 161898fbe..d0cdcb7c8 100644 --- a/spring-cql/src/main/java/org/springframework/cassandra/core/converter/RowToMapConverter.java +++ b/spring-cql/src/main/java/org/springframework/cassandra/core/converter/RowToMapConverter.java @@ -34,6 +34,7 @@ import com.datastax.driver.core.Row; * @author Matthew T. Adams * @author David Webb * @author Mark Paluch + * @author Antoine Toulme */ @ReadingConverter public class RowToMapConverter implements Converter> { @@ -47,16 +48,18 @@ public class RowToMapConverter implements Converter> { return null; } + CodecRegistry codecRegistry = CodecRegistry.DEFAULT_INSTANCE; ColumnDefinitions cols = row.getColumnDefinitions(); Map map = new HashMap(cols.size()); for (Definition def : cols.asList()) { String name = def.getName(); - map.put( - name, - row.isNull(name) ? null : CodecRegistry.DEFAULT_INSTANCE.codecFor(def.getType()) - .deserialize(row.getBytesUnsafe(name), ProtocolVersion.NEWEST_SUPPORTED)); + + map.put(name, + row.isNull(name) ? null + : codecRegistry.codecFor(def.getType()).deserialize(row.getBytesUnsafe(name), + ProtocolVersion.NEWEST_SUPPORTED)); } return map; diff --git a/spring-cql/src/test/java/org/springframework/cassandra/config/CassandraCqlClusterFactoryBeanUnitTests.java b/spring-cql/src/test/java/org/springframework/cassandra/config/CassandraCqlClusterFactoryBeanUnitTests.java index 0679c7865..4e5490445 100644 --- a/spring-cql/src/test/java/org/springframework/cassandra/config/CassandraCqlClusterFactoryBeanUnitTests.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/config/CassandraCqlClusterFactoryBeanUnitTests.java @@ -24,6 +24,7 @@ import org.springframework.test.util.ReflectionTestUtils; import com.datastax.driver.core.AuthProvider; import com.datastax.driver.core.Configuration; +import com.datastax.driver.core.JdkSSLOptions; import com.datastax.driver.core.PlainTextAuthProvider; import com.datastax.driver.core.PoolingOptions; import com.datastax.driver.core.ProtocolOptions.Compression; @@ -257,7 +258,7 @@ public class CassandraCqlClusterFactoryBeanUnitTests { @Test public void shouldSetSslOptions() throws Exception { - SSLOptions sslOptions = new SSLOptions(); + SSLOptions sslOptions = JdkSSLOptions.builder().build(); CassandraCqlClusterFactoryBean bean = new CassandraCqlClusterFactoryBean(); bean.setSslEnabled(true); @@ -278,7 +279,7 @@ public class CassandraCqlClusterFactoryBeanUnitTests { bean.setMetricsEnabled(false); bean.afterPropertiesSet(); - assertThat(getConfiguration(bean).getMetricsOptions(), is(nullValue())); + assertThat(getConfiguration(bean).getMetricsOptions().isEnabled(), is(false)); } /** diff --git a/spring-cql/src/test/java/org/springframework/cassandra/config/java/AbstractClusterConfigurationUnitTests.java b/spring-cql/src/test/java/org/springframework/cassandra/config/java/AbstractClusterConfigurationUnitTests.java index 8f26da188..894d81ff6 100644 --- a/spring-cql/src/test/java/org/springframework/cassandra/config/java/AbstractClusterConfigurationUnitTests.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/config/java/AbstractClusterConfigurationUnitTests.java @@ -245,7 +245,7 @@ public class AbstractClusterConfigurationUnitTests { }; Cluster cluster = getCluster(clusterConfiguration); - assertThat(getConfiguration(cluster).getMetricsOptions(), is(nullValue())); + assertThat(getConfiguration(cluster).getMetricsOptions().isEnabled(), is(false)); } /** diff --git a/spring-cql/src/test/java/org/springframework/cassandra/support/CassandraExceptionTranslatorTest.java b/spring-cql/src/test/java/org/springframework/cassandra/support/CassandraExceptionTranslatorTest.java index b846cb993..ed01b7714 100644 --- a/spring-cql/src/test/java/org/springframework/cassandra/support/CassandraExceptionTranslatorTest.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/support/CassandraExceptionTranslatorTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2013-2016 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 + * 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, @@ -73,7 +73,7 @@ public class CassandraExceptionTranslatorTest { @Test public void testInvalidConfigurationInQueryException() { String msg = "msg"; - InvalidQueryException cx = new InvalidConfigurationInQueryException(msg); + InvalidQueryException cx = new InvalidConfigurationInQueryException(null, msg); DataAccessException dax = tx.translateExceptionIfPossible(cx); assertNotNull(dax); assertTrue(dax instanceof CassandraInvalidConfigurationInQueryException); diff --git a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/CassandraRule.java b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/CassandraRule.java index dec262852..97a527039 100644 --- a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/CassandraRule.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/CassandraRule.java @@ -27,11 +27,13 @@ import org.junit.rules.ExternalResource; import org.springframework.cassandra.core.SessionCallback; import org.springframework.cassandra.test.integration.support.CassandraConnectionProperties; import org.springframework.cassandra.test.integration.support.CqlDataSet; +import org.springframework.cassandra.test.integration.support.FastShutdownNettyOptions; import org.springframework.dao.DataAccessException; import org.springframework.util.Assert; import org.springframework.util.SocketUtils; import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.QueryOptions; import com.datastax.driver.core.Session; /** @@ -48,6 +50,7 @@ import com.datastax.driver.core.Session; * * * @author Mark Paluch + * @since 1.5 */ public class CassandraRule extends ExternalResource { @@ -70,7 +73,7 @@ public class CassandraRule extends ExternalResource { * @param yamlConfigurationResource name of the configuration resource, must not be {@literal null} and not empty */ public CassandraRule(String yamlConfigurationResource) { - this(yamlConfigurationResource, EmbeddedCassandraServerHelper.DEFAULT_STARTUP_TIMEOUT); + this(yamlConfigurationResource, EmbeddedCassandraServerHelper.DEFAULT_STARTUP_TIMEOUT_MS); } /** @@ -310,7 +313,15 @@ public class CassandraRule extends ExternalResource { port = properties.getCassandraPort(); } cassandraPort = port; - cluster = new Cluster.Builder().addContactPoints(hostIp).withPort(port).build(); + + QueryOptions queryOptions = new QueryOptions(); + queryOptions.setRefreshSchemaIntervalMillis(0); + + cluster = new Cluster.Builder().addContactPoints(hostIp).// + withPort(port).// + withQueryOptions(queryOptions).// + withNettyOptions(FastShutdownNettyOptions.INSTANCE).// + build(); } else { cluster = parent.cluster; cassandraPort = parent.cassandraPort; diff --git a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/EmbeddedCassandraServerHelper.java b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/EmbeddedCassandraServerHelper.java index 1d41185f7..0924ac3b7 100644 --- a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/EmbeddedCassandraServerHelper.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/EmbeddedCassandraServerHelper.java @@ -22,10 +22,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; import org.apache.cassandra.config.DatabaseDescriptor; @@ -45,7 +42,7 @@ class EmbeddedCassandraServerHelper { private static Logger log = LoggerFactory.getLogger(EmbeddedCassandraServerHelper.class); - public static final long DEFAULT_STARTUP_TIMEOUT = 10000; + public static final long DEFAULT_STARTUP_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(20); public static final String DEFAULT_TMP_DIR = "target/embeddedCassandra"; private final static AtomicReference sync = new AtomicReference(); diff --git a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/CassandraCqlClusterFactoryBeanIntegrationTests.java b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/CassandraCqlClusterFactoryBeanIntegrationTests.java index 4f762e895..aaf9d9999 100644 --- a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/CassandraCqlClusterFactoryBeanIntegrationTests.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/CassandraCqlClusterFactoryBeanIntegrationTests.java @@ -15,13 +15,16 @@ */ package org.springframework.cassandra.test.integration.config; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.cassandra.config.CassandraCqlClusterFactoryBean; -import org.springframework.cassandra.test.integration.AbstractEmbeddedCassandraIntegrationTest; +import org.springframework.cassandra.test.integration.support.FastShutdownNettyOptions; +import org.springframework.test.util.ReflectionTestUtils; import com.datastax.driver.core.ProtocolVersion; @@ -29,8 +32,9 @@ import com.datastax.driver.core.ProtocolVersion; * Unit tests for {@link CassandraCqlClusterFactoryBean}. * * @author Kirk Clemens + * @author Mark Paluch */ -public class CassandraCqlClusterFactoryBeanIntegrationTests extends AbstractEmbeddedCassandraIntegrationTest { +public class CassandraCqlClusterFactoryBeanIntegrationTests { private CassandraCqlClusterFactoryBean cassandraCqlClusterFactoryBean; @@ -47,27 +51,26 @@ public class CassandraCqlClusterFactoryBeanIntegrationTests extends AbstractEmbe @Test public void configuredProtocolVersionShouldBeSet() throws Exception { - cassandraCqlClusterFactoryBean.setProtocolVersion(ProtocolVersion.V4); - cassandraCqlClusterFactoryBean.setPort(cassandraEnvironment.getPort()); + cassandraCqlClusterFactoryBean.setNettyOptions(FastShutdownNettyOptions.INSTANCE); + cassandraCqlClusterFactoryBean.setProtocolVersion(ProtocolVersion.V2); cassandraCqlClusterFactoryBean.afterPropertiesSet(); - assertEquals(ProtocolVersion.V4, getProtocolVersionEnum(cassandraCqlClusterFactoryBean)); + assertEquals(ProtocolVersion.V2, getProtocolVersionEnum(cassandraCqlClusterFactoryBean)); } @Test public void defaultProtocolVersionShouldBeSet() throws Exception { - cassandraCqlClusterFactoryBean.setPort(cassandraEnvironment.getPort()); cassandraCqlClusterFactoryBean.afterPropertiesSet(); - assertEquals(ProtocolVersion.NEWEST_SUPPORTED, getProtocolVersionEnum(cassandraCqlClusterFactoryBean)); + assertThat(getProtocolVersionEnum(cassandraCqlClusterFactoryBean), is(nullValue())); } private ProtocolVersion getProtocolVersionEnum(CassandraCqlClusterFactoryBean cassandraCqlClusterFactoryBean) throws Exception { // initialize connection factory - cassandraCqlClusterFactoryBean.getObject().init(); - return cassandraCqlClusterFactoryBean.getObject().getConfiguration().getProtocolOptions().getProtocolVersion(); + return (ProtocolVersion) ReflectionTestUtils.getField( + cassandraCqlClusterFactoryBean.getObject().getConfiguration().getProtocolOptions(), "initialProtocolVersion"); } } diff --git a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/java/CqlTemplateConfigIntegrationTests.java b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/java/CqlTemplateConfigIntegrationTests.java index 9cc0bda2d..99295da00 100644 --- a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/java/CqlTemplateConfigIntegrationTests.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/java/CqlTemplateConfigIntegrationTests.java @@ -23,23 +23,24 @@ import org.junit.Before; import org.junit.Test; import org.springframework.cassandra.config.java.AbstractCqlTemplateConfiguration; import org.springframework.cassandra.core.CqlTemplate; -import org.springframework.cassandra.support.RandomKeySpaceName; import org.springframework.cassandra.test.integration.AbstractEmbeddedCassandraIntegrationTest; +import org.springframework.cassandra.test.integration.support.FastShutdownNettyOptions; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration; +import com.datastax.driver.core.NettyOptions; import com.datastax.driver.core.Session; /** + * Integration tests for {@link AbstractCqlTemplateConfiguration}. + * * @author Matthews T. Adams * @author Oliver Gierke * @author Mark Paluch */ public class CqlTemplateConfigIntegrationTests extends AbstractEmbeddedCassandraIntegrationTest { - public static final String KEYSPACE_NAME = RandomKeySpaceName.create(); - @Configuration public static class Config extends AbstractCqlTemplateConfiguration { @@ -52,6 +53,11 @@ public class CqlTemplateConfigIntegrationTests extends AbstractEmbeddedCassandra protected int getPort() { return cassandraEnvironment.getPort(); } + + @Override + protected NettyOptions getNettyOptions() { + return FastShutdownNettyOptions.INSTANCE; + } } Session session; @@ -59,6 +65,7 @@ public class CqlTemplateConfigIntegrationTests extends AbstractEmbeddedCassandra @Before public void setUp() { + this.context = new AnnotationConfigApplicationContext(Config.class); this.session = context.getBean(Session.class); } diff --git a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/java/KeyspaceCreatingJavaConfig.java b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/java/KeyspaceCreatingJavaConfig.java index d00a368a3..06d96b182 100644 --- a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/java/KeyspaceCreatingJavaConfig.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/java/KeyspaceCreatingJavaConfig.java @@ -1,12 +1,12 @@ /* - * Copyright 2013-2014 the original author or authors. - * + * Copyright 2013-2016 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. @@ -24,6 +24,10 @@ import org.springframework.cassandra.core.keyspace.KeyspaceOption; import org.springframework.cassandra.test.integration.support.AbstractTestJavaConfig; import org.springframework.context.annotation.Configuration; +/** + * @author Matthew T. Adams + * @author Mark Paluch + */ @Configuration public class KeyspaceCreatingJavaConfig extends AbstractTestJavaConfig { diff --git a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/xml/TestHostStateListener.java b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/xml/TestHostStateListener.java index a756a5fa9..6c767f9d7 100644 --- a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/xml/TestHostStateListener.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/xml/TestHostStateListener.java @@ -1,12 +1,12 @@ /* - * Copyright 2013-2014 the original author or authors. - * + * Copyright 2013-2016 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. @@ -23,7 +23,11 @@ import com.datastax.driver.core.Host; import com.datastax.driver.core.Host.StateListener; /** + * {@link StateListener} that logs latency events and their payload. This class can be considered a test dummy and is + * suitable for mocking. + * * @author David Webb + * @author Antoine Toulme */ public class TestHostStateListener implements StateListener { @@ -31,32 +35,32 @@ public class TestHostStateListener implements StateListener { @Override public void onAdd(Host host) { - log.info("Host Added: " + host.getAddress()); + log.info("Host Added: {}", host.getAddress()); } @Override public void onUp(Host host) { - log.info("Host Up: " + host.getAddress()); + log.info("Host Up: {}", host.getAddress()); } @Override public void onDown(Host host) { - log.info("Host Down: " + host.getAddress()); + log.info("Host Down: {}", host.getAddress()); } @Override public void onRemove(Host host) { - log.info("Host Removed: " + host.getAddress()); + log.info("Host Removed: {}", host.getAddress()); } @Override public void onRegister(Cluster cluster) { - log.info("Cluster registered: " + cluster.getClusterName()); + log.info("Cluster registered: {}", cluster.getClusterName()); } @Override public void onUnregister(Cluster cluster) { - log.info("Cluster unregistered: " + cluster.getClusterName()); + log.info("Cluster unregistered: {}", cluster.getClusterName()); } } diff --git a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/xml/TestLatencyTracker.java b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/xml/TestLatencyTracker.java index 656cac26f..07a282557 100644 --- a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/xml/TestLatencyTracker.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/config/xml/TestLatencyTracker.java @@ -1,12 +1,12 @@ /* - * Copyright 2013-2015 the original author or authors. - * + * Copyright 2013-2016 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. @@ -24,8 +24,12 @@ import com.datastax.driver.core.LatencyTracker; import com.datastax.driver.core.Statement; /** + * {@link LatencyTracker} that logs latency events and their payload. This class can be considered a test dummy and is suitable for + * mocking. + * * @author David Webb * @author Oliver Gierke + * @author Antoine Toulme */ public class TestLatencyTracker implements LatencyTracker { @@ -33,15 +37,16 @@ public class TestLatencyTracker implements LatencyTracker { @Override public void update(Host host, Statement statement, Exception exception, long newLatencyNanos) { - LOG.info("Latency Tracker: " + host.getAddress() + ", " + newLatencyNanos + " nanoseconds."); - } - - @Override - public void onRegister(Cluster cluster) { - } - - @Override - public void onUnregister(Cluster cluster) { + LOG.info("Latency Tracker update: {}, {} nanoseconds.", host.getAddress(), newLatencyNanos); } + @Override + public void onRegister(Cluster cluster) { + LOG.info("Latency Tracker onRegister: {}", cluster); + } + + @Override + public void onUnregister(Cluster cluster) { + LOG.info("Latency Tracker onUnregister: {}", cluster); + } } diff --git a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CqlIndexSpecificationAssertions.java b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CqlIndexSpecificationAssertions.java index 627b98a4c..a912913de 100644 --- a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CqlIndexSpecificationAssertions.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CqlIndexSpecificationAssertions.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2016 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. @@ -15,6 +15,7 @@ */ package org.springframework.cassandra.test.integration.core.cql.generator; +import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import org.springframework.cassandra.core.keyspace.IndexDescriptor; @@ -26,24 +27,40 @@ import com.datastax.driver.core.TableMetadata; /** * @author David Webb * @author Matthew T. Adams + * @author Antoine Toulme */ public class CqlIndexSpecificationAssertions { + /** + * Assert the existence of an index using the index name. + * + * @param expected + * @param keyspace + * @param session + */ public static void assertIndex(IndexDescriptor expected, String keyspace, Session session) { TableMetadata tableMetadata = session.getCluster().getMetadata().getKeyspace(keyspace.toLowerCase()) .getTable(expected.getTableName().toCql()); - - IndexMetadata imd = tableMetadata.getIndex(expected.getName().toCql()); - assertEquals(expected.getName(), imd == null ? null : imd.getName()); + IndexMetadata indexMetadata = tableMetadata.getIndex(expected.getName().toCql()); + + assertThat(indexMetadata, is(not(nullValue()))); + assertThat(indexMetadata.getName(), is(equalTo(expected.getName().toCql()))); } + /** + * Assert the absence of an index using the index name. + * + * @param expected + * @param keyspace + * @param session + */ public static void assertNoIndex(IndexDescriptor expected, String keyspace, Session session) { TableMetadata tableMetadata = session.getCluster().getMetadata().getKeyspace(keyspace.toLowerCase()) .getTable(expected.getTableName().toCql()); - - IndexMetadata imd = tableMetadata.getIndex(expected.getName().toCql()); - assertNull(imd); + IndexMetadata indexMetadata = tableMetadata.getIndex(expected.getName().toCql()); + + assertThat(indexMetadata, is(nullValue())); } } diff --git a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CqlTableSpecificationAssertions.java b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CqlTableSpecificationAssertions.java index 8a839018b..7d879340b 100644 --- a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CqlTableSpecificationAssertions.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CqlTableSpecificationAssertions.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2016 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. @@ -35,8 +35,9 @@ import com.datastax.driver.core.TableOptionsMetadata; /** * @author Matthew T. Adams - * @author Matthew T. Adams + * @author David Webb * @author Alex Shvid + * @author Antoine Toulme */ public class CqlTableSpecificationAssertions { diff --git a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/AbstractTestJavaConfig.java b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/AbstractTestJavaConfig.java index c30fc9852..a72bcb7eb 100644 --- a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/AbstractTestJavaConfig.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/AbstractTestJavaConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2016 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. @@ -18,8 +18,14 @@ package org.springframework.cassandra.test.integration.support; import org.springframework.cassandra.config.java.AbstractSessionConfiguration; import org.springframework.context.annotation.Configuration; +import com.datastax.driver.core.NettyOptions; +import com.datastax.driver.core.QueryOptions; + /** + * Java-based configuration for integration tests using defaults for a smooth test run. + * * @author Matthew T. Adams + * @author Mark Paluch */ @Configuration public abstract class AbstractTestJavaConfig extends AbstractSessionConfiguration { @@ -30,4 +36,20 @@ public abstract class AbstractTestJavaConfig extends AbstractSessionConfiguratio protected int getPort() { return PROPERTIES.getCassandraPort(); } + + @Override + protected NettyOptions getNettyOptions() { + return FastShutdownNettyOptions.INSTANCE; + } + + @Override + protected QueryOptions getQueryOptions() { + + // The driver blocks otherwise up to 1 sec on schema refreshes. + // see also https://datastax-oss.atlassian.net/browse/JAVA-1120 + // ideally, this issue will be resolved with Cassandra Java Driver 3.0.2 + QueryOptions queryOptions = new QueryOptions(); + queryOptions.setRefreshSchemaIntervalMillis(0); + return queryOptions; + } } diff --git a/spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/FastShutdownNettyOptions.java b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/FastShutdownNettyOptions.java new file mode 100644 index 000000000..0dedb3272 --- /dev/null +++ b/spring-cql/src/test/java/org/springframework/cassandra/test/integration/support/FastShutdownNettyOptions.java @@ -0,0 +1,38 @@ +/* + * Copyright 2016 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.test.integration.support; + +import java.util.concurrent.TimeUnit; + +import com.datastax.driver.core.NettyOptions; + +import io.netty.channel.EventLoopGroup; + +/** + * {@link NettyOptions} to shutdown a {@link com.datastax.driver.core.Cluster} instance without wait time. + * + * @author Mark Paluch + * @since 1.5 + */ +public class FastShutdownNettyOptions extends NettyOptions { + + public final static FastShutdownNettyOptions INSTANCE = new FastShutdownNettyOptions(); + + @Override + public void onClusterClose(EventLoopGroup eventLoopGroup) { + eventLoopGroup.shutdownGracefully(0, 0, TimeUnit.MILLISECONDS); + } +} diff --git a/spring-cql/src/test/resources/org/springframework/cassandra/test/integration/config/xml/PropertyPlaceholderNamespaceCreatingXmlConfigIntegrationTests-context.xml b/spring-cql/src/test/resources/org/springframework/cassandra/test/integration/config/xml/PropertyPlaceholderNamespaceCreatingXmlConfigIntegrationTests-context.xml index 4b17b0902..f15ff72f3 100644 --- a/spring-cql/src/test/resources/org/springframework/cassandra/test/integration/config/xml/PropertyPlaceholderNamespaceCreatingXmlConfigIntegrationTests-context.xml +++ b/spring-cql/src/test/resources/org/springframework/cassandra/test/integration/config/xml/PropertyPlaceholderNamespaceCreatingXmlConfigIntegrationTests-context.xml @@ -9,9 +9,12 @@ - + + + + -