diff --git a/attic/gradle/build.gradle b/attic/gradle/build.gradle index a98d09edf..b2419f178 100644 --- a/attic/gradle/build.gradle +++ b/attic/gradle/build.gradle @@ -69,14 +69,15 @@ sourceCompatibility = 1.6 targetCompatibility = 1.6 javadoc { - ext.srcDir = file("${projectDir}/docs/src/api") - destinationDir = file("${buildDir}/api") + ext.srcDir = file("${projectDir}/src/main/doc") + ext.destinationDir = file("${buildDir}/docs/javadoc") ext.tmpDir = file("${buildDir}/api-work") configure(options) { - //stylesheetFile = file("${srcDir}/spring-javadoc.css") + stylesheetFile = file("${srcDir}/spring-javadoc.css") //overview = "${srcDir}/overview.html" docFilesSubDirs = true + outputLevel = org.gradle.external.javadoc.JavadocOutputLevel.QUIET breakIterator = true showFromProtected() @@ -94,6 +95,16 @@ javadoc { exclude "org/springframework/data/cassandra/config/**" } + logger.error("BuildDir => ${buildDir}"); + logger.error("DestDir => ${destinationDir}"); + logger.error("ExtDestDir => ${ext.destinationDir}"); + + copy { + from "src/main/doc/resources" + into "${ext.destinationDir}/resources" + include '**/*' + } + title = "${rootProject.description} ${version} API" } diff --git a/attic/gradle/gradle.properties b/attic/gradle/gradle.properties index 883b974a6..30c49caf8 100644 --- a/attic/gradle/gradle.properties +++ b/attic/gradle/gradle.properties @@ -23,4 +23,4 @@ nettyVersion = 3.6.2.Final # -------------------- # Project wide version # -------------------- -version=2.0.0.BUILD-SNAPSHOT \ No newline at end of file +version=1.2.0.BUILD-SNAPSHOT \ No newline at end of file diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/CachedPreparedStatementCreator.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/CachedPreparedStatementCreator.java deleted file mode 100644 index 90fdba895..000000000 --- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/CachedPreparedStatementCreator.java +++ /dev/null @@ -1,80 +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.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.util.Assert; - -import com.datastax.driver.core.PreparedStatement; -import com.datastax.driver.core.Session; -import com.datastax.driver.core.exceptions.DriverException; - -/** - * Created a PreparedStatement and retrieved the PreparedStatement from cache if the statement has been prepared - * previously. In general, this creator should be used over the {@link SimplePreparedStatementCreator} as it provides - * better performance. - * - *

- * There is overhead in Cassandra when Preparing a Statement. This is negligible on a single data center configuration, - * but when your cluster spans multiple data centers, preparing the same statement over and over again is not necessary - * and causes performance issues in high throughput use cases. - *

- * - * @author David Webb - * - */ -public class CachedPreparedStatementCreator implements PreparedStatementCreator, CqlProvider { - - private static Logger log = LoggerFactory.getLogger(CachedPreparedStatementCreator.class); - - private final String cql; - - private PreparedStatement cache; - - /** - * Create a CachedPreparedStatementCreator from the provided CQL. - * - * @param cql - */ - public CachedPreparedStatementCreator(String cql) { - Assert.notNull(cql, "CQL is required to create a PreparedStatement"); - this.cql = cql; - } - - /* (non-Javadoc) - * @see org.springframework.cassandra.core.PreparedStatementCreator#createPreparedStatement(com.datastax.driver.core.Session) - */ - @Override - public PreparedStatement createPreparedStatement(Session session) throws DriverException { - if (cache == null) { - log.debug("PreparedStatement cache is null, preparing new Statement"); - cache = session.prepare(getCql()); - } else { - log.debug("Using cached PreparedStatement"); - } - return cache; - } - - /* (non-Javadoc) - * @see org.springframework.cassandra.core.CqlProvider#getCql() - */ - @Override - public String getCql() { - return this.cql; - } - -} diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/CassandraOperations.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/CassandraOperations.java index 991c9ec95..3d5d8cf41 100644 --- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/CassandraOperations.java +++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/CassandraOperations.java @@ -398,4 +398,44 @@ public interface CassandraOperations { */ Session getSession(); + /** + * This is an operation designed for high performance writes. The cql is used to create a PreparedStatement once, then + * all row values are bound to the single PreparedStatement and executed against the Session. + * + *

+ * This is used internally by the other ingest() methods, but can be used if you want to write your own RowIterator. + * The Object[] length returned by the next() implementation must match the number of bind variables in the CQL. + *

+ * + * @param cql The CQL + * @param rowIterator Implementation to provide the Object[] to be bound to the CQL. + */ + void ingest(String cql, RowIterator rowIterator); + + /** + * This is an operation designed for high performance writes. The cql is used to create a PreparedStatement once, then + * all row values are bound to the single PreparedStatement and executed against the Session. + * + *

+ * The List length must match the number of bind variables in the CQL. + *

+ * + * @param cql The CQL + * @param rows List of List with data to bind to the CQL. + */ + void ingest(String cql, List> rows); + + /** + * This is an operation designed for high performance writes. The cql is used to create a PreparedStatement once, then + * all row values are bound to the single PreparedStatement and executed against the Session. + * + *

+ * The Object[] length of the nested array must match the number of bind variables in the CQL. + *

+ * + * @param cql The CQL + * @param rows Object array of Object array of values to bind to the CQL. + */ + void ingest(String cql, Object[][] rows); + } diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/CassandraTemplate.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/CassandraTemplate.java index 7689c083d..cf4c3f20e 100644 --- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/CassandraTemplate.java +++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/CassandraTemplate.java @@ -560,4 +560,60 @@ public class CassandraTemplate extends CassandraAccessor implements CassandraOpe } }); } + + /* (non-Javadoc) + * @see org.springframework.cassandra.core.CassandraOperations#execute(java.lang.String, org.springframework.cassandra.core.RowProvider, int) + */ + @Override + public void ingest(String cql, RowIterator rowIterator) { + + PreparedStatement preparedStatement = getSession().prepare(cql); + + while (rowIterator.hasNext()) { + getSession().execute(preparedStatement.bind(rowIterator.next())); + } + + } + + /* (non-Javadoc) + * @see org.springframework.cassandra.core.CassandraOperations#execute(java.lang.String, java.util.List) + */ + @Override + public void ingest(String cql, List> rows) { + + Assert.notNull(rows); + Assert.notEmpty(rows); + + Object[][] values = new Object[rows.size()][]; + int i = 0; + for (List row : rows) { + values[i++] = row.toArray(); + } + + ingest(cql, values); + + } + + /* (non-Javadoc) + * @see org.springframework.cassandra.core.CassandraOperations#execute(java.lang.String, java.lang.Object[][]) + */ + @Override + public void ingest(String cql, final Object[][] rows) { + + ingest(cql, new RowIterator() { + + int index = 0; + + @Override + public Object[] next() { + return rows[index++]; + } + + @Override + public boolean hasNext() { + return index < rows.length; + } + + }); + } } \ No newline at end of file diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/CqlParameter.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/CqlParameter.java deleted file mode 100644 index bfd5db193..000000000 --- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/CqlParameter.java +++ /dev/null @@ -1,139 +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 java.util.LinkedList; -import java.util.List; - -import org.springframework.util.Assert; - -import com.datastax.driver.core.DataType; - -/** - * @author David Webb - * - */ -public class CqlParameter { - - /** The name of the parameter, if any */ - private String name; - - /** SQL type constant from {@link DataType} */ - private final DataType type; - - /** The scale to apply in case of a NUMERIC or DECIMAL type, if any */ - private Integer scale; - - /** - * Create a new anonymous CqlParameter, supplying the SQL type. - * - * @param type Cassandra Data Type of the parameter according to {@link DataType} - */ - public CqlParameter(DataType type) { - this.type = type; - } - - /** - * Create a new anonymous CqlParameter, supplying the SQL type. - * - * @param type Cassandra Data Type of the parameter according to {@link DataType} - * @param scale the number of digits after the decimal point - */ - public CqlParameter(DataType type, int scale) { - this.type = type; - this.scale = scale; - } - - /** - * Create a new CqlParameter, supplying name and SQL type. - * - * @param name name of the parameter, as used in input and output maps - * @param type Cassandra Data Type of the parameter according to {@link DataType} - */ - public CqlParameter(String name, DataType type) { - this.name = name; - this.type = type; - } - - /** - * Create a new CqlParameter, supplying name and SQL type. - * - * @param name name of the parameter, as used in input and output maps - * @param type Cassandra Data Type of the parameter according to {@link DataType} - * @param scale the number of digits after the decimal point (for DECIMAL and NUMERIC types) - */ - public CqlParameter(String name, DataType type, int scale) { - this.name = name; - this.type = type; - this.scale = scale; - } - - /** - * Copy constructor. - * - * @param otherParam the CqlParameter object to copy from - */ - public CqlParameter(CqlParameter otherParam) { - Assert.notNull(otherParam, "CqlParameter object must not be null"); - this.name = otherParam.name; - this.type = otherParam.type; - this.scale = otherParam.scale; - } - - /** - * Return the name of the parameter. - */ - public String getName() { - return this.name; - } - - /** - * Return the SQL type of the parameter. - */ - public DataType getType() { - return this.type; - } - - /** - * Return the scale of the parameter, if any. - */ - public Integer getScale() { - return this.scale; - } - - /** - * Return whether this parameter holds input values that should be set before execution even if they are {@code null}. - *

- * This implementation always returns {@code true}. - */ - public boolean isInputValueProvided() { - return true; - } - - /** - * Convert a list of JDBC types, as defined in {@code java.sql.Types}, to a List of CqlParameter objects as used in - * this package. - */ - public static List sqlTypesToAnonymousParameterList(DataType[] types) { - List result = new LinkedList(); - if (types != null) { - for (DataType type : types) { - result.add(new CqlParameter(type)); - } - } - return result; - } -} diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/CqlParameterValue.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/CqlParameterValue.java deleted file mode 100644 index c2932815f..000000000 --- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/CqlParameterValue.java +++ /dev/null @@ -1,68 +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 com.datastax.driver.core.DataType; - -/** - * @author David Webb - * - */ -public class CqlParameterValue extends CqlParameter { - - private final Object value; - - /** - * Create a new CqlParameterValue, supplying the Cassandra DataType. - * - * @param type Cassandra Data Type of the parameter according to {@link DataType} - * @param value the value object - */ - public CqlParameterValue(DataType type, Object value) { - super(type); - this.value = value; - } - - /** - * Create a new CqlParameterValue, supplying the Cassandra DataType. - * - * @param type Cassandra Data Type of the parameter according to {@link DataType} - * @param scale the number of digits after the decimal point (for DECIMAL and NUMERIC types) - * @param value the value object - */ - public CqlParameterValue(DataType type, int scale, Object value) { - super(type, scale); - this.value = value; - } - - /** - * Create a new CqlParameterValue based on the given CqlParameter declaration. - * - * @param declaredParam the declared CqlParameter to define a value for - * @param value the value object - */ - public CqlParameterValue(CqlParameter declaredParam, Object value) { - super(declaredParam); - this.value = value; - } - - /** - * Return the value object that this parameter value holds. - */ - public Object getValue() { - return this.value; - } -} diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/PreparedStatementCreatorFactory.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/PreparedStatementCreatorFactory.java deleted file mode 100644 index 974b0436e..000000000 --- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/PreparedStatementCreatorFactory.java +++ /dev/null @@ -1,202 +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 java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.util.Assert; - -import com.datastax.driver.core.BoundStatement; -import com.datastax.driver.core.PreparedStatement; -import com.datastax.driver.core.Session; -import com.datastax.driver.core.exceptions.DriverException; - -/** - * @author David Webb - * - */ -public class PreparedStatementCreatorFactory { - - /** - * The CQL, which won't change when the parameters change - */ - private final String cql; - - /** List of CqlParameter objects. May not be {@code null}. */ - private final List declaredParameters; - - /** - * Create a new factory. - */ - public PreparedStatementCreatorFactory(String cql) { - this.cql = cql; - this.declaredParameters = new LinkedList(); - } - - /** - * Create a new factory with the given CQL and parameters. - * - * @param cql CQL - * @param declaredParameters list of {@link CqlParameter} objects - * @see CqlParameter - */ - public PreparedStatementCreatorFactory(String cql, List declaredParameters) { - this.cql = cql; - this.declaredParameters = declaredParameters; - } - - /** - * Return a new PreparedStatementBinder for the given parameters. - * - * @param params list of parameters (may be {@code null}) - */ - public PreparedStatementBinder newPreparedStatementBinder(List params) { - return new PreparedStatementCreatorImpl(params != null ? params : Collections.emptyList()); - } - - /** - * Return a new PreparedStatementBinder for the given parameters. - * - * @param params the parameter array (may be {@code null}) - */ - public PreparedStatementBinder newPreparedStatementBinder(Object[] params) { - return new PreparedStatementCreatorImpl(params != null ? Arrays.asList(params) : Collections.emptyList()); - } - - /** - * Return a new PreparedStatementCreator for the given parameters. - * - * @param params list of parameters (may be {@code null}) - */ - public PreparedStatementCreator newPreparedStatementCreator(List params) { - return new PreparedStatementCreatorImpl(params != null ? params : Collections.emptyList()); - } - - /** - * Return a new PreparedStatementCreator for the given parameters. - * - * @param params the parameter array (may be {@code null}) - */ - public PreparedStatementCreator newPreparedStatementCreator(Object[] params) { - return new PreparedStatementCreatorImpl(params != null ? Arrays.asList(params) : Collections.emptyList()); - } - - /** - * Return a new PreparedStatementCreator for the given parameters. - * - * @param sqlToUse the actual SQL statement to use (if different from the factory's, for example because of named - * parameter expanding) - * @param params the parameter array (may be {@code null}) - */ - public PreparedStatementCreator newPreparedStatementCreator(String sqlToUse, Object[] params) { - return new PreparedStatementCreatorImpl(sqlToUse, params != null ? Arrays.asList(params) : Collections.emptyList()); - } - - /** - * PreparedStatementCreator implementation returned by this class. - */ - private class PreparedStatementCreatorImpl implements PreparedStatementCreator, PreparedStatementBinder, CqlProvider { - - private final String actualCql; - - private final List parameters; - - public PreparedStatementCreatorImpl(List parameters) { - this(cql, parameters); - } - - /** - * @param actualCql - * @param parameters - */ - public PreparedStatementCreatorImpl(String actualCql, List parameters) { - this.actualCql = actualCql; - Assert.notNull(parameters, "Parameters List must not be null"); - this.parameters = parameters; - if (this.parameters.size() != declaredParameters.size()) { - Set names = new HashSet(); - for (int i = 0; i < parameters.size(); i++) { - Object param = parameters.get(i); - if (param instanceof CqlParameterValue) { - names.add(((CqlParameterValue) param).getName()); - } else { - names.add("Parameter #" + i); - } - } - if (names.size() != declaredParameters.size()) { - throw new InvalidDataAccessApiUsageException("CQL [" + cql + "]: given " + names.size() - + " parameters but expected " + declaredParameters.size()); - } - } - } - - /* (non-Javadoc) - * @see org.springframework.cassandra.core.PreparedStatementCreator#createPreparedStatement(com.datastax.driver.core.Session) - */ - @Override - public PreparedStatement createPreparedStatement(Session session) throws DriverException { - return session.prepare(this.actualCql); - } - - /* (non-Javadoc) - * @see org.springframework.cassandra.core.PreparedStatementBinder#bindValues(com.datastax.driver.core.PreparedStatement) - */ - @Override - public BoundStatement bindValues(PreparedStatement ps) throws DriverException { - if (this.parameters == null || this.parameters.size() == 0) { - return ps.bind(); - } - - // Test the type of the first value - Object v = this.parameters.get(0); - Object[] values; - if (v instanceof CqlParameterValue) { - LinkedList valuesList = new LinkedList(); - for (Object value : this.parameters) { - valuesList.add(((CqlParameterValue) value).getValue()); - } - values = valuesList.toArray(); - } else { - values = this.parameters.toArray(); - } - - return ps.bind(values); - } - - /* (non-Javadoc) - * @see org.springframework.cassandra.core.CqlProvider#getCql() - */ - @Override - public String getCql() { - return cql; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("PreparedStatementCreatorFactory.PreparedStatementCreatorImpl: cql=["); - sb.append(cql).append("]; parameters=").append(this.parameters); - return sb.toString(); - } - - } -} diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/PreparedStatementCreatorImpl.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/PreparedStatementCreatorImpl.java index 2bedb7f67..cbf5afd43 100644 --- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/PreparedStatementCreatorImpl.java +++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/PreparedStatementCreatorImpl.java @@ -47,7 +47,7 @@ public class PreparedStatementCreatorImpl implements PreparedStatementCreator, C public BoundStatement bindValues(PreparedStatement ps) throws DriverException { // Nothing to set if there are no values if (values == null) { - return null; + return new BoundStatement(ps); } return ps.bind(values.toArray()); diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/RowIterator.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/RowIterator.java new file mode 100644 index 000000000..9fb98ce57 --- /dev/null +++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/RowIterator.java @@ -0,0 +1,29 @@ +/* + * 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; + + +/** + * @author David Webb + * + */ +public interface RowIterator { + + Object[] next(); + + boolean hasNext(); + +} diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/ColumnSpecification.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/ColumnSpecification.java index 1ef827972..b14635d0e 100644 --- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/ColumnSpecification.java +++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/ColumnSpecification.java @@ -27,7 +27,7 @@ public class ColumnSpecification { /** * Default ordering of primary key fields; value is {@link Ordering#ASCENDING}. */ - public static final Ordering DFAULT_ORDERING = ASCENDING; + public static final Ordering DEFAULT_ORDERING = ASCENDING; private String name; private DataType type; // TODO: determining if we should be coupling this to Datastax Java Driver type? @@ -80,12 +80,12 @@ public class ColumnSpecification { /** * Identifies this column as a primary key column with default ordering. Sets the column's {@link #keyType} to - * {@link KeyType#PRIMARY} and its {@link #ordering} to {@link #DFAULT_ORDERING}. + * {@link KeyType#PRIMARY} and its {@link #ordering} to {@link #DEFAULT_ORDERING}. * * @return this */ public ColumnSpecification primary() { - return primary(DFAULT_ORDERING); + return primary(DEFAULT_ORDERING); } /** diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/support/CassandraExceptionTranslator.java b/spring-cassandra/src/main/java/org/springframework/cassandra/support/CassandraExceptionTranslator.java index 1733e2b76..b2fe93910 100644 --- a/spring-cassandra/src/main/java/org/springframework/cassandra/support/CassandraExceptionTranslator.java +++ b/spring-cassandra/src/main/java/org/springframework/cassandra/support/CassandraExceptionTranslator.java @@ -70,14 +70,14 @@ public class CassandraExceptionTranslator implements PersistenceExceptionTransla */ public DataAccessException translateExceptionIfPossible(RuntimeException x) { - if (!(x instanceof DriverException)) { - return null; - } - if (x instanceof DataAccessException) { return (DataAccessException) x; } + if (!(x instanceof DriverException)) { + return null; + } + // Remember: subclasses must come before superclasses, otherwise the // superclass would match before the subclass! diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/AbstractEmbeddedCassandraIntegrationTest.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/AbstractEmbeddedCassandraIntegrationTest.java similarity index 70% rename from spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/AbstractEmbeddedCassandraIntegrationTest.java rename to spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/AbstractEmbeddedCassandraIntegrationTest.java index f6046ac02..c636965fc 100644 --- a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/AbstractEmbeddedCassandraIntegrationTest.java +++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/AbstractEmbeddedCassandraIntegrationTest.java @@ -1,4 +1,4 @@ -package org.springframework.cassandra.test.integration.core.cql.generator; +package org.springframework.cassandra.test.integration; import java.io.IOException; import java.util.UUID; @@ -6,6 +6,7 @@ import java.util.UUID; 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; @@ -15,12 +16,20 @@ import com.datastax.driver.core.Session; public abstract class AbstractEmbeddedCassandraIntegrationTest { + protected final static String CASSANDRA_CONFIG = "cassandra.yaml"; + protected final static String CASSANDRA_HOST = "localhost"; + protected final static int CASSANDRA_NATIVE_PORT = 9042; + @BeforeClass public static void beforeClass() throws ConfigurationException, TTransportException, IOException, InterruptedException { - EmbeddedCassandraServerHelper.startEmbeddedCassandra("cassandra.yaml"); + EmbeddedCassandraServerHelper.startEmbeddedCassandra(CASSANDRA_CONFIG); } + /** + * Whether to clear the cluster before the next test. + */ + protected boolean clear = true; /** * Whether to connect to Cassandra. */ @@ -46,7 +55,7 @@ public abstract class AbstractEmbeddedCassandraIntegrationTest { } public Cluster cluster() { - return Cluster.builder().addContactPoint("localhost").withPort(9042).build(); + return Cluster.builder().addContactPoint(CASSANDRA_HOST).withPort(CASSANDRA_NATIVE_PORT).build(); } @Before @@ -64,8 +73,17 @@ public abstract class AbstractEmbeddedCassandraIntegrationTest { session.execute("CREATE KEYSPACE " + keyspace + " WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};"); session.execute("USE " + keyspace + ";"); - } // else keyspace already exists + } else {// else keyspace already exists + session = cluster.connect(keyspace); + } } } } + + @After + public void after() { + if (clear && connected()) { + EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); + } + } } diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CreateTableCqlGeneratorIntegrationTests.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CreateTableCqlGeneratorIntegrationTests.java index be7b762d9..82872f163 100644 --- a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CreateTableCqlGeneratorIntegrationTests.java +++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CreateTableCqlGeneratorIntegrationTests.java @@ -3,6 +3,7 @@ package org.springframework.cassandra.test.integration.core.cql.generator; import static org.springframework.cassandra.test.integration.core.cql.generator.CqlTableSpecificationAssertions.assertTable; import org.junit.Test; +import org.springframework.cassandra.test.integration.AbstractEmbeddedCassandraIntegrationTest; import org.springframework.cassandra.test.unit.core.cql.generator.CreateTableCqlGeneratorTests.BasicTest; import org.springframework.cassandra.test.unit.core.cql.generator.CreateTableCqlGeneratorTests.CompositePartitionKeyTest; import org.springframework.cassandra.test.unit.core.cql.generator.CreateTableCqlGeneratorTests.CreateTableTest; diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/template/Book.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/template/Book.java new file mode 100644 index 000000000..7b5464321 --- /dev/null +++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/template/Book.java @@ -0,0 +1,99 @@ +/* + * 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.test.integration.core.template; + +/** + * Test POJO + * + * @author David Webb + * + */ +public class Book { + + private String isbn; + + private String title; + private String author; + private int pages; + + /** + * @return Returns the isbn. + */ + public String getIsbn() { + return isbn; + } + + /** + * @param isbn The isbn to set. + */ + public void setIsbn(String isbn) { + this.isbn = isbn; + } + + /** + * @return Returns the title. + */ + public String getTitle() { + return title; + } + + /** + * @param title The title to set. + */ + public void setTitle(String title) { + this.title = title; + } + + /** + * @return Returns the author. + */ + public String getAuthor() { + return author; + } + + /** + * @param author The author to set. + */ + public void setAuthor(String author) { + this.author = author; + } + + /** + * @return Returns the pages. + */ + public int getPages() { + return pages; + } + + /** + * @param pages The pages to set. + */ + public void setPages(int pages) { + this.pages = pages; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("isbn -> " + isbn).append("\n"); + sb.append("tile -> " + title).append("\n"); + sb.append("author -> " + author).append("\n"); + sb.append("pages -> " + pages).append("\n"); + return sb.toString(); + } +} diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/template/CassandraOperationsTest.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/template/CassandraOperationsTest.java new file mode 100644 index 000000000..bd413e819 --- /dev/null +++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/template/CassandraOperationsTest.java @@ -0,0 +1,274 @@ +/* + * 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.test.integration.core.template; + +import static org.junit.Assert.assertNotNull; + +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import junit.framework.Assert; + +import org.cassandraunit.CassandraCQLUnit; +import org.cassandraunit.dataset.cql.ClassPathCQLDataSet; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cassandra.core.CassandraOperations; +import org.springframework.cassandra.core.CassandraTemplate; +import org.springframework.cassandra.core.HostMapper; +import org.springframework.cassandra.core.PreparedStatementBinder; +import org.springframework.cassandra.core.ResultSetExtractor; +import org.springframework.cassandra.core.RingMember; +import org.springframework.cassandra.core.RowIterator; +import org.springframework.cassandra.test.integration.AbstractEmbeddedCassandraIntegrationTest; +import org.springframework.dao.DataAccessException; + +import com.datastax.driver.core.BoundStatement; +import com.datastax.driver.core.Host; +import com.datastax.driver.core.PreparedStatement; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.exceptions.DriverException; + +/** + * Unit Tests for CassandraTemplate + * + * @author David Webb + * + */ +public class CassandraOperationsTest extends AbstractEmbeddedCassandraIntegrationTest { + + private CassandraOperations cassandraTemplate; + + private static Logger log = LoggerFactory.getLogger(CassandraOperationsTest.class); + + /* + * Objects used for test data + */ + final Object[] o1 = new Object[] { "1234", "Moby Dick", "Herman Manville", new Integer(456) }; + final Object[] o2 = new Object[] { "2345", "War and Peace", "Russian Dude", new Integer(456) }; + final Object[] o3 = new Object[] { "3456", "Jane Ayre", "Charlotte", new Integer(456) }; + + /** + * This loads any test specific Cassandra objects + */ + @Rule + public CassandraCQLUnit cassandraCQLUnit = new CassandraCQLUnit(new ClassPathCQLDataSet( + "cassandraOperationsTest-cql-dataload.cql", this.keyspace), CASSANDRA_CONFIG, CASSANDRA_HOST, + CASSANDRA_NATIVE_PORT); + + @Before + public void setupTemplate() { + cassandraTemplate = new CassandraTemplate(session); + } + + @Test + public void ringTest() { + + List ring = cassandraTemplate.describeRing(); + + /* + * There must be 1 node in the cluster if the embedded server is + * running. + */ + assertNotNull(ring); + + for (RingMember h : ring) { + log.info("ringTest Host -> " + h.address); + } + } + + @Test + public void hostMapperTest() { + + List ring = (List) cassandraTemplate.describeRing(new HostMapper() { + + @Override + public Collection mapHosts(Set host) throws DriverException { + + List list = new LinkedList(); + + for (Host h : host) { + MyHost mh = new MyHost(); + mh.someName = h.getAddress().getCanonicalHostName(); + list.add(mh); + } + + return list; + } + + }); + + assertNotNull(ring); + Assert.assertTrue(ring.size() > 0); + + for (MyHost h : ring) { + log.info("hostMapperTest Host -> " + h.someName); + } + + } + + @Test + public void ingestionTestListOfList() { + + String cql = "insert into book (isbn, title, author, pages) values (?, ?, ?, ?)"; + + List> values = new LinkedList>(); + + List l1 = new LinkedList(); + l1.add("1234"); + l1.add("Moby Dick"); + l1.add("Herman Manville"); + l1.add(new Integer(456)); + + values.add(l1); + + List l2 = new LinkedList(); + l2.add("2345"); + l2.add("War and Peace"); + l2.add("Russian Dude"); + l2.add(new Integer(456)); + + values.add(l2); + + // values.add(new Object[] { "3456", "Jane Ayre", "Charlotte", new Integer(456) }); + + cassandraTemplate.ingest(cql, values); + + // Assert that the rows were inserted into Cassandra + Book b1 = getBook("1234"); + Book b2 = getBook("2345"); + + Assert.assertEquals(b1.getIsbn(), l1.get(0)); + Assert.assertEquals(b2.getIsbn(), l2.get(0)); + } + + @Test + public void ingestionTestObjectArray() { + + String cql = "insert into book (isbn, title, author, pages) values (?, ?, ?, ?)"; + + Object[][] values = new Object[3][]; + values[0] = o1; + values[1] = o2; + values[2] = o3; + + cassandraTemplate.ingest(cql, values); + + // Assert that the rows were inserted into Cassandra + Book b1 = getBook("1234"); + Book b2 = getBook("2345"); + Book b3 = getBook("3456"); + + Assert.assertEquals(b1.getIsbn(), values[0][0]); + Assert.assertEquals(b2.getTitle(), values[1][1]); + Assert.assertEquals(b3.getAuthor(), values[2][2]); + } + + /** + * This is an implementation of RowIterator for the purposes of testing passing your own Impl to CassandraTemplate + * + * @author David Webb + */ + final class MyRowIterator implements RowIterator { + + private Object[][] values; + + public MyRowIterator(Object[][] values) { + this.values = values; + } + + int index = 0; + + /* (non-Javadoc) + * @see org.springframework.cassandra.core.RowIterator#next() + */ + @Override + public Object[] next() { + return values[index++]; + } + + /* (non-Javadoc) + * @see org.springframework.cassandra.core.RowIterator#hasNext() + */ + @Override + public boolean hasNext() { + return index < values.length; + } + + } + + @Test + public void ingestionTestRowIterator() { + + String cql = "insert into book (isbn, title, author, pages) values (?, ?, ?, ?)"; + + final Object[][] v = new Object[3][]; + v[0] = o1; + v[1] = o2; + v[2] = o3; + RowIterator ri = new MyRowIterator(v); + + cassandraTemplate.ingest(cql, ri); + + // Assert that the rows were inserted into Cassandra + Book b1 = getBook("1234"); + Book b2 = getBook("2345"); + Book b3 = getBook("3456"); + + Assert.assertEquals(b1.getIsbn(), o1[0]); + Assert.assertEquals(b2.getTitle(), o2[1]); + Assert.assertEquals(b3.getAuthor(), o3[2]); + } + + public Book getBook(final String isbn) { + + Book b = this.cassandraTemplate.query("select * from book where isbn = ?", new PreparedStatementBinder() { + + @Override + public BoundStatement bindValues(PreparedStatement ps) throws DriverException { + return ps.bind(isbn); + } + }, new ResultSetExtractor() { + + @Override + public Book extractData(ResultSet rs) throws DriverException, DataAccessException { + Book b = new Book(); + Row r = rs.one(); + b.setIsbn(r.getString("isbn")); + b.setTitle(r.getString("title")); + b.setAuthor(r.getString("author")); + b.setPages(r.getInt("pages")); + return b; + } + }); + + return b; + + } + + /** + * For testing a HostMapper Implementation + */ + public class MyHost { + public String someName; + } +} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/config/TestConfig.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/config/TestConfig.java index e69e13cd2..415f5393e 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/config/TestConfig.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/config/TestConfig.java @@ -22,12 +22,14 @@ import com.datastax.driver.core.Cluster.Builder; @Configuration public class TestConfig extends AbstractCassandraConfiguration { + public static final String keyspace = "test"; + /* (non-Javadoc) * @see org.springframework.data.cassandra.config.AbstractCassandraConfiguration#getKeyspaceName() */ @Override protected String getKeyspaceName() { - return "test"; + return keyspace; } /* (non-Javadoc) diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/template/CassandraOperationsTest.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/template/CassandraOperationsTest.java deleted file mode 100644 index 3945a1942..000000000 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/template/CassandraOperationsTest.java +++ /dev/null @@ -1,299 +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.test.integration.template; - -import static org.junit.Assert.assertNotNull; - -import java.io.IOException; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import junit.framework.Assert; - -import org.apache.cassandra.exceptions.ConfigurationException; -import org.apache.thrift.transport.TTransportException; -import org.cassandraunit.CassandraCQLUnit; -import org.cassandraunit.DataLoader; -import org.cassandraunit.dataset.cql.ClassPathCQLDataSet; -import org.cassandraunit.dataset.yaml.ClassPathYamlDataSet; -import org.cassandraunit.utils.EmbeddedCassandraServerHelper; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.cache.interceptor.DefaultKeyGenerator; -import org.springframework.cassandra.core.CachedPreparedStatementCreator; -import org.springframework.cassandra.core.CassandraOperations; -import org.springframework.cassandra.core.CqlParameter; -import org.springframework.cassandra.core.CqlParameterValue; -import org.springframework.cassandra.core.HostMapper; -import org.springframework.cassandra.core.PreparedStatementBinder; -import org.springframework.cassandra.core.PreparedStatementCreatorFactory; -import org.springframework.cassandra.core.ResultSetExtractor; -import org.springframework.cassandra.core.RingMember; -import org.springframework.dao.DataAccessException; -import org.springframework.data.cassandra.test.integration.config.TestConfig; -import org.springframework.data.cassandra.test.integration.table.Book; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.support.AnnotationConfigContextLoader; - -import com.datastax.driver.core.BoundStatement; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Host; -import com.datastax.driver.core.PreparedStatement; -import com.datastax.driver.core.ResultSet; -import com.datastax.driver.core.Row; -import com.datastax.driver.core.Session; -import com.datastax.driver.core.exceptions.DriverException; - -/** - * Unit Tests for CassandraTemplate - * - * @author David Webb - * - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { TestConfig.class }, loader = AnnotationConfigContextLoader.class) -public class CassandraOperationsTest { - - /** - * @author David Webb - * - */ - public class MyHost { - - public String someName; - - } - - @Autowired - private CassandraOperations cassandraTemplate; - - private static Logger log = LoggerFactory.getLogger(CassandraOperationsTest.class); - - private final static String CASSANDRA_CONFIG = "cassandra.yaml"; - private final static String KEYSPACE_NAME = "test"; - private final static String CASSANDRA_HOST = "localhost"; - private final static int CASSANDRA_NATIVE_PORT = 9042; - private final static int CASSANDRA_THRIFT_PORT = 9160; - - @Rule - public CassandraCQLUnit cassandraCQLUnit = new CassandraCQLUnit(new ClassPathCQLDataSet( - "cassandraOperationsTest-cql-dataload.cql", KEYSPACE_NAME), CASSANDRA_CONFIG, CASSANDRA_HOST, - CASSANDRA_NATIVE_PORT); - - @BeforeClass - public static void startCassandra() throws IOException, TTransportException, ConfigurationException, - InterruptedException { - - EmbeddedCassandraServerHelper.startEmbeddedCassandra(CASSANDRA_CONFIG); - - /* - * Load data file to creat the test keyspace before we init the template - */ - DataLoader dataLoader = new DataLoader("Test Cluster", CASSANDRA_HOST + ":" + CASSANDRA_THRIFT_PORT); - dataLoader.load(new ClassPathYamlDataSet("cassandra-keyspace.yaml")); - } - - @Test - public void ringTest() { - - List ring = cassandraTemplate.describeRing(); - - /* - * There must be 1 node in the cluster if the embedded server is - * running. - */ - assertNotNull(ring); - - for (RingMember h : ring) { - log.info("ringTest Host -> " + h.address); - } - } - - @Test - public void hostMapperTest() { - - List ring = (List) cassandraTemplate.describeRing(new HostMapper() { - - @Override - public Collection mapHosts(Set host) throws DriverException { - - List list = new LinkedList(); - - for (Host h : host) { - MyHost mh = new MyHost(); - mh.someName = h.getAddress().getCanonicalHostName(); - list.add(mh); - } - - return list; - } - - }); - - assertNotNull(ring); - Assert.assertTrue(ring.size() > 0); - - for (MyHost h : ring) { - log.info("hostMapperTest Host -> " + h.someName); - } - - } - - @Test - public void preparedStatementFactoryTest() { - - String cql = "select * from book where isbn = ?"; - - List parameters = new LinkedList(); - parameters.add(new CqlParameter("isbn", DataType.text())); - - PreparedStatementCreatorFactory factory = new PreparedStatementCreatorFactory(cql, parameters); - - List values = new LinkedList(); - values.add(new CqlParameterValue(DataType.text(), "999999999")); - - Book b = cassandraTemplate.query(factory.newPreparedStatementCreator(values), - factory.newPreparedStatementBinder(values), new ResultSetExtractor() { - - @Override - public Book extractData(ResultSet rs) throws DriverException, DataAccessException { - Row r = rs.one(); - Book b = new Book(); - b.setIsbn(r.getString("isbn")); - b.setTitle(r.getString("title")); - b.setAuthor(r.getString("author")); - b.setPages(r.getInt("pages")); - return b; - } - }); - - log.info(b.toString()); - - } - - // @Test - public void cachedPreparedStatementTest() { - - log.info(echoString("Hello")); - log.info(echoString("Hello")); - - String cql = "select * from book where isbn = ?"; - - CachedPreparedStatementCreator cpsc = new CachedPreparedStatementCreator(cql); - - Book b = cassandraTemplate.query(cpsc, new PreparedStatementBinder() { - - @Override - public BoundStatement bindValues(PreparedStatement ps) throws DriverException { - return ps.bind("999999999"); - } - }, new ResultSetExtractor() { - - @Override - public Book extractData(ResultSet rs) throws DriverException, DataAccessException { - Row r = rs.one(); - Book b = new Book(); - b.setIsbn(r.getString("isbn")); - b.setTitle(r.getString("title")); - b.setAuthor(r.getString("author")); - b.setPages(r.getInt("pages")); - return b; - } - }); - - assertNotNull(b); - - log.info(b.toString()); - - try { - DefaultKeyGenerator generator = new DefaultKeyGenerator(); - - // TODO Why does method have to be public to work? Options? - Object cacheKey = generator.generate(CachedPreparedStatementCreator.class, - CachedPreparedStatementCreator.class.getMethod("getCachedPreparedStatement", Session.class, String.class), - cassandraTemplate.getSession(), cql); - - log.info("cacheKey -> " + cacheKey); - - // ConcurrentMapCache cache = (ConcurrentMapCache) cacheManager.getCache("sdc-pstmts"); - // ConcurrentMap cacheMap = cache.getNativeCache(); - // assertNotNull(cacheMap); - // log.info("CacheMap.size() -> " + cacheMap.size()); - // ValueWrapper vw = cache.get(cacheKey); - // PreparedStatement pstmt = (PreparedStatement) vw.get(); - // assertNotNull(pstmt); - // log.info(pstmt.getQueryString()); - // assertEquals(pstmt.getQueryString(), cql); - } catch (NoSuchMethodException e) { - log.error("Failed to find method", e); - } - - CachedPreparedStatementCreator cpsc2 = new CachedPreparedStatementCreator(cql); - - Book b2 = cassandraTemplate.query(cpsc2, new PreparedStatementBinder() { - - @Override - public BoundStatement bindValues(PreparedStatement ps) throws DriverException { - return ps.bind("999999999"); - } - }, new ResultSetExtractor() { - - @Override - public Book extractData(ResultSet rs) throws DriverException, DataAccessException { - Row r = rs.one(); - Book b = new Book(); - b.setIsbn(r.getString("isbn")); - b.setTitle(r.getString("title")); - b.setAuthor(r.getString("author")); - b.setPages(r.getInt("pages")); - return b; - } - }); - - assertNotNull(b2); - - log.info(b2.toString()); - - } - - @Cacheable("sdc-pstmts") - public String echoString(String s) { - log.info("In EchoString"); - return s; - } - - @After - public void clearCassandra() { - EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); - - } - - @AfterClass - public static void stopCassandra() { - // EmbeddedCassandraServerHelper.stopEmbeddedCassandra(); - } -}