From 3cb6639e05256e21957074a4ef81e282f07632b4 Mon Sep 17 00:00:00 2001 From: dwebb Date: Thu, 14 Nov 2013 15:37:50 -0500 Subject: [PATCH 1/4] wip: Finished Implementation of update methods. --- .../cassandra/core/CassandraOperations.java | 4 +- .../cassandra/core/CassandraTemplate.java | 168 ++++++++++++++---- .../data/cassandra/util/CqlUtils.java | 107 +++++++++++ 3 files changed, 242 insertions(+), 37 deletions(-) diff --git a/src/main/java/org/springframework/data/cassandra/core/CassandraOperations.java b/src/main/java/org/springframework/data/cassandra/core/CassandraOperations.java index d9035f1cd..2b463fb16 100644 --- a/src/main/java/org/springframework/data/cassandra/core/CassandraOperations.java +++ b/src/main/java/org/springframework/data/cassandra/core/CassandraOperations.java @@ -24,9 +24,9 @@ import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.ResultSetFuture; /** + * Main Inteface that should be used for Cassandra interactions + * * @author Alex Shvid - */ -/** * @author David Webb * */ diff --git a/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java b/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java index 0015d51b4..2d3ada4c9 100644 --- a/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java +++ b/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java @@ -208,6 +208,7 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public void deleteAsychronously(List entities, String tableName) { + insertAsynchronously(entities, tableName, new HashMap()); } /* (non-Javadoc) @@ -227,8 +228,7 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public void deleteAsychronously(List entities, String tableName, QueryOptions options) { - // TODO Auto-generated method stub - + deleteAsychronously(entities, tableName, options.toMap()); } /* (non-Javadoc) @@ -571,8 +571,9 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public List update(List entities) { - // TODO Auto-generated method stub - return null; + String tableName = getTableName(entities.get(0).getClass()); + Assert.notNull(tableName); + return update(entities, tableName); } /* (non-Javadoc) @@ -580,8 +581,7 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public List update(List entities, String tableName) { - // TODO Auto-generated method stub - return null; + return update(entities, tableName, new HashMap()); } /* (non-Javadoc) @@ -589,8 +589,11 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public List update(List entities, String tableName, Map optionsByName) { - // TODO Auto-generated method stub - return null; + Assert.notNull(entities); + Assert.notEmpty(entities); + Assert.notNull(tableName); + Assert.notNull(optionsByName); + return doBatchUpdate(tableName, entities, optionsByName, false); } /* (non-Javadoc) @@ -598,8 +601,7 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public List update(List entities, String tableName, QueryOptions options) { - // TODO Auto-generated method stub - return null; + return update(entities, tableName, options.toMap()); } /* (non-Javadoc) @@ -607,8 +609,9 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public T update(T entity) { - // TODO Auto-generated method stub - return null; + String tableName = getTableName(entity.getClass()); + Assert.notNull(tableName); + return update(entity, tableName); } /* (non-Javadoc) @@ -616,8 +619,7 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public T update(T entity, String tableName) { - // TODO Auto-generated method stub - return null; + return update(entity, tableName, new HashMap()); } /* (non-Javadoc) @@ -625,8 +627,10 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public T update(T entity, String tableName, Map optionsByName) { - // TODO Auto-generated method stub - return null; + Assert.notNull(entity); + Assert.notNull(tableName); + Assert.notNull(optionsByName); + return doUpdate(tableName, entity, optionsByName, false); } /* (non-Javadoc) @@ -634,8 +638,7 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public T update(T entity, String tableName, QueryOptions options) { - // TODO Auto-generated method stub - return null; + return update(entity, tableName, options.toMap()); } /* (non-Javadoc) @@ -643,8 +646,9 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public List updateAsynchronously(List entities) { - // TODO Auto-generated method stub - return null; + String tableName = getTableName(entities.get(0).getClass()); + Assert.notNull(tableName); + return updateAsynchronously(entities, tableName); } /* (non-Javadoc) @@ -652,8 +656,7 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public List updateAsynchronously(List entities, String tableName) { - // TODO Auto-generated method stub - return null; + return updateAsynchronously(entities, tableName, new HashMap()); } /* (non-Javadoc) @@ -661,8 +664,11 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public List updateAsynchronously(List entities, String tableName, Map optionsByName) { - // TODO Auto-generated method stub - return null; + Assert.notNull(entities); + Assert.notEmpty(entities); + Assert.notNull(tableName); + Assert.notNull(optionsByName); + return doBatchUpdate(tableName, entities, optionsByName, true); } /* (non-Javadoc) @@ -670,8 +676,7 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public List updateAsynchronously(List entities, String tableName, QueryOptions options) { - // TODO Auto-generated method stub - return null; + return updateAsynchronously(entities, tableName, options.toMap()); } /* (non-Javadoc) @@ -679,8 +684,9 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public T updateAsynchronously(T entity) { - // TODO Auto-generated method stub - return null; + String tableName = getTableName(entity.getClass()); + Assert.notNull(tableName); + return updateAsynchronously(entity, tableName); } /* (non-Javadoc) @@ -688,8 +694,7 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public T updateAsynchronously(T entity, String tableName) { - // TODO Auto-generated method stub - return null; + return updateAsynchronously(entity, tableName, new HashMap()); } /* (non-Javadoc) @@ -697,8 +702,10 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public T updateAsynchronously(T entity, String tableName, Map optionsByName) { - // TODO Auto-generated method stub - return null; + Assert.notNull(entity); + Assert.notNull(tableName); + Assert.notNull(optionsByName); + return doUpdate(tableName, entity, optionsByName, true); } /* (non-Javadoc) @@ -706,8 +713,7 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public T updateAsynchronously(T entity, String tableName, QueryOptions options) { - // TODO Auto-generated method stub - return null; + return updateAsynchronously(entity, tableName, options.toMap()); } /** @@ -773,7 +779,10 @@ public class CassandraTemplate implements CassandraOperations { * Insert a row into a Cassandra CQL Table * * @param tableName - * @param entity + * @param entities + * @param optionsByName + * @param insertAsychronously + * @return */ protected List doBatchInsert(final String tableName, final List entities, Map optionsByName, final boolean insertAsychronously) { @@ -811,6 +820,51 @@ public class CassandraTemplate implements CassandraOperations { } } + /** + * Update a Batch of rows in a Cassandra CQL Table + * + * @param tableName + * @param entities + * @param optionsByName + * @param updateAsychronously + * @return + */ + protected List doBatchUpdate(final String tableName, final List entities, + Map optionsByName, final boolean updateAsychronously) { + + Assert.notEmpty(entities); + + CassandraPersistentEntity CPEntity = getEntity(entities.get(0)); + + Assert.notNull(CPEntity); + + try { + + final Batch b = CqlUtils.toUpdateBatchQuery(keyspace.getKeyspace(), tableName, entities, CPEntity, optionsByName); + log.info(b.toString()); + + return execute(new SessionCallback>() { + + @Override + public List doInSession(Session s) throws DataAccessException { + + if (updateAsychronously) { + s.executeAsync(b); + } else { + s.execute(b); + } + + return entities; + + } + }); + + } catch (EntityWriterException e) { + throw exceptionTranslator.translateExceptionIfPossible(new RuntimeException( + "Failed to translate Object to Query", e)); + } + } + /** * Perform the removal of a Row. * @@ -892,6 +946,50 @@ public class CassandraTemplate implements CassandraOperations { } + /** + * Update a row into a Cassandra CQL Table + * + * @param tableName + * @param entity + * @param optionsByName + * @param updateAsychronously + * @return + */ + protected T doUpdate(final String tableName, final T entity, final Map optionsByName, + final boolean updateAsychronously) { + + CassandraPersistentEntity CPEntity = getEntity(entity); + + Assert.notNull(CPEntity); + + try { + + final Query q = CqlUtils.toUpdateQuery(keyspace.getKeyspace(), tableName, entity, CPEntity, optionsByName); + log.info(q.toString()); + + return execute(new SessionCallback() { + + @Override + public T doInSession(Session s) throws DataAccessException { + + if (updateAsychronously) { + s.executeAsync(q); + } else { + s.execute(q); + } + + return entity; + + } + }); + + } catch (EntityWriterException e) { + throw exceptionTranslator.translateExceptionIfPossible(new RuntimeException( + "Failed to translate Object to Query", e)); + } + + } + /** * Verify the object is not an iterable type * diff --git a/src/main/java/org/springframework/data/cassandra/util/CqlUtils.java b/src/main/java/org/springframework/data/cassandra/util/CqlUtils.java index 65fc10a1f..5d333912c 100644 --- a/src/main/java/org/springframework/data/cassandra/util/CqlUtils.java +++ b/src/main/java/org/springframework/data/cassandra/util/CqlUtils.java @@ -27,6 +27,7 @@ import com.datastax.driver.core.querybuilder.Delete; import com.datastax.driver.core.querybuilder.Delete.Where; import com.datastax.driver.core.querybuilder.Insert; import com.datastax.driver.core.querybuilder.QueryBuilder; +import com.datastax.driver.core.querybuilder.Update; /** * @@ -263,6 +264,112 @@ public abstract class CqlUtils { } + /** + * Generates a Query Object for an Update + * + * @param keyspaceName + * @param tableName + * @param entity + * @param objectToSave + * @param optionsByName + * @param mappingContext + * @param beanClassLoader + * + * @return The Query object to run with session.execute(); + * @throws EntityWriterException + */ + public static Query toUpdateQuery(String keyspaceName, String tableName, final Object objectToSave, + CassandraPersistentEntity entity, Map optionsByName) throws EntityWriterException { + + final Update q = QueryBuilder.update(keyspaceName, tableName); + final Exception innerException = new Exception(); + + entity.doWithProperties(new PropertyHandler() { + public void doWithPersistentProperty(CassandraPersistentProperty prop) { + + /* + * See if the object has a value for that column, and if so, add it to the Query + */ + try { + + Object o = prop.getGetter().invoke(objectToSave, new Object[0]); + + log.info("Getter Invoke [" + prop.getColumnName() + " => " + o); + + if (o != null) { + if (prop.isIdProperty()) { + q.where(QueryBuilder.eq(prop.getColumnName(), o)); + } else { + q.with(QueryBuilder.add(prop.getColumnName(), o)); + } + } + + } catch (IllegalAccessException e) { + innerException.initCause(e); + } catch (IllegalArgumentException e) { + innerException.initCause(e); + } catch (InvocationTargetException e) { + innerException.initCause(e); + } + } + }); + + if (innerException.getCause() != null) { + throw new EntityWriterException("Failed to convert Persistent Entity to CQL/Query", innerException.getCause()); + } + + /* + * Add Query Options + */ + addQueryOptions(q, optionsByName); + + /* + * Add TTL to Insert object + */ + if (optionsByName.get(QueryOptions.QueryOptionMapKeys.TTL) != null) { + q.using(QueryBuilder.ttl((Integer) optionsByName.get(QueryOptions.QueryOptionMapKeys.TTL))); + } + + return q; + + } + + /** + * Generates a Batch Object for multiple Updates + * + * @param keyspaceName + * @param tableName + * @param entity + * @param objectsToSave + * @param mappingContext + * @param beanClassLoader + * + * @return The Query object to run with session.execute(); + * @throws EntityWriterException + */ + public static Batch toUpdateBatchQuery(final String keyspaceName, final String tableName, + final List objectsToSave, CassandraPersistentEntity entity, Map optionsByName) + throws EntityWriterException { + + /* + * Return variable is a Batch statement + */ + final Batch b = QueryBuilder.batch(); + + List queries = new ArrayList(); + + for (final T objectToSave : objectsToSave) { + + queries.add(toUpdateQuery(keyspaceName, tableName, objectToSave, entity, optionsByName)); + + } + + addQueryOptions(b, optionsByName); + + return b; + + } + /** * Generates a Batch Object for multiple inserts * From 55e49401fa07e3652b690a8067cfbfd7801c24e8 Mon Sep 17 00:00:00 2001 From: dwebb Date: Thu, 14 Nov 2013 15:44:02 -0500 Subject: [PATCH 2/4] wip: Unit Tests - renamed package for Cassandra Table POJOs. --- .../data/cassandra/{test => table}/Comment.java | 2 +- .../data/cassandra/{test => table}/LogEntry.java | 2 +- .../data/cassandra/{test => table}/Notification.java | 2 +- .../springframework/data/cassandra/{test => table}/Post.java | 2 +- .../data/cassandra/{test => table}/Timeline.java | 2 +- .../springframework/data/cassandra/{test => table}/User.java | 2 +- .../data/cassandra/{test => table}/UserAlter.java | 2 +- .../data/cassandra/template/CassandraOperationsTest.java | 4 ++-- 8 files changed, 9 insertions(+), 9 deletions(-) rename src/test/java/org/springframework/data/cassandra/{test => table}/Comment.java (98%) rename src/test/java/org/springframework/data/cassandra/{test => table}/LogEntry.java (97%) rename src/test/java/org/springframework/data/cassandra/{test => table}/Notification.java (97%) rename src/test/java/org/springframework/data/cassandra/{test => table}/Post.java (98%) rename src/test/java/org/springframework/data/cassandra/{test => table}/Timeline.java (97%) rename src/test/java/org/springframework/data/cassandra/{test => table}/User.java (98%) rename src/test/java/org/springframework/data/cassandra/{test => table}/UserAlter.java (98%) diff --git a/src/test/java/org/springframework/data/cassandra/test/Comment.java b/src/test/java/org/springframework/data/cassandra/table/Comment.java similarity index 98% rename from src/test/java/org/springframework/data/cassandra/test/Comment.java rename to src/test/java/org/springframework/data/cassandra/table/Comment.java index bd7712703..3a5356ddf 100644 --- a/src/test/java/org/springframework/data/cassandra/test/Comment.java +++ b/src/test/java/org/springframework/data/cassandra/table/Comment.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.cassandra.test; +package org.springframework.data.cassandra.table; import java.util.Date; import java.util.Set; diff --git a/src/test/java/org/springframework/data/cassandra/test/LogEntry.java b/src/test/java/org/springframework/data/cassandra/table/LogEntry.java similarity index 97% rename from src/test/java/org/springframework/data/cassandra/test/LogEntry.java rename to src/test/java/org/springframework/data/cassandra/table/LogEntry.java index 700c3b084..1b8ac1c79 100644 --- a/src/test/java/org/springframework/data/cassandra/test/LogEntry.java +++ b/src/test/java/org/springframework/data/cassandra/table/LogEntry.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.cassandra.test; +package org.springframework.data.cassandra.table; import java.util.Date; diff --git a/src/test/java/org/springframework/data/cassandra/test/Notification.java b/src/test/java/org/springframework/data/cassandra/table/Notification.java similarity index 97% rename from src/test/java/org/springframework/data/cassandra/test/Notification.java rename to src/test/java/org/springframework/data/cassandra/table/Notification.java index b0c17ed19..989c569bf 100644 --- a/src/test/java/org/springframework/data/cassandra/test/Notification.java +++ b/src/test/java/org/springframework/data/cassandra/table/Notification.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.cassandra.test; +package org.springframework.data.cassandra.table; import java.util.Date; diff --git a/src/test/java/org/springframework/data/cassandra/test/Post.java b/src/test/java/org/springframework/data/cassandra/table/Post.java similarity index 98% rename from src/test/java/org/springframework/data/cassandra/test/Post.java rename to src/test/java/org/springframework/data/cassandra/table/Post.java index c02dcf689..eee8bcdc6 100644 --- a/src/test/java/org/springframework/data/cassandra/test/Post.java +++ b/src/test/java/org/springframework/data/cassandra/table/Post.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.cassandra.test; +package org.springframework.data.cassandra.table; import java.util.Date; import java.util.Map; diff --git a/src/test/java/org/springframework/data/cassandra/test/Timeline.java b/src/test/java/org/springframework/data/cassandra/table/Timeline.java similarity index 97% rename from src/test/java/org/springframework/data/cassandra/test/Timeline.java rename to src/test/java/org/springframework/data/cassandra/table/Timeline.java index 53a1ebffc..6aec5dfef 100644 --- a/src/test/java/org/springframework/data/cassandra/test/Timeline.java +++ b/src/test/java/org/springframework/data/cassandra/table/Timeline.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.cassandra.test; +package org.springframework.data.cassandra.table; import java.util.Date; diff --git a/src/test/java/org/springframework/data/cassandra/test/User.java b/src/test/java/org/springframework/data/cassandra/table/User.java similarity index 98% rename from src/test/java/org/springframework/data/cassandra/test/User.java rename to src/test/java/org/springframework/data/cassandra/table/User.java index fd091cf73..b313d0a40 100644 --- a/src/test/java/org/springframework/data/cassandra/test/User.java +++ b/src/test/java/org/springframework/data/cassandra/table/User.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.cassandra.test; +package org.springframework.data.cassandra.table; import java.util.Set; diff --git a/src/test/java/org/springframework/data/cassandra/test/UserAlter.java b/src/test/java/org/springframework/data/cassandra/table/UserAlter.java similarity index 98% rename from src/test/java/org/springframework/data/cassandra/test/UserAlter.java rename to src/test/java/org/springframework/data/cassandra/table/UserAlter.java index 900df065f..499014619 100644 --- a/src/test/java/org/springframework/data/cassandra/test/UserAlter.java +++ b/src/test/java/org/springframework/data/cassandra/table/UserAlter.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.cassandra.test; +package org.springframework.data.cassandra.table; import java.util.Set; diff --git a/src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTest.java b/src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTest.java index 0564a07d7..e875bdb8c 100644 --- a/src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTest.java +++ b/src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTest.java @@ -40,8 +40,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.cassandra.config.TestConfig; import org.springframework.data.cassandra.core.CassandraTemplate; import org.springframework.data.cassandra.core.RingMember; -import org.springframework.data.cassandra.test.LogEntry; -import org.springframework.data.cassandra.test.User; +import org.springframework.data.cassandra.table.LogEntry; +import org.springframework.data.cassandra.table.User; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; From e68f6ed32a8abc73624a39d9564304e3ba2fd6a2 Mon Sep 17 00:00:00 2001 From: dwebb Date: Thu, 14 Nov 2013 16:50:31 -0500 Subject: [PATCH 3/4] wip: Unit tests with CQLLoader working as @Rule --- .../AbstractCassandraConfiguration.java | 3 +- .../data/cassandra/config/TestConfig.java | 5 +- .../CassandraOperationsTableTest.java | 4 +- .../template/CassandraOperationsTest.java | 47 ++++++++++--------- ...ndra-data.yaml => cassandra-keyspace.yaml} | 0 src/test/resources/cql-dataload.cql | 1 + 6 files changed, 32 insertions(+), 28 deletions(-) rename src/test/resources/{cassandra-data.yaml => cassandra-keyspace.yaml} (100%) create mode 100644 src/test/resources/cql-dataload.cql diff --git a/src/main/java/org/springframework/data/cassandra/config/AbstractCassandraConfiguration.java b/src/main/java/org/springframework/data/cassandra/config/AbstractCassandraConfiguration.java index 738514b39..73ae8fd96 100644 --- a/src/main/java/org/springframework/data/cassandra/config/AbstractCassandraConfiguration.java +++ b/src/main/java/org/springframework/data/cassandra/config/AbstractCassandraConfiguration.java @@ -26,6 +26,7 @@ import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.data.annotation.Persistent; import org.springframework.data.cassandra.convert.CassandraConverter; import org.springframework.data.cassandra.convert.MappingCassandraConverter; +import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.data.cassandra.core.CassandraTemplate; import org.springframework.data.cassandra.core.Keyspace; import org.springframework.data.cassandra.mapping.CassandraMappingContext; @@ -116,7 +117,7 @@ public abstract class AbstractCassandraConfiguration { * @throws Exception */ @Bean - public CassandraTemplate cassandraTemplate() throws Exception { + public CassandraOperations cassandraTemplate() throws Exception { return new CassandraTemplate(keyspace()); } diff --git a/src/test/java/org/springframework/data/cassandra/config/TestConfig.java b/src/test/java/org/springframework/data/cassandra/config/TestConfig.java index cb2f23829..4369a996c 100644 --- a/src/test/java/org/springframework/data/cassandra/config/TestConfig.java +++ b/src/test/java/org/springframework/data/cassandra/config/TestConfig.java @@ -3,6 +3,7 @@ package org.springframework.data.cassandra.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.cassandra.core.CassandraKeyspaceFactoryBean; +import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.data.cassandra.core.CassandraTemplate; import com.datastax.driver.core.Cluster; @@ -51,9 +52,9 @@ public class TestConfig extends AbstractCassandraConfiguration { } @Bean - public CassandraTemplate cassandraTemplate() { + public CassandraOperations cassandraTemplate() { - CassandraTemplate template = new CassandraTemplate(keyspaceFactoryBean().getObject()); + CassandraOperations template = new CassandraTemplate(keyspaceFactoryBean().getObject()); return template; diff --git a/src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTableTest.java b/src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTableTest.java index 105c4afa4..349aea9c4 100644 --- a/src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTableTest.java +++ b/src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTableTest.java @@ -64,7 +64,7 @@ public class CassandraOperationsTableTest { * Load data file to creat the test keyspace before we init the template */ DataLoader dataLoader = new DataLoader("Test Cluster", "localhost:9160"); - dataLoader.load(new ClassPathYamlDataSet("cassandra-data.yaml")); + dataLoader.load(new ClassPathYamlDataSet("cassandra-keyspace.yaml")); } @@ -75,7 +75,7 @@ public class CassandraOperationsTableTest { * Load data file to creat the test keyspace before we init the template */ DataLoader dataLoader = new DataLoader("Test Cluster", "localhost:9160"); - dataLoader.load(new ClassPathYamlDataSet("cassandra-data.yaml")); + dataLoader.load(new ClassPathYamlDataSet("cassandra-keyspace.yaml")); log.info("Creating Table..."); diff --git a/src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTest.java b/src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTest.java index e875bdb8c..14d426b40 100644 --- a/src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTest.java +++ b/src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTest.java @@ -25,20 +25,22 @@ 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.Before; 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.data.cassandra.config.TestConfig; -import org.springframework.data.cassandra.core.CassandraTemplate; +import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.data.cassandra.core.RingMember; import org.springframework.data.cassandra.table.LogEntry; import org.springframework.data.cassandra.table.User; @@ -46,8 +48,6 @@ 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.Session; - /** * @author David Webb * @@ -57,23 +57,27 @@ import com.datastax.driver.core.Session; public class CassandraOperationsTest { @Autowired - private CassandraTemplate cassandraTemplate; + private CassandraOperations cassandraTemplate; private static Logger log = LoggerFactory.getLogger(CassandraOperationsTest.class); - protected Session session; + private final static String KEYSPACE_NAME = "test"; + + @Rule + public CassandraCQLUnit cassandraCQLUnit = new CassandraCQLUnit(new ClassPathCQLDataSet("cql-dataload.cql", "test"), + "cassandra.yaml", "localhost", 9042); @BeforeClass public static void startCassandra() throws IOException, TTransportException, ConfigurationException, InterruptedException { + EmbeddedCassandraServerHelper.startEmbeddedCassandra("cassandra.yaml"); /* * Load data file to creat the test keyspace before we init the template */ DataLoader dataLoader = new DataLoader("Test Cluster", "localhost:9160"); - dataLoader.load(new ClassPathYamlDataSet("cassandra-data.yaml")); - + dataLoader.load(new ClassPathYamlDataSet("cassandra-keyspace.yaml")); } @Before @@ -82,15 +86,20 @@ public class CassandraOperationsTest { /* * Load data file to creat the test keyspace before we init the template */ - DataLoader dataLoader = new DataLoader("Test Cluster", "localhost:9160"); - dataLoader.load(new ClassPathYamlDataSet("cassandra-data.yaml")); + // DataLoader dataLoader = new DataLoader("Test Cluster", "localhost:9160"); + // dataLoader.load(new ClassPathYamlDataSet("cassandra-keyspace.yaml")); log.info("Creating Table..."); + createTables(); - // cassandraTemplate.createTable(User.class); + } - // cassandraTemplate.createTable(LogEntry.class); + private void createTables() { + // cassandraTemplate + // .executeQuery("create table users (username text, firstName text, lastName text, PRIMARY KEY (username));"); + + // cassandraCQLUnit. } @Test @@ -109,16 +118,7 @@ public class CassandraOperationsTest { } } - /** - * This test inserts and selects users from the test.users table This is testing the CassandraTemplate: - *
    - *
  • insert()
  • - *
  • selectOne()
  • - *
  • select()
  • - *
  • remove()
  • - *
- */ - // @Test + @Test public void UsersTest() { User u = new User(); @@ -165,7 +165,7 @@ public class CassandraOperationsTest { } - @After + // @After public void clearCassandra() { EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); @@ -173,6 +173,7 @@ public class CassandraOperationsTest { @AfterClass public static void stopCassandra() { + EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); EmbeddedCassandraServerHelper.stopEmbeddedCassandra(); } } diff --git a/src/test/resources/cassandra-data.yaml b/src/test/resources/cassandra-keyspace.yaml similarity index 100% rename from src/test/resources/cassandra-data.yaml rename to src/test/resources/cassandra-keyspace.yaml diff --git a/src/test/resources/cql-dataload.cql b/src/test/resources/cql-dataload.cql new file mode 100644 index 000000000..1e441fc91 --- /dev/null +++ b/src/test/resources/cql-dataload.cql @@ -0,0 +1 @@ +create table users (username text, firstName text, lastName text, age int, PRIMARY KEY (username)); \ No newline at end of file From 10e5241d0c8846d5a7132392619f408be8b71940 Mon Sep 17 00:00:00 2001 From: dwebb Date: Thu, 14 Nov 2013 17:00:45 -0500 Subject: [PATCH 4/4] wip: Update Operations test now passing. --- .../data/cassandra/util/CqlUtils.java | 2 +- .../data/cassandra/table/Book.java | 91 +++++++++++++++++++ .../template/CassandraOperationsTest.java | 61 +++---------- src/test/resources/cql-dataload.cql | 2 +- 4 files changed, 108 insertions(+), 48 deletions(-) create mode 100644 src/test/java/org/springframework/data/cassandra/table/Book.java diff --git a/src/main/java/org/springframework/data/cassandra/util/CqlUtils.java b/src/main/java/org/springframework/data/cassandra/util/CqlUtils.java index 5d333912c..86fff443c 100644 --- a/src/main/java/org/springframework/data/cassandra/util/CqlUtils.java +++ b/src/main/java/org/springframework/data/cassandra/util/CqlUtils.java @@ -300,7 +300,7 @@ public abstract class CqlUtils { if (prop.isIdProperty()) { q.where(QueryBuilder.eq(prop.getColumnName(), o)); } else { - q.with(QueryBuilder.add(prop.getColumnName(), o)); + q.with(QueryBuilder.set(prop.getColumnName(), o)); } } diff --git a/src/test/java/org/springframework/data/cassandra/table/Book.java b/src/test/java/org/springframework/data/cassandra/table/Book.java new file mode 100644 index 000000000..c2c0bae7b --- /dev/null +++ b/src/test/java/org/springframework/data/cassandra/table/Book.java @@ -0,0 +1,91 @@ +/* + * 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.table; + +import org.springframework.data.cassandra.mapping.RowId; +import org.springframework.data.cassandra.mapping.Table; + +/** + * @author David Webb + * + */ +@Table(name = "book") +public class Book { + + @RowId + 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; + } + +} diff --git a/src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTest.java b/src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTest.java index 14d426b40..f1de1124b 100644 --- a/src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTest.java +++ b/src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTest.java @@ -18,11 +18,8 @@ package org.springframework.data.cassandra.template; import static org.junit.Assert.assertNotNull; import java.io.IOException; -import java.util.Date; import java.util.List; -import junit.framework.Assert; - import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.thrift.transport.TTransportException; import org.cassandraunit.CassandraCQLUnit; @@ -30,6 +27,7 @@ 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.Before; import org.junit.BeforeClass; @@ -42,8 +40,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.cassandra.config.TestConfig; import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.data.cassandra.core.RingMember; -import org.springframework.data.cassandra.table.LogEntry; -import org.springframework.data.cassandra.table.User; +import org.springframework.data.cassandra.table.Book; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; @@ -119,53 +116,26 @@ public class CassandraOperationsTest { } @Test - public void UsersTest() { + public void insertTest() { - User u = new User(); - u.setUsername("cassandra"); - u.setFirstName("Apache"); - u.setLastName("Cassnadra"); - u.setAge(40); + /* + * Test Single Insert + */ + Book b = new Book(); + b.setIsbn("123456"); + b.setTitle("Spring Data Cassandra Guide"); + b.setAuthor("Cassandra Guru"); + b.setPages(521); - cassandraTemplate.insert(u, "users"); + cassandraTemplate.insert(b); - User us = cassandraTemplate.selectOne("select * from test.users where username='cassandra';", User.class); + b.setPages(245); - log.debug("Output from select One"); - log.debug(us.getFirstName()); - log.debug(us.getLastName()); - - List users = cassandraTemplate.select("Select * from test.users", User.class); - - log.debug("Output from select All"); - for (User x : users) { - log.debug(x.getFirstName()); - log.debug(x.getLastName()); - } - - cassandraTemplate.delete(u); - - User delUser = cassandraTemplate.selectOne("select * from test.users where username='cassandra';", User.class); - - log.info("delUser => " + delUser); - - Assert.assertNull(delUser); + cassandraTemplate.update(b); } - // @Test - public void multiplePKTest() { - - LogEntry l = new LogEntry(); - l.setLogDate(new Date()); - l.setHostname("localhost"); - l.setLogData("Host is Up"); - - cassandraTemplate.insert(l); - - } - - // @After + @After public void clearCassandra() { EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); @@ -173,7 +143,6 @@ public class CassandraOperationsTest { @AfterClass public static void stopCassandra() { - EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); EmbeddedCassandraServerHelper.stopEmbeddedCassandra(); } } diff --git a/src/test/resources/cql-dataload.cql b/src/test/resources/cql-dataload.cql index 1e441fc91..f7a2385f5 100644 --- a/src/test/resources/cql-dataload.cql +++ b/src/test/resources/cql-dataload.cql @@ -1 +1 @@ -create table users (username text, firstName text, lastName text, age int, PRIMARY KEY (username)); \ No newline at end of file +create table book (isbn text, title text, author text, pages int, PRIMARY KEY (isbn)); \ No newline at end of file