diff --git a/src/main/java/org/springframework/cassandra/core/CassandraOperations.java b/src/main/java/org/springframework/cassandra/core/CassandraOperations.java new file mode 100644 index 000000000..730f0b078 --- /dev/null +++ b/src/main/java/org/springframework/cassandra/core/CassandraOperations.java @@ -0,0 +1,75 @@ +/* + * 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.List; +import java.util.Map; + +import org.springframework.dao.DataAccessException; + +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.ResultSetFuture; + +/** + * Operations for interacting with Cassandra. These operations are used by the Repository implementation, but can also + * be used directly when that is desired by the developer. + * + * @author Alex Shvid + * @author David Webb + * @author Matthew Adams + * + */ +public interface CassandraOperations { + + T execute(SessionCallback sessionCallback); + + void execute(final String cql); + + RuntimeException potentiallyConvertRuntimeException(RuntimeException ex); + + T query(String cql, ResultSetExtractor rse) throws DataAccessException; + + void query(String cql, RowCallbackHandler rch) throws DataAccessException; + + List query(String cql, RowMapper rowMapper) throws DataAccessException; + + T queryForObject(String cql, RowMapper rowMapper) throws DataAccessException; + + T queryForObject(String cql, Class requiredType) throws DataAccessException; + + Map queryForMap(String cql) throws DataAccessException; + + List queryForList(String cql, Class elementType) throws DataAccessException; + + List> queryForList(String cql) throws DataAccessException; + + /** + * Execute query and return Cassandra ResultSet + * + * @param cql must not be {@literal null}. + * @return + */ + ResultSet executeQuery(final String cql); + + /** + * Execute async query and return Cassandra ResultSetFuture + * + * @param cql must not be {@literal null}. + * @return + */ + ResultSetFuture executeQueryAsynchronously(final String cql); + +} diff --git a/src/main/java/org/springframework/cassandra/core/CassandraTemplate.java b/src/main/java/org/springframework/cassandra/core/CassandraTemplate.java new file mode 100644 index 000000000..36122f9f8 --- /dev/null +++ b/src/main/java/org/springframework/cassandra/core/CassandraTemplate.java @@ -0,0 +1,299 @@ +/* + * 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.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.cassandra.support.CassandraAccessor; +import org.springframework.dao.DataAccessException; +import org.springframework.data.cassandra.core.CassandraDataTemplate; +import org.springframework.util.Assert; + +import com.datastax.driver.core.ColumnDefinitions; +import com.datastax.driver.core.ColumnDefinitions.Definition; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.ResultSetFuture; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.exceptions.DriverException; + +/** + * The CassandraTemplate is a Spring convenience wrapper for low level and explicit operations on the Cassandra + * Database. For working iwth POJOs, use the {@link CassandraDataTemplate} + * + * @author Alex Shvid + * @author David Webb + */ +public class CassandraTemplate extends CassandraAccessor implements CassandraOperations { + + /** + * Blank constructor. You must wire in the Session before use. + * + */ + public CassandraTemplate() { + } + + /** + * Constructor used for a basic template configuration + * + * @param session must not be {@literal null}. + */ + public CassandraTemplate(Session session) { + setSession(session); + afterPropertiesSet(); + } + + /* (non-Javadoc) + * @see org.springframework.data.cassandra.core.CassandraOperations#execute(org.springframework.data.cassandra.core.SessionCallback) + */ + @Override + public T execute(SessionCallback sessionCallback) { + return doExecute(sessionCallback); + } + + /* (non-Javadoc) + * @see org.springframework.data.cassandra.core.CassandraOperations#execute(java.lang.String) + */ + @Override + public void execute(final String cql) { + + doExecute(new SessionCallback() { + + @Override + public Object doInSession(Session s) throws DataAccessException { + return s.execute(cql); + } + }); + + } + + /* (non-Javadoc) + * @see org.springframework.data.cassandra.core.CassandraOperations#executeQuery(java.lang.String) + */ + @Override + public ResultSet executeQuery(final String query) { + + return doExecute(new SessionCallback() { + + @Override + public ResultSet doInSession(Session s) throws DataAccessException { + + return s.execute(query); + + } + + }); + + } + + /* (non-Javadoc) + * @see org.springframework.data.cassandra.core.CassandraOperations#executeQueryAsync(java.lang.String) + */ + @Override + public ResultSetFuture executeQueryAsynchronously(final String query) { + + return doExecute(new SessionCallback() { + + @Override + public ResultSetFuture doInSession(Session s) throws DataAccessException { + + return s.executeAsync(query); + + } + + }); + + } + + /** + * Attempt to translate a Runtime Exception to a Spring Data Exception + * + * @param ex + * @return + */ + public RuntimeException potentiallyConvertRuntimeException(RuntimeException ex) { + RuntimeException resolved = getExceptionTranslator().translateExceptionIfPossible(ex); + return resolved == null ? ex : resolved; + } + + /** + * Execute a command at the Session Level + * + * @param callback + * @return + */ + protected T doExecute(SessionCallback callback) { + + Assert.notNull(callback); + + try { + + return callback.doInSession(getSession()); + + } catch (DataAccessException e) { + throw potentiallyConvertRuntimeException(e); + } + } + + /* (non-Javadoc) + * @see org.springframework.cassandra.core.CassandraOperations#query(java.lang.String, org.springframework.cassandra.core.ResultSetExtractor) + */ + public T query(String cql, ResultSetExtractor rse) throws DataAccessException { + try { + ResultSet rs = getSession().execute(cql); + return rse.extractData(rs); + } catch (DriverException dx) { + throw getExceptionTranslator().translateExceptionIfPossible(dx); + } + } + + /* (non-Javadoc) + * @see org.springframework.cassandra.core.CassandraOperations#query(java.lang.String, org.springframework.cassandra.core.RowCallbackHandler) + */ + public void query(String cql, RowCallbackHandler rch) throws DataAccessException { + try { + ResultSet rs = getSession().execute(cql); + for (Row row : rs.all()) { + rch.processRow(row); + } + } catch (DriverException dx) { + throw getExceptionTranslator().translateExceptionIfPossible(dx); + } + + } + + /* (non-Javadoc) + * @see org.springframework.cassandra.core.CassandraOperations#query(java.lang.String, org.springframework.cassandra.core.RowMapper) + */ + public List query(String cql, RowMapper rowMapper) throws DataAccessException { + try { + ResultSet rs = getSession().execute(cql); + int i = 0; + List mappedRows = new ArrayList(); + for (Row row : rs.all()) { + mappedRows.add(rowMapper.mapRow(row, i++)); + } + return mappedRows; + } catch (DriverException dx) { + throw getExceptionTranslator().translateExceptionIfPossible(dx); + } + } + + /* (non-Javadoc) + * @see org.springframework.cassandra.core.CassandraOperations#queryForObject(java.lang.String, org.springframework.cassandra.core.RowMapper) + */ + public T queryForObject(String cql, RowMapper rowMapper) throws DataAccessException { + try { + ResultSet rs = getSession().execute(cql); + List rows = rs.all(); + Assert.notNull(rows, "null row list returned from query"); + Assert.isTrue(rows.size() == 1, "row list has " + rows.size() + " rows instead of one"); + return rowMapper.mapRow(rows.get(0), 0); + } catch (DriverException dx) { + throw getExceptionTranslator().translateExceptionIfPossible(dx); + } + } + + /* (non-Javadoc) + * @see org.springframework.cassandra.core.CassandraOperations#queryForObject(java.lang.String, java.lang.Class) + */ + @SuppressWarnings("unchecked") + public T queryForObject(String cql, Class requiredType) throws DataAccessException { + ResultSet rs = getSession().execute(cql); + if (rs == null) { + return null; + } + Row row = rs.one(); + if (row == null) { + return null; + } + return (T) firstColumnToObject(row); + } + + /** + * @param row + * @return + */ + protected Object firstColumnToObject(Row row) { + ColumnDefinitions cols = row.getColumnDefinitions(); + if (cols.size() == 0) { + return null; + } + return cols.getType(0).deserialize(row.getBytesUnsafe(0)); + } + + /* (non-Javadoc) + * @see org.springframework.cassandra.core.CassandraOperations#queryForMap(java.lang.String) + */ + public Map queryForMap(String cql) throws DataAccessException { + ResultSet rs = getSession().execute(cql); + if (rs == null) { + return null; + } + return toMap(rs.one()); + } + + /** + * @param row + * @return + */ + protected Map toMap(Row row) { + if (row == null) { + return null; + } + + ColumnDefinitions cols = row.getColumnDefinitions(); + Map map = new HashMap(cols.size()); + + for (Definition def : cols.asList()) { + String name = def.getName(); + map.put(name, def.getType().deserialize(row.getBytesUnsafe(name))); + } + + return map; + } + + /* (non-Javadoc) + * @see org.springframework.cassandra.core.CassandraOperations#queryForList(java.lang.String, java.lang.Class) + */ + @SuppressWarnings("unchecked") + public List queryForList(String cql, Class elementType) throws DataAccessException { + ResultSet rs = getSession().execute(cql); + List rows = rs.all(); + List list = new ArrayList(rows.size()); + for (Row row : rows) { + list.add((T) firstColumnToObject(row)); + } + return list; + } + + /* (non-Javadoc) + * @see org.springframework.cassandra.core.CassandraOperations#queryForList(java.lang.String) + */ + public List> queryForList(String cql) throws DataAccessException { + ResultSet rs = getSession().execute(cql); + List rows = rs.all(); + List> list = new ArrayList>(rows.size()); + for (Row row : rows) { + list.add(toMap(row)); + } + return list; + } + +} diff --git a/src/main/java/org/springframework/cassandra/core/ResultSetExtractor.java b/src/main/java/org/springframework/cassandra/core/ResultSetExtractor.java new file mode 100644 index 000000000..94b03aae9 --- /dev/null +++ b/src/main/java/org/springframework/cassandra/core/ResultSetExtractor.java @@ -0,0 +1,11 @@ +package org.springframework.cassandra.core; + +import org.springframework.dao.DataAccessException; + +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.exceptions.DriverException; + +public interface ResultSetExtractor { + + T extractData(ResultSet rs) throws DriverException, DataAccessException; +} diff --git a/src/main/java/org/springframework/data/cassandra/core/RowCallback.java b/src/main/java/org/springframework/cassandra/core/RowCallback.java similarity index 94% rename from src/main/java/org/springframework/data/cassandra/core/RowCallback.java rename to src/main/java/org/springframework/cassandra/core/RowCallback.java index 77127383d..57b12493f 100644 --- a/src/main/java/org/springframework/data/cassandra/core/RowCallback.java +++ b/src/main/java/org/springframework/cassandra/core/RowCallback.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.cassandra.core; +package org.springframework.cassandra.core; import com.datastax.driver.core.Row; diff --git a/src/main/java/org/springframework/cassandra/core/RowCallbackHandler.java b/src/main/java/org/springframework/cassandra/core/RowCallbackHandler.java new file mode 100644 index 000000000..8eaf6da8e --- /dev/null +++ b/src/main/java/org/springframework/cassandra/core/RowCallbackHandler.java @@ -0,0 +1,10 @@ +package org.springframework.cassandra.core; + +import com.datastax.driver.core.Row; +import com.datastax.driver.core.exceptions.DriverException; + +public interface RowCallbackHandler { + + void processRow(Row row) throws DriverException; + +} diff --git a/src/main/java/org/springframework/cassandra/core/RowMapper.java b/src/main/java/org/springframework/cassandra/core/RowMapper.java new file mode 100644 index 000000000..4de62c128 --- /dev/null +++ b/src/main/java/org/springframework/cassandra/core/RowMapper.java @@ -0,0 +1,10 @@ +package org.springframework.cassandra.core; + +import com.datastax.driver.core.Row; +import com.datastax.driver.core.exceptions.DriverException; + +public interface RowMapper { + + T mapRow(Row row, int rowNum) throws DriverException; + +} diff --git a/src/main/java/org/springframework/data/cassandra/core/SessionCallback.java b/src/main/java/org/springframework/cassandra/core/SessionCallback.java similarity index 90% rename from src/main/java/org/springframework/data/cassandra/core/SessionCallback.java rename to src/main/java/org/springframework/cassandra/core/SessionCallback.java index 918c7b42b..96a8d8167 100644 --- a/src/main/java/org/springframework/data/cassandra/core/SessionCallback.java +++ b/src/main/java/org/springframework/cassandra/core/SessionCallback.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.cassandra.core; +package org.springframework.cassandra.core; import org.springframework.dao.DataAccessException; import com.datastax.driver.core.Session; /** - * Interface for operations on a Cassnadra Session. + * Interface for operations on a Cassandra Session. * * @author David Webb * diff --git a/src/main/java/org/springframework/cassandra/core/SessionFactoryBean.java b/src/main/java/org/springframework/cassandra/core/SessionFactoryBean.java new file mode 100644 index 000000000..c930c9f2d --- /dev/null +++ b/src/main/java/org/springframework/cassandra/core/SessionFactoryBean.java @@ -0,0 +1,87 @@ +/* + * Copyright 2011-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cassandra.core; + +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.data.cassandra.core.Keyspace; + +import com.datastax.driver.core.Session; + +/** + * @author David Webb + * + */ +public class SessionFactoryBean implements FactoryBean, InitializingBean { + + private Keyspace keyspace; + + public SessionFactoryBean() { + } + + public SessionFactoryBean(Keyspace keyspace) { + setKeyspace(keyspace); + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() + */ + @Override + public void afterPropertiesSet() throws Exception { + if (keyspace == null) { + throw new IllegalStateException("Keyspace required."); + } + } + + /** + * @return Returns the keyspace. + */ + public Keyspace getKeyspace() { + return keyspace; + } + + /** + * @param keyspace The keyspace to set. + */ + public void setKeyspace(Keyspace keyspace) { + this.keyspace = keyspace; + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#getObject() + */ + @Override + public Session getObject() throws Exception { + return keyspace.getSession(); + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#getObjectType() + */ + @Override + public Class getObjectType() { + return Session.class; + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#isSingleton() + */ + @Override + public boolean isSingleton() { + return true; + } + +} diff --git a/src/main/java/org/springframework/cassandra/support/CassandraAccessor.java b/src/main/java/org/springframework/cassandra/support/CassandraAccessor.java new file mode 100644 index 000000000..acc5db9af --- /dev/null +++ b/src/main/java/org/springframework/cassandra/support/CassandraAccessor.java @@ -0,0 +1,76 @@ +/* + * 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.support; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.InitializingBean; + +import com.datastax.driver.core.Session; + +/** + * @author David Webb + * + */ +public class CassandraAccessor implements InitializingBean { + + /** Logger available to subclasses */ + protected final Log logger = LogFactory.getLog(getClass()); + + private Session session; + + private CassandraExceptionTranslator exceptionTranslator; + + /** + * Set the exception translator for this instance. + * + * @see org.springframework.cassandra.support.CassandraExceptionTranslator + */ + public void setExceptionTranslator(CassandraExceptionTranslator exceptionTranslator) { + this.exceptionTranslator = exceptionTranslator; + } + + /** + * Return the exception translator for this instance. + */ + public synchronized CassandraExceptionTranslator getExceptionTranslator() { + return this.exceptionTranslator; + } + + /** + * Ensure that the Cassandra Session has been set + */ + public void afterPropertiesSet() { + if (getSession() == null) { + throw new IllegalArgumentException("Property 'session' is required"); + } + } + + /** + * @return Returns the session. + */ + public Session getSession() { + return session; + } + + /** + * @param session The session to set. + */ + public void setSession(Session session) { + this.session = session; + } + +} diff --git a/src/main/java/org/springframework/data/cassandra/core/CassandraExceptionTranslator.java b/src/main/java/org/springframework/cassandra/support/CassandraExceptionTranslator.java similarity index 76% rename from src/main/java/org/springframework/data/cassandra/core/CassandraExceptionTranslator.java rename to src/main/java/org/springframework/cassandra/support/CassandraExceptionTranslator.java index b16159b4b..1733e2b76 100644 --- a/src/main/java/org/springframework/data/cassandra/core/CassandraExceptionTranslator.java +++ b/src/main/java/org/springframework/cassandra/support/CassandraExceptionTranslator.java @@ -13,26 +13,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.cassandra.core; +package org.springframework.cassandra.support; +import org.springframework.cassandra.support.exception.CassandraAuthenticationException; +import org.springframework.cassandra.support.exception.CassandraConnectionFailureException; +import org.springframework.cassandra.support.exception.CassandraInsufficientReplicasAvailableException; +import org.springframework.cassandra.support.exception.CassandraInternalException; +import org.springframework.cassandra.support.exception.CassandraInvalidConfigurationInQueryException; +import org.springframework.cassandra.support.exception.CassandraInvalidQueryException; +import org.springframework.cassandra.support.exception.CassandraKeyspaceExistsException; +import org.springframework.cassandra.support.exception.CassandraQuerySyntaxException; +import org.springframework.cassandra.support.exception.CassandraReadTimeoutException; +import org.springframework.cassandra.support.exception.CassandraTableExistsException; +import org.springframework.cassandra.support.exception.CassandraTraceRetrievalException; +import org.springframework.cassandra.support.exception.CassandraTruncateException; +import org.springframework.cassandra.support.exception.CassandraTypeMismatchException; +import org.springframework.cassandra.support.exception.CassandraUnauthorizedException; +import org.springframework.cassandra.support.exception.CassandraUncategorizedException; +import org.springframework.cassandra.support.exception.CassandraWriteTimeoutException; import org.springframework.dao.DataAccessException; import org.springframework.dao.support.PersistenceExceptionTranslator; -import org.springframework.data.cassandra.core.exceptions.CassandraAuthenticationException; -import org.springframework.data.cassandra.core.exceptions.CassandraConnectionFailureException; -import org.springframework.data.cassandra.core.exceptions.CassandraInsufficientReplicasAvailableException; -import org.springframework.data.cassandra.core.exceptions.CassandraInternalException; -import org.springframework.data.cassandra.core.exceptions.CassandraInvalidConfigurationInQueryException; -import org.springframework.data.cassandra.core.exceptions.CassandraInvalidQueryException; -import org.springframework.data.cassandra.core.exceptions.CassandraKeyspaceExistsException; -import org.springframework.data.cassandra.core.exceptions.CassandraQuerySyntaxException; -import org.springframework.data.cassandra.core.exceptions.CassandraReadTimeoutException; -import org.springframework.data.cassandra.core.exceptions.CassandraTableExistsException; -import org.springframework.data.cassandra.core.exceptions.CassandraTraceRetrievalException; -import org.springframework.data.cassandra.core.exceptions.CassandraTruncateException; -import org.springframework.data.cassandra.core.exceptions.CassandraTypeMismatchException; -import org.springframework.data.cassandra.core.exceptions.CassandraUnauthorizedException; -import org.springframework.data.cassandra.core.exceptions.CassandraUncategorizedException; -import org.springframework.data.cassandra.core.exceptions.CassandraWriteTimeoutException; import com.datastax.driver.core.WriteType; import com.datastax.driver.core.exceptions.AlreadyExistsException; diff --git a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraAuthenticationException.java b/src/main/java/org/springframework/cassandra/support/exception/CassandraAuthenticationException.java similarity index 95% rename from src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraAuthenticationException.java rename to src/main/java/org/springframework/cassandra/support/exception/CassandraAuthenticationException.java index 19aa8c3be..9e5a57153 100644 --- a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraAuthenticationException.java +++ b/src/main/java/org/springframework/cassandra/support/exception/CassandraAuthenticationException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.cassandra.core.exceptions; +package org.springframework.cassandra.support.exception; import java.net.InetAddress; diff --git a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraConnectionFailureException.java b/src/main/java/org/springframework/cassandra/support/exception/CassandraConnectionFailureException.java similarity index 96% rename from src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraConnectionFailureException.java rename to src/main/java/org/springframework/cassandra/support/exception/CassandraConnectionFailureException.java index a23facb20..633ad8b6b 100644 --- a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraConnectionFailureException.java +++ b/src/main/java/org/springframework/cassandra/support/exception/CassandraConnectionFailureException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.cassandra.core.exceptions; +package org.springframework.cassandra.support.exception; import java.net.InetAddress; import java.util.Collections; diff --git a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraInsufficientReplicasAvailableException.java b/src/main/java/org/springframework/cassandra/support/exception/CassandraInsufficientReplicasAvailableException.java similarity index 96% rename from src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraInsufficientReplicasAvailableException.java rename to src/main/java/org/springframework/cassandra/support/exception/CassandraInsufficientReplicasAvailableException.java index 8b30e8596..7072fd9fe 100644 --- a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraInsufficientReplicasAvailableException.java +++ b/src/main/java/org/springframework/cassandra/support/exception/CassandraInsufficientReplicasAvailableException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.cassandra.core.exceptions; +package org.springframework.cassandra.support.exception; import org.springframework.dao.TransientDataAccessException; diff --git a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraInternalException.java b/src/main/java/org/springframework/cassandra/support/exception/CassandraInternalException.java similarity index 94% rename from src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraInternalException.java rename to src/main/java/org/springframework/cassandra/support/exception/CassandraInternalException.java index 380ba56e1..1da76f11b 100644 --- a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraInternalException.java +++ b/src/main/java/org/springframework/cassandra/support/exception/CassandraInternalException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.cassandra.core.exceptions; +package org.springframework.cassandra.support.exception; import org.springframework.dao.DataAccessException; diff --git a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraInvalidConfigurationInQueryException.java b/src/main/java/org/springframework/cassandra/support/exception/CassandraInvalidConfigurationInQueryException.java similarity index 95% rename from src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraInvalidConfigurationInQueryException.java rename to src/main/java/org/springframework/cassandra/support/exception/CassandraInvalidConfigurationInQueryException.java index 5fabd5745..ae29eff31 100644 --- a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraInvalidConfigurationInQueryException.java +++ b/src/main/java/org/springframework/cassandra/support/exception/CassandraInvalidConfigurationInQueryException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.cassandra.core.exceptions; +package org.springframework.cassandra.support.exception; import org.springframework.dao.InvalidDataAccessApiUsageException; diff --git a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraInvalidQueryException.java b/src/main/java/org/springframework/cassandra/support/exception/CassandraInvalidQueryException.java similarity index 95% rename from src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraInvalidQueryException.java rename to src/main/java/org/springframework/cassandra/support/exception/CassandraInvalidQueryException.java index 1591e61b3..3ee84ac47 100644 --- a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraInvalidQueryException.java +++ b/src/main/java/org/springframework/cassandra/support/exception/CassandraInvalidQueryException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.cassandra.core.exceptions; +package org.springframework.cassandra.support.exception; import org.springframework.dao.InvalidDataAccessApiUsageException; diff --git a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraKeyspaceExistsException.java b/src/main/java/org/springframework/cassandra/support/exception/CassandraKeyspaceExistsException.java similarity index 95% rename from src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraKeyspaceExistsException.java rename to src/main/java/org/springframework/cassandra/support/exception/CassandraKeyspaceExistsException.java index a6fa952a2..5fd297e3b 100644 --- a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraKeyspaceExistsException.java +++ b/src/main/java/org/springframework/cassandra/support/exception/CassandraKeyspaceExistsException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.cassandra.core.exceptions; +package org.springframework.cassandra.support.exception; /** * Spring data access exception for Cassandra when a keyspace being created already exists. diff --git a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraQuerySyntaxException.java b/src/main/java/org/springframework/cassandra/support/exception/CassandraQuerySyntaxException.java similarity index 94% rename from src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraQuerySyntaxException.java rename to src/main/java/org/springframework/cassandra/support/exception/CassandraQuerySyntaxException.java index 949d550c5..8cbc1d979 100644 --- a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraQuerySyntaxException.java +++ b/src/main/java/org/springframework/cassandra/support/exception/CassandraQuerySyntaxException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.cassandra.core.exceptions; +package org.springframework.cassandra.support.exception; import org.springframework.dao.InvalidDataAccessApiUsageException; diff --git a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraReadTimeoutException.java b/src/main/java/org/springframework/cassandra/support/exception/CassandraReadTimeoutException.java similarity index 95% rename from src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraReadTimeoutException.java rename to src/main/java/org/springframework/cassandra/support/exception/CassandraReadTimeoutException.java index da695656e..a2bff225f 100644 --- a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraReadTimeoutException.java +++ b/src/main/java/org/springframework/cassandra/support/exception/CassandraReadTimeoutException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.cassandra.core.exceptions; +package org.springframework.cassandra.support.exception; import org.springframework.dao.QueryTimeoutException; diff --git a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraSchemaElementExistsException.java b/src/main/java/org/springframework/cassandra/support/exception/CassandraSchemaElementExistsException.java similarity index 96% rename from src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraSchemaElementExistsException.java rename to src/main/java/org/springframework/cassandra/support/exception/CassandraSchemaElementExistsException.java index a94c37eee..79d981190 100644 --- a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraSchemaElementExistsException.java +++ b/src/main/java/org/springframework/cassandra/support/exception/CassandraSchemaElementExistsException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.cassandra.core.exceptions; +package org.springframework.cassandra.support.exception; import org.springframework.dao.NonTransientDataAccessException; diff --git a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraTableExistsException.java b/src/main/java/org/springframework/cassandra/support/exception/CassandraTableExistsException.java similarity index 94% rename from src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraTableExistsException.java rename to src/main/java/org/springframework/cassandra/support/exception/CassandraTableExistsException.java index a8f0fb13d..7c23f242a 100644 --- a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraTableExistsException.java +++ b/src/main/java/org/springframework/cassandra/support/exception/CassandraTableExistsException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.cassandra.core.exceptions; +package org.springframework.cassandra.support.exception; /** * Spring data access exception for when a Cassandra table being created already exists. diff --git a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraTraceRetrievalException.java b/src/main/java/org/springframework/cassandra/support/exception/CassandraTraceRetrievalException.java similarity index 94% rename from src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraTraceRetrievalException.java rename to src/main/java/org/springframework/cassandra/support/exception/CassandraTraceRetrievalException.java index 456db7495..9dc700a83 100644 --- a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraTraceRetrievalException.java +++ b/src/main/java/org/springframework/cassandra/support/exception/CassandraTraceRetrievalException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.cassandra.core.exceptions; +package org.springframework.cassandra.support.exception; import org.springframework.dao.TransientDataAccessException; diff --git a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraTruncateException.java b/src/main/java/org/springframework/cassandra/support/exception/CassandraTruncateException.java similarity index 94% rename from src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraTruncateException.java rename to src/main/java/org/springframework/cassandra/support/exception/CassandraTruncateException.java index 71834c1a7..fe7d18205 100644 --- a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraTruncateException.java +++ b/src/main/java/org/springframework/cassandra/support/exception/CassandraTruncateException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.cassandra.core.exceptions; +package org.springframework.cassandra.support.exception; import org.springframework.dao.TransientDataAccessException; diff --git a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraTypeMismatchException.java b/src/main/java/org/springframework/cassandra/support/exception/CassandraTypeMismatchException.java similarity index 94% rename from src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraTypeMismatchException.java rename to src/main/java/org/springframework/cassandra/support/exception/CassandraTypeMismatchException.java index bc8c08e1c..972aa01e7 100644 --- a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraTypeMismatchException.java +++ b/src/main/java/org/springframework/cassandra/support/exception/CassandraTypeMismatchException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.cassandra.core.exceptions; +package org.springframework.cassandra.support.exception; import org.springframework.dao.TypeMismatchDataAccessException; diff --git a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraUnauthorizedException.java b/src/main/java/org/springframework/cassandra/support/exception/CassandraUnauthorizedException.java similarity index 94% rename from src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraUnauthorizedException.java rename to src/main/java/org/springframework/cassandra/support/exception/CassandraUnauthorizedException.java index 74da9ef2a..7893b8b93 100644 --- a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraUnauthorizedException.java +++ b/src/main/java/org/springframework/cassandra/support/exception/CassandraUnauthorizedException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.cassandra.core.exceptions; +package org.springframework.cassandra.support.exception; import org.springframework.dao.PermissionDeniedDataAccessException; diff --git a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraUncategorizedException.java b/src/main/java/org/springframework/cassandra/support/exception/CassandraUncategorizedException.java similarity index 94% rename from src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraUncategorizedException.java rename to src/main/java/org/springframework/cassandra/support/exception/CassandraUncategorizedException.java index ecab6d54b..f3ee3c9b6 100644 --- a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraUncategorizedException.java +++ b/src/main/java/org/springframework/cassandra/support/exception/CassandraUncategorizedException.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.cassandra.core.exceptions; +package org.springframework.cassandra.support.exception; import org.springframework.dao.UncategorizedDataAccessException; diff --git a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraWriteTimeoutException.java b/src/main/java/org/springframework/cassandra/support/exception/CassandraWriteTimeoutException.java similarity index 95% rename from src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraWriteTimeoutException.java rename to src/main/java/org/springframework/cassandra/support/exception/CassandraWriteTimeoutException.java index d7ab05240..2836668df 100644 --- a/src/main/java/org/springframework/data/cassandra/core/exceptions/CassandraWriteTimeoutException.java +++ b/src/main/java/org/springframework/cassandra/support/exception/CassandraWriteTimeoutException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.cassandra.core.exceptions; +package org.springframework.cassandra.support.exception; import org.springframework.dao.QueryTimeoutException; 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 fe0a1c79a..9b9cb50bd 100644 --- a/src/main/java/org/springframework/data/cassandra/config/AbstractCassandraConfiguration.java +++ b/src/main/java/org/springframework/data/cassandra/config/AbstractCassandraConfiguration.java @@ -20,6 +20,8 @@ import java.util.Set; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.cassandra.core.CassandraOperations; +import org.springframework.cassandra.core.CassandraTemplate; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.context.annotation.Configuration; @@ -29,8 +31,6 @@ import org.springframework.data.cassandra.convert.CassandraConverter; import org.springframework.data.cassandra.convert.MappingCassandraConverter; import org.springframework.data.cassandra.core.CassandraAdminOperations; import org.springframework.data.cassandra.core.CassandraAdminTemplate; -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; import org.springframework.data.cassandra.mapping.CassandraPersistentEntity; @@ -127,7 +127,7 @@ public abstract class AbstractCassandraConfiguration implements BeanClassLoaderA */ @Bean public CassandraOperations cassandraTemplate() throws Exception { - return new CassandraTemplate(keyspace()); + return new CassandraTemplate(session()); } /** diff --git a/src/main/java/org/springframework/data/cassandra/config/BeanNames.java b/src/main/java/org/springframework/data/cassandra/config/BeanNames.java index 588e6f3b4..762b206fe 100644 --- a/src/main/java/org/springframework/data/cassandra/config/BeanNames.java +++ b/src/main/java/org/springframework/data/cassandra/config/BeanNames.java @@ -17,6 +17,7 @@ package org.springframework.data.cassandra.config; /** * @author Alex Shvid + * @author David Webb */ public final class BeanNames { @@ -25,5 +26,6 @@ public final class BeanNames { public static final String CASSANDRA_CLUSTER = "cassandra-cluster"; public static final String CASSANDRA_KEYSPACE = "cassandra-keyspace"; + public static final String CASSANDRA_SESSION = "cassandra-session"; } diff --git a/src/main/java/org/springframework/data/cassandra/config/CassandraNamespaceHandler.java b/src/main/java/org/springframework/data/cassandra/config/CassandraNamespaceHandler.java index a5def8d97..c69c39cf6 100644 --- a/src/main/java/org/springframework/data/cassandra/config/CassandraNamespaceHandler.java +++ b/src/main/java/org/springframework/data/cassandra/config/CassandraNamespaceHandler.java @@ -29,6 +29,7 @@ public class CassandraNamespaceHandler extends NamespaceHandlerSupport { registerBeanDefinitionParser("cluster", new CassandraClusterParser()); registerBeanDefinitionParser("keyspace", new CassandraKeyspaceParser()); + registerBeanDefinitionParser("session", new CassandraSessionParser()); } diff --git a/src/main/java/org/springframework/data/cassandra/config/CassandraSessionParser.java b/src/main/java/org/springframework/data/cassandra/config/CassandraSessionParser.java new file mode 100644 index 000000000..f99cfb5bf --- /dev/null +++ b/src/main/java/org/springframework/data/cassandra/config/CassandraSessionParser.java @@ -0,0 +1,69 @@ +/* + * Copyright 2011-2012 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.config; + +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.cassandra.core.SessionFactoryBean; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * Parser for <session;gt; definitions. + * + * @author David Webb + */ + +public class CassandraSessionParser extends AbstractSimpleBeanDefinitionParser { + + @Override + protected Class getBeanClass(Element element) { + return SessionFactoryBean.class; + } + + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.factory.xml.ParserContext) + */ + @Override + protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) + throws BeanDefinitionStoreException { + + String id = super.resolveId(element, definition, parserContext); + return StringUtils.hasText(id) ? id : BeanNames.CASSANDRA_SESSION; + } + + @Override + protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { + + String keyspaceRef = element.getAttribute("cassandra-keyspace-ref"); + if (!StringUtils.hasText(keyspaceRef)) { + keyspaceRef = BeanNames.CASSANDRA_KEYSPACE; + } + builder.addPropertyReference("keyspace", keyspaceRef); + + postProcess(builder, element); + } + + @Override + protected void postProcess(BeanDefinitionBuilder builder, Element element) { + + } + +} diff --git a/src/main/java/org/springframework/data/cassandra/core/CassandraAdminTemplate.java b/src/main/java/org/springframework/data/cassandra/core/CassandraAdminTemplate.java index b17d12a21..83e51c2a8 100644 --- a/src/main/java/org/springframework/data/cassandra/core/CassandraAdminTemplate.java +++ b/src/main/java/org/springframework/data/cassandra/core/CassandraAdminTemplate.java @@ -5,11 +5,13 @@ import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.cassandra.core.SessionCallback; +import org.springframework.cassandra.support.CassandraExceptionTranslator; +import org.springframework.cassandra.support.exception.CassandraTableExistsException; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.data.cassandra.convert.CassandraConverter; -import org.springframework.data.cassandra.core.exceptions.CassandraTableExistsException; import org.springframework.data.cassandra.mapping.CassandraPersistentEntity; import org.springframework.data.cassandra.mapping.CassandraPersistentProperty; import org.springframework.data.cassandra.util.CqlUtils; diff --git a/src/main/java/org/springframework/data/cassandra/core/CassandraClusterFactoryBean.java b/src/main/java/org/springframework/data/cassandra/core/CassandraClusterFactoryBean.java index 456bfd5b0..5221028cb 100644 --- a/src/main/java/org/springframework/data/cassandra/core/CassandraClusterFactoryBean.java +++ b/src/main/java/org/springframework/data/cassandra/core/CassandraClusterFactoryBean.java @@ -18,6 +18,7 @@ package org.springframework.data.cassandra.core; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; +import org.springframework.cassandra.support.CassandraExceptionTranslator; import org.springframework.dao.DataAccessException; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.data.cassandra.config.CompressionType; diff --git a/src/main/java/org/springframework/data/cassandra/core/CassandraOperations.java b/src/main/java/org/springframework/data/cassandra/core/CassandraDataOperations.java similarity index 95% rename from src/main/java/org/springframework/data/cassandra/core/CassandraOperations.java rename to src/main/java/org/springframework/data/cassandra/core/CassandraDataOperations.java index 98f512fd3..780db138d 100644 --- a/src/main/java/org/springframework/data/cassandra/core/CassandraOperations.java +++ b/src/main/java/org/springframework/data/cassandra/core/CassandraDataOperations.java @@ -20,8 +20,6 @@ import java.util.Map; import org.springframework.data.cassandra.convert.CassandraConverter; -import com.datastax.driver.core.ResultSet; -import com.datastax.driver.core.ResultSetFuture; import com.datastax.driver.core.querybuilder.Select; /** @@ -30,9 +28,10 @@ import com.datastax.driver.core.querybuilder.Select; * * @author Alex Shvid * @author David Webb + * @author Matthew Adams * */ -public interface CassandraOperations { +public interface CassandraDataOperations { /** * Describe the current Ring @@ -49,22 +48,6 @@ public interface CassandraOperations { */ String getTableName(Class entityClass); - /** - * Execute query and return Cassandra ResultSet - * - * @param query must not be {@literal null}. - * @return - */ - ResultSet executeQuery(final String query); - - /** - * Execute async query and return Cassandra ResultSetFuture - * - * @param query must not be {@literal null}. - * @return - */ - ResultSetFuture executeQueryAsynchronously(final String query); - /** * Execute query and convert ResultSet to the list of entities * @@ -72,7 +55,7 @@ public interface CassandraOperations { * @param selectClass must not be {@literal null}, mapped entity type. * @return */ - List selectByCQL(String query, Class selectClass); + List select(String cql, Class selectClass); /** * Execute query and convert ResultSet to the entity @@ -81,12 +64,14 @@ public interface CassandraOperations { * @param selectClass must not be {@literal null}, mapped entity type. * @return */ - T selectOneByCQL(String query, Class selectClass); + T selectOne(String cql, Class selectClass); List select(Select selectQuery, Class selectClass); T selectOne(Select selectQuery, Class selectClass); + Long count(Select selectQuery); + /** * Insert the given object to the table by id. * diff --git a/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java b/src/main/java/org/springframework/data/cassandra/core/CassandraDataTemplate.java similarity index 87% rename from src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java rename to src/main/java/org/springframework/data/cassandra/core/CassandraDataTemplate.java index 598730268..122865606 100644 --- a/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java +++ b/src/main/java/org/springframework/data/cassandra/core/CassandraDataTemplate.java @@ -25,12 +25,11 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.springframework.cassandra.core.CassandraTemplate; +import org.springframework.cassandra.core.SessionCallback; import org.springframework.dao.DataAccessException; import org.springframework.dao.DuplicateKeyException; import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.data.cassandra.convert.CassandraConverter; import org.springframework.data.cassandra.exception.EntityWriterException; import org.springframework.data.cassandra.mapping.CassandraPersistentEntity; @@ -43,23 +42,29 @@ import com.datastax.driver.core.Host; import com.datastax.driver.core.Metadata; import com.datastax.driver.core.Query; import com.datastax.driver.core.ResultSet; -import com.datastax.driver.core.ResultSetFuture; import com.datastax.driver.core.Row; import com.datastax.driver.core.Session; import com.datastax.driver.core.querybuilder.Batch; import com.datastax.driver.core.querybuilder.Select; /** - * The Cassandra Template is a convenience API for all Cassnadra DML Operations. + * The Cassandra Data Template is a convenience API for all Cassandra Operations using POJOs. This is the "Spring Data" + * flavor of the template. For low level Cassandra Operations use the {@link CassandraTemplate} * * @author Alex Shvid * @author David Webb */ -public class CassandraTemplate implements CassandraOperations { +public class CassandraDataTemplate extends CassandraTemplate implements CassandraDataOperations { - private static Logger log = LoggerFactory.getLogger(CassandraTemplate.class); + /* + * Default Keyspace if none is passed in. + */ + private static final String KEYSPACE_DEFAULT = "system"; + + /* + * List of iterable classes when testing POJOs for specific operations. + */ public static final Collection ITERABLE_CLASSES; - static { Set iterableClasses = new HashSet(); @@ -70,24 +75,63 @@ public class CassandraTemplate implements CassandraOperations { ITERABLE_CLASSES = Collections.unmodifiableCollection(iterableClasses); } - private final Keyspace keyspace; - private final Session session; - private final CassandraConverter cassandraConverter; - private final MappingContext, CassandraPersistentProperty> mappingContext; - private final PersistenceExceptionTranslator exceptionTranslator = new CassandraExceptionTranslator(); + + /* + * Required elements for successful Template Operations. These can be set with the Constructor, or wired in + * later. + * + * TODO - DW - Discuss Autowiring these. + */ + private String keyspace; + private CassandraConverter cassandraConverter; + private MappingContext, CassandraPersistentProperty> mappingContext; + + /** + * Default Constructor for wiring in the required components later + */ + public CassandraDataTemplate() { + } + + /** + * Constructor if only session is known at time of Template Creation + * + * @param session must not be {@literal null} + */ + public CassandraDataTemplate(Session session) { + this(session, null, null); + } + + /** + * Constructor if only session and converter are known at time of Template Creation + * + * @param session must not be {@literal null} + * @param converter must not be {@literal null}. + */ + public CassandraDataTemplate(Session session, CassandraConverter converter) { + this(session, converter, null); + } /** * Constructor used for a basic template configuration * - * @param keyspace must not be {@literal null}. + * @param session must not be {@literal null}. + * @param converter must not be {@literal null}. */ - public CassandraTemplate(Keyspace keyspace) { - this.keyspace = keyspace; - this.session = keyspace.getSession(); - this.cassandraConverter = keyspace.getCassandraConverter(); + public CassandraDataTemplate(Session session, CassandraConverter converter, String keyspace) { + setSession(session); + this.keyspace = keyspace == null ? KEYSPACE_DEFAULT : keyspace; + this.cassandraConverter = converter; this.mappingContext = this.cassandraConverter.getMappingContext(); } + /* (non-Javadoc) + * @see org.springframework.data.cassandra.core.CassandraOperations#selectCount(com.datastax.driver.core.querybuilder.Select) + */ + @Override + public Long count(Select selectQuery) { + return doSelectCount(selectQuery); + } + /* (non-Javadoc) * @see org.springframework.data.cassandra.core.CassandraOperations#delete(java.util.List) */ @@ -332,7 +376,7 @@ public class CassandraTemplate implements CassandraOperations { /* * Get the cluster metadata for this session */ - Metadata clusterMetadata = execute(new SessionCallback() { + Metadata clusterMetadata = doExecute(new SessionCallback() { @Override public Metadata doInSession(Session s) throws DataAccessException { @@ -386,44 +430,6 @@ public class CassandraTemplate implements CassandraOperations { return entity.getTable(); } - /* (non-Javadoc) - * @see org.springframework.data.cassandra.core.CassandraOperations#executeQuery(java.lang.String) - */ - @Override - public ResultSet executeQuery(final String query) { - - return execute(new SessionCallback() { - - @Override - public ResultSet doInSession(Session s) throws DataAccessException { - - return s.execute(query); - - } - - }); - - } - - /* (non-Javadoc) - * @see org.springframework.data.cassandra.core.CassandraOperations#executeQueryAsync(java.lang.String) - */ - @Override - public ResultSetFuture executeQueryAsynchronously(final String query) { - - return execute(new SessionCallback() { - - @Override - public ResultSetFuture doInSession(Session s) throws DataAccessException { - - return s.executeAsync(query); - - } - - }); - - } - /* (non-Javadoc) * @see org.springframework.data.cassandra.core.CassandraOperations#getConverter() */ @@ -677,16 +683,16 @@ public class CassandraTemplate implements CassandraOperations { * @see org.springframework.data.cassandra.core.CassandraOperations#select(com.datastax.driver.core.querybuilder.Select, java.lang.Class) */ @Override - public List select(Select selectQuery, Class selectClass) { - return selectByCQL(selectQuery.getQueryString(), selectClass); + public List select(Select cql, Class selectClass) { + return select(cql.getQueryString(), selectClass); } /* (non-Javadoc) * @see org.springframework.data.cassandra.core.CassandraOperations#select(java.lang.String, java.lang.Class) */ @Override - public List selectByCQL(String query, Class selectClass) { - return doSelect(query, new ReadRowCallback(cassandraConverter, selectClass)); + public List select(String cql, Class selectClass) { + return doSelect(cql, new ReadRowCallback(cassandraConverter, selectClass)); } /* (non-Javadoc) @@ -694,15 +700,15 @@ public class CassandraTemplate implements CassandraOperations { */ @Override public T selectOne(Select selectQuery, Class selectClass) { - return selectOneByCQL(selectQuery.getQueryString(), selectClass); + return selectOne(selectQuery.getQueryString(), selectClass); } /* (non-Javadoc) * @see org.springframework.data.cassandra.core.CassandraOperations#selectOne(java.lang.String, java.lang.Class) */ @Override - public T selectOneByCQL(String query, Class selectClass) { - return doSelectOne(query, new ReadRowCallback(cassandraConverter, selectClass)); + public T selectOne(String cql, Class selectClass) { + return doSelectOne(cql, new ReadRowCallback(cassandraConverter, selectClass)); } /* (non-Javadoc) @@ -954,7 +960,7 @@ public class CassandraTemplate implements CassandraOperations { */ private List doSelect(final String query, ReadRowCallback readRowCallback) { - ResultSet resultSet = execute(new SessionCallback() { + ResultSet resultSet = doExecute(new SessionCallback() { @Override public ResultSet doInSession(Session s) throws DataAccessException { @@ -976,6 +982,36 @@ public class CassandraTemplate implements CassandraOperations { return result; } + /** + * @param selectQuery + * @return + */ + private Long doSelectCount(final Select query) { + + Long count = null; + + ResultSet resultSet = doExecute(new SessionCallback() { + + @Override + public ResultSet doInSession(Session s) throws DataAccessException { + return s.execute(query); + } + }); + + if (resultSet == null) { + return null; + } + + Iterator iterator = resultSet.iterator(); + while (iterator.hasNext()) { + Row row = iterator.next(); + count = row.getLong(0); + } + + return count; + + } + /** * @param query * @param readRowCallback @@ -986,7 +1022,7 @@ public class CassandraTemplate implements CassandraOperations { /* * Run the Query */ - ResultSet resultSet = execute(new SessionCallback() { + ResultSet resultSet = doExecute(new SessionCallback() { @Override public ResultSet doInSession(Session s) throws DataAccessException { @@ -1011,11 +1047,6 @@ public class CassandraTemplate implements CassandraOperations { return null; } - private RuntimeException potentiallyConvertRuntimeException(RuntimeException ex) { - RuntimeException resolved = this.exceptionTranslator.translateExceptionIfPossible(ex); - return resolved == null ? ex : resolved; - } - /** * Perform the deletion on a list of objects * @@ -1029,11 +1060,10 @@ public class CassandraTemplate implements CassandraOperations { try { - final Batch b = CqlUtils.toDeleteBatchQuery(keyspace.getKeyspace(), tableName, entities, optionsByName, - cassandraConverter); - log.info(b.toString()); + final Batch b = CqlUtils.toDeleteBatchQuery(keyspace, tableName, entities, optionsByName, cassandraConverter); + logger.info(b.toString()); - execute(new SessionCallback() { + doExecute(new SessionCallback() { @Override public Object doInSession(Session s) throws DataAccessException { @@ -1050,8 +1080,8 @@ public class CassandraTemplate implements CassandraOperations { }); } catch (EntityWriterException e) { - throw exceptionTranslator.translateExceptionIfPossible(new RuntimeException( - "Failed to translate Object to Query", e)); + throw getExceptionTranslator().translateExceptionIfPossible( + new RuntimeException("Failed to translate Object to Query", e)); } } @@ -1071,11 +1101,10 @@ public class CassandraTemplate implements CassandraOperations { try { - final Batch b = CqlUtils.toInsertBatchQuery(keyspace.getKeyspace(), tableName, entities, optionsByName, - cassandraConverter); - log.info(b.getQueryString()); + final Batch b = CqlUtils.toInsertBatchQuery(keyspace, tableName, entities, optionsByName, cassandraConverter); + logger.info(b.getQueryString()); - return execute(new SessionCallback>() { + return doExecute(new SessionCallback>() { @Override public List doInSession(Session s) throws DataAccessException { @@ -1092,8 +1121,8 @@ public class CassandraTemplate implements CassandraOperations { }); } catch (EntityWriterException e) { - throw exceptionTranslator.translateExceptionIfPossible(new RuntimeException( - "Failed to translate Object to Query", e)); + throw getExceptionTranslator().translateExceptionIfPossible( + new RuntimeException("Failed to translate Object to Query", e)); } } @@ -1113,11 +1142,10 @@ public class CassandraTemplate implements CassandraOperations { try { - final Batch b = CqlUtils.toUpdateBatchQuery(keyspace.getKeyspace(), tableName, entities, optionsByName, - cassandraConverter); - log.info(b.toString()); + final Batch b = CqlUtils.toUpdateBatchQuery(keyspace, tableName, entities, optionsByName, cassandraConverter); + logger.info(b.toString()); - return execute(new SessionCallback>() { + return doExecute(new SessionCallback>() { @Override public List doInSession(Session s) throws DataAccessException { @@ -1134,8 +1162,8 @@ public class CassandraTemplate implements CassandraOperations { }); } catch (EntityWriterException e) { - throw exceptionTranslator.translateExceptionIfPossible(new RuntimeException( - "Failed to translate Object to Query", e)); + throw getExceptionTranslator().translateExceptionIfPossible( + new RuntimeException("Failed to translate Object to Query", e)); } } @@ -1150,11 +1178,10 @@ public class CassandraTemplate implements CassandraOperations { try { - final Query q = CqlUtils.toDeleteQuery(keyspace.getKeyspace(), tableName, objectToRemove, optionsByName, - cassandraConverter); - log.info(q.toString()); + final Query q = CqlUtils.toDeleteQuery(keyspace, tableName, objectToRemove, optionsByName, cassandraConverter); + logger.info(q.toString()); - execute(new SessionCallback() { + doExecute(new SessionCallback() { @Override public Object doInSession(Session s) throws DataAccessException { @@ -1171,8 +1198,27 @@ public class CassandraTemplate implements CassandraOperations { }); } catch (EntityWriterException e) { - throw exceptionTranslator.translateExceptionIfPossible(new RuntimeException( - "Failed to translate Object to Query", e)); + throw getExceptionTranslator().translateExceptionIfPossible( + new RuntimeException("Failed to translate Object to Query", e)); + } + } + + /** + * Execute a command at the Session Level + * + * @param callback + * @return + */ + protected T doExecute(SessionCallback callback) { + + Assert.notNull(callback); + + try { + + return callback.doInSession(getSession()); + + } catch (DataAccessException e) { + throw potentiallyConvertRuntimeException(e); } } @@ -1187,17 +1233,16 @@ public class CassandraTemplate implements CassandraOperations { try { - final Query q = CqlUtils.toInsertQuery(keyspace.getKeyspace(), tableName, entity, optionsByName, - cassandraConverter); - log.info(q.toString()); + final Query q = CqlUtils.toInsertQuery(keyspace, tableName, entity, optionsByName, cassandraConverter); + logger.info(q.toString()); if (q.getConsistencyLevel() != null) { - log.info(q.getConsistencyLevel().name()); + logger.info(q.getConsistencyLevel().name()); } if (q.getRetryPolicy() != null) { - log.info(q.getRetryPolicy().toString()); + logger.info(q.getRetryPolicy().toString()); } - return execute(new SessionCallback() { + return doExecute(new SessionCallback() { @Override public T doInSession(Session s) throws DataAccessException { @@ -1214,8 +1259,8 @@ public class CassandraTemplate implements CassandraOperations { }); } catch (EntityWriterException e) { - throw exceptionTranslator.translateExceptionIfPossible(new RuntimeException( - "Failed to translate Object to Query", e)); + throw getExceptionTranslator().translateExceptionIfPossible( + new RuntimeException("Failed to translate Object to Query", e)); } } @@ -1234,11 +1279,10 @@ public class CassandraTemplate implements CassandraOperations { try { - final Query q = CqlUtils.toUpdateQuery(keyspace.getKeyspace(), tableName, entity, optionsByName, - cassandraConverter); - log.info(q.toString()); + final Query q = CqlUtils.toUpdateQuery(keyspace, tableName, entity, optionsByName, cassandraConverter); + logger.info(q.toString()); - return execute(new SessionCallback() { + return doExecute(new SessionCallback() { @Override public T doInSession(Session s) throws DataAccessException { @@ -1255,8 +1299,8 @@ public class CassandraTemplate implements CassandraOperations { }); } catch (EntityWriterException e) { - throw exceptionTranslator.translateExceptionIfPossible(new RuntimeException( - "Failed to translate Object to Query", e)); + throw getExceptionTranslator().translateExceptionIfPossible( + new RuntimeException("Failed to translate Object to Query", e)); } } @@ -1273,24 +1317,4 @@ public class CassandraTemplate implements CassandraOperations { } } } - - /** - * Execute a command at the Session Level - * - * @param callback - * @return - */ - protected T execute(SessionCallback callback) { - - Assert.notNull(callback); - - try { - - return callback.doInSession(session); - - } catch (DataAccessException e) { - throw potentiallyConvertRuntimeException(e); - } - } - } diff --git a/src/main/java/org/springframework/data/cassandra/core/CassandraKeyspaceFactoryBean.java b/src/main/java/org/springframework/data/cassandra/core/CassandraKeyspaceFactoryBean.java index eba2c00f6..82bd0e855 100644 --- a/src/main/java/org/springframework/data/cassandra/core/CassandraKeyspaceFactoryBean.java +++ b/src/main/java/org/springframework/data/cassandra/core/CassandraKeyspaceFactoryBean.java @@ -24,6 +24,7 @@ import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; +import org.springframework.cassandra.support.CassandraExceptionTranslator; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.dao.support.PersistenceExceptionTranslator; diff --git a/src/main/java/org/springframework/data/cassandra/core/ReadRowCallback.java b/src/main/java/org/springframework/data/cassandra/core/ReadRowCallback.java index bccc4ded7..a87050ebb 100644 --- a/src/main/java/org/springframework/data/cassandra/core/ReadRowCallback.java +++ b/src/main/java/org/springframework/data/cassandra/core/ReadRowCallback.java @@ -15,6 +15,7 @@ */ package org.springframework.data.cassandra.core; +import org.springframework.cassandra.core.RowCallback; import org.springframework.data.convert.EntityReader; import org.springframework.util.Assert; diff --git a/src/main/resources/org/springframework/data/cassandra/config/spring-cassandra-1.0.xsd b/src/main/resources/org/springframework/data/cassandra/config/spring-cassandra-1.0.xsd index e602807c2..72094d834 100644 --- a/src/main/resources/org/springframework/data/cassandra/config/spring-cassandra-1.0.xsd +++ b/src/main/resources/org/springframework/data/cassandra/config/spring-cassandra-1.0.xsd @@ -15,6 +15,20 @@ Defines the configuration elements for the Spring Data Cassandra support. ]]> + + + + + + + + + + + - + - + - + @@ -61,8 +76,7 @@ The port to connect to Cassandra server as native CQL client. Default is 9042 ]]> - + - + @@ -103,76 +117,81 @@ AuthInfoProvider implementation. - + - + - + - - + + - + - + - - + + - + - + - - + + - - + - - - + + + - + @@ -209,196 +228,227 @@ The reference to a CassandraConverter instance. Default is null. - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - + + - - - + + + - - - + + + - - - + + + - - + + - - + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - - - - - + + + + + + - - - - - - + + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - - - - + + + + + + + - - - - - + + + + - - - - - + + + + - - - + + + - - - - + + + - - - - - + + + + - - - + + + + + + + + + The name of the Session definition (by default + "cassandra-session") + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file 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 4369a996c..b72f71d4e 100644 --- a/src/test/java/org/springframework/data/cassandra/config/TestConfig.java +++ b/src/test/java/org/springframework/data/cassandra/config/TestConfig.java @@ -2,9 +2,9 @@ package org.springframework.data.cassandra.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.data.cassandra.core.CassandraDataOperations; +import org.springframework.data.cassandra.core.CassandraDataTemplate; 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; import com.datastax.driver.core.Cluster.Builder; @@ -52,9 +52,10 @@ public class TestConfig extends AbstractCassandraConfiguration { } @Bean - public CassandraOperations cassandraTemplate() { + public CassandraDataOperations cassandraDataTemplate() { - CassandraOperations template = new CassandraTemplate(keyspaceFactoryBean().getObject()); + CassandraDataOperations template = new CassandraDataTemplate(keyspaceFactoryBean().getObject().getSession(), + keyspaceFactoryBean().getObject().getCassandraConverter(), keyspaceFactoryBean().getObject().getKeyspace()); return template; diff --git a/src/test/java/org/springframework/data/cassandra/core/CassandraExceptionTranslatorTest.java b/src/test/java/org/springframework/data/cassandra/core/CassandraExceptionTranslatorTest.java index 414d9961c..931724cb5 100644 --- a/src/test/java/org/springframework/data/cassandra/core/CassandraExceptionTranslatorTest.java +++ b/src/test/java/org/springframework/data/cassandra/core/CassandraExceptionTranslatorTest.java @@ -5,12 +5,13 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import org.junit.Test; +import org.springframework.cassandra.support.CassandraExceptionTranslator; +import org.springframework.cassandra.support.exception.CassandraInvalidConfigurationInQueryException; +import org.springframework.cassandra.support.exception.CassandraInvalidQueryException; +import org.springframework.cassandra.support.exception.CassandraKeyspaceExistsException; +import org.springframework.cassandra.support.exception.CassandraSchemaElementExistsException; +import org.springframework.cassandra.support.exception.CassandraTableExistsException; import org.springframework.dao.DataAccessException; -import org.springframework.data.cassandra.core.exceptions.CassandraInvalidConfigurationInQueryException; -import org.springframework.data.cassandra.core.exceptions.CassandraInvalidQueryException; -import org.springframework.data.cassandra.core.exceptions.CassandraKeyspaceExistsException; -import org.springframework.data.cassandra.core.exceptions.CassandraSchemaElementExistsException; -import org.springframework.data.cassandra.core.exceptions.CassandraTableExistsException; import com.datastax.driver.core.exceptions.AlreadyExistsException; import com.datastax.driver.core.exceptions.InvalidConfigurationInQueryException; diff --git a/src/test/java/org/springframework/data/cassandra/template/CassandraAdminTest.java b/src/test/java/org/springframework/data/cassandra/template/CassandraAdminTest.java index 475db3fa6..cf6242e14 100644 --- a/src/test/java/org/springframework/data/cassandra/template/CassandraAdminTest.java +++ b/src/test/java/org/springframework/data/cassandra/template/CassandraAdminTest.java @@ -32,9 +32,9 @@ import org.mockito.Mock; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cassandra.core.CassandraOperations; import org.springframework.context.ApplicationContext; import org.springframework.data.cassandra.config.TestConfig; -import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; diff --git a/src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTest.java b/src/test/java/org/springframework/data/cassandra/template/CassandraDataOperationsTest.java similarity index 74% rename from src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTest.java rename to src/test/java/org/springframework/data/cassandra/template/CassandraDataOperationsTest.java index 7235c9334..30c216ba8 100644 --- a/src/test/java/org/springframework/data/cassandra/template/CassandraOperationsTest.java +++ b/src/test/java/org/springframework/data/cassandra/template/CassandraDataOperationsTest.java @@ -43,7 +43,7 @@ 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.CassandraOperations; +import org.springframework.data.cassandra.core.CassandraDataOperations; import org.springframework.data.cassandra.core.ConsistencyLevel; import org.springframework.data.cassandra.core.QueryOptions; import org.springframework.data.cassandra.core.RetryPolicy; @@ -64,12 +64,12 @@ import com.datastax.driver.core.querybuilder.Select; */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { TestConfig.class }, loader = AnnotationConfigContextLoader.class) -public class CassandraOperationsTest { +public class CassandraDataOperationsTest { @Autowired - private CassandraOperations cassandraTemplate; + private CassandraDataOperations cassandraDataTemplate; - private static Logger log = LoggerFactory.getLogger(CassandraOperationsTest.class); + private static Logger log = LoggerFactory.getLogger(CassandraDataOperationsTest.class); private final static String CASSANDRA_CONFIG = "cassandra.yaml"; private final static String KEYSPACE_NAME = "test"; @@ -97,7 +97,7 @@ public class CassandraOperationsTest { @Test public void ringTest() { - List ring = cassandraTemplate.describeRing(); + List ring = cassandraDataTemplate.describeRing(); /* * There must be 1 node in the cluster if the embedded server is @@ -122,7 +122,7 @@ public class CassandraOperationsTest { b1.setAuthor("Cassandra Guru"); b1.setPages(521); - cassandraTemplate.insert(b1); + cassandraDataTemplate.insert(b1); Book b2 = new Book(); b2.setIsbn("123456-2"); @@ -130,7 +130,7 @@ public class CassandraOperationsTest { b2.setAuthor("Cassandra Guru"); b2.setPages(521); - cassandraTemplate.insert(b2, "book_alt"); + cassandraDataTemplate.insert(b2, "book_alt"); /* * Test Single Insert with entity @@ -145,7 +145,7 @@ public class CassandraOperationsTest { options.setConsistencyLevel(ConsistencyLevel.ONE); options.setRetryPolicy(RetryPolicy.DOWNGRADING_CONSISTENCY); - cassandraTemplate.insert(b3, "book", options); + cassandraDataTemplate.insert(b3, "book", options); /* * Test Single Insert with entity @@ -161,7 +161,7 @@ public class CassandraOperationsTest { optionsByName.put(QueryOptions.QueryOptionMapKeys.RETRY_POLICY, RetryPolicy.FALLTHROUGH); optionsByName.put(QueryOptions.QueryOptionMapKeys.TTL, 30); - cassandraTemplate.insert(b4, "book", optionsByName); + cassandraDataTemplate.insert(b4, "book", optionsByName); /* * Test Single Insert with entity @@ -172,7 +172,7 @@ public class CassandraOperationsTest { b5.setAuthor("Cassandra Guru"); b5.setPages(265); - cassandraTemplate.insert(b5, options); + cassandraDataTemplate.insert(b5, options); /* * Test Single Insert with entity @@ -183,7 +183,7 @@ public class CassandraOperationsTest { b6.setAuthor("Cassandra Guru"); b6.setPages(465); - cassandraTemplate.insert(b6, optionsByName); + cassandraDataTemplate.insert(b6, optionsByName); } @@ -199,7 +199,7 @@ public class CassandraOperationsTest { b1.setAuthor("Cassandra Guru"); b1.setPages(521); - cassandraTemplate.insertAsynchronously(b1); + cassandraDataTemplate.insertAsynchronously(b1); Book b2 = new Book(); b2.setIsbn("123456-2"); @@ -207,7 +207,7 @@ public class CassandraOperationsTest { b2.setAuthor("Cassandra Guru"); b2.setPages(521); - cassandraTemplate.insertAsynchronously(b2, "book_alt"); + cassandraDataTemplate.insertAsynchronously(b2, "book_alt"); /* * Test Single Insert with entity @@ -222,7 +222,7 @@ public class CassandraOperationsTest { options.setConsistencyLevel(ConsistencyLevel.ONE); options.setRetryPolicy(RetryPolicy.DOWNGRADING_CONSISTENCY); - cassandraTemplate.insertAsynchronously(b3, "book", options); + cassandraDataTemplate.insertAsynchronously(b3, "book", options); /* * Test Single Insert with entity @@ -238,7 +238,7 @@ public class CassandraOperationsTest { optionsByName.put(QueryOptions.QueryOptionMapKeys.RETRY_POLICY, RetryPolicy.FALLTHROUGH); optionsByName.put(QueryOptions.QueryOptionMapKeys.TTL, 30); - cassandraTemplate.insertAsynchronously(b4, "book", optionsByName); + cassandraDataTemplate.insertAsynchronously(b4, "book", optionsByName); /* * Test Single Insert with entity @@ -249,7 +249,7 @@ public class CassandraOperationsTest { b5.setAuthor("Cassandra Guru"); b5.setPages(265); - cassandraTemplate.insertAsynchronously(b5, options); + cassandraDataTemplate.insertAsynchronously(b5, options); /* * Test Single Insert with entity @@ -260,7 +260,7 @@ public class CassandraOperationsTest { b6.setAuthor("Cassandra Guru"); b6.setPages(465); - cassandraTemplate.insertAsynchronously(b6, optionsByName); + cassandraDataTemplate.insertAsynchronously(b6, optionsByName); } @@ -280,27 +280,27 @@ public class CassandraOperationsTest { books = getBookList(20); - cassandraTemplate.insert(books); + cassandraDataTemplate.insert(books); books = getBookList(20); - cassandraTemplate.insert(books, "book_alt"); + cassandraDataTemplate.insert(books, "book_alt"); books = getBookList(20); - cassandraTemplate.insert(books, "book", options); + cassandraDataTemplate.insert(books, "book", options); books = getBookList(20); - cassandraTemplate.insert(books, "book", optionsByName); + cassandraDataTemplate.insert(books, "book", optionsByName); books = getBookList(20); - cassandraTemplate.insert(books, options); + cassandraDataTemplate.insert(books, options); books = getBookList(20); - cassandraTemplate.insert(books, optionsByName); + cassandraDataTemplate.insert(books, optionsByName); } @@ -320,27 +320,27 @@ public class CassandraOperationsTest { books = getBookList(20); - cassandraTemplate.insertAsynchronously(books); + cassandraDataTemplate.insertAsynchronously(books); books = getBookList(20); - cassandraTemplate.insertAsynchronously(books, "book_alt"); + cassandraDataTemplate.insertAsynchronously(books, "book_alt"); books = getBookList(20); - cassandraTemplate.insertAsynchronously(books, "book", options); + cassandraDataTemplate.insertAsynchronously(books, "book", options); books = getBookList(20); - cassandraTemplate.insertAsynchronously(books, "book", optionsByName); + cassandraDataTemplate.insertAsynchronously(books, "book", optionsByName); books = getBookList(20); - cassandraTemplate.insertAsynchronously(books, options); + cassandraDataTemplate.insertAsynchronously(books, options); books = getBookList(20); - cassandraTemplate.insertAsynchronously(books, optionsByName); + cassandraDataTemplate.insertAsynchronously(books, optionsByName); } @@ -387,7 +387,7 @@ public class CassandraOperationsTest { b1.setAuthor("Cassandra Guru"); b1.setPages(521); - cassandraTemplate.update(b1); + cassandraDataTemplate.update(b1); Book b2 = new Book(); b2.setIsbn("123456-2"); @@ -395,7 +395,7 @@ public class CassandraOperationsTest { b2.setAuthor("Cassandra Guru"); b2.setPages(521); - cassandraTemplate.update(b2, "book_alt"); + cassandraDataTemplate.update(b2, "book_alt"); /* * Test Single Insert with entity @@ -406,7 +406,7 @@ public class CassandraOperationsTest { b3.setAuthor("Cassandra Guru"); b3.setPages(265); - cassandraTemplate.update(b3, "book", options); + cassandraDataTemplate.update(b3, "book", options); /* * Test Single Insert with entity @@ -417,7 +417,7 @@ public class CassandraOperationsTest { b4.setAuthor("Cassandra Guru"); b4.setPages(465); - cassandraTemplate.update(b4, "book", optionsByName); + cassandraDataTemplate.update(b4, "book", optionsByName); /* * Test Single Insert with entity @@ -428,7 +428,7 @@ public class CassandraOperationsTest { b5.setAuthor("Cassandra Guru"); b5.setPages(265); - cassandraTemplate.update(b5, options); + cassandraDataTemplate.update(b5, options); /* * Test Single Insert with entity @@ -439,7 +439,7 @@ public class CassandraOperationsTest { b6.setAuthor("Cassandra Guru"); b6.setPages(465); - cassandraTemplate.update(b6, optionsByName); + cassandraDataTemplate.update(b6, optionsByName); } @@ -466,7 +466,7 @@ public class CassandraOperationsTest { b1.setAuthor("Cassandra Guru"); b1.setPages(521); - cassandraTemplate.updateAsynchronously(b1); + cassandraDataTemplate.updateAsynchronously(b1); Book b2 = new Book(); b2.setIsbn("123456-2"); @@ -474,7 +474,7 @@ public class CassandraOperationsTest { b2.setAuthor("Cassandra Guru"); b2.setPages(521); - cassandraTemplate.updateAsynchronously(b2, "book_alt"); + cassandraDataTemplate.updateAsynchronously(b2, "book_alt"); /* * Test Single Insert with entity @@ -485,7 +485,7 @@ public class CassandraOperationsTest { b3.setAuthor("Cassandra Guru"); b3.setPages(265); - cassandraTemplate.updateAsynchronously(b3, "book", options); + cassandraDataTemplate.updateAsynchronously(b3, "book", options); /* * Test Single Insert with entity @@ -496,7 +496,7 @@ public class CassandraOperationsTest { b4.setAuthor("Cassandra Guru"); b4.setPages(465); - cassandraTemplate.updateAsynchronously(b4, "book", optionsByName); + cassandraDataTemplate.updateAsynchronously(b4, "book", optionsByName); /* * Test Single Insert with entity @@ -507,7 +507,7 @@ public class CassandraOperationsTest { b5.setAuthor("Cassandra Guru"); b5.setPages(265); - cassandraTemplate.updateAsynchronously(b5, options); + cassandraDataTemplate.updateAsynchronously(b5, options); /* * Test Single Insert with entity @@ -518,7 +518,7 @@ public class CassandraOperationsTest { b6.setAuthor("Cassandra Guru"); b6.setPages(465); - cassandraTemplate.updateAsynchronously(b6, optionsByName); + cassandraDataTemplate.updateAsynchronously(b6, optionsByName); } @@ -538,51 +538,51 @@ public class CassandraOperationsTest { books = getBookList(20); - cassandraTemplate.insert(books); + cassandraDataTemplate.insert(books); alterBooks(books); - cassandraTemplate.update(books); + cassandraDataTemplate.update(books); books = getBookList(20); - cassandraTemplate.insert(books, "book_alt"); + cassandraDataTemplate.insert(books, "book_alt"); alterBooks(books); - cassandraTemplate.update(books, "book_alt"); + cassandraDataTemplate.update(books, "book_alt"); books = getBookList(20); - cassandraTemplate.insert(books, "book", options); + cassandraDataTemplate.insert(books, "book", options); alterBooks(books); - cassandraTemplate.update(books, "book", options); + cassandraDataTemplate.update(books, "book", options); books = getBookList(20); - cassandraTemplate.insert(books, "book", optionsByName); + cassandraDataTemplate.insert(books, "book", optionsByName); alterBooks(books); - cassandraTemplate.update(books, "book", optionsByName); + cassandraDataTemplate.update(books, "book", optionsByName); books = getBookList(20); - cassandraTemplate.insert(books, options); + cassandraDataTemplate.insert(books, options); alterBooks(books); - cassandraTemplate.update(books, options); + cassandraDataTemplate.update(books, options); books = getBookList(20); - cassandraTemplate.insert(books, optionsByName); + cassandraDataTemplate.insert(books, optionsByName); alterBooks(books); - cassandraTemplate.update(books, optionsByName); + cassandraDataTemplate.update(books, optionsByName); } @@ -602,51 +602,51 @@ public class CassandraOperationsTest { books = getBookList(20); - cassandraTemplate.insert(books); + cassandraDataTemplate.insert(books); alterBooks(books); - cassandraTemplate.updateAsynchronously(books); + cassandraDataTemplate.updateAsynchronously(books); books = getBookList(20); - cassandraTemplate.insert(books, "book_alt"); + cassandraDataTemplate.insert(books, "book_alt"); alterBooks(books); - cassandraTemplate.updateAsynchronously(books, "book_alt"); + cassandraDataTemplate.updateAsynchronously(books, "book_alt"); books = getBookList(20); - cassandraTemplate.insert(books, "book", options); + cassandraDataTemplate.insert(books, "book", options); alterBooks(books); - cassandraTemplate.updateAsynchronously(books, "book", options); + cassandraDataTemplate.updateAsynchronously(books, "book", options); books = getBookList(20); - cassandraTemplate.insert(books, "book", optionsByName); + cassandraDataTemplate.insert(books, "book", optionsByName); alterBooks(books); - cassandraTemplate.updateAsynchronously(books, "book", optionsByName); + cassandraDataTemplate.updateAsynchronously(books, "book", optionsByName); books = getBookList(20); - cassandraTemplate.insert(books, options); + cassandraDataTemplate.insert(books, options); alterBooks(books); - cassandraTemplate.updateAsynchronously(books, options); + cassandraDataTemplate.updateAsynchronously(books, options); books = getBookList(20); - cassandraTemplate.insert(books, optionsByName); + cassandraDataTemplate.insert(books, optionsByName); alterBooks(books); - cassandraTemplate.updateAsynchronously(books, optionsByName); + cassandraDataTemplate.updateAsynchronously(books, optionsByName); } @@ -681,12 +681,12 @@ public class CassandraOperationsTest { Book b1 = new Book(); b1.setIsbn("123456-1"); - cassandraTemplate.delete(b1); + cassandraDataTemplate.delete(b1); Book b2 = new Book(); b2.setIsbn("123456-2"); - cassandraTemplate.delete(b2, "book_alt"); + cassandraDataTemplate.delete(b2, "book_alt"); /* * Test Single Insert with entity @@ -694,7 +694,7 @@ public class CassandraOperationsTest { Book b3 = new Book(); b3.setIsbn("123456-3"); - cassandraTemplate.delete(b3, "book", options); + cassandraDataTemplate.delete(b3, "book", options); /* * Test Single Insert with entity @@ -702,7 +702,7 @@ public class CassandraOperationsTest { Book b4 = new Book(); b4.setIsbn("123456-4"); - cassandraTemplate.delete(b4, "book", optionsByName); + cassandraDataTemplate.delete(b4, "book", optionsByName); /* * Test Single Insert with entity @@ -710,7 +710,7 @@ public class CassandraOperationsTest { Book b5 = new Book(); b5.setIsbn("123456-5"); - cassandraTemplate.delete(b5, options); + cassandraDataTemplate.delete(b5, options); /* * Test Single Insert with entity @@ -718,7 +718,7 @@ public class CassandraOperationsTest { Book b6 = new Book(); b6.setIsbn("123456-6"); - cassandraTemplate.delete(b6, optionsByName); + cassandraDataTemplate.delete(b6, optionsByName); } @@ -741,12 +741,12 @@ public class CassandraOperationsTest { Book b1 = new Book(); b1.setIsbn("123456-1"); - cassandraTemplate.deleteAsynchronously(b1); + cassandraDataTemplate.deleteAsynchronously(b1); Book b2 = new Book(); b2.setIsbn("123456-2"); - cassandraTemplate.deleteAsynchronously(b2, "book_alt"); + cassandraDataTemplate.deleteAsynchronously(b2, "book_alt"); /* * Test Single Insert with entity @@ -754,7 +754,7 @@ public class CassandraOperationsTest { Book b3 = new Book(); b3.setIsbn("123456-3"); - cassandraTemplate.deleteAsynchronously(b3, "book", options); + cassandraDataTemplate.deleteAsynchronously(b3, "book", options); /* * Test Single Insert with entity @@ -762,7 +762,7 @@ public class CassandraOperationsTest { Book b4 = new Book(); b4.setIsbn("123456-4"); - cassandraTemplate.deleteAsynchronously(b4, "book", optionsByName); + cassandraDataTemplate.deleteAsynchronously(b4, "book", optionsByName); /* * Test Single Insert with entity @@ -770,7 +770,7 @@ public class CassandraOperationsTest { Book b5 = new Book(); b5.setIsbn("123456-5"); - cassandraTemplate.deleteAsynchronously(b5, options); + cassandraDataTemplate.deleteAsynchronously(b5, options); /* * Test Single Insert with entity @@ -778,7 +778,7 @@ public class CassandraOperationsTest { Book b6 = new Book(); b6.setIsbn("123456-6"); - cassandraTemplate.deleteAsynchronously(b6, optionsByName); + cassandraDataTemplate.deleteAsynchronously(b6, optionsByName); } @Test @@ -797,39 +797,39 @@ public class CassandraOperationsTest { books = getBookList(20); - cassandraTemplate.insert(books); + cassandraDataTemplate.insert(books); - cassandraTemplate.delete(books); + cassandraDataTemplate.delete(books); books = getBookList(20); - cassandraTemplate.insert(books, "book_alt"); + cassandraDataTemplate.insert(books, "book_alt"); - cassandraTemplate.delete(books, "book_alt"); + cassandraDataTemplate.delete(books, "book_alt"); books = getBookList(20); - cassandraTemplate.insert(books, "book", options); + cassandraDataTemplate.insert(books, "book", options); - cassandraTemplate.delete(books, "book", options); + cassandraDataTemplate.delete(books, "book", options); books = getBookList(20); - cassandraTemplate.insert(books, "book", optionsByName); + cassandraDataTemplate.insert(books, "book", optionsByName); - cassandraTemplate.delete(books, "book", optionsByName); + cassandraDataTemplate.delete(books, "book", optionsByName); books = getBookList(20); - cassandraTemplate.insert(books, options); + cassandraDataTemplate.insert(books, options); - cassandraTemplate.delete(books, options); + cassandraDataTemplate.delete(books, options); books = getBookList(20); - cassandraTemplate.insert(books, optionsByName); + cassandraDataTemplate.insert(books, optionsByName); - cassandraTemplate.delete(books, optionsByName); + cassandraDataTemplate.delete(books, optionsByName); } @@ -849,44 +849,44 @@ public class CassandraOperationsTest { books = getBookList(20); - cassandraTemplate.insert(books); + cassandraDataTemplate.insert(books); - cassandraTemplate.deleteAsynchronously(books); + cassandraDataTemplate.deleteAsynchronously(books); books = getBookList(20); - cassandraTemplate.insert(books, "book_alt"); + cassandraDataTemplate.insert(books, "book_alt"); - cassandraTemplate.deleteAsynchronously(books, "book_alt"); + cassandraDataTemplate.deleteAsynchronously(books, "book_alt"); books = getBookList(20); - cassandraTemplate.insert(books, "book", options); + cassandraDataTemplate.insert(books, "book", options); - cassandraTemplate.deleteAsynchronously(books, "book", options); + cassandraDataTemplate.deleteAsynchronously(books, "book", options); books = getBookList(20); - cassandraTemplate.insert(books, "book", optionsByName); + cassandraDataTemplate.insert(books, "book", optionsByName); - cassandraTemplate.deleteAsynchronously(books, "book", optionsByName); + cassandraDataTemplate.deleteAsynchronously(books, "book", optionsByName); books = getBookList(20); - cassandraTemplate.insert(books, options); + cassandraDataTemplate.insert(books, options); - cassandraTemplate.deleteAsynchronously(books, options); + cassandraDataTemplate.deleteAsynchronously(books, options); books = getBookList(20); - cassandraTemplate.insert(books, optionsByName); + cassandraDataTemplate.insert(books, optionsByName); - cassandraTemplate.deleteAsynchronously(books, optionsByName); + cassandraDataTemplate.deleteAsynchronously(books, optionsByName); } @Test - public void selectTest() { + public void selectOneTest() { /* * Test Single Insert with entity @@ -897,12 +897,12 @@ public class CassandraOperationsTest { b1.setAuthor("Cassandra Guru"); b1.setPages(521); - cassandraTemplate.insert(b1); + cassandraDataTemplate.insert(b1); Select select = QueryBuilder.select().all().from("book"); select.where(QueryBuilder.eq("isbn", "123456-1")); - Book b = cassandraTemplate.selectOne(select, Book.class); + Book b = cassandraDataTemplate.selectOne(select, Book.class); log.info("SingleSelect Book Title -> " + b.getTitle()); log.info("SingleSelect Book Author -> " + b.getAuthor()); @@ -912,6 +912,40 @@ public class CassandraOperationsTest { } + @Test + public void selectTest() { + + List books = getBookList(20); + + cassandraDataTemplate.insert(books); + + Select select = QueryBuilder.select().all().from("book"); + + List b = cassandraDataTemplate.select(select, Book.class); + + log.info("Book Count -> " + b.size()); + + Assert.assertEquals(b.size(), 20); + + } + + @Test + public void selectCountTest() { + + List books = getBookList(20); + + cassandraDataTemplate.insert(books); + + Select select = QueryBuilder.select().countAll().from("book"); + + Long count = cassandraDataTemplate.count(select); + + log.info("Book Count -> " + count); + + Assert.assertEquals(count, new Long(20)); + + } + @After public void clearCassandra() { EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); diff --git a/src/test/resources/org/springframework/data/cassandra/config/CassandraNamespaceTests-context.xml b/src/test/resources/org/springframework/data/cassandra/config/CassandraNamespaceTests-context.xml index d4ad0544a..47b10b527 100644 --- a/src/test/resources/org/springframework/data/cassandra/config/CassandraNamespaceTests-context.xml +++ b/src/test/resources/org/springframework/data/cassandra/config/CassandraNamespaceTests-context.xml @@ -1,49 +1,55 @@ - + - - - - - + + + + + - + - - - + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + +