Merge branch 'DATACASS-32' of https://github.com/shvid/spring-data-cassandra into DATACASS-32

This commit is contained in:
Matthew Adams
2013-11-19 16:03:49 -06:00
43 changed files with 1238 additions and 492 deletions

View File

@@ -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> T execute(SessionCallback<T> sessionCallback);
void execute(final String cql);
RuntimeException potentiallyConvertRuntimeException(RuntimeException ex);
<T> T query(String cql, ResultSetExtractor<T> rse) throws DataAccessException;
void query(String cql, RowCallbackHandler rch) throws DataAccessException;
<T> List<T> query(String cql, RowMapper<T> rowMapper) throws DataAccessException;
<T> T queryForObject(String cql, RowMapper<T> rowMapper) throws DataAccessException;
<T> T queryForObject(String cql, Class<T> requiredType) throws DataAccessException;
Map<String, Object> queryForMap(String cql) throws DataAccessException;
<T> List<T> queryForList(String cql, Class<T> elementType) throws DataAccessException;
List<Map<String, Object>> 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);
}

View File

@@ -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> T execute(SessionCallback<T> 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<Object>() {
@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<ResultSet>() {
@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<ResultSetFuture>() {
@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> T doExecute(SessionCallback<T> 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> T query(String cql, ResultSetExtractor<T> 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 <T> List<T> query(String cql, RowMapper<T> rowMapper) throws DataAccessException {
try {
ResultSet rs = getSession().execute(cql);
int i = 0;
List<T> mappedRows = new ArrayList<T>();
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> T queryForObject(String cql, RowMapper<T> rowMapper) throws DataAccessException {
try {
ResultSet rs = getSession().execute(cql);
List<Row> 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> T queryForObject(String cql, Class<T> 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<String, Object> queryForMap(String cql) throws DataAccessException {
ResultSet rs = getSession().execute(cql);
if (rs == null) {
return null;
}
return toMap(rs.one());
}
/**
* @param row
* @return
*/
protected Map<String, Object> toMap(Row row) {
if (row == null) {
return null;
}
ColumnDefinitions cols = row.getColumnDefinitions();
Map<String, Object> map = new HashMap<String, Object>(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 <T> List<T> queryForList(String cql, Class<T> elementType) throws DataAccessException {
ResultSet rs = getSession().execute(cql);
List<Row> rows = rs.all();
List<T> list = new ArrayList<T>(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<Map<String, Object>> queryForList(String cql) throws DataAccessException {
ResultSet rs = getSession().execute(cql);
List<Row> rows = rs.all();
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(rows.size());
for (Row row : rows) {
list.add(toMap(row));
}
return list;
}
}

View File

@@ -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> {
T extractData(ResultSet rs) throws DriverException, DataAccessException;
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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> {
T mapRow(Row row, int rowNum) throws DriverException;
}

View File

@@ -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
*

View File

@@ -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<Session>, 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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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.

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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.

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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());
}
/**

View File

@@ -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";
}

View File

@@ -29,6 +29,7 @@ public class CassandraNamespaceHandler extends NamespaceHandlerSupport {
registerBeanDefinitionParser("cluster", new CassandraClusterParser());
registerBeanDefinitionParser("keyspace", new CassandraKeyspaceParser());
registerBeanDefinitionParser("session", new CassandraSessionParser());
}

View File

@@ -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 &lt;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) {
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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
*/
<T> List<T> selectByCQL(String query, Class<T> selectClass);
<T> List<T> select(String cql, Class<T> 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> T selectOneByCQL(String query, Class<T> selectClass);
<T> T selectOne(String cql, Class<T> selectClass);
<T> List<T> select(Select selectQuery, Class<T> selectClass);
<T> T selectOne(Select selectQuery, Class<T> selectClass);
Long count(Select selectQuery);
/**
* Insert the given object to the table by id.
*

View File

@@ -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<String> ITERABLE_CLASSES;
static {
Set<String> iterableClasses = new HashSet<String>();
@@ -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<? extends CassandraPersistentEntity<?>, 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<? extends CassandraPersistentEntity<?>, 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>() {
Metadata clusterMetadata = doExecute(new SessionCallback<Metadata>() {
@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<ResultSet>() {
@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<ResultSetFuture>() {
@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 <T> List<T> select(Select selectQuery, Class<T> selectClass) {
return selectByCQL(selectQuery.getQueryString(), selectClass);
public <T> List<T> select(Select cql, Class<T> selectClass) {
return select(cql.getQueryString(), selectClass);
}
/* (non-Javadoc)
* @see org.springframework.data.cassandra.core.CassandraOperations#select(java.lang.String, java.lang.Class)
*/
@Override
public <T> List<T> selectByCQL(String query, Class<T> selectClass) {
return doSelect(query, new ReadRowCallback<T>(cassandraConverter, selectClass));
public <T> List<T> select(String cql, Class<T> selectClass) {
return doSelect(cql, new ReadRowCallback<T>(cassandraConverter, selectClass));
}
/* (non-Javadoc)
@@ -694,15 +700,15 @@ public class CassandraTemplate implements CassandraOperations {
*/
@Override
public <T> T selectOne(Select selectQuery, Class<T> 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> T selectOneByCQL(String query, Class<T> selectClass) {
return doSelectOne(query, new ReadRowCallback<T>(cassandraConverter, selectClass));
public <T> T selectOne(String cql, Class<T> selectClass) {
return doSelectOne(cql, new ReadRowCallback<T>(cassandraConverter, selectClass));
}
/* (non-Javadoc)
@@ -954,7 +960,7 @@ public class CassandraTemplate implements CassandraOperations {
*/
private <T> List<T> doSelect(final String query, ReadRowCallback<T> readRowCallback) {
ResultSet resultSet = execute(new SessionCallback<ResultSet>() {
ResultSet resultSet = doExecute(new SessionCallback<ResultSet>() {
@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<ResultSet>() {
@Override
public ResultSet doInSession(Session s) throws DataAccessException {
return s.execute(query);
}
});
if (resultSet == null) {
return null;
}
Iterator<Row> 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 resultSet = doExecute(new SessionCallback<ResultSet>() {
@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<Object>() {
doExecute(new SessionCallback<Object>() {
@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<List<T>>() {
return doExecute(new SessionCallback<List<T>>() {
@Override
public List<T> 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<List<T>>() {
return doExecute(new SessionCallback<List<T>>() {
@Override
public List<T> 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<Object>() {
doExecute(new SessionCallback<Object>() {
@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> T doExecute(SessionCallback<T> 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<T>() {
return doExecute(new SessionCallback<T>() {
@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<T>() {
return doExecute(new SessionCallback<T>() {
@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> T execute(SessionCallback<T> callback) {
Assert.notNull(callback);
try {
return callback.doInSession(session);
} catch (DataAccessException e) {
throw potentiallyConvertRuntimeException(e);
}
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -15,6 +15,20 @@ Defines the configuration elements for the Spring Data Cassandra support.
]]></xsd:documentation>
</xsd:annotation>
<xsd:element name="session" type="sessionType">
<xsd:annotation>
<xsd:documentation
source="org.springframework.cassandra.core.SessionFactoryBean"><![CDATA[
Defines a Cassandra Session instance used for accessing Cassandra Keyspace'.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="com.datastax.driver.core.Session" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="cluster" type="clusterType">
<xsd:annotation>
<xsd:documentation
@@ -31,13 +45,14 @@ Defines a Cassandra Cluster instance used for accessing Cassandra'.
<xsd:complexType name="clusterType">
<xsd:sequence>
<xsd:element name="local-pooling-options"
type="poolingOptionsType" maxOccurs="1" minOccurs="0">
<xsd:element name="local-pooling-options" type="poolingOptionsType"
maxOccurs="1" minOccurs="0">
</xsd:element>
<xsd:element name="remote-pooling-options"
type="poolingOptionsType" maxOccurs="1" minOccurs="0">
<xsd:element name="remote-pooling-options" type="poolingOptionsType"
maxOccurs="1" minOccurs="0">
</xsd:element>
<xsd:element name="socket-options" type="socketOptionsType" maxOccurs="1" minOccurs="0"></xsd:element>
<xsd:element name="socket-options" type="socketOptionsType"
maxOccurs="1" minOccurs="0"></xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:ID" use="optional">
<xsd:annotation>
@@ -61,8 +76,7 @@ The port to connect to Cassandra server as native CQL client. Default is 9042
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="compression" default="NONE"
use="optional">
<xsd:attribute name="compression" default="NONE" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The protocol options compression. Default is 'none'.
@@ -92,7 +106,7 @@ Uses SNAPPY compression algorithm.
<xsd:documentation><![CDATA[
AuthInfoProvider implementation.
]]></xsd:documentation>
</xsd:annotation>
</xsd:annotation>
<xsd:simpleType>
<xsd:annotation>
<xsd:appinfo>
@@ -103,76 +117,81 @@ AuthInfoProvider implementation.
</xsd:annotation>
<xsd:union memberTypes="xsd:string" />
</xsd:simpleType>
</xsd:attribute>
</xsd:attribute>
<xsd:attribute name="load-balancing-policy" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
LoadBalancingPolicy implementation.
]]></xsd:documentation>
</xsd:annotation>
</xsd:annotation>
<xsd:simpleType>
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="com.datastax.driver.core.policies.LoadBalancingPolicy" />
<tool:assignable-to
type="com.datastax.driver.core.policies.LoadBalancingPolicy" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string" />
</xsd:simpleType>
</xsd:attribute>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="reconnection-policy" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
ReconnectionPolicy implementation.
]]></xsd:documentation>
</xsd:annotation>
</xsd:annotation>
<xsd:simpleType>
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="com.datastax.driver.core.policies.ReconnectionPolicy" />
<tool:assignable-to
type="com.datastax.driver.core.policies.ReconnectionPolicy" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string" />
</xsd:simpleType>
</xsd:attribute>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="retry-policy" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
RetryPolicy implementation.
]]></xsd:documentation>
</xsd:annotation>
</xsd:annotation>
<xsd:simpleType>
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="com.datastax.driver.core.policies.RetryPolicy" />
<tool:assignable-to
type="com.datastax.driver.core.policies.RetryPolicy" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string" />
</xsd:simpleType>
</xsd:attribute>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
<xsd:element name="keyspace" type="keyspaceType">
<xsd:annotation>
<xsd:documentation source="org.springframework.data.cassandra.core.CassandraKeyspaceFactoryBean"><![CDATA[
<xsd:annotation>
<xsd:documentation
source="org.springframework.data.cassandra.core.CassandraKeyspaceFactoryBean"><![CDATA[
Defines a Cassandra Session instance used for accessing Cassandra Keyspace'.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="com.datastax.driver.core.Session" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:complexType name="keyspaceType">
<xsd:sequence>
<xsd:element name="keyspace-attributes" type="keyspaceAttributesType" maxOccurs="1" minOccurs="0"></xsd:element>
<xsd:element name="keyspace-attributes" type="keyspaceAttributesType"
maxOccurs="1" minOccurs="0"></xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:ID" use="optional">
<xsd:annotation>
@@ -209,196 +228,227 @@ The reference to a CassandraConverter instance. Default is null.
</xsd:attribute>
</xsd:complexType>
<xsd:simpleType name="clusterRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="com.datastax.driver.core.Cluster"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="clusterRef" final="union">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="com.datastax.driver.core.Cluster" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string" />
</xsd:simpleType>
<xsd:simpleType name="converterRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.cassandra.convert.CassandraConverter"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="converterRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to
type="org.springframework.data.cassandra.convert.CassandraConverter" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string" />
</xsd:simpleType>
<xsd:complexType name="poolingOptionsType">
<xsd:attribute name="min-simultaneous-requests"
type="xsd:string">
<xsd:complexType name="poolingOptionsType">
<xsd:attribute name="min-simultaneous-requests" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
if the utilisation of opened connections drops below by this configured threshold, then cassandra drops connections till core-connections.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="max-simultaneous-requests"
type="xsd:string">
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="max-simultaneous-requests" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
If the utilisation of connections reaches this configurable threshold, then cassandra creates more connections up to max-connections.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="core-connections" type="xsd:string">
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="core-connections" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
For each host, the driver keeps a core amount of connections open at all time.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="max-connections" type="xsd:string">
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="max-connections" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
More connections are created up to a configurable maximum number of connections.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="socketOptionsType">
<xsd:attribute name="connect-timeout-mls" type="xsd:string">
<xsd:complexType name="socketOptionsType">
<xsd:attribute name="connect-timeout-mls" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Sets connection timeout for client socket in milliseconds.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="keep-alive" type="xsd:string">
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="keep-alive" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Sets the SO_KEEPALIVE socket option.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="reuse-address" type="xsd:string">
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="reuse-address" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Sets the SO_REUSEADDR socket option.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="so-linger" type="xsd:string">
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="so-linger" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Sets the SO_LINGER socket option.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="tcp-no-delay" type="xsd:string">
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="tcp-no-delay" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Sets the SO_TCPNODELAY socket option.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="receive-buffer-size" type="xsd:string">
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="receive-buffer-size" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Sets the SO_RCVBUF socket option.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="send-buffer-size" type="xsd:string">
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="send-buffer-size" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Sets the SO_SNDBUF socket option.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="keyspaceAttributesType">
<xsd:sequence>
<xsd:element name="table" type="tableType" maxOccurs="unbounded" minOccurs="0"></xsd:element>
</xsd:sequence>
<xsd:attribute name="auto" default="validate">
<xsd:annotation>
<xsd:documentation><![CDATA[
<xsd:complexType name="keyspaceAttributesType">
<xsd:sequence>
<xsd:element name="table" type="tableType" maxOccurs="unbounded"
minOccurs="0"></xsd:element>
</xsd:sequence>
<xsd:attribute name="auto" default="validate">
<xsd:annotation>
<xsd:documentation><![CDATA[
The keyspace manipulation operation on startup. Default value is 'validate'.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="validate">
<xsd:annotation>
<xsd:documentation><![CDATA[
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="validate">
<xsd:annotation>
<xsd:documentation><![CDATA[
Validate the keyspace, makes no changes.
]]></xsd:documentation>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="update">
<xsd:annotation>
<xsd:documentation><![CDATA[
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="update">
<xsd:annotation>
<xsd:documentation><![CDATA[
Update the keyspace.
]]></xsd:documentation>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="create">
<xsd:annotation>
<xsd:documentation><![CDATA[
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="create">
<xsd:annotation>
<xsd:documentation><![CDATA[
Creates the keyspace, destroying previous data.
]]></xsd:documentation>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="create-drop">
<xsd:annotation>
<xsd:documentation><![CDATA[
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="create-drop">
<xsd:annotation>
<xsd:documentation><![CDATA[
Creates and then drop the keyspace at the end of the session.
]]></xsd:documentation>
</xsd:annotation>
</xsd:enumeration>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="replication-stategy" type="xsd:string"
use="optional" default="SimpleStrategy">
<xsd:annotation>
<xsd:documentation><![CDATA[
</xsd:annotation>
</xsd:enumeration>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="replication-stategy" type="xsd:string"
use="optional" default="SimpleStrategy">
<xsd:annotation>
<xsd:documentation><![CDATA[
Replication strategy of the Cassandra keyspace. Default value is 'SimpleStrategy'.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="replication-factor" type="xsd:string"
use="optional" default="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="replication-factor" type="xsd:string"
use="optional" default="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
Replication factor used by the Cassandra keyspace. Default value is '1'.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="durable-writes" type="xsd:string"
use="optional" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="durable-writes" type="xsd:string"
use="optional" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Support durable writes in the Cassandra keyspace. Default value is 'true'.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="tableType">
<xsd:attribute name="entity" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
<xsd:complexType name="tableType">
<xsd:attribute name="entity" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Entity class name.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="name" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="name" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Table name override.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="sessionType">
<xsd:attribute name="id" type="xsd:ID" use="optional">
<xsd:annotation>
<xsd:documentation>
The name of the Session definition (by default
"cassandra-session")
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="cassandra-keyspace-ref" type="keyspaceRef"
use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
The reference to a Cassandra Keyspace instance. Will default to 'cassandra-keyspace'.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:simpleType name="keyspaceRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="com.datastax.driver.core.Session" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string" />
</xsd:simpleType>
</xsd:schema>

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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<RingMember> ring = cassandraTemplate.describeRing();
List<RingMember> 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<Book> books = getBookList(20);
cassandraDataTemplate.insert(books);
Select select = QueryBuilder.select().all().from("book");
List<Book> b = cassandraDataTemplate.select(select, Book.class);
log.info("Book Count -> " + b.size());
Assert.assertEquals(b.size(), 20);
}
@Test
public void selectCountTest() {
List<Book> 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();

View File

@@ -1,49 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cassandra="http://www.springframework.org/schema/data/cassandra"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/data/cassandra http://www.springframework.org/schema/data/cassandra/spring-cassandra-1.0.xsd
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cassandra="http://www.springframework.org/schema/data/cassandra"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/data/cassandra http://www.springframework.org/schema/data/cassandra/spring-cassandra-1.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:property-placeholder
location="classpath:/org/springframework/data/cassandra/config/cassandra.properties" />
<context:property-placeholder
location="classpath:/org/springframework/data/cassandra/config/cassandra.properties" />
<cassandra:cluster id="cassandra-cluster"
contactPoints="${cassandra.contactPoints}" port="${cassandra.port}"
compression="SNAPPY">
<cassandra:local-pooling-options
min-simultaneous-requests="25" max-simultaneous-requests="100"
core-connections="2" max-connections="8" />
<cassandra:remote-pooling-options
min-simultaneous-requests="25" max-simultaneous-requests="100"
core-connections="1" max-connections="2" />
<cassandra:socket-options
connect-timeout-mls="5000" keep-alive="true" reuse-address="true"
so-linger="60" tcp-no-delay="true" receive-buffer-size="65536"
send-buffer-size="65536" />
</cassandra:cluster>
<cassandra:cluster id="cassandra-cluster"
contactPoints="${cassandra.contactPoints}" port="${cassandra.port}"
compression="SNAPPY">
<cassandra:local-pooling-options
min-simultaneous-requests="25" max-simultaneous-requests="100"
core-connections="2" max-connections="8" />
<cassandra:remote-pooling-options
min-simultaneous-requests="25" max-simultaneous-requests="100"
core-connections="1" max-connections="2" />
<cassandra:socket-options
connect-timeout-mls="5000" keep-alive="true" reuse-address="true"
so-linger="60" tcp-no-delay="true" receive-buffer-size="65536"
send-buffer-size="65536" />
</cassandra:cluster>
<bean id="cassandra-mapping" class=" org.springframework.data.cassandra.mapping.CassandraMappingContext" />
<bean id="cassandra-mapping"
class=" org.springframework.data.cassandra.mapping.CassandraMappingContext" />
<bean id="cassandra-converter" class=" org.springframework.data.cassandra.convert.MappingCassandraConverter">
<constructor-arg ref="cassandra-mapping" />
</bean>
<bean id="cassandra-converter"
class=" org.springframework.data.cassandra.convert.MappingCassandraConverter">
<constructor-arg ref="cassandra-mapping" />
</bean>
<cassandra:keyspace id="cassandra-keyspace" name="${cassandra.keyspace}"
cassandra-cluster-ref="cassandra-cluster" cassandra-converter-ref="cassandra-converter">
<cassandra:keyspace-attributes auto="update" replication-stategy="SimpleStrategy" replication-factor="1" durable-writes="true">
<cassandra:table entity="org.springframework.data.cassandra.table.Comment" />
<cassandra:table entity="org.springframework.data.cassandra.table.Notification" />
<cassandra:table entity="org.springframework.data.cassandra.table.Post" />
<cassandra:table entity="org.springframework.data.cassandra.table.Timeline" />
<cassandra:table entity="org.springframework.data.cassandra.table.User" />
</cassandra:keyspace-attributes>
</cassandra:keyspace>
<bean id="cassandraTemplate"
class="org.springframework.data.cassandra.core.CassandraTemplate">
<constructor-arg ref="cassandra-keyspace" />
</bean>
<cassandra:keyspace id="cassandra-keyspace" name="${cassandra.keyspace}"
cassandra-cluster-ref="cassandra-cluster" cassandra-converter-ref="cassandra-converter">
<cassandra:keyspace-attributes auto="update"
replication-stategy="SimpleStrategy" replication-factor="1"
durable-writes="true">
<cassandra:table entity="org.springframework.data.cassandra.table.Comment" />
<cassandra:table
entity="org.springframework.data.cassandra.table.Notification" />
<cassandra:table entity="org.springframework.data.cassandra.table.Post" />
<cassandra:table entity="org.springframework.data.cassandra.table.Timeline" />
<cassandra:table entity="org.springframework.data.cassandra.table.User" />
</cassandra:keyspace-attributes>
</cassandra:keyspace>
<cassandra:session id="cassandra-session" cassandra-keyspace-ref="cassandra-keyspace"/>
<bean id="cassandraTemplate" class="org.springframework.cassandra.core.CassandraTemplate">
<constructor-arg ref="cassandra-session" />
</bean>
</beans>