DATACASS-1 - WIP before merging from master
This commit is contained in:
@@ -27,7 +27,6 @@ import org.springframework.cassandra.core.CassandraTemplate;
|
||||
import org.springframework.cassandra.support.CassandraExceptionTranslator;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.datastax.driver.core.Cluster;
|
||||
@@ -46,12 +45,12 @@ public class CassandraSessionFactoryBean implements FactoryBean<Session>, Initia
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(CassandraSessionFactoryBean.class);
|
||||
|
||||
private Cluster cluster;
|
||||
private Session session;
|
||||
private String keyspaceName;
|
||||
private List<String> startupScripts = new ArrayList<String>();
|
||||
private List<String> shutdownScripts = new ArrayList<String>();
|
||||
private final PersistenceExceptionTranslator exceptionTranslator = new CassandraExceptionTranslator();
|
||||
protected Cluster cluster;
|
||||
protected Session session;
|
||||
protected String keyspaceName;
|
||||
protected List<String> startupScripts = new ArrayList<String>();
|
||||
protected List<String> shutdownScripts = new ArrayList<String>();
|
||||
protected final PersistenceExceptionTranslator exceptionTranslator = new CassandraExceptionTranslator();
|
||||
|
||||
@Override
|
||||
public Session getObject() {
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.cassandra.config.CassandraSessionFactoryBean;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
@@ -53,39 +54,45 @@ public class CassandraSessionParser extends AbstractSimpleBeanDefinitionParser {
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
String keyspaceName = element.getAttribute("keyspace-name");
|
||||
if (!StringUtils.hasText(keyspaceName)) {
|
||||
keyspaceName = null;
|
||||
}
|
||||
builder.addPropertyValue("keyspaceName", keyspaceName);
|
||||
parseKeyspaceName(element, builder);
|
||||
parseClusterRef(element, builder);
|
||||
parseScripts(element, builder, "startup-cql", "startupScript");
|
||||
parseScripts(element, builder, "shutdown-cql", "shutdownScript");
|
||||
}
|
||||
|
||||
protected void parseScripts(Element element, BeanDefinitionBuilder builder, String elementName, String propertyName) {
|
||||
|
||||
List<String> scripts = parseScripts(element, elementName);
|
||||
builder.addPropertyValue(propertyName, scripts);
|
||||
}
|
||||
|
||||
protected void parseClusterRef(Element element, BeanDefinitionBuilder builder) {
|
||||
|
||||
String clusterRef = element.getAttribute("cluster-ref");
|
||||
if (!StringUtils.hasText(clusterRef)) {
|
||||
clusterRef = BeanNames.CASSANDRA_CLUSTER;
|
||||
}
|
||||
builder.addPropertyReference("cluster", clusterRef);
|
||||
|
||||
parseChildElements(element, builder);
|
||||
}
|
||||
|
||||
protected void parseChildElements(Element element, BeanDefinitionBuilder builder) {
|
||||
protected void parseKeyspaceName(Element element, BeanDefinitionBuilder builder) {
|
||||
|
||||
List<String> scripts = parseScripts(element, "startup-cql");
|
||||
builder.addPropertyValue("startupScripts", scripts);
|
||||
|
||||
scripts = parseScripts(element, "shutdown-cql");
|
||||
builder.addPropertyValue("shutdownScripts", scripts);
|
||||
String keyspaceName = element.getAttribute("keyspace-name");
|
||||
if (!StringUtils.hasText(keyspaceName)) {
|
||||
keyspaceName = null;
|
||||
}
|
||||
builder.addPropertyValue("keyspaceName", keyspaceName);
|
||||
}
|
||||
|
||||
protected List<String> parseScripts(Element element, String elementName) {
|
||||
|
||||
NodeList nodes = element.getElementsByTagName("startup-cql");
|
||||
NodeList nodes = element.getElementsByTagName(elementName);
|
||||
int length = nodes.getLength();
|
||||
List<String> scripts = new ArrayList<String>(length);
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
Element script = (Element) nodes.item(i);
|
||||
scripts.add(script.getTextContent());
|
||||
scripts.add(DomUtils.getTextValue(script));
|
||||
}
|
||||
|
||||
return scripts;
|
||||
|
||||
@@ -357,7 +357,7 @@ Arbitrary CQL script to be executed against the session's keyspace during bean d
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
|
||||
|
||||
<xsd:attribute name="id" type="xsd:ID" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package org.springframework.data.cassandra.config;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.cassandra.config.CassandraSessionFactoryBean;
|
||||
import org.springframework.data.cassandra.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.core.CassandraAdminTemplate;
|
||||
import org.springframework.data.cassandra.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.TableMetadata;
|
||||
|
||||
public class CassandraDataSessionFactoryBean extends CassandraSessionFactoryBean {
|
||||
|
||||
protected SchemaAction schemaAction;
|
||||
protected CassandraAdminTemplate admin;
|
||||
protected CassandraConverter converter;
|
||||
protected CassandraMappingContext mappingContext;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
super.afterPropertiesSet();
|
||||
|
||||
admin = new CassandraAdminTemplate(session);
|
||||
admin.setCassandraConverter(converter);
|
||||
|
||||
performSchemaAction();
|
||||
}
|
||||
|
||||
protected void performSchemaAction() {
|
||||
|
||||
boolean dropTables = false;
|
||||
boolean dropUnused = false;
|
||||
|
||||
switch (schemaAction) {
|
||||
|
||||
case NONE:
|
||||
return;
|
||||
|
||||
case RECREATE_DROP_UNUSED:
|
||||
dropUnused = true;
|
||||
// don't break!
|
||||
case RECREATE:
|
||||
dropTables = true;
|
||||
// don't break!
|
||||
case CREATE:
|
||||
createTables(dropTables, dropUnused);
|
||||
}
|
||||
}
|
||||
|
||||
protected void createTables(boolean dropTables, boolean dropUnused) {
|
||||
|
||||
for (TableMetadata table : session.getCluster().getMetadata().getKeyspace(keyspaceName).getTables()) {
|
||||
if (dropTables) {
|
||||
if (dropUnused || mappingContext.usesTable(table)) {
|
||||
admin.dropTable(table.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collection<? extends CassandraPersistentEntity<?>> entities = converter.getMappingContext().getPersistentEntities();
|
||||
|
||||
for (CassandraPersistentEntity<?> entity : entities) {
|
||||
admin.createTable(false, entity.getTableName(), entity.getType(), null /* TODO */);
|
||||
}
|
||||
}
|
||||
|
||||
public SchemaAction getSchemaAction() {
|
||||
return schemaAction;
|
||||
}
|
||||
|
||||
public void setSchemaAction(SchemaAction schemaAction) {
|
||||
Assert.notNull(schemaAction);
|
||||
this.schemaAction = schemaAction;
|
||||
}
|
||||
|
||||
public CassandraConverter getConverter() {
|
||||
return converter;
|
||||
}
|
||||
|
||||
public void setConverter(CassandraConverter converter) {
|
||||
Assert.notNull(converter);
|
||||
this.converter = converter;
|
||||
this.mappingContext = converter.getCassandraMappingContext();
|
||||
}
|
||||
}
|
||||
@@ -17,54 +17,10 @@ package org.springframework.data.cassandra.config;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Keyspace attributes are used for manipulation around keyspace at the startup. Auto property defines the way how to do
|
||||
* this. Other attributes used to ensure or update keyspace settings.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
public class KeyspaceAttributes extends org.springframework.cassandra.config.KeyspaceAttributes {
|
||||
|
||||
/*
|
||||
* auto possible values:
|
||||
* validate: validate the keyspace, makes no changes.
|
||||
* update: update the keyspace.
|
||||
* create: creates the keyspace, destroying previous data.
|
||||
* create-drop: drop the keyspace at the end of the session.
|
||||
*/
|
||||
public static final String AUTO_VALIDATE = "validate";
|
||||
public static final String AUTO_UPDATE = "update";
|
||||
public static final String AUTO_CREATE = "create";
|
||||
public static final String AUTO_CREATE_DROP = "create-drop";
|
||||
|
||||
private String auto = AUTO_VALIDATE;
|
||||
|
||||
private Collection<TableAttributes> tables;
|
||||
|
||||
public String getAuto() {
|
||||
return auto;
|
||||
}
|
||||
|
||||
public void setAuto(String auto) {
|
||||
this.auto = auto;
|
||||
}
|
||||
|
||||
public boolean isValidate() {
|
||||
return AUTO_VALIDATE.equals(auto);
|
||||
}
|
||||
|
||||
public boolean isUpdate() {
|
||||
return AUTO_UPDATE.equals(auto);
|
||||
}
|
||||
|
||||
public boolean isCreate() {
|
||||
return AUTO_CREATE.equals(auto);
|
||||
}
|
||||
|
||||
public boolean isCreateDrop() {
|
||||
return AUTO_CREATE_DROP.equals(auto);
|
||||
}
|
||||
|
||||
public Collection<TableAttributes> getTables() {
|
||||
return tables;
|
||||
}
|
||||
@@ -72,5 +28,4 @@ public class KeyspaceAttributes extends org.springframework.cassandra.config.Key
|
||||
public void setTables(Collection<TableAttributes> tables) {
|
||||
this.tables = tables;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.springframework.data.cassandra.config;
|
||||
|
||||
/**
|
||||
* Enum identifying any schema actions to take at startup.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public enum SchemaAction {
|
||||
|
||||
/**
|
||||
* Take no schema actions.
|
||||
*/
|
||||
NONE,
|
||||
|
||||
/**
|
||||
* Create each table as necessary. Fail if a table already exists.
|
||||
*/
|
||||
CREATE,
|
||||
|
||||
/**
|
||||
* Create each table as necessary, dropping the table first if it exists.
|
||||
*/
|
||||
RECREATE,
|
||||
|
||||
/**
|
||||
* Drop <em>all</em> tables in the keyspace, then create each table as necessary.
|
||||
*/
|
||||
RECREATE_DROP_UNUSED;
|
||||
|
||||
// TODO:
|
||||
// /**
|
||||
// * Validate that each required table and column exists. Fail if any required table or column does not exists.
|
||||
// */
|
||||
// VALIDATE("VALIDATE"),
|
||||
//
|
||||
// /**
|
||||
// * Alter or create each table and column as necessary, leaving unused tables and columns untouched.
|
||||
// */
|
||||
// UPDATE("UPDATE"),
|
||||
//
|
||||
// /**
|
||||
// * Alter or create each table and column as necessary, removing unused tables and columns.
|
||||
// */
|
||||
// UPDATE_DROP_UNUNSED("UPDATE_DROP_UNUSED");
|
||||
}
|
||||
@@ -31,8 +31,7 @@ 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.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -74,9 +73,8 @@ public abstract class AbstractSpringDataCassandraConfiguration extends AbstractC
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
@Bean
|
||||
public MappingContext<? extends CassandraPersistentEntity<?>, CassandraPersistentProperty> cassandraMappingContext()
|
||||
throws ClassNotFoundException {
|
||||
CassandraMappingContext context = new CassandraMappingContext();
|
||||
public CassandraMappingContext cassandraMappingContext() throws ClassNotFoundException {
|
||||
DefaultCassandraMappingContext context = new DefaultCassandraMappingContext();
|
||||
context.setInitialEntitySet(getInitialEntitySet());
|
||||
return context;
|
||||
}
|
||||
|
||||
@@ -13,9 +13,7 @@
|
||||
* 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.xml.NamespaceHandlerSupport;
|
||||
package org.springframework.data.cassandra.config.xml;
|
||||
|
||||
/**
|
||||
* Namespace handler for <cassandra>.
|
||||
@@ -23,10 +21,10 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
|
||||
public class CassandraNamespaceHandler extends NamespaceHandlerSupport {
|
||||
public class CassandraNamespaceHandler extends org.springframework.cassandra.config.xml.CassandraNamespaceHandler {
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
|
||||
// registerBeanDefinitionParser("keyspace", new CassandraKeyspaceParser());
|
||||
super.init();
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.convert;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
|
||||
import org.springframework.data.cassandra.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.convert.EntityConverter;
|
||||
@@ -24,10 +24,10 @@ import org.springframework.data.convert.EntityConverter;
|
||||
* Central Cassandra specific converter interface from Object to Row.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public interface CassandraConverter extends
|
||||
EntityConverter<CassandraPersistentEntity<?>, CassandraPersistentProperty, Object, Object> {
|
||||
|
||||
// TODO: move this method to a more appropriate location
|
||||
CreateTableSpecification getCreateTableSpecification(CassandraPersistentEntity<?> entity);
|
||||
CassandraMappingContext getCassandraMappingContext();
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.data.cassandra.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.convert.EntityInstantiator;
|
||||
@@ -49,13 +50,14 @@ import com.datastax.driver.core.querybuilder.Update;
|
||||
* {@link Row}.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class MappingCassandraConverter extends AbstractCassandraConverter implements CassandraConverter,
|
||||
ApplicationContextAware, BeanClassLoaderAware {
|
||||
|
||||
protected static final Logger log = LoggerFactory.getLogger(MappingCassandraConverter.class);
|
||||
|
||||
protected final MappingContext<? extends CassandraPersistentEntity<?>, CassandraPersistentProperty> mappingContext;
|
||||
protected final CassandraMappingContext mappingContext;
|
||||
protected ApplicationContext applicationContext;
|
||||
private SpELContext spELContext;
|
||||
private boolean useFieldAccessOnly = true;
|
||||
@@ -63,12 +65,11 @@ public class MappingCassandraConverter extends AbstractCassandraConverter implem
|
||||
private ClassLoader beanClassLoader;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappingCassandraConverter} given the new {@link MappingContext}.
|
||||
* Creates a new {@link MappingCassandraConverter} with the given {@link CassandraMappingContext}.
|
||||
*
|
||||
* @param mappingContext must not be {@literal null}.
|
||||
*/
|
||||
public MappingCassandraConverter(
|
||||
MappingContext<? extends CassandraPersistentEntity<?>, CassandraPersistentProperty> mappingContext) {
|
||||
public MappingCassandraConverter(CassandraMappingContext mappingContext) {
|
||||
super(new DefaultConversionService());
|
||||
this.mappingContext = mappingContext;
|
||||
this.spELContext = new SpELContext(RowReaderPropertyAccessor.INSTANCE);
|
||||
@@ -80,7 +81,6 @@ public class MappingCassandraConverter extends AbstractCassandraConverter implem
|
||||
Class<R> beanClassLoaderClass = transformClassToBeanClassLoaderClass(clazz);
|
||||
|
||||
TypeInformation<? extends R> type = ClassTypeInformation.from(beanClassLoaderClass);
|
||||
// TypeInformation<? extends R> typeToUse = typeMapper.readType(row, type);
|
||||
TypeInformation<? extends R> typeToUse = type;
|
||||
Class<? extends R> rawType = typeToUse.getType();
|
||||
|
||||
@@ -108,12 +108,13 @@ public class MappingCassandraConverter extends AbstractCassandraConverter implem
|
||||
this.spELContext = new SpELContext(this.spELContext, applicationContext);
|
||||
}
|
||||
|
||||
protected <S extends Object> S readEntityFromRow(final CassandraPersistentEntity<S> entity, final Row row) {
|
||||
protected <S> S readEntityFromRow(final CassandraPersistentEntity<S> entity, final Row row) {
|
||||
|
||||
final DefaultSpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator(row, spELContext);
|
||||
|
||||
final PropertyValueProvider<CassandraPersistentProperty> propertyProvider = new CassandraPropertyValueProvider(row,
|
||||
evaluator);
|
||||
|
||||
PersistentEntityParameterValueProvider<CassandraPersistentProperty> parameterProvider = new PersistentEntityParameterValueProvider<CassandraPersistentProperty>(
|
||||
entity, propertyProvider, null);
|
||||
|
||||
@@ -144,7 +145,8 @@ public class MappingCassandraConverter extends AbstractCassandraConverter implem
|
||||
}
|
||||
|
||||
if (prop.isCompositePrimaryKey()) {
|
||||
// TODO: handle composite primary key properties via recursion into this method
|
||||
// handle composite primary key properties via recursion into this method
|
||||
throw new UnsupportedOperationException("composite primary keys are TODO");
|
||||
}
|
||||
|
||||
boolean hasValueForProperty = row.getColumnDefinitions().contains(prop.getColumnName());
|
||||
@@ -268,55 +270,6 @@ public class MappingCassandraConverter extends AbstractCassandraConverter implem
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreateTableSpecification getCreateTableSpecification(CassandraPersistentEntity<?> entity) {
|
||||
|
||||
final CreateTableSpecification spec = new CreateTableSpecification();
|
||||
|
||||
spec.name(entity.getTableName());
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty prop) {
|
||||
|
||||
if (prop.isCompositePrimaryKey()) {
|
||||
|
||||
CassandraPersistentEntity<?> pkEntity = mappingContext.getPersistentEntity(prop.getRawType());
|
||||
|
||||
pkEntity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty pkProp) {
|
||||
|
||||
if (pkProp.isPartitionKeyColumn()) {
|
||||
spec.partitionKeyColumn(pkProp.getColumnName(), pkProp.getDataType());
|
||||
} else {
|
||||
spec.clusteredKeyColumn(pkProp.getColumnName(), pkProp.getDataType(), pkProp.getPrimaryKeyOrdering());
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
if (prop.isIdProperty()) {
|
||||
spec.partitionKeyColumn(prop.getColumnName(), prop.getDataType());
|
||||
} else {
|
||||
spec.column(prop.getColumnName(), prop.getDataType());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (spec.getPartitionKeyColumns().isEmpty()) {
|
||||
throw new MappingException("not found partition key in the entity " + entity.getType());
|
||||
}
|
||||
|
||||
return spec;
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> Class<T> transformClassToBeanClassLoaderClass(Class<T> entity) {
|
||||
try {
|
||||
@@ -334,4 +287,8 @@ public class MappingCassandraConverter extends AbstractCassandraConverter implem
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CassandraMappingContext getCassandraMappingContext() {
|
||||
return mappingContext;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import java.util.Map;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cassandra.core.SessionCallback;
|
||||
import org.springframework.cassandra.core.cql.generator.CreateTableCqlGenerator;
|
||||
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
|
||||
import org.springframework.cassandra.support.CassandraAccessor;
|
||||
import org.springframework.cassandra.support.CassandraExceptionTranslator;
|
||||
import org.springframework.cassandra.support.exception.CassandraTableExistsException;
|
||||
@@ -13,10 +15,9 @@ 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.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.cassandra.util.CqlUtils;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.ResultSet;
|
||||
@@ -32,7 +33,7 @@ public class CassandraAdminTemplate extends CassandraAccessor implements Cassand
|
||||
|
||||
private Session session;
|
||||
private CassandraConverter converter;
|
||||
private MappingContext<? extends CassandraPersistentEntity<?>, CassandraPersistentProperty> mappingContext;
|
||||
private CassandraMappingContext mappingContext;
|
||||
|
||||
private final PersistenceExceptionTranslator exceptionTranslator = new CassandraExceptionTranslator();
|
||||
|
||||
@@ -45,34 +46,32 @@ public class CassandraAdminTemplate extends CassandraAccessor implements Cassand
|
||||
setSession(session);
|
||||
}
|
||||
|
||||
protected CassandraAdminTemplate setCassandraConverter(CassandraConverter converter) {
|
||||
public void setCassandraConverter(CassandraConverter converter) {
|
||||
Assert.notNull(converter);
|
||||
this.converter = converter;
|
||||
return setMappingContext(converter.getMappingContext());
|
||||
setMappingContext(converter.getCassandraMappingContext());
|
||||
}
|
||||
|
||||
protected CassandraAdminTemplate setMappingContext(
|
||||
MappingContext<? extends CassandraPersistentEntity<?>, CassandraPersistentProperty> mappingContext) {
|
||||
protected void setMappingContext(CassandraMappingContext mappingContext) {
|
||||
Assert.notNull(mappingContext);
|
||||
return this;
|
||||
this.mappingContext = mappingContext;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.CassandraAdminOperations#createTable(boolean, java.lang.String, java.lang.Class, java.util.Map)
|
||||
*/
|
||||
@Override
|
||||
public boolean createTable(boolean ifNotExists, final String tableName, Class<?> entityClass,
|
||||
Map<String, Object> optionsByName) {
|
||||
|
||||
try {
|
||||
|
||||
final CassandraPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
|
||||
|
||||
execute(new SessionCallback<Object>() {
|
||||
@Override
|
||||
public Object doInSession(Session s) throws DataAccessException {
|
||||
|
||||
String cql = CqlUtils.createTable(tableName, entity, converter);
|
||||
String cql = new CreateTableCqlGenerator(mappingContext.getCreateTableSpecificationFor(entity)).toCql();
|
||||
|
||||
log.info("CREATE TABLE CQL -> " + cql);
|
||||
|
||||
s.execute(cql);
|
||||
return null;
|
||||
}
|
||||
@@ -120,6 +119,7 @@ public class CassandraAdminTemplate extends CassandraAccessor implements Cassand
|
||||
|
||||
execute(new SessionCallback<Object>() {
|
||||
|
||||
@Override
|
||||
public Object doInSession(Session s) throws DataAccessException {
|
||||
|
||||
for (String q : queryList) {
|
||||
@@ -179,6 +179,7 @@ public class CassandraAdminTemplate extends CassandraAccessor implements Cassand
|
||||
|
||||
return execute(new SessionCallback<TableMetadata>() {
|
||||
|
||||
@Override
|
||||
public TableMetadata doInSession(Session s) throws DataAccessException {
|
||||
|
||||
return s.getCluster().getMetadata().getKeyspace(keyspace).getTable(tableName);
|
||||
|
||||
@@ -39,9 +39,10 @@ import org.springframework.util.StringUtils;
|
||||
public class BasicCassandraPersistentEntity<T> extends BasicPersistentEntity<T, CassandraPersistentProperty> implements
|
||||
CassandraPersistentEntity<T>, ApplicationContextAware {
|
||||
|
||||
private final String table;
|
||||
private final SpelExpressionParser parser;
|
||||
private final StandardEvaluationContext context;
|
||||
private String table;
|
||||
private final SpelExpressionParser spelParser;
|
||||
private final StandardEvaluationContext spelContext;
|
||||
private final Class<T> type;
|
||||
|
||||
/**
|
||||
* Creates a new {@link BasicCassandraPersistentEntity} with the given {@link TypeInformation}. Will default the table
|
||||
@@ -53,25 +54,32 @@ public class BasicCassandraPersistentEntity<T> extends BasicPersistentEntity<T,
|
||||
|
||||
super(typeInformation, DefaultCassandraPersistentPropertyColumnComparator.IT);
|
||||
|
||||
this.parser = new SpelExpressionParser();
|
||||
this.context = new StandardEvaluationContext();
|
||||
this.spelParser = new SpelExpressionParser();
|
||||
this.spelContext = new StandardEvaluationContext();
|
||||
|
||||
Class<?> rawType = typeInformation.getType();
|
||||
Table anno = rawType.getAnnotation(Table.class);
|
||||
this.type = typeInformation.getType();
|
||||
|
||||
determineTableName();
|
||||
}
|
||||
|
||||
protected void determineTableName() {
|
||||
Table anno = type.getAnnotation(Table.class);
|
||||
|
||||
this.table = anno != null && StringUtils.hasText(anno.value()) ? anno.value() : CassandraNamingUtils
|
||||
.getPreferredTableName(rawType);
|
||||
.getPreferredTableName(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
|
||||
context.addPropertyAccessor(new BeanFactoryAccessor());
|
||||
context.setBeanResolver(new BeanFactoryResolver(applicationContext));
|
||||
context.setRootObject(applicationContext);
|
||||
spelContext.addPropertyAccessor(new BeanFactoryAccessor());
|
||||
spelContext.setBeanResolver(new BeanFactoryResolver(applicationContext));
|
||||
spelContext.setRootObject(applicationContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
Expression expression = parser.parseExpression(table, ParserContext.TEMPLATE_EXPRESSION);
|
||||
return expression.getValue(context, String.class);
|
||||
Expression expression = spelParser.parseExpression(table, ParserContext.TEMPLATE_EXPRESSION);
|
||||
return expression.getValue(spelContext, String.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,16 +52,6 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP
|
||||
super(field, propertyDescriptor, owner, simpleTypeHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIdProperty() {
|
||||
|
||||
if (super.isIdProperty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return isAnnotationPresent(PrimaryKey.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompositePrimaryKey() {
|
||||
return getField().getType().isAnnotationPresent(PrimaryKeyClass.class);
|
||||
|
||||
@@ -1,76 +1,29 @@
|
||||
/*
|
||||
* 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.mapping;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.data.mapping.context.AbstractMappingContext;
|
||||
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
import com.datastax.driver.core.TableMetadata;
|
||||
|
||||
/**
|
||||
* Default implementation of a {@link MappingContext} for Cassandra using {@link CassandraPersistentEntity} and
|
||||
* {@link CassandraPersistentProperty} as primary abstractions.
|
||||
* A {@link MappingContext} for Cassandra.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraMappingContext extends
|
||||
AbstractMappingContext<CassandraPersistentEntity<?>, CassandraPersistentProperty> implements
|
||||
ApplicationContextAware {
|
||||
|
||||
private ApplicationContext context;
|
||||
public interface CassandraMappingContext extends
|
||||
MappingContext<CassandraPersistentEntity<?>, CassandraPersistentProperty> {
|
||||
|
||||
/**
|
||||
* Creates a new {@link CassandraMappingContext}.
|
||||
* Returns a {@link CreateTableSpecification} for the given entity, including all mapping information.
|
||||
*
|
||||
* @param The entity. May not be null.
|
||||
*/
|
||||
public CassandraMappingContext() {
|
||||
setSimpleTypeHolder(new CassandraSimpleTypeHolder());
|
||||
}
|
||||
CreateTableSpecification getCreateTableSpecificationFor(CassandraPersistentEntity<?> entity);
|
||||
|
||||
@Override
|
||||
public CassandraPersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor,
|
||||
CassandraPersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
|
||||
return createPersistentProperty(field, descriptor, owner, (CassandraSimpleTypeHolder) simpleTypeHolder);
|
||||
}
|
||||
|
||||
public CassandraPersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor,
|
||||
CassandraPersistentEntity<?> owner, CassandraSimpleTypeHolder simpleTypeHolder) {
|
||||
return new CachingCassandraPersistentProperty(field, descriptor, owner, simpleTypeHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> CassandraPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
|
||||
BasicCassandraPersistentEntity<T> entity = new BasicCassandraPersistentEntity<T>(typeInformation);
|
||||
|
||||
if (context != null) {
|
||||
entity.setApplicationContext(context);
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.context = applicationContext;
|
||||
}
|
||||
/**
|
||||
* Returns whether this mapping context has any entities mapped to the given table.
|
||||
*
|
||||
* @param table May not be null.
|
||||
*/
|
||||
boolean usesTable(TableMetadata table);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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.mapping;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.data.mapping.context.AbstractMappingContext;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.TableMetadata;
|
||||
|
||||
/**
|
||||
* Default implementation of a {@link MappingContext} for Cassandra using {@link CassandraPersistentEntity} and
|
||||
* {@link CassandraPersistentProperty} as primary abstractions.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class DefaultCassandraMappingContext extends
|
||||
AbstractMappingContext<CassandraPersistentEntity<?>, CassandraPersistentProperty> implements
|
||||
CassandraMappingContext, ApplicationContextAware {
|
||||
|
||||
protected ApplicationContext context;
|
||||
protected Map<String, Set<CassandraPersistentEntity<?>>> entitySetsByTableName = new HashMap<String, Set<CassandraPersistentEntity<?>>>();
|
||||
|
||||
/**
|
||||
* Creates a new {@link DefaultCassandraMappingContext}.
|
||||
*/
|
||||
public DefaultCassandraMappingContext() {
|
||||
setSimpleTypeHolder(new CassandraSimpleTypeHolder());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CassandraPersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor,
|
||||
CassandraPersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
|
||||
|
||||
return createPersistentProperty(field, descriptor, owner, (CassandraSimpleTypeHolder) simpleTypeHolder);
|
||||
}
|
||||
|
||||
public CassandraPersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor,
|
||||
CassandraPersistentEntity<?> owner, CassandraSimpleTypeHolder simpleTypeHolder) {
|
||||
|
||||
return new CachingCassandraPersistentProperty(field, descriptor, owner, simpleTypeHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> CassandraPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
|
||||
BasicCassandraPersistentEntity<T> entity = new BasicCassandraPersistentEntity<T>(typeInformation);
|
||||
|
||||
if (context != null) {
|
||||
entity.setApplicationContext(context);
|
||||
}
|
||||
|
||||
Set<CassandraPersistentEntity<?>> entities = entitySetsByTableName.get(entity.getTableName());
|
||||
if (entities == null) {
|
||||
entities = new HashSet<CassandraPersistentEntity<?>>();
|
||||
}
|
||||
entities.add(entity);
|
||||
entitySetsByTableName.put(entity.getTableName(), entities);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.context = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesTable(TableMetadata table) {
|
||||
return entitySetsByTableName.containsKey(table.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreateTableSpecification getCreateTableSpecificationFor(CassandraPersistentEntity<?> entity) {
|
||||
|
||||
Assert.notNull(entity);
|
||||
|
||||
final CreateTableSpecification spec = new CreateTableSpecification();
|
||||
|
||||
spec.name(entity.getTableName());
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty prop) {
|
||||
|
||||
if (prop.isCompositePrimaryKey()) {
|
||||
|
||||
CassandraPersistentEntity<?> pkEntity = getPersistentEntity(prop.getRawType());
|
||||
|
||||
pkEntity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty pkProp) {
|
||||
|
||||
if (pkProp.isPartitionKeyColumn()) {
|
||||
spec.partitionKeyColumn(pkProp.getColumnName(), pkProp.getDataType());
|
||||
} else {
|
||||
spec.clusteredKeyColumn(pkProp.getColumnName(), pkProp.getDataType(), pkProp.getPrimaryKeyOrdering());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
if (prop.isIdProperty()) {
|
||||
spec.partitionKeyColumn(prop.getColumnName(), prop.getDataType());
|
||||
} else {
|
||||
spec.column(prop.getColumnName(), prop.getDataType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (spec.getPartitionKeyColumns().isEmpty()) {
|
||||
throw new MappingException("no partition key columns found in the entity " + entity.getType());
|
||||
}
|
||||
|
||||
return spec;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* Interface that stores information about the mapping between a table and the entity or the entities that are mapped to
|
||||
* it.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public interface TableMapping {
|
||||
|
||||
/**
|
||||
* Convenience method to return the only member of the set of entity classes. This method can be used when the caller
|
||||
* knows that there is only one entity class in this mapping. If there are multiple and this method is called, an
|
||||
* {@link IllegalStateException} is thrown.
|
||||
*/
|
||||
@NotNull
|
||||
Class<?> getEntityClass();
|
||||
|
||||
/**
|
||||
* Convenience method to set this mapping to use a single entity class.
|
||||
*
|
||||
* @param entityClass The class; may not be null.
|
||||
*/
|
||||
void setEntityClass(@NotNull Class<?> entityClass);
|
||||
|
||||
/**
|
||||
* Sets the set of entity classes of this mapping.
|
||||
*/
|
||||
void setEntityClasses(Set<Class<?>> entityClasses);
|
||||
|
||||
/**
|
||||
* Returns the set of entity classes of this mapping. Never returns null.
|
||||
*/
|
||||
@NotNull
|
||||
Set<Class<?>> getEntityClasses();
|
||||
|
||||
/**
|
||||
* Returns the name of this mapping. Never returns null.
|
||||
*/
|
||||
@NotNull
|
||||
String getTableName();
|
||||
|
||||
/**
|
||||
* Sets the table name of this mapping.
|
||||
*/
|
||||
void setTableName(@NotNull String tableName);
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link TableMapping}.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class TableMappingImpl implements TableMapping {
|
||||
|
||||
private Set<Class<?>> entityClasses = new HashSet<Class<?>>();
|
||||
private String tableName;
|
||||
|
||||
public TableMappingImpl(Class<?> entityClass, String tableName) {
|
||||
this(tableName);
|
||||
setEntityClass(entityClass);
|
||||
}
|
||||
|
||||
public TableMappingImpl(Set<Class<?>> entityClasses, String tableName) {
|
||||
this(tableName);
|
||||
setEntityClasses(entityClasses);
|
||||
}
|
||||
|
||||
protected TableMappingImpl(String tableName) {
|
||||
setTableName(tableName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getEntityClass() {
|
||||
if (entityClasses.size() != 1) {
|
||||
throw new IllegalStateException("more than one entity class exists in this TableMapping");
|
||||
}
|
||||
return entityClasses.iterator().next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Class<?>> getEntityClasses() {
|
||||
return entityClasses;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEntityClasses(Set<Class<?>> entityClasses) {
|
||||
this.entityClasses = entityClasses == null ? new HashSet<Class<?>>() : new HashSet<Class<?>>(entityClasses);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTableName(String tableName) {
|
||||
Assert.notNull(tableName);
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEntityClass(Class<?> entityClass) {
|
||||
if (entityClass == null) {
|
||||
throw new IllegalArgumentException("entity class required");
|
||||
}
|
||||
|
||||
entityClasses.clear();
|
||||
entityClasses.add(entityClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
|
||||
if (this == that) {
|
||||
return true;
|
||||
}
|
||||
if (that == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(that instanceof TableMapping)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TableMapping thatMapping = (TableMapping) that;
|
||||
|
||||
if (!this.tableName.equals(thatMapping.getTableName())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.entityClasses.equals(thatMapping.getEntityClasses());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return tableName.hashCode() ^ entityClasses.hashCode();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.springframework.data.cassandra.mapping;
|
||||
|
||||
public interface TableMappings {
|
||||
|
||||
TableMapping getTableMappingByClass(Class<?> entityClass);
|
||||
|
||||
TableMapping getTableMappingByTableName(String tableName);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class TableMappingsImpl implements TableMappings {
|
||||
|
||||
private Map<Class<?>, TableMapping> mappingsByClass = new HashMap<Class<?>, TableMapping>();
|
||||
private Map<String, TableMapping> mappingsByTable = new HashMap<String, TableMapping>();
|
||||
|
||||
public TableMappingsImpl(Set<TableMapping> mappings) {
|
||||
setMappings(mappings);
|
||||
}
|
||||
|
||||
public void setMappings(Set<TableMapping> mappings) {
|
||||
|
||||
mappingsByClass.clear();
|
||||
mappingsByTable.clear();
|
||||
|
||||
if (mappings == null || mappings.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (TableMapping mapping : mappings) {
|
||||
|
||||
if (mapping == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mappingsByTable.put(mapping.getTableName(), mapping);
|
||||
|
||||
for (Class<?> entityClass : mapping.getEntityClasses()) {
|
||||
mappingsByClass.put(entityClass, mapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableMapping getTableMappingByClass(Class<?> entityClass) {
|
||||
return mappingsByClass.get(entityClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableMapping getTableMappingByTableName(String tableName) {
|
||||
return mappingsByTable.get(tableName);
|
||||
}
|
||||
}
|
||||
@@ -39,24 +39,6 @@ public abstract class CqlUtils {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(CqlUtils.class);
|
||||
|
||||
/**
|
||||
* Generates the CQL String to create a table in Cassandra
|
||||
*
|
||||
* @param tableName
|
||||
* @param entity
|
||||
* @return The CQL that can be passed to session.execute()
|
||||
*/
|
||||
public static String createTable(String tableName, final CassandraPersistentEntity<?> entity,
|
||||
CassandraConverter cassandraConverter) {
|
||||
|
||||
CreateTableSpecification spec = cassandraConverter.getCreateTableSpecification(entity);
|
||||
spec.name(tableName);
|
||||
|
||||
CreateTableCqlGenerator generator = new CreateTableCqlGenerator(spec);
|
||||
|
||||
return generator.toCql();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the List of CQL for the indexes required for Cassandra mapped Table.
|
||||
*
|
||||
@@ -68,6 +50,7 @@ public abstract class CqlUtils {
|
||||
final List<String> result = new ArrayList<String>();
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty prop) {
|
||||
|
||||
if (prop.isIndexed()) {
|
||||
@@ -101,6 +84,7 @@ public abstract class CqlUtils {
|
||||
final List<String> result = new ArrayList<String>();
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty prop) {
|
||||
|
||||
String columnName = prop.getColumnName();
|
||||
|
||||
@@ -1 +1 @@
|
||||
http\://www.springframework.org/schema/data/cassandra=org.springframework.data.cassandra.config.CassandraNamespaceHandler
|
||||
http\://www.springframework.org/schema/data/cassandra=org.springframework.data.cassandra.config.xml.CassandraNamespaceHandler
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<xsd:schema xmlns="http://www.springframework.org/schema/data/cassandra"
|
||||
xmlns:base="http://www.springframework.org/schema/cassandra" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
targetNamespace="http://www.springframework.org/schema/data/cassandra"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool"
|
||||
schemaLocation="http://www.springframework.org/schema/tool/spring-tool.xsd" />
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/cassandra"
|
||||
schemaLocation="http://www.springframework.org/schema/cassandra/spring-cassandra.xsd" />
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines the configuration elements for Spring Data Cassandra support.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
|
||||
<xsd:element name="session" type="sessionType" />
|
||||
|
||||
<xsd:element name="cluster" type="clusterType"/>
|
||||
|
||||
<xsd:element name="keyspace" type="keyspaceType" />
|
||||
|
||||
<xsd:complexType name="clusterType">
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="base:clusterType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="tables" minOccurs="0" maxOccurs="unbounded" type="tablesType"></xsd:element>
|
||||
</xsd:sequence>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="datacenterType">
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="base:datacenterType"/>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="keyspaceType">
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="base:keyspaceType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="table" type="tableType" minOccurs="0" maxOccurs="unbounded"></xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="cassandra-converter-ref" type="cassandraConverterRefType" use="optional"></xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="cassandraConverterRefType" final="union">
|
||||
<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:complexContent>
|
||||
<xsd:extension base="base:poolingOptionsType"/>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="socketOptionsType">
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="base:socketOptionsType"/>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="replicationType">
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="base:replicationType"/>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="sessionType">
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="base:sessionType"/>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<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:element name="data-template" type="templateType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation
|
||||
source="org.springframework.cassandra.config.xml.TemplateFactoryBean"><![CDATA[
|
||||
Defines a CassandraTemplate.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="org.springframework.data.cassandra.CassandraDataTemplate" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:complexType name="dataTemplateType">
|
||||
<xsd:attribute name="id" type="xsd:ID" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the template; default is "cassandra-data-template".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="session-ref" type="base:sessionRef" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The reference to a Cassandra session; default is "cassandra-session".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
-->
|
||||
|
||||
<xsd:complexType name="tablesType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="table" type="tableType" minOccurs="0" maxOccurs="unbounded"></xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="keyspace-name" type="xsd:string" use="optional"></xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<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="table-name" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Table name override.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
<!--
|
||||
<xsd:simpleType name="clusterRef" final="union">
|
||||
<xsd:union memberTypes="base:clusterRef" />
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="sessionRef" final="union">
|
||||
<xsd:union memberTypes="base:sessionRef" />
|
||||
</xsd:simpleType>
|
||||
-->
|
||||
</xsd:schema>
|
||||
@@ -1,38 +1,259 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<xsd:schema xmlns="http://www.springframework.org/schema/data/cassandra"
|
||||
xmlns:base="http://www.springframework.org/schema/cassandra" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
targetNamespace="http://www.springframework.org/schema/data/cassandra"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool"
|
||||
schemaLocation="http://www.springframework.org/schema/tool/spring-tool.xsd" />
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/cassandra"
|
||||
schemaLocation="http://www.springframework.org/schema/cassandra/spring-cassandra.xsd" />
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines the configuration elements for Spring Data Cassandra support.
|
||||
]]></xsd:documentation>
|
||||
Defines the configuration elements for Spring Cassandra support.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
|
||||
<xsd:element name="session" type="base:sessionType" />
|
||||
<xsd:element name="session" type="sessionType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation
|
||||
source="org.springframework.cassandra.config.xml.SessionFactoryBean"><![CDATA[
|
||||
Defines a Cassandra session.
|
||||
]]></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="base:clusterType" />
|
||||
<xsd:element name="template" type="templateType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation
|
||||
source="org.springframework.cassandra.config.xml.TemplateFactoryBean"><![CDATA[
|
||||
Defines a CassandraTemplate.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="org.springframework.cassandra.CassandraTemplate" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="keyspace" type="base:keyspaceType" />
|
||||
<xsd:element name="cluster" type="clusterType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation
|
||||
source="org.springframework.cassandra.config.xml.CassandraClusterFactoryBean"><![CDATA[
|
||||
Defines a Cassandra cluster.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="com.datastax.driver.core.Cluster" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="local-pooling-options" type="base:poolingOptionsType" />
|
||||
<xsd:complexType name="clusterType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="local-pooling-options" type="poolingOptionsType"
|
||||
maxOccurs="1" minOccurs="0">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Local pooling options.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="remote-pooling-options" type="poolingOptionsType"
|
||||
maxOccurs="1" minOccurs="0">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Remote pooling options.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="socket-options" type="socketOptionsType"
|
||||
maxOccurs="1" minOccurs="0">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Socket options.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="keyspace" type="keyspaceType"
|
||||
minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Provides the ability to define a keyspace.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="startup-cql" type="xsd:string"
|
||||
minOccurs="0" maxOccurs="unbounded">
|
||||
<!-- TODO: cql could come from a resource via a resource attribute... -->
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Arbitrary CQL script to be executed against the system keyspace during bean initialization. Multiple elements will be executed in document order.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="shutdown-cql" type="xsd:string"
|
||||
minOccurs="0" maxOccurs="unbounded">
|
||||
<!-- TODO: cql could come from a resource via a resource attribute... -->
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Arbitrary CQL script to be executed against the system keyspace during bean destruction. Multiple elements will be executed in document order.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:ID" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the Cassandra Cluster definition; default is "cassandra-cluster".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="contactPoints" type="xsd:string"
|
||||
use="optional" default="localhost">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The comma separated list of Cassandra servers. Default is "localhost".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="port" type="xsd:string" use="optional"
|
||||
default="9042">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The native CQL port to connect to. Default is 9042.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="compression" default="NONE" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The protocol compression option. Default is "NONE".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="NONE">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
No compression.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:enumeration>
|
||||
<xsd:enumeration value="SNAPPY">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
SNAPPY compression algorithm.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:enumeration>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="auth-info-provider" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
AuthInfoProvider implementation.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="com.datastax.driver.core.AuthInfoProvider" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="load-balancing-policy" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
LoadBalancingPolicy implementation.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<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:attribute name="reconnection-policy" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
ReconnectionPolicy implementation.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<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:attribute name="retry-policy" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
RetryPolicy implementation.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<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:complexType>
|
||||
|
||||
<xsd:element name="remote-pooling-options" type="base:poolingOptionsType" />
|
||||
<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:element name="socket-options" type="base:socketOptionsType" />
|
||||
<xsd:simpleType name="sessionRef" final="union">
|
||||
<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:element name="keyspace-attributes" type="base:keyspaceAttributesType" />
|
||||
|
||||
<xsd:simpleType name="converterRef">
|
||||
<xsd:simpleType name="cassandraConverterRef" final="union">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
@@ -44,21 +265,319 @@ Defines the configuration elements for Spring Data Cassandra support.
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
|
||||
<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: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: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:documentation><![CDATA[
|
||||
More connections are created up to a configurable maximum number of connections.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<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: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: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: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: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: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:documentation><![CDATA[
|
||||
Sets the SO_SNDBUF socket option.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="sessionType">
|
||||
<xsd:sequence>
|
||||
<!-- TODO: support custom table mappings
|
||||
|
||||
<xsd:element name="mapping" minOccurs="0" maxOccurs="1" type="mappingType"/>
|
||||
-->
|
||||
<xsd:element name="startup-cql" type="xsd:string"
|
||||
minOccurs="0" maxOccurs="unbounded">
|
||||
<!-- TODO: cql could come from a resource via a resource attribute... -->
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Arbitrary CQL script to be executed against the session's keyspace during bean initialization. Multiple elements will be executed in document order.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="shutdown-cql" type="xsd:string"
|
||||
minOccurs="0" maxOccurs="unbounded">
|
||||
<!-- TODO: cql could come from a resource via a resource attribute... -->
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Arbitrary CQL script to be executed against the session's keyspace during bean destruction. Multiple elements will be executed in document order.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
|
||||
<xsd:attribute name="id" type="xsd:ID" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the session definition; default is "cassandra-session".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="cluster-ref" type="clusterRef" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The reference to a Cassandra cluster; default is "cassandra-cluster".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="keyspace-name" type="xsd:string"
|
||||
use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of a Cassandra Keyspace. No default; for the system keyspace, use the empty string.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="schema-actions" type="xsd:string"
|
||||
use="optional" default="NONE">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The schema action to take on the Cassandra Keyspace. See the SchemaAction enum.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="cassandra-converter-ref" type="cassandraConverterRef"
|
||||
use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The reference to a CassandraConverter; default is "cassandra-converter".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="templateType">
|
||||
<xsd:attribute name="id" type="xsd:ID" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the template; default is "cassandra-template".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="session-ref" type="sessionRef" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The reference to a Cassandra session; default is "cassandra-session".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="cassandra-converter-ref" type="cassandraConverterRef"
|
||||
use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The reference to a CassandraConverter; default is "cassandra-converter".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="keyspaceType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Provides the ability to define keyspaces.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="replication" type="replicationType"
|
||||
minOccurs="0" maxOccurs="1">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Provides the ability to configure the keyspace's replication settings.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of this keyspace. Required.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="action" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The keyspace action to take at startup and possibly shutdown.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="CREATE">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Action value that causes keyspace creation during bean initialization.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:enumeration>
|
||||
<xsd:enumeration value="CREATE-DROP">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Action value that causes keyspace creation during bean initialization and keyspace dropping during bean destruction.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:enumeration>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="durable-writes" type="xsd:boolean"
|
||||
use="optional" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Whether or not the keyspace supports durable writes.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="replicationType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Provides the ability to configure the keyspace's replication settings.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="data-center" type="datacenterType"
|
||||
minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Provides the ability to specify replication factors by data center.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="class" type="xsd:string" use="optional"
|
||||
default="SimpleStrategy">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the replication class; default is "SimpleStrategy".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="replication-factor" type="xsd:integer"
|
||||
use="optional" default="1">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The replication factor; default is 1.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="datacenterType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Provides the ability to specify replication factors by data center.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the data center.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="replication-factor" type="xsd:integer"
|
||||
use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The replication factor for the data center.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<!-- TODO: support custom table mappings
|
||||
|
||||
<xsd:complexType name="mappingType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="table" type="tableType" minOccurs="0"
|
||||
maxOccurs="1"></xsd:element>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="tableType">
|
||||
<xsd:attribute name="entity" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Entity class name.
|
||||
]]></xsd:documentation>
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="name" type="xsd:string" use="optional">
|
||||
<xsd:attribute name="table-name" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Table name override.
|
||||
]]></xsd:documentation>
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
-->
|
||||
</xsd:schema>
|
||||
@@ -6,13 +6,17 @@ import org.apache.cassandra.exceptions.ConfigurationException;
|
||||
import org.apache.thrift.transport.TTransportException;
|
||||
import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
// @RunWith(SpringJUnit4ClassRunner.class)
|
||||
// @ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class CassandraNamespaceTests {
|
||||
|
||||
@Autowired
|
||||
@@ -29,9 +33,8 @@ public class CassandraNamespaceTests {
|
||||
EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopCassandra() {
|
||||
EmbeddedCassandraServerHelper.stopEmbeddedCassandra();
|
||||
@Test
|
||||
public void test() {
|
||||
Assert.notNull(ctx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import org.apache.cassandra.exceptions.ConfigurationException;
|
||||
import org.apache.thrift.transport.TTransportException;
|
||||
import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -42,9 +41,4 @@ public class DriverTests {
|
||||
public void clearCassandra() {
|
||||
EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopCassandra() {
|
||||
EmbeddedCassandraServerHelper.stopEmbeddedCassandra();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import org.springframework.data.cassandra.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.convert.MappingCassandraConverter;
|
||||
import org.springframework.data.cassandra.core.CassandraDataOperations;
|
||||
import org.springframework.data.cassandra.core.CassandraDataTemplate;
|
||||
import org.springframework.data.cassandra.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext;
|
||||
|
||||
/**
|
||||
* Setup any spring configuration for unit tests
|
||||
@@ -27,7 +27,7 @@ public class TestConfig extends AbstractSpringDataCassandraConfiguration {
|
||||
|
||||
@Bean
|
||||
public CassandraConverter cassandraConverter() {
|
||||
return new MappingCassandraConverter(new CassandraMappingContext());
|
||||
return new MappingCassandraConverter(new DefaultCassandraMappingContext());
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -1,54 +1,46 @@
|
||||
<?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:cassandra-base="http://www.springframework.org/schema/cassandra"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cass="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">
|
||||
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/cassandra http://www.springframework.org/schema/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/test/integration/config/cassandra.properties" />
|
||||
|
||||
<cassandra:cluster id="cassandra-cluster"
|
||||
contactPoints="${cassandra.contactPoints}" port="${cassandra.port}"
|
||||
compression="SNAPPY">
|
||||
<cassandra-base:local-pooling-options
|
||||
<cass:cluster id="cassandra-cluster" contactPoints="${cassandra.contactPoints}"
|
||||
port="${cassandra.port}">
|
||||
<cass:local-pooling-options
|
||||
min-simultaneous-requests="25" max-simultaneous-requests="100"
|
||||
core-connections="2" max-connections="8" />
|
||||
<cassandra-base:remote-pooling-options
|
||||
<cass:remote-pooling-options
|
||||
min-simultaneous-requests="25" max-simultaneous-requests="100"
|
||||
core-connections="1" max-connections="2" />
|
||||
<cassandra-base: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>
|
||||
<cass: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" />
|
||||
<cass:keyspace name="TestKS123" action="CREATE"
|
||||
durable-writes="true" />
|
||||
</cass:cluster>
|
||||
|
||||
<!-- TODO: not require that this bean be defined -->
|
||||
<bean id="cassandra-mapping"
|
||||
class=" org.springframework.data.cassandra.mapping.CassandraMappingContext" />
|
||||
class="org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext"/>
|
||||
|
||||
<!-- TODO: not require that this bean be defined -->
|
||||
<bean id="cassandra-converter"
|
||||
class=" org.springframework.data.cassandra.convert.MappingCassandraConverter">
|
||||
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-base:keyspace-attributes auto="update"
|
||||
replication-stategy="SimpleStrategy" replication-factor="1"
|
||||
durable-writes="true">
|
||||
<cassandra:table entity="org.springframework.data.cassandra.test.integration.table.Comment" />
|
||||
<cassandra:table
|
||||
entity="org.springframework.data.cassandra.test.integration.table.Notification" />
|
||||
<cassandra:table entity="org.springframework.data.cassandra.test.integration.table.Post" />
|
||||
<cassandra:table entity="org.springframework.data.cassandra.test.integration.table.Timeline" />
|
||||
<cassandra:table entity="org.springframework.data.cassandra.test.integration.table.User" />
|
||||
</cassandra-base:keyspace-attributes>
|
||||
</cassandra:keyspace>
|
||||
|
||||
<cassandra:session id="cassandra-session" keyspace-name="${cassandra.keyspace}"/>
|
||||
|
||||
<cassandra:template session-ref="cassandra-session"/>
|
||||
<cass:session id="cassandra-session" keyspace-name="TestKS123"
|
||||
schema-actions="NONE" cluster-ref="cassandra-cluster"
|
||||
cassandra-converter-ref="cassandra-converter">
|
||||
</cass:session>
|
||||
|
||||
<cass:template session-ref="cassandra-session" />
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
cassandra.contactPoints=localhost
|
||||
cassandra.port=9042
|
||||
cassandra.keyspace=TestKS123
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
</cassandra:cluster>
|
||||
|
||||
<bean id="cassandra-mapping"
|
||||
class=" org.springframework.data.cassandra.mapping.CassandraMappingContext" />
|
||||
class=" org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext" />
|
||||
|
||||
<bean id="cassandra-converter"
|
||||
class=" org.springframework.data.cassandra.convert.MappingCassandraConverter">
|
||||
|
||||
Reference in New Issue
Block a user