Merge branch 'DATACASS-91'
This commit is contained in:
@@ -22,7 +22,7 @@ import static org.springframework.cassandra.config.xml.ParsingUtils.addRequiredP
|
||||
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.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.cassandra.config.CassandraSessionFactoryBean;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -37,7 +37,7 @@ import org.w3c.dom.NamedNodeMap;
|
||||
* @author David Webb
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraSessionParser extends AbstractSimpleBeanDefinitionParser {
|
||||
public class CassandraSessionParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
*/
|
||||
package org.springframework.cassandra.config.xml;
|
||||
|
||||
import static org.springframework.cassandra.config.xml.ParsingUtils.*;
|
||||
import static org.springframework.cassandra.config.xml.ParsingUtils.addOptionalPropertyReference;
|
||||
|
||||
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.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.cassandra.config.CassandraTemplateFactoryBean;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -32,7 +32,7 @@ import org.w3c.dom.Element;
|
||||
* @author David Webb
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraTemplateParser extends AbstractSimpleBeanDefinitionParser {
|
||||
public class CassandraTemplateParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
|
||||
@@ -22,7 +22,7 @@ package org.springframework.cassandra.config.xml;
|
||||
*/
|
||||
public interface DefaultBeanNames {
|
||||
|
||||
public static final String CLUSTER = "cassandra-cluster";
|
||||
public static final String SESSION = "cassandra-session";
|
||||
public static final String TEMPLATE = "cql-template";
|
||||
public static final String CLUSTER = "cassandraCluster";
|
||||
public static final String SESSION = "cassandraSession";
|
||||
public static final String TEMPLATE = "cqlTemplate";
|
||||
}
|
||||
|
||||
@@ -10,69 +10,66 @@
|
||||
location="classpath:/org/springframework/cassandra/test/integration/config/xml/ppncxct.properties" />
|
||||
|
||||
<bean id="authProvider" class="com.datastax.driver.core.sasl.DseAuthProvider" />
|
||||
|
||||
<bean id="loadBalancingPolicy" class="com.datastax.driver.core.policies.DCAwareRoundRobinPolicy">
|
||||
|
||||
<bean id="loadBalancingPolicy"
|
||||
class="com.datastax.driver.core.policies.DCAwareRoundRobinPolicy">
|
||||
<constructor-arg name="localDc" value="${lb.policy.dcAware.localDc}" />
|
||||
<constructor-arg name="usedHostsPerRemoteDc" value="${lb.policy.dcAware.remoteHosts}" />
|
||||
<constructor-arg name="usedHostsPerRemoteDc"
|
||||
value="${lb.policy.dcAware.remoteHosts}" />
|
||||
</bean>
|
||||
|
||||
<bean id="reconnectionPolicy" class="com.datastax.driver.core.policies.ConstantReconnectionPolicy">
|
||||
<constructor-arg name="constantDelayMs" value="${cluster.reconnection.delayMillis}"/>
|
||||
|
||||
<bean id="reconnectionPolicy"
|
||||
class="com.datastax.driver.core.policies.ConstantReconnectionPolicy">
|
||||
<constructor-arg name="constantDelayMs"
|
||||
value="${cluster.reconnection.delayMillis}" />
|
||||
</bean>
|
||||
|
||||
<bean id="retryPolicy" class="com.datastax.driver.core.policies.DowngradingConsistencyRetryPolicy" />
|
||||
|
||||
<bean id="hostStateListener" class="org.springframework.cassandra.test.integration.config.xml.TestHostStateListener"/>
|
||||
|
||||
<bean id="latencyTracker" class="org.springframework.cassandra.test.integration.config.xml.TestLatencyTracker"/>
|
||||
<bean id="retryPolicy"
|
||||
class="com.datastax.driver.core.policies.DowngradingConsistencyRetryPolicy" />
|
||||
|
||||
<cassandra:cluster id="cassandra-cluster"
|
||||
contact-points="${cluster.contactPoints}" port="${cluster.port}"
|
||||
compression="${cluster.compression}" auth-info-provider-ref="authProvider"
|
||||
load-balancing-policy-ref="loadBalancingPolicy" username="${auth.username}" password="${auth.password}"
|
||||
<bean id="hostStateListener"
|
||||
class="org.springframework.cassandra.test.integration.config.xml.TestHostStateListener" />
|
||||
|
||||
<bean id="latencyTracker"
|
||||
class="org.springframework.cassandra.test.integration.config.xml.TestLatencyTracker" />
|
||||
|
||||
<cassandra:cluster contact-points="${cluster.contactPoints}"
|
||||
port="${cluster.port}" compression="${cluster.compression}"
|
||||
auth-info-provider-ref="authProvider" load-balancing-policy-ref="loadBalancingPolicy"
|
||||
username="${auth.username}" password="${auth.password}"
|
||||
deferred-initialization="${cluster.deferredInit}" metrics-enabled="${cluster.metricsEnabled}"
|
||||
jmx-reporting-enabled="${cluster.jmxReportingEnabled}"
|
||||
reconnection-policy-ref="reconnectionPolicy"
|
||||
retry-policy-ref="retryPolicy"
|
||||
host-state-listener-ref="hostStateListener"
|
||||
latency-tracker-ref="latencyTracker">
|
||||
<cassandra:local-pooling-options
|
||||
reconnection-policy-ref="reconnectionPolicy" retry-policy-ref="retryPolicy"
|
||||
host-state-listener-ref="hostStateListener" latency-tracker-ref="latencyTracker">
|
||||
<cassandra:local-pooling-options
|
||||
min-simultaneous-requests="${local.min.requests}"
|
||||
max-simultaneous-requests="${local.max.requests}"
|
||||
core-connections="${local.core.connections}"
|
||||
max-connections="${local.max.connections}"
|
||||
/>
|
||||
<cassandra:remote-pooling-options
|
||||
max-simultaneous-requests="${local.max.requests}" core-connections="${local.core.connections}"
|
||||
max-connections="${local.max.connections}" />
|
||||
<cassandra:remote-pooling-options
|
||||
min-simultaneous-requests="${remote.min.requests}"
|
||||
max-simultaneous-requests="${remote.max.requests}"
|
||||
core-connections="${remote.core.connections}"
|
||||
max-connections="${remote.max.connections}"
|
||||
/>
|
||||
<cassandra:socket-options
|
||||
connect-timeout-millis="${socket.connectTimeoutMillis}"
|
||||
keep-alive="${socket.keepAlive}"
|
||||
read-timeout-millis="${socket.readTimeoutMillis}"
|
||||
reuse-address="${socket.reuseAddress}"
|
||||
so-linger="${socket.soLinger}"
|
||||
tcp-no-delay="${socket.tcpNoDelay}"
|
||||
receive-buffer-size="${socket.receiveBufferSize}"
|
||||
send-buffer-size="${socket.sendBufferSize}"
|
||||
/>
|
||||
<cassandra:keyspace name="${keyspace.name}" action="${keyspace.action}"/>
|
||||
<cassandra:keyspace name="Foo123" action="CREATE_DROP" durable-writes="true">
|
||||
max-simultaneous-requests="${remote.max.requests}" core-connections="${remote.core.connections}"
|
||||
max-connections="${remote.max.connections}" />
|
||||
<cassandra:socket-options
|
||||
connect-timeout-millis="${socket.connectTimeoutMillis}" keep-alive="${socket.keepAlive}"
|
||||
read-timeout-millis="${socket.readTimeoutMillis}" reuse-address="${socket.reuseAddress}"
|
||||
so-linger="${socket.soLinger}" tcp-no-delay="${socket.tcpNoDelay}"
|
||||
receive-buffer-size="${socket.receiveBufferSize}" send-buffer-size="${socket.sendBufferSize}" />
|
||||
<cassandra:keyspace name="${keyspace.name}" action="${keyspace.action}" />
|
||||
<cassandra:keyspace name="Foo123" action="CREATE_DROP"
|
||||
durable-writes="true">
|
||||
<cassandra:replication class="NETWORK_TOPOLOGY_STRATEGY">
|
||||
<cassandra:data-center replication-factor="${dc1.rf}" name="${dc1.name}"/>
|
||||
<cassandra:data-center replication-factor="${dc1.rf}" name="${dc2.name}"/>
|
||||
<cassandra:data-center replication-factor="${dc1.rf}"
|
||||
name="${dc1.name}" />
|
||||
<cassandra:data-center replication-factor="${dc1.rf}"
|
||||
name="${dc2.name}" />
|
||||
</cassandra:replication>
|
||||
</cassandra:keyspace>
|
||||
</cassandra:cluster>
|
||||
|
||||
<cassandra:session id="cassandra-session"
|
||||
keyspace-name="system">
|
||||
</cassandra:session>
|
||||
<cassandra:session keyspace-name="system" />
|
||||
|
||||
<bean id="cassandraTemplate" class="org.springframework.cassandra.core.CqlTemplate">
|
||||
<constructor-arg ref="cassandra-session" />
|
||||
<constructor-arg ref="cassandraSession" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
<context:property-placeholder
|
||||
location="classpath:org.springframework.cassandra.test.integration.support.SpringCassandraBuildProperties.properties" />
|
||||
|
||||
<cassandra:cluster id="cassandra-cluster"
|
||||
contact-points="localhost" port="${build.cassandra.native_transport_port}">
|
||||
<cassandra:cluster contact-points="localhost"
|
||||
port="${build.cassandra.native_transport_port}">
|
||||
<cassandra:local-pooling-options
|
||||
min-simultaneous-requests="25" max-simultaneous-requests="100"
|
||||
core-connections="2" max-connections="8" />
|
||||
@@ -18,16 +18,15 @@
|
||||
min-simultaneous-requests="25" max-simultaneous-requests="100"
|
||||
core-connections="1" max-connections="2" />
|
||||
<cassandra:socket-options
|
||||
connect-timeout-millis="5000" keep-alive="true" read-timeout-millis="60000" reuse-address="true"
|
||||
so-linger="60" tcp-no-delay="true" receive-buffer-size="65536"
|
||||
send-buffer-size="65536" />
|
||||
connect-timeout-millis="5000" keep-alive="true" read-timeout-millis="60000"
|
||||
reuse-address="true" so-linger="60" tcp-no-delay="true"
|
||||
receive-buffer-size="65536" send-buffer-size="65536" />
|
||||
</cassandra:cluster>
|
||||
|
||||
<cassandra:session id="cassandra-session"
|
||||
keyspace-name="xmlconfigtest" />
|
||||
<cassandra:session keyspace-name="xmlconfigtest" />
|
||||
|
||||
<bean id="cassandraTemplate" class="org.springframework.cassandra.core.CqlTemplate">
|
||||
<constructor-arg ref="cassandra-session" />
|
||||
<constructor-arg ref="cassandraSession" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package org.springframework.data.cassandra.config;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Parameter used in conjunction with:
|
||||
* <p/>
|
||||
* {@link BeanDefinitionBuilder#addConstructorArgReference(String)},
|
||||
* {@link BeanDefinitionBuilder#addConstructorArgValue(Object)},
|
||||
* {@link BeanDefinitionBuilder#addPropertyReference(String, String)}, and
|
||||
* {@link BeanDefinitionBuilder#addPropertyValue(String, Object)}.
|
||||
* <p/>
|
||||
* Easy and succinct to create if methods {@link #ref(CharSequence)} or {@link #val(Object)} are used and imported
|
||||
* statically.
|
||||
*
|
||||
* @see BeanDefinitionBuilderArgument#ref(CharSequence)
|
||||
* @see BeanDefinitionBuilderArgument#val(Object)
|
||||
*/
|
||||
public class BeanDefinitionBuilderArgument {
|
||||
|
||||
/**
|
||||
* Returns a {@link BeanDefinitionBuilderArgument} with {@link #reference} equal to <code>true</code>. Convenient if
|
||||
* imported statically.
|
||||
*
|
||||
* @param value The name of the bean reference.
|
||||
*/
|
||||
public static BeanDefinitionBuilderArgument ref(CharSequence value) {
|
||||
return new BeanDefinitionBuilderArgument(true, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link BeanDefinitionBuilderArgument} with {@link #reference} equal to <code>false</code>. Convenient if
|
||||
* imported statically.
|
||||
*
|
||||
* @param value The constructor argument's value.
|
||||
*/
|
||||
public static BeanDefinitionBuilderArgument val(Object value) {
|
||||
return new BeanDefinitionBuilderArgument(false, value);
|
||||
}
|
||||
|
||||
protected boolean reference;
|
||||
protected Object value;
|
||||
|
||||
protected BeanDefinitionBuilderArgument(boolean reference, Object value) {
|
||||
this.reference = reference;
|
||||
if (this.reference && (value == null || !(value instanceof CharSequence))) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"reference argument must have value of type CharSequence, not [%s]", value == null ? "null" : value
|
||||
.getClass().getName()));
|
||||
}
|
||||
if (!StringUtils.hasText((CharSequence) value)) {
|
||||
throw new IllegalArgumentException("given CharSequence has no text");
|
||||
}
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean isReference() {
|
||||
return reference;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
package org.springframework.data.cassandra.config;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
public class BeanDefinitionUtils {
|
||||
|
||||
/**
|
||||
* Returns a {@link BeanDefinitionBuilder} iff no {@link BeanDefinition} of the required type is found in the given
|
||||
* {@link ListableBeanFactory}, otherwise returns <code>null</code>, indicating that at least one existed.
|
||||
*
|
||||
* @param factory The {@link ListableBeanFactory} in which to look for the {@link BeanDefinition}, including
|
||||
* ancestors.
|
||||
* @param requiredType The {@link BeanDefinition}'s required type.
|
||||
* @param instantiableType The instantiable type for the {@link BeanDefinitionBuilder}.
|
||||
* @param constructorArgs Any {@link BeanDefinitionBuilderArgument}s required by the instantiableType's constructor.
|
||||
* @return A {@link BeanDefinitionBuilder} iff no {@link BeanDefinition} of the required type is found, otherwise
|
||||
* <code>null</code>.
|
||||
* @see BeanDefinitionUtils#createBeanDefinitionBuilderIfNoBeanDefinitionOfTypeExists(ListableBeanFactory, Class,
|
||||
* Class, BeanDefinitionBuilderArgument...)
|
||||
* @see BeanDefinitionBuilderArgument#ref(Object)
|
||||
* @see BeanDefinitionBuilderArgument#val(Object)
|
||||
*/
|
||||
public static BeanDefinitionBuilder createBeanDefinitionBuilderIfNoBeanDefinitionOfTypeExists(
|
||||
ListableBeanFactory factory, Class<?> requiredType, Class<?> instantiableType,
|
||||
BeanDefinitionBuilderArgument... constructorArgs) {
|
||||
|
||||
String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(factory, requiredType, true, false);
|
||||
if (names.length > 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(instantiableType);
|
||||
if (constructorArgs == null) {
|
||||
return builder;
|
||||
}
|
||||
|
||||
for (BeanDefinitionBuilderArgument arg : constructorArgs) {
|
||||
if (arg.reference) {
|
||||
builder.addConstructorArgReference(arg.value.toString());
|
||||
} else {
|
||||
builder.addConstructorArgValue(arg.value);
|
||||
}
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the single {@link BeanDefinitionHolder} with the given type, or null of none were found and
|
||||
* <code>required</code> was <code>false</code>, otherwise throws {@link IllegalArgumentException}.
|
||||
*
|
||||
* @param registry The {@link BeanDefinitionRegistry}, often the very same instance as the <code>factor</code>
|
||||
* parameter.
|
||||
* @param factory The {@link ListableBeanFactory}, often the very same instance as the <code>registry</code>
|
||||
* parameter.
|
||||
* @param type The required {@link BeanDefinition}'s type.
|
||||
* @param includeNonSingletons Whether to include beans with scope other than <code>singleton</code>
|
||||
* @param allowEagerInit Whether to allow eager initialization of beans.
|
||||
* @param required Whether to allow the return of null if none were found.
|
||||
* @return The {@link BeanDefinitionHolder} or null if none found, depending on the value of <code>required</code>.
|
||||
* @throws IllegalArgumentException If multiple were found.
|
||||
* @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, Class, boolean, boolean)
|
||||
*/
|
||||
public static BeanDefinitionHolder getSingleBeanDefinitionOfType(BeanDefinitionRegistry registry,
|
||||
ListableBeanFactory factory, Class<?> type, boolean includeNonSingletons, boolean allowEagerInit, boolean required) {
|
||||
|
||||
BeanDefinitionHolder[] definitions = getBeanDefinitionsOfType(registry, factory, type, includeNonSingletons,
|
||||
allowEagerInit);
|
||||
|
||||
if (definitions.length == 1) {
|
||||
return definitions[0];
|
||||
}
|
||||
|
||||
if (definitions.length == 0 && !required) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] names = new String[definitions.length];
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
names[i] = definitions[i].getBeanName();
|
||||
}
|
||||
|
||||
throw new IllegalStateException(String.format("expected one bean definition of type [%s], but found %d: %s",
|
||||
type.getName(), definitions.length, StringUtils.arrayToCommaDelimitedString(names)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all {@link BeanDefinitionHolder}s with the given type.
|
||||
*
|
||||
* @param registry The {@link BeanDefinitionRegistry}, often the very same instance as the <code>factor</code>
|
||||
* parameter.
|
||||
* @param factory The {@link ListableBeanFactory}, often the very same instance as the <code>registry</code>
|
||||
* parameter.
|
||||
* @param type The required {@link BeanDefinition}'s type.
|
||||
* @param includeNonSingletons Whether to include beans with scope other than <code>singleton</code>
|
||||
* @param allowEagerInit Whether to allow eager initialization of beans.
|
||||
* @param required Whether to allow the return of null if none were found.
|
||||
* @return The {@link BeanDefinitionHolder}s -- never returns null.
|
||||
* @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, Class, boolean, boolean)
|
||||
*/
|
||||
public static BeanDefinitionHolder[] getBeanDefinitionsOfType(BeanDefinitionRegistry registry,
|
||||
ListableBeanFactory factory, Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
|
||||
|
||||
String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(factory, type, includeNonSingletons,
|
||||
allowEagerInit);
|
||||
|
||||
if (names.length == 0) {
|
||||
return new BeanDefinitionHolder[] {};
|
||||
}
|
||||
|
||||
BeanDefinitionHolder[] array = new BeanDefinitionHolder[names.length];
|
||||
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
|
||||
String name = names[i];
|
||||
BeanDefinition beanDefinition = null;
|
||||
|
||||
while (beanDefinition == null) {
|
||||
try {
|
||||
beanDefinition = registry.getBeanDefinition(name);
|
||||
} catch (NoSuchBeanDefinitionException x) {
|
||||
if (FactoryBean.class.isAssignableFrom(type)) { // try unmangled BeanFactory-prefixed name
|
||||
name = name.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
|
||||
} else {
|
||||
throw x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
array[i] = new BeanDefinitionHolder(beanDefinition, name);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,7 @@ 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.data.cassandra.mapping.EntityMapping;
|
||||
import org.springframework.data.cassandra.mapping.Mapping;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.datastax.driver.core.KeyspaceMetadata;
|
||||
import com.datastax.driver.core.Metadata;
|
||||
@@ -22,8 +19,6 @@ public class CassandraDataSessionFactoryBean extends CassandraSessionFactoryBean
|
||||
protected CassandraAdminTemplate admin;
|
||||
protected CassandraConverter converter;
|
||||
protected CassandraMappingContext mappingContext;
|
||||
protected Mapping mapping;
|
||||
protected ClassLoader entityClassLoader = getClass().getClassLoader();
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
@@ -34,42 +29,9 @@ public class CassandraDataSessionFactoryBean extends CassandraSessionFactoryBean
|
||||
|
||||
admin = new CassandraAdminTemplate(session, converter);
|
||||
|
||||
mapping = mapping == null ? new Mapping() : mapping;
|
||||
|
||||
processMappingOverrides();
|
||||
performSchemaAction();
|
||||
}
|
||||
|
||||
protected void processMappingOverrides() throws ClassNotFoundException {
|
||||
|
||||
if (mapping == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (EntityMapping entityMapping : mapping.getEntityMappings()) {
|
||||
|
||||
if (entityMapping == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String entityClassName = entityMapping.getEntityClassName();
|
||||
Class<?> entityClass = Class.forName(entityClassName, false, entityClassLoader);
|
||||
|
||||
CassandraPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
|
||||
|
||||
if (entity == null) {
|
||||
throw new IllegalStateException(String.format("unknown persistent entity class name [%s]", entityClassName));
|
||||
}
|
||||
|
||||
String tableName = entityMapping.getTableName();
|
||||
if (!StringUtils.hasText(tableName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
entity.setTableName(tableName);
|
||||
}
|
||||
}
|
||||
|
||||
protected void performSchemaAction() {
|
||||
|
||||
boolean dropTables = false;
|
||||
@@ -138,22 +100,4 @@ public class CassandraDataSessionFactoryBean extends CassandraSessionFactoryBean
|
||||
this.converter = converter;
|
||||
this.mappingContext = converter.getMappingContext();
|
||||
}
|
||||
|
||||
public Mapping getMapping() {
|
||||
return mapping;
|
||||
}
|
||||
|
||||
public void setMapping(Mapping mapping) {
|
||||
Assert.notNull(mapping);
|
||||
this.mapping = mapping;
|
||||
}
|
||||
|
||||
public ClassLoader getEntityClassLoader() {
|
||||
return entityClassLoader;
|
||||
}
|
||||
|
||||
public void setEntityClassLoader(ClassLoader entityClassLoader) {
|
||||
Assert.notNull(entityClassLoader);
|
||||
this.entityClassLoader = entityClassLoader;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
package org.springframework.data.cassandra.config;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.data.cassandra.mapping.PrimaryKeyClass;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Scans packages for Cassandra entities.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraEntityClassScanner {
|
||||
|
||||
public static Set<Class<?>> scan(String... entityBasePackages) throws ClassNotFoundException {
|
||||
return new CassandraEntityClassScanner(entityBasePackages).scanForEntityClasses();
|
||||
}
|
||||
|
||||
public static Set<Class<?>> scan(Class<?>... entityBasePackageClasses) throws ClassNotFoundException {
|
||||
return new CassandraEntityClassScanner(entityBasePackageClasses).scanForEntityClasses();
|
||||
}
|
||||
|
||||
public static Set<Class<?>> scan(Collection<String> entityBasePackages) throws ClassNotFoundException {
|
||||
return new CassandraEntityClassScanner(entityBasePackages).scanForEntityClasses();
|
||||
}
|
||||
|
||||
public static Set<Class<?>> scan(Collection<String> entityBasePackages, Collection<Class<?>> entityBasePackageClasses)
|
||||
throws ClassNotFoundException {
|
||||
return new CassandraEntityClassScanner(entityBasePackages, entityBasePackageClasses).scanForEntityClasses();
|
||||
}
|
||||
|
||||
protected Set<String> entityBasePackages = new HashSet<String>();
|
||||
protected Set<Class<?>> entityBasePackageClasses = new HashSet<Class<?>>();
|
||||
protected ClassLoader beanClassLoader;
|
||||
|
||||
public CassandraEntityClassScanner() {
|
||||
}
|
||||
|
||||
public CassandraEntityClassScanner(Class<?>... entityBasePackageClasses) {
|
||||
this(null, Arrays.asList(entityBasePackageClasses));
|
||||
}
|
||||
|
||||
public CassandraEntityClassScanner(String... entityBasePackages) {
|
||||
this(Arrays.asList(entityBasePackages));
|
||||
}
|
||||
|
||||
public CassandraEntityClassScanner(Collection<String> entityBasePackages) {
|
||||
this(entityBasePackages, null);
|
||||
}
|
||||
|
||||
public CassandraEntityClassScanner(Collection<String> entityBasePackages,
|
||||
Collection<Class<?>> entityBasePackageClasses) {
|
||||
|
||||
setEntityBasePackages(entityBasePackages);
|
||||
setEntityBasePackageClasses(entityBasePackageClasses);
|
||||
}
|
||||
|
||||
public Set<String> getEntityBasePackages() {
|
||||
return Collections.unmodifiableSet(entityBasePackages);
|
||||
}
|
||||
|
||||
public void setEntityBasePackages(Collection<String> entityBasePackages) {
|
||||
this.entityBasePackages = entityBasePackages == null ? new HashSet<String>() : new HashSet<String>(
|
||||
entityBasePackages);
|
||||
}
|
||||
|
||||
public Set<Class<?>> getEntityBasePackageClasses() {
|
||||
return Collections.unmodifiableSet(entityBasePackageClasses);
|
||||
}
|
||||
|
||||
public void setEntityBasePackageClasses(Collection<Class<?>> entityBasePackageClasses) {
|
||||
this.entityBasePackageClasses = entityBasePackageClasses == null ? new HashSet<Class<?>>() : new HashSet<Class<?>>(
|
||||
entityBasePackageClasses);
|
||||
}
|
||||
|
||||
public void setBeanClassLoader(ClassLoader beanClassLoader) {
|
||||
this.beanClassLoader = beanClassLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans the mapping base package for entity classes annotated with {@link Table} or {@link Persistent}.
|
||||
*
|
||||
* @see #getEntityBasePackages()
|
||||
* @return <code>Set<Class<?>></code> representing the annotated entity classes found.
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
public Set<Class<?>> scanForEntityClasses() throws ClassNotFoundException {
|
||||
|
||||
Set<Class<?>> classes = new HashSet<Class<?>>();
|
||||
|
||||
for (String basePackage : getEntityBasePackages()) {
|
||||
classes.addAll(scanBasePackageForEntities(basePackage));
|
||||
}
|
||||
|
||||
for (Class<?> basePackageClass : getEntityBasePackageClasses()) {
|
||||
classes.addAll(scanBasePackageForEntities(basePackageClass.getPackage().getName()));
|
||||
}
|
||||
|
||||
return classes;
|
||||
}
|
||||
|
||||
protected Set<Class<?>> scanBasePackageForEntities(String basePackage) throws ClassNotFoundException {
|
||||
|
||||
HashSet<Class<?>> classes = new HashSet<Class<?>>();
|
||||
|
||||
if (StringUtils.hasText(basePackage)) {
|
||||
ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(
|
||||
false);
|
||||
for (Class<? extends Annotation> annoClass : getEntityAnnotations()) {
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(annoClass));
|
||||
}
|
||||
|
||||
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
|
||||
classes.add(ClassUtils.forName(candidate.getBeanClassName(), beanClassLoader));
|
||||
}
|
||||
}
|
||||
|
||||
return classes;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Class<? extends Annotation>[] getEntityAnnotations() {
|
||||
return new Class[] { Table.class, Persistent.class, PrimaryKeyClass.class };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
package org.springframework.data.cassandra.config;
|
||||
|
||||
import static org.springframework.data.cassandra.config.BeanDefinitionUtils.getBeanDefinitionsOfType;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
|
||||
import org.springframework.data.cassandra.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.convert.MappingCassandraConverter;
|
||||
import org.springframework.data.cassandra.core.CassandraOperations;
|
||||
import org.springframework.data.cassandra.core.CassandraTemplate;
|
||||
import org.springframework.data.cassandra.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.datastax.driver.core.Session;
|
||||
|
||||
/**
|
||||
* {@link BeanDefinitionRegistryPostProcessor} that does its best to register any missing Spring Data Cassandra beans
|
||||
* that can be defaulted. Specifically, it attempts to create default bean definitions for the following required
|
||||
* interface types via their default implementation types:
|
||||
* <ul>
|
||||
* <li>{@link CassandraOperations} via {@link CassandraTemplate}</li>
|
||||
* <li>{@link CassandraMappingContext} via {@link DefaultCassandraMappingContext}</li>
|
||||
* <li> {@link CassandraConverter} via {@link MappingCassandraConverter}</li>
|
||||
* </ul>
|
||||
* <p/>
|
||||
* If there are multiple definitions for any type that another type depends on, an {@link IllegalStateException} is
|
||||
* thrown. For example, if there are two definitions for type {@link CassandraMappingContext} present and no definition
|
||||
* for type {@link CassandraConverter}, then it's impossible to know which {@link CassandraMappingContext} is to be used
|
||||
* when creating a default definition for the {@link CassandraConverter}.
|
||||
* <p/>
|
||||
* If a single definition of a required type is present, then it is used. For example, if there is already a
|
||||
* {@link CassandraMappingContext} definition present, then it will be used in the
|
||||
* {@link DefaultCassandraMappingContext} bean definition.
|
||||
* <p/>
|
||||
* It requires that a single {@link Session} or {@link CassandraDataSessionFactoryBean} definition be present. As
|
||||
* described above, multiple {@link Session} definitions, multiple {@link CassandraDataSessionFactoryBean} definitions,
|
||||
* or both a {@link Session} and {@link CassandraDataSessionFactoryBean} will cause an {@link IllegalStateException} to
|
||||
* be thrown.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraMappingBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {
|
||||
|
||||
/**
|
||||
* Does nothing.
|
||||
*/
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that {@link BeanDefinition}s for a {@link CassandraMappingContext} and a {@link CassandraConverter} exist.
|
||||
*/
|
||||
@Override
|
||||
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
|
||||
|
||||
if (!(registry instanceof ListableBeanFactory)) {
|
||||
return;
|
||||
}
|
||||
ListableBeanFactory factory = (ListableBeanFactory) registry;
|
||||
|
||||
registerMissingDefaultableBeanDefinitions(registry, factory);
|
||||
}
|
||||
|
||||
protected void registerMissingDefaultableBeanDefinitions(BeanDefinitionRegistry registry, ListableBeanFactory factory) {
|
||||
|
||||
// see if any template definitions exist, which requires a converter, which requires a mapping context
|
||||
BeanDefinitionHolder[] templateBeans = getBeanDefinitionsOfType(registry, factory, CassandraOperations.class, true,
|
||||
false);
|
||||
|
||||
if (templateBeans.length >= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// need a session & converter for the default template
|
||||
|
||||
// see if an actual Session definition exists
|
||||
String sessionBeanName = findSessionBeanName(registry, factory);
|
||||
|
||||
// see if any converter bean definitions exist, which requires a mapping context
|
||||
BeanDefinitionHolder[] converterBeans = getBeanDefinitionsOfType(registry, factory,
|
||||
MappingCassandraConverter.class, true, false);
|
||||
|
||||
if (converterBeans.length == 1) {
|
||||
|
||||
registerDefaultTemplate(registry, sessionBeanName, converterBeans[0].getBeanName());
|
||||
return;
|
||||
} else if (converterBeans.length > 1) {
|
||||
// then throw, because we need to create a default converter, but we wouldn't know which mapping context to use
|
||||
throw new IllegalStateException(String.format(
|
||||
"found %d beans of type [%s] - can't disambiguate for creation of [%s]", converterBeans.length,
|
||||
CassandraConverter.class.getName(), CassandraTemplate.class.getName()));
|
||||
}
|
||||
|
||||
// see if any mapping context bean definitions exist
|
||||
BeanDefinitionHolder[] contextBeans = getBeanDefinitionsOfType(registry, factory, CassandraMappingContext.class,
|
||||
true, false);
|
||||
|
||||
if (contextBeans.length > 1) {
|
||||
// then throw, because we need to create a default converter, but we wouldn't know which mapping context to use
|
||||
throw new IllegalStateException(String.format(
|
||||
"found %d beans of type [%s] - can't disambiguate for creation of [%s]", contextBeans.length,
|
||||
CassandraMappingContext.class.getName(), MappingCassandraConverter.class.getName()));
|
||||
}
|
||||
|
||||
// create the mapping context if necessary
|
||||
BeanDefinitionHolder contextBean = contextBeans.length == 1 ? contextBeans[0] : null;
|
||||
if (contextBean == null) {
|
||||
contextBean = regsiterDefaultContext(registry);
|
||||
}
|
||||
|
||||
// create the default converter & template bean definitions
|
||||
BeanDefinitionHolder converter = registerDefaultConverter(registry, contextBean.getBeanName());
|
||||
registerDefaultTemplate(registry, sessionBeanName, converter.getBeanName());
|
||||
}
|
||||
|
||||
public String findSessionBeanName(BeanDefinitionRegistry registry, ListableBeanFactory factory) {
|
||||
|
||||
// first, search for any session and session factory beans
|
||||
BeanDefinitionHolder[] sessionBeans = getBeanDefinitionsOfType(registry, factory, Session.class, true, false);
|
||||
BeanDefinitionHolder[] sessionFactoryBeans = getBeanDefinitionsOfType(registry, factory,
|
||||
CassandraDataSessionFactoryBean.class, true, false);
|
||||
|
||||
int sessionCount = sessionBeans.length;
|
||||
int sessionFactoryCount = sessionFactoryBeans.length;
|
||||
int totalCount = sessionCount + sessionFactoryCount;
|
||||
|
||||
if (totalCount == 0 || totalCount > 1) { // can't create default template -- none or multiple
|
||||
throw createSessionException(totalCount, Session.class, CassandraDataSessionFactoryBean.class);
|
||||
}
|
||||
|
||||
if (sessionCount == 1) {
|
||||
return sessionBeans[0].getBeanName();
|
||||
}
|
||||
// else it must be the one session factory bean
|
||||
return sessionFactoryBeans[0].getBeanName();
|
||||
}
|
||||
|
||||
protected IllegalStateException createSessionException(int beanDefinitionCount, Class<?>... types) {
|
||||
|
||||
return new IllegalStateException(String.format("found %d beans of type%s [%s] - %s for creation of default [%s]",
|
||||
beanDefinitionCount, beanDefinitionCount == 1 ? "" : "s", StringUtils.arrayToCommaDelimitedString(types),
|
||||
beanDefinitionCount == 0 ? "need exactly one" : "can't disambiguate", CassandraTemplate.class.getName()));
|
||||
}
|
||||
|
||||
protected BeanDefinitionHolder regsiterDefaultContext(BeanDefinitionRegistry registry) {
|
||||
|
||||
BeanDefinitionHolder contextBean = new BeanDefinitionHolder(BeanDefinitionBuilder.genericBeanDefinition(
|
||||
DefaultCassandraMappingContext.class).getBeanDefinition(), DefaultDataBeanNames.CONTEXT);
|
||||
|
||||
registry.registerBeanDefinition(contextBean.getBeanName(), contextBean.getBeanDefinition());
|
||||
|
||||
return contextBean;
|
||||
}
|
||||
|
||||
public BeanDefinitionHolder registerDefaultConverter(BeanDefinitionRegistry registry, String contextBeanName) {
|
||||
|
||||
BeanDefinitionBuilder converterBeanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
MappingCassandraConverter.class).addConstructorArgReference(contextBeanName);
|
||||
BeanDefinitionHolder beanDefinition = new BeanDefinitionHolder(converterBeanDefinitionBuilder.getBeanDefinition(),
|
||||
DefaultDataBeanNames.CONVERTER);
|
||||
|
||||
registry.registerBeanDefinition(beanDefinition.getBeanName(), beanDefinition.getBeanDefinition());
|
||||
|
||||
return beanDefinition;
|
||||
}
|
||||
|
||||
public BeanDefinitionHolder registerDefaultTemplate(BeanDefinitionRegistry registry, String sessionBeanName,
|
||||
String converterBeanName) {
|
||||
|
||||
BeanDefinitionBuilder templateBeanDefinitionBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(CassandraTemplate.class).addConstructorArgReference(sessionBeanName)
|
||||
.addConstructorArgReference(converterBeanName);
|
||||
BeanDefinition beanDefinition = templateBeanDefinitionBuilder.getBeanDefinition();
|
||||
|
||||
BeanDefinitionHolder template = new BeanDefinitionHolder(beanDefinition, DefaultDataBeanNames.TEMPLATE);
|
||||
registry.registerBeanDefinition(template.getBeanName(), template.getBeanDefinition());
|
||||
|
||||
return template;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import org.springframework.cassandra.config.xml.DefaultBeanNames;
|
||||
|
||||
public interface DefaultDataBeanNames extends DefaultBeanNames {
|
||||
|
||||
public static final String DATA_TEMPLATE = "cassandra-template";
|
||||
public static final String CONVERTER = "cassandra-converter";
|
||||
public static final String DATA_TEMPLATE = "cassandraTemplate";
|
||||
public static final String CONVERTER = "cassandraConverter";
|
||||
public static final String CONTEXT = "cassandraMapping";
|
||||
}
|
||||
|
||||
@@ -15,18 +15,12 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.config.java;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.cassandra.config.java.AbstractClusterConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.data.cassandra.config.CassandraDataSessionFactoryBean;
|
||||
import org.springframework.data.cassandra.config.CassandraEntityClassScanner;
|
||||
import org.springframework.data.cassandra.config.SchemaAction;
|
||||
import org.springframework.data.cassandra.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.convert.MappingCassandraConverter;
|
||||
@@ -34,12 +28,8 @@ 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.DefaultCassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.Mapping;
|
||||
import org.springframework.data.cassandra.mapping.PrimaryKeyClass;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Base class for Spring Data Cassandra configuration using JavaConfig.
|
||||
@@ -54,7 +44,6 @@ public abstract class AbstractSpringDataCassandraConfiguration extends AbstractC
|
||||
protected abstract String getKeyspaceName();
|
||||
|
||||
protected ClassLoader beanClassLoader;
|
||||
protected Mapping mapping = new Mapping();
|
||||
|
||||
/**
|
||||
* The {@link SchemaAction} to perform. Defaults to {@link SchemaAction#NONE}.
|
||||
@@ -64,11 +53,11 @@ public abstract class AbstractSpringDataCassandraConfiguration extends AbstractC
|
||||
}
|
||||
|
||||
/**
|
||||
* The base package to scan for entities annotated with {@link Table} annotations. By default, returns the package
|
||||
* name of {@literal this} (<code>this.getClass().getPackage().getName()</code>).
|
||||
* The base packages to scan for entities annotated with {@link Table} annotations. By default, returns the package
|
||||
* name of {@literal this} (<code>this.getClass().getPackage().getName()</code>). This method must never return null.
|
||||
*/
|
||||
public String getEntityBasePackage() {
|
||||
return getClass().getPackage().getName();
|
||||
public String[] getEntityBasePackages() {
|
||||
return new String[] { getClass().getPackage().getName() };
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -77,15 +66,12 @@ public abstract class AbstractSpringDataCassandraConfiguration extends AbstractC
|
||||
CassandraDataSessionFactoryBean bean = new CassandraDataSessionFactoryBean();
|
||||
|
||||
bean.setCluster(cluster().getObject());
|
||||
bean.setConverter(converter());
|
||||
bean.setConverter(cassandraConverter());
|
||||
bean.setSchemaAction(getSchemaAction());
|
||||
bean.setKeyspaceName(getKeyspaceName());
|
||||
bean.setStartupScripts(getStartupScripts());
|
||||
bean.setShutdownScripts(getShutdownScripts());
|
||||
|
||||
bean.setEntityClassLoader(beanClassLoader);
|
||||
bean.setMapping(mapping);
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
@@ -96,7 +82,7 @@ public abstract class AbstractSpringDataCassandraConfiguration extends AbstractC
|
||||
*/
|
||||
@Bean
|
||||
public CassandraAdminOperations cassandraTemplate() throws Exception {
|
||||
return new CassandraAdminTemplate(session().getObject(), converter());
|
||||
return new CassandraAdminTemplate(session().getObject(), cassandraConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,59 +91,21 @@ public abstract class AbstractSpringDataCassandraConfiguration extends AbstractC
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
@Bean
|
||||
public CassandraMappingContext cassandraMappingContext() throws ClassNotFoundException {
|
||||
DefaultCassandraMappingContext context = new DefaultCassandraMappingContext();
|
||||
context.setInitialEntitySet(getInitialEntitySet());
|
||||
return context;
|
||||
public CassandraMappingContext cassandraMapping() throws ClassNotFoundException {
|
||||
|
||||
DefaultCassandraMappingContext bean = new DefaultCassandraMappingContext();
|
||||
bean.setInitialEntitySet(CassandraEntityClassScanner.scan(getEntityBasePackages()));
|
||||
bean.setBeanClassLoader(beanClassLoader);
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link CassandraConverter} instance to convert Rows to Objects, Objects to BuiltStatements
|
||||
*
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
@Bean
|
||||
public CassandraConverter converter() throws ClassNotFoundException {
|
||||
MappingCassandraConverter converter = new MappingCassandraConverter(cassandraMappingContext());
|
||||
converter.setBeanClassLoader(beanClassLoader);
|
||||
return converter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans the mapping base package for entity classes annotated with {@link Table} or {@link Persistent}.
|
||||
*
|
||||
* @see #getEntityBasePackage()
|
||||
* @return <code>Set<Class<?>></code> representing the annotated entity classes found.
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
|
||||
String basePackage = getEntityBasePackage();
|
||||
Set<Class<?>> initialEntitySet = new HashSet<Class<?>>();
|
||||
|
||||
if (StringUtils.hasText(basePackage)) {
|
||||
ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(
|
||||
false);
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Table.class));
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(PrimaryKeyClass.class));
|
||||
|
||||
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
|
||||
|
||||
Class<?> clazz = ClassUtils.forName(candidate.getBeanClassName(), beanClassLoader);
|
||||
initialEntitySet.add(clazz);
|
||||
}
|
||||
}
|
||||
|
||||
processMappingOverrides(initialEntitySet);
|
||||
|
||||
return initialEntitySet;
|
||||
}
|
||||
|
||||
protected void processMappingOverrides(Set<Class<?>> entityTypes) {
|
||||
|
||||
// TODO: search for external entity mapping info (xml/properties/yaml/etc) here & update this.mapping
|
||||
// similar to JPA's or JDO's external metadata search algorithms
|
||||
public CassandraConverter cassandraConverter() throws Exception {
|
||||
return new MappingCassandraConverter(cassandraMapping());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package org.springframework.data.cassandra.config.xml;
|
||||
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.cassandra.config.xml.CassandraClusterParser;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Spring Data Cassandra XML namespace parser for the <cluster> element.
|
||||
@@ -8,4 +11,12 @@ import org.springframework.cassandra.config.xml.CassandraClusterParser;
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraDataClusterParser extends CassandraClusterParser {
|
||||
|
||||
@Override
|
||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
||||
|
||||
CassandraMappingXmlBeanFactoryPostProcessorRegistrar.ensureRegistration(element, parserContext);
|
||||
|
||||
return super.parseInternal(element, parserContext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,5 +36,7 @@ public class CassandraDataNamespaceHandler extends NamespaceHandlerSupport {
|
||||
registerBeanDefinitionParser("cluster", new CassandraDataClusterParser());
|
||||
registerBeanDefinitionParser("session", new CassandraDataSessionParser());
|
||||
registerBeanDefinitionParser("template", new CassandraDataTemplateParser());
|
||||
registerBeanDefinitionParser("converter", new CassandraMappingConverterParser());
|
||||
registerBeanDefinitionParser("mapping", new CassandraMappingContextParser());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
package org.springframework.data.cassandra.config.xml;
|
||||
|
||||
import static org.springframework.cassandra.config.xml.ParsingUtils.*;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import static org.springframework.cassandra.config.xml.ParsingUtils.addOptionalPropertyReference;
|
||||
import static org.springframework.cassandra.config.xml.ParsingUtils.addOptionalPropertyValue;
|
||||
import static org.springframework.cassandra.config.xml.ParsingUtils.addRequiredPropertyReference;
|
||||
import static org.springframework.cassandra.config.xml.ParsingUtils.addRequiredPropertyValue;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.cassandra.config.xml.CassandraSessionParser;
|
||||
import org.springframework.data.cassandra.config.DefaultDataBeanNames;
|
||||
import org.springframework.data.cassandra.config.CassandraDataSessionFactoryBean;
|
||||
import org.springframework.data.cassandra.config.DefaultDataBeanNames;
|
||||
import org.springframework.data.cassandra.config.SchemaAction;
|
||||
import org.springframework.data.cassandra.mapping.EntityMapping;
|
||||
import org.springframework.data.cassandra.mapping.Mapping;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
@@ -30,6 +26,14 @@ public class CassandraDataSessionParser extends CassandraSessionParser {
|
||||
return CassandraDataSessionFactoryBean.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
super.doParse(element, parserContext, builder);
|
||||
|
||||
CassandraMappingXmlBeanFactoryPostProcessorRegistrar.ensureRegistration(element, parserContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void parseUnhandledSessionElementAttribute(Attr attribute, ParserContext parserContext,
|
||||
BeanDefinitionBuilder builder) {
|
||||
@@ -46,55 +50,11 @@ public class CassandraDataSessionParser extends CassandraSessionParser {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void parseUnhandledElement(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
protected void setDefaultProperties(BeanDefinitionBuilder builder) {
|
||||
|
||||
if ("mapping".equals(element.getLocalName())) {
|
||||
parseMapping(element, parserContext, builder);
|
||||
} else {
|
||||
super.parseUnhandledElement(element, parserContext, builder);
|
||||
}
|
||||
}
|
||||
super.setDefaultProperties(builder);
|
||||
|
||||
protected void parseMapping(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
// TODO: parse <mapping> attributes here, if there ever are any
|
||||
|
||||
Set<EntityMapping> mappings = new HashSet<EntityMapping>();
|
||||
|
||||
for (Element child : DomUtils.getChildElementsByTagName(element, "entity")) {
|
||||
|
||||
EntityMapping entityMapping = parseEntity(child);
|
||||
|
||||
if (entityMapping != null) {
|
||||
mappings.add(entityMapping);
|
||||
}
|
||||
}
|
||||
|
||||
Mapping mapping = new Mapping();
|
||||
mapping.setEntityMappings(mappings);
|
||||
|
||||
builder.addPropertyValue("mapping", mapping);
|
||||
}
|
||||
|
||||
protected EntityMapping parseEntity(Element entity) {
|
||||
|
||||
String className = entity.getAttribute("class");
|
||||
if (!StringUtils.hasText(className)) {
|
||||
throw new IllegalStateException("class attribute must not be empty");
|
||||
}
|
||||
|
||||
Element table = DomUtils.getChildElementByTagName(entity, "table");
|
||||
if (table == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String tableName = table.getAttribute("name");
|
||||
if (!StringUtils.hasText(tableName)) {
|
||||
tableName = null;
|
||||
}
|
||||
|
||||
// TODO: parse future entity mappings here, like table options
|
||||
|
||||
return new EntityMapping(className, tableName);
|
||||
addRequiredPropertyValue(builder, "schemaAction", SchemaAction.NONE.name());
|
||||
addRequiredPropertyReference(builder, "converter", DefaultDataBeanNames.CONVERTER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,9 @@ public class CassandraDataTemplateParser extends CassandraTemplateParser {
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
CassandraMappingXmlBeanFactoryPostProcessorRegistrar.ensureRegistration(element, parserContext);
|
||||
|
||||
super.doParse(element, parserContext, builder);
|
||||
|
||||
parseConverterAttribute(element, parserContext, builder);
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package org.springframework.data.cassandra.config.xml;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
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.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.data.cassandra.config.DefaultDataBeanNames;
|
||||
import org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.EntityMapping;
|
||||
import org.springframework.data.cassandra.mapping.Mapping;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Spring Data Cassandra XML namespace parser for the <mapping> element.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraMappingContextParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return DefaultCassandraMappingContext.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||
throws BeanDefinitionStoreException {
|
||||
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : DefaultDataBeanNames.CONTEXT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
CassandraMappingXmlBeanFactoryPostProcessorRegistrar.ensureRegistration(element, parserContext);
|
||||
|
||||
parseMapping(element, builder);
|
||||
}
|
||||
|
||||
protected void parseMapping(Element element, BeanDefinitionBuilder builder) {
|
||||
|
||||
Set<EntityMapping> mappings = new HashSet<EntityMapping>();
|
||||
|
||||
for (Element entity : DomUtils.getChildElementsByTagName(element, "entity")) {
|
||||
|
||||
EntityMapping entityMapping = parseEntity(entity);
|
||||
|
||||
if (entityMapping != null) {
|
||||
mappings.add(entityMapping);
|
||||
}
|
||||
}
|
||||
|
||||
Mapping mapping = new Mapping();
|
||||
mapping.setEntityMappings(mappings);
|
||||
|
||||
builder.addPropertyValue("mapping", mapping);
|
||||
}
|
||||
|
||||
protected EntityMapping parseEntity(Element entity) {
|
||||
|
||||
String className = entity.getAttribute("class");
|
||||
if (!StringUtils.hasText(className)) {
|
||||
throw new IllegalStateException("class attribute must not be empty");
|
||||
}
|
||||
|
||||
Element table = DomUtils.getChildElementByTagName(entity, "table");
|
||||
if (table == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String tableName = table.getAttribute("name");
|
||||
if (!StringUtils.hasText(tableName)) {
|
||||
tableName = null;
|
||||
}
|
||||
|
||||
// TODO: parse future entity mappings here, like table options
|
||||
|
||||
return new EntityMapping(className, tableName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.springframework.data.cassandra.config.xml;
|
||||
|
||||
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.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.data.cassandra.config.DefaultDataBeanNames;
|
||||
import org.springframework.data.cassandra.convert.MappingCassandraConverter;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Spring Data Cassandra XML namespace parser for the <converter> element.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraMappingConverterParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return MappingCassandraConverter.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||
throws BeanDefinitionStoreException {
|
||||
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : DefaultDataBeanNames.CONVERTER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
CassandraMappingXmlBeanFactoryPostProcessorRegistrar.ensureRegistration(element, parserContext);
|
||||
|
||||
String mappingRef = element.getAttribute("mapping-ref");
|
||||
if (!StringUtils.hasText(mappingRef)) {
|
||||
mappingRef = DefaultDataBeanNames.CONTEXT;
|
||||
}
|
||||
|
||||
builder.addConstructorArgReference(mappingRef);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.springframework.data.cassandra.config.xml;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.data.cassandra.config.CassandraMappingBeanFactoryPostProcessor;
|
||||
import org.springframework.data.config.BeanComponentDefinitionBuilder;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Ensures that a {@link CassandraMappingBeanFactoryPostProcessor} is registered.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraMappingXmlBeanFactoryPostProcessorRegistrar {
|
||||
|
||||
/**
|
||||
* Ensures that a {@link CassandraMappingBeanFactoryPostProcessor} is registered. This method is a no-op if one is
|
||||
* already registered.
|
||||
*/
|
||||
public static void ensureRegistration(Element element, ParserContext parserContext) {
|
||||
|
||||
BeanDefinitionRegistry registry = parserContext.getRegistry();
|
||||
if (!(registry instanceof GenericApplicationContext)) {
|
||||
return;
|
||||
}
|
||||
ConfigurableListableBeanFactory factory = ((GenericApplicationContext) registry).getBeanFactory();
|
||||
|
||||
String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(factory,
|
||||
CassandraMappingBeanFactoryPostProcessor.class, true, false);
|
||||
if (names.length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
BeanComponentDefinitionBuilder componentBuilder = new BeanComponentDefinitionBuilder(element, parserContext);
|
||||
BeanDefinitionBuilder definitionBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(CassandraMappingBeanFactoryPostProcessor.class);
|
||||
|
||||
parserContext.registerBeanComponent(componentBuilder.getComponent(definitionBuilder));
|
||||
}
|
||||
}
|
||||
@@ -123,7 +123,7 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
|
||||
Assert.notNull(type);
|
||||
Assert.notNull(id);
|
||||
|
||||
CassandraPersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(type);
|
||||
CassandraPersistentEntity<?> entity = mappingContext.getPersistentEntity(type);
|
||||
|
||||
Select select = QueryBuilder.select().countAll().from(entity.getTableName());
|
||||
appendIdCriteria(select.where(), entity, id);
|
||||
@@ -152,9 +152,9 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
|
||||
Assert.notNull(type);
|
||||
Assert.notNull(id);
|
||||
|
||||
CassandraPersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(type);
|
||||
CassandraPersistentEntity<?> entity = mappingContext.getPersistentEntity(type);
|
||||
|
||||
Delete delete = QueryBuilder.delete().all().from(entity.getTableName());
|
||||
Delete delete = QueryBuilder.delete().from(entity.getTableName());
|
||||
appendIdCriteria(delete.where(), entity, id);
|
||||
|
||||
execute(delete.getQueryString());
|
||||
@@ -192,7 +192,7 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
|
||||
|
||||
@Override
|
||||
public String getTableName(Class<?> type) {
|
||||
return mappingContext.getRequiredPersistentEntity(type).getTableName();
|
||||
return mappingContext.getPersistentEntity(type).getTableName();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -252,7 +252,7 @@ public class CassandraTemplate extends CqlTemplate implements CassandraOperation
|
||||
@Override
|
||||
public <T> List<T> selectBySimpleIds(Class<T> type, Iterable<?> ids) {
|
||||
|
||||
CassandraPersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(type);
|
||||
CassandraPersistentEntity<?> entity = mappingContext.getPersistentEntity(type);
|
||||
|
||||
if (entity.getIdProperty().isCompositePrimaryKey()) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
|
||||
@@ -4,7 +4,6 @@ import java.util.Collection;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
import com.datastax.driver.core.TableMetadata;
|
||||
|
||||
@@ -59,22 +58,17 @@ public interface CassandraMappingContext extends
|
||||
boolean usesTable(TableMetadata table);
|
||||
|
||||
/**
|
||||
* Returns the {@link CassandraPersistentEntity} for the given type. If it doesn't exist, this method throws
|
||||
* {@link IllegalArgumentException}.
|
||||
* Returns the existing {@link CassandraPersistentEntity} for the given {@link Class}. If it is not yet known to this
|
||||
* {@link CassandraMappingContext}, an {@link IllegalArgumentException} is thrown.
|
||||
*
|
||||
* @param type The Java type of the persistent entity.
|
||||
* @return The {@link CassandraPersistentEntity} describing the persistent Java type.
|
||||
* @throws IllegalArgumentException if the persistent entity is unknown
|
||||
* @param type The class of the existing persistent entity.
|
||||
* @return The existing persistent entity.
|
||||
*/
|
||||
public CassandraPersistentEntity<?> getRequiredPersistentEntity(Class<?> type);
|
||||
CassandraPersistentEntity<?> getExistingPersistentEntity(Class<?> type);
|
||||
|
||||
/**
|
||||
* Returns the {@link CassandraPersistentEntity} for the given type. If it doesn't exist, this method throws
|
||||
* {@link IllegalArgumentException}.
|
||||
*
|
||||
* @param type The {@link TypeInformation} of the persistent entity.
|
||||
* @return The {@link CassandraPersistentEntity} describing the persistent Java type.
|
||||
* @throws IllegalArgumentException if the persistent entity is unknown
|
||||
* Returns whether this {@link CassandraMappingContext} already contains a {@link CassandraPersistentEntity} for the
|
||||
* given type.
|
||||
*/
|
||||
public CassandraPersistentEntity<?> getRequiredPersistentEntity(TypeInformation<?> type);
|
||||
boolean contains(Class<?> type);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ 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 org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.datastax.driver.core.TableMetadata;
|
||||
|
||||
@@ -52,9 +54,14 @@ public class DefaultCassandraMappingContext extends
|
||||
CassandraMappingContext, ApplicationContextAware {
|
||||
|
||||
protected ApplicationContext context;
|
||||
protected Mapping mapping = new Mapping();
|
||||
protected ClassLoader beanClassLoader;
|
||||
|
||||
// useful caches
|
||||
protected Map<String, Set<CassandraPersistentEntity<?>>> entitySetsByTableName = new HashMap<String, Set<CassandraPersistentEntity<?>>>();
|
||||
protected Set<CassandraPersistentEntity<?>> nonPrimaryKeyEntities = new HashSet<CassandraPersistentEntity<?>>();
|
||||
protected Set<CassandraPersistentEntity<?>> primaryKeyEntities = new HashSet<CassandraPersistentEntity<?>>();
|
||||
protected Map<Class<?>, CassandraPersistentEntity<?>> entitiesByType = new HashMap<Class<?>, CassandraPersistentEntity<?>>();
|
||||
|
||||
/**
|
||||
* Creates a new {@link DefaultCassandraMappingContext}.
|
||||
@@ -63,6 +70,14 @@ public class DefaultCassandraMappingContext extends
|
||||
setSimpleTypeHolder(new CassandraSimpleTypeHolder());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
|
||||
super.initialize();
|
||||
|
||||
processMappingOverrides();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<CassandraPersistentEntity<?>> getPersistentEntities() {
|
||||
return getPersistentEntities(false);
|
||||
@@ -123,6 +138,8 @@ public class DefaultCassandraMappingContext extends
|
||||
nonPrimaryKeyEntities.add(entity);
|
||||
}
|
||||
|
||||
entitiesByType.put(entity.getType(), entity);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
@@ -184,28 +201,65 @@ public class DefaultCassandraMappingContext extends
|
||||
return spec;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CassandraPersistentEntity<?> getRequiredPersistentEntity(Class<?> type) {
|
||||
public void setMapping(Mapping mapping) {
|
||||
|
||||
CassandraPersistentEntity<?> entity = getPersistentEntity(type);
|
||||
Assert.notNull(mapping);
|
||||
|
||||
if (entity == null) {
|
||||
throw new IllegalArgumentException(String.format("no persistence metadata found for type [%s]", type.getName()));
|
||||
this.mapping = mapping;
|
||||
}
|
||||
|
||||
protected void processMappingOverrides() {
|
||||
|
||||
if (mapping == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
return entity;
|
||||
for (EntityMapping entityMapping : mapping.getEntityMappings()) {
|
||||
|
||||
if (entityMapping == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String entityClassName = entityMapping.getEntityClassName();
|
||||
Class<?> entityClass;
|
||||
try {
|
||||
entityClass = ClassUtils.forName(entityClassName, beanClassLoader);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new IllegalStateException(String.format("unknown persistent entity name [%s]", entityClassName), e);
|
||||
}
|
||||
|
||||
CassandraPersistentEntity<?> entity = getPersistentEntity(entityClass);
|
||||
|
||||
if (entity == null) {
|
||||
throw new IllegalStateException(String.format("unknown persistent entity class name [%s]", entityClassName));
|
||||
}
|
||||
|
||||
String tableName = entityMapping.getTableName();
|
||||
if (!StringUtils.hasText(tableName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
entity.setTableName(tableName);
|
||||
}
|
||||
}
|
||||
|
||||
public void setBeanClassLoader(ClassLoader beanClassLoader) {
|
||||
this.beanClassLoader = beanClassLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CassandraPersistentEntity<?> getRequiredPersistentEntity(TypeInformation<?> type) {
|
||||
public CassandraPersistentEntity<?> getExistingPersistentEntity(Class<?> type) {
|
||||
|
||||
CassandraPersistentEntity<?> entity = getPersistentEntity(type);
|
||||
|
||||
if (entity == null) {
|
||||
throw new IllegalArgumentException(String.format("no persistence metadata found for type [%s]",
|
||||
type.getActualType()));
|
||||
CassandraPersistentEntity<?> entity = entitiesByType.get(type);
|
||||
if (entity != null) {
|
||||
return entity;
|
||||
}
|
||||
|
||||
return entity;
|
||||
throw new IllegalArgumentException(String.format("unknown persistent type [%s]", type.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Class<?> type) {
|
||||
return entitiesByType.containsKey(type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.cassandra.repository.config;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.cassandra.config.xml.ParsingUtils;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.data.cassandra.config.DefaultDataBeanNames;
|
||||
import org.springframework.data.cassandra.repository.support.CassandraRepositoryFactoryBean;
|
||||
import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
|
||||
@@ -52,7 +53,7 @@ public class CassandraRepositoryConfigurationExtension extends RepositoryConfigu
|
||||
Element element = config.getElement();
|
||||
|
||||
ParsingUtils.addOptionalPropertyReference(builder, "cassandraTemplate", element, CASSANDRA_TEMPLATE_REF,
|
||||
"cassandra-template");
|
||||
DefaultDataBeanNames.TEMPLATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -452,8 +452,6 @@ Arbitrary CQL script to be executed against the session's keyspace during bean d
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="mapping" type="mappingType" minOccurs="0"
|
||||
maxOccurs="1" />
|
||||
</xsd:sequence>
|
||||
|
||||
<xsd:attribute name="id" type="xsd:ID" use="optional">
|
||||
@@ -482,7 +480,7 @@ The name of a Cassandra Keyspace. No default; for the system keyspace, use the
|
||||
use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The reference to a CassandraConverter; default is "cassandra-converter".
|
||||
The reference to a CassandraConverter; default is "cassandraConverter".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
@@ -500,7 +498,7 @@ The schema action to perform; default is NONE.
|
||||
<xsd:attribute name="id" type="xsd:ID" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the template; default is "cassandra-template".
|
||||
The name of the template; default is "cassandraTemplate".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
@@ -515,7 +513,7 @@ The reference to a Cassandra session; default is "cassandra-session".
|
||||
use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The reference to a CassandraConverter; default is "cassandra-converter".
|
||||
The reference to a CassandraConverter; default is "cassandraConverter".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
@@ -629,13 +627,6 @@ The replication factor for the data center.
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:complexType name="mappingType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="entity" type="entityType" minOccurs="0"
|
||||
maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="entityType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="table" type="tableType" minOccurs="0"
|
||||
@@ -676,11 +667,10 @@ Table name override.
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:attributeGroup name="cassandra-repository-attributes">
|
||||
<xsd:attribute name="cassandra-template-ref" type="cassandraTemplateRef"
|
||||
default="cassandra-template">
|
||||
<xsd:attribute name="cassandra-template-ref" type="cassandraTemplateRef">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The reference to a cassandraTemplate. Will default to 'cassandra-template'.
|
||||
The reference to a cassandraTemplate. Will default to 'cassandraTemplate'.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
@@ -696,4 +686,65 @@ The reference to a cassandraTemplate. Will default to 'cassandra-template'.
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="mapping">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines a CassandraMappingContext for holding rich entity mapping information.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:exports
|
||||
type="org.springframework.data.cassandra.mapping.CassandraMappingContext" />
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="entity" type="entityType" minOccurs="0"
|
||||
maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="entity-base-packages" type="xsd:string"
|
||||
use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The comma-delimited base packages in which to scan for entities and their mapping information.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="converter">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines a CassandraConverter for getting rich mapping functionality.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:exports
|
||||
type="org.springframework.data.cassandra.convert.CassandraConverter" />
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="mapping-ref" type="mappingContextRef"
|
||||
use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation
|
||||
source="org.springframework.data.cassandra.mapping.CassandraMappingContext"><![CDATA[
|
||||
The reference to a CassandraMappingContext. Will default to 'cassandraMapping'.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:simpleType name="mappingContextRef">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to
|
||||
type="org.springframework.data.cassandra.mapping.CassandraMappingContext" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
|
||||
@@ -69,8 +69,8 @@ public class CommentRepositoryJavaConfigIntegrationTests extends AbstractSpringD
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEntityBasePackage() {
|
||||
return Comment.class.getPackage().getName();
|
||||
public String[] getEntityBasePackages() {
|
||||
return new String[] { Comment.class.getPackage().getName() };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.springframework.data.cassandra.test.integration.mappingcontext;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.PrimaryKey;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
|
||||
public class MappingContextIntegrationTests {
|
||||
|
||||
public static class Transient {
|
||||
}
|
||||
|
||||
@Table
|
||||
public static class X {
|
||||
@PrimaryKey
|
||||
String key;
|
||||
}
|
||||
|
||||
@Table
|
||||
public static class Y {
|
||||
@PrimaryKey
|
||||
String key;
|
||||
}
|
||||
|
||||
DefaultCassandraMappingContext ctx = new DefaultCassandraMappingContext();
|
||||
|
||||
@Test
|
||||
// TODO: (expected = MappingException.class)
|
||||
public void testGetPersistentEntityOfTransientType() {
|
||||
|
||||
// TODO: when entity verification is added (DATACASS-85), this should throw a MappingException
|
||||
CassandraPersistentEntity<?> entity = ctx.getPersistentEntity(Transient.class);
|
||||
|
||||
// TODO: remove following lines after DATACASS-85
|
||||
assertNotNull(entity);
|
||||
assertEquals(Transient.class.getSimpleName().toLowerCase(), entity.getTableName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetExistingPersistentEntityHappyPath() {
|
||||
|
||||
ctx.getPersistentEntity(X.class);
|
||||
|
||||
assertTrue(ctx.contains(X.class));
|
||||
assertNotNull(ctx.getExistingPersistentEntity(X.class));
|
||||
assertFalse(ctx.contains(Y.class));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.springframework.data.cassandra.test.integration.minimal.config;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.cassandra.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.test.integration.minimal.config.entities.AbsMin;
|
||||
import org.springframework.data.cassandra.test.integration.support.AbstractSpringDataEmbeddedCassandraIntegrationTest;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class AbsoluteMinimumXmlConfigIntegrationTest extends AbstractSpringDataEmbeddedCassandraIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
CassandraMappingContext context;
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
assertNotNull(context);
|
||||
|
||||
context.getPersistentEntity(AbsMin.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.springframework.data.cassandra.test.integration.minimal.config.entities;
|
||||
|
||||
import org.springframework.data.cassandra.mapping.PrimaryKey;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
|
||||
@Table
|
||||
public class AbsMin {
|
||||
|
||||
@PrimaryKey
|
||||
String key;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.springframework.data.cassandra.test.integration.minimal.config.entities;
|
||||
|
||||
import org.springframework.data.cassandra.repository.CassandraRepository;
|
||||
|
||||
public interface AbsMinRepository extends CassandraRepository<AbsMin, String> {
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.springframework.data.cassandra.test.integration.multipackagescanning;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.cassandra.config.CassandraEntityClassScanner;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext;
|
||||
import org.springframework.data.cassandra.test.integration.multipackagescanning.first.First;
|
||||
import org.springframework.data.cassandra.test.integration.multipackagescanning.second.Second;
|
||||
import org.springframework.data.cassandra.test.integration.multipackagescanning.third.Third;
|
||||
|
||||
public class MultipackageScanningIntegrationTests {
|
||||
|
||||
DefaultCassandraMappingContext mapping;
|
||||
String pkg = getClass().getPackage().getName();
|
||||
|
||||
@Before
|
||||
public void before() throws ClassNotFoundException {
|
||||
|
||||
mapping = new DefaultCassandraMappingContext();
|
||||
mapping.setInitialEntitySet(CassandraEntityClassScanner.scan(pkg + ".first", pkg + ".second"));
|
||||
|
||||
mapping.initialize();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
Collection<CassandraPersistentEntity<?>> entities = mapping.getPersistentEntities();
|
||||
|
||||
Collection<Class<?>> types = new HashSet<Class<?>>(entities.size());
|
||||
for (CassandraPersistentEntity<?> entity : entities) {
|
||||
types.add(entity.getType());
|
||||
}
|
||||
|
||||
assertTrue(types.contains(First.class));
|
||||
assertTrue(types.contains(Second.class));
|
||||
assertFalse(types.contains(Third.class));
|
||||
assertFalse(types.contains(Top.class));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.springframework.data.cassandra.test.integration.multipackagescanning;
|
||||
|
||||
import org.springframework.data.cassandra.mapping.PrimaryKey;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
|
||||
@Table
|
||||
public class Top {
|
||||
|
||||
@PrimaryKey
|
||||
String key;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.springframework.data.cassandra.test.integration.multipackagescanning.first;
|
||||
|
||||
import org.springframework.data.cassandra.mapping.PrimaryKey;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
|
||||
@Table
|
||||
public class First {
|
||||
|
||||
@PrimaryKey
|
||||
String key;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.springframework.data.cassandra.test.integration.multipackagescanning.second;
|
||||
|
||||
import org.springframework.data.cassandra.mapping.PrimaryKey;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
|
||||
@Table
|
||||
public class Second {
|
||||
|
||||
@PrimaryKey
|
||||
String key;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.springframework.data.cassandra.test.integration.multipackagescanning.third;
|
||||
|
||||
import org.springframework.data.cassandra.mapping.PrimaryKey;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
|
||||
@Table
|
||||
public class Third {
|
||||
|
||||
@PrimaryKey
|
||||
String key;
|
||||
}
|
||||
@@ -68,8 +68,8 @@ public class UserRepositoryJavaConfigIntegrationTests extends AbstractSpringData
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEntityBasePackage() {
|
||||
return User.class.getPackage().getName();
|
||||
public String[] getEntityBasePackages() {
|
||||
return new String[] { User.class.getPackage().getName() };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,8 +66,8 @@ public class CassandraDataOperationsTest extends AbstractSpringDataEmbeddedCassa
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEntityBasePackage() {
|
||||
return Book.class.getPackage().getName();
|
||||
public String[] getEntityBasePackages() {
|
||||
return new String[] { Book.class.getPackage().getName() };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,33 +1,34 @@
|
||||
<?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: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"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
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/util http://www.springframework.org/schema/util/spring-util-3.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">
|
||||
|
||||
<import resource="classpath:/spring-data-cassandra-basic.xml" />
|
||||
|
||||
<cassandra:cluster id="cassandra-cluster"
|
||||
port="${cassandra.native_transport_port}">
|
||||
<cass:mapping
|
||||
entity-base-packages="org.springframework.data.cassandra.test.integration.composites">
|
||||
<cass:entity
|
||||
class="org.springframework.data.cassandra.test.integration.composites.Comment">
|
||||
<cass:table name="comments_x" />
|
||||
</cass:entity>
|
||||
</cass:mapping>
|
||||
|
||||
<cassandra:keyspace name="CommentRepositoryXmlConfigIntegrationTests"
|
||||
<cass:cluster port="${cassandra.native_transport_port}">
|
||||
<cass:keyspace name="CommentRepositoryXmlConfigIntegrationTests"
|
||||
action="CREATE" durable-writes="true">
|
||||
</cassandra:keyspace>
|
||||
</cassandra:cluster>
|
||||
</cass:keyspace>
|
||||
</cass:cluster>
|
||||
|
||||
<cassandra:session id="cassandra-session"
|
||||
cluster-ref="cassandra-cluster" keyspace-name="CommentRepositoryXmlConfigIntegrationTests"
|
||||
cassandra-converter-ref="cassandra-converter" schema-action="CREATE">
|
||||
<cassandra:mapping>
|
||||
<cassandra:entity
|
||||
class="org.springframework.data.cassandra.test.integration.composites.Comment">
|
||||
<cassandra:table name="comments" />
|
||||
</cassandra:entity>
|
||||
</cassandra:mapping>
|
||||
</cassandra:session>
|
||||
<cass:session keyspace-name="CommentRepositoryXmlConfigIntegrationTests"
|
||||
schema-action="CREATE">
|
||||
</cass:session>
|
||||
|
||||
<cassandra:repositories
|
||||
<cass:repositories
|
||||
base-package="org.springframework.data.cassandra.test.integration.composites" />
|
||||
</beans>
|
||||
|
||||
@@ -11,9 +11,8 @@
|
||||
<context:property-placeholder
|
||||
location="classpath:/org/springframework/data/cassandra/test/integration/config/cassandra.properties" />
|
||||
|
||||
<cass:cluster id="cassandra-cluster"
|
||||
contact-points="${cassandra.contactPoints}" port="${cassandra.native_transport_port}"
|
||||
compression="SNAPPY">
|
||||
<cass:cluster contact-points="${cassandra.contactPoints}"
|
||||
port="${cassandra.native_transport_port}" compression="SNAPPY">
|
||||
<cass:local-pooling-options
|
||||
min-simultaneous-requests="25" max-simultaneous-requests="100"
|
||||
core-connections="2" max-connections="8" />
|
||||
@@ -27,21 +26,13 @@
|
||||
durable-writes="true" />
|
||||
</cass:cluster>
|
||||
|
||||
<!-- TODO: not require that this bean be defined -->
|
||||
<bean id="cassandra-mapping"
|
||||
class="org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext"/>
|
||||
<!-- TODO: not require that these beans be defined -->
|
||||
<cass:mapping />
|
||||
<cass:converter />
|
||||
|
||||
<!-- TODO: not require that this bean be defined -->
|
||||
<bean id="cassandra-converter"
|
||||
class="org.springframework.data.cassandra.convert.MappingCassandraConverter">
|
||||
<constructor-arg ref="cassandra-mapping" />
|
||||
</bean>
|
||||
<cass:session keyspace-name="${cassandra.keyspace}"
|
||||
schema-action="NONE" />
|
||||
|
||||
<cass:session id="cassandra-session" keyspace-name="${cassandra.keyspace}"
|
||||
schema-action="NONE" cluster-ref="cassandra-cluster"
|
||||
cassandra-converter-ref="cassandra-converter">
|
||||
</cass:session>
|
||||
|
||||
<cass:template session-ref="cassandra-session" />
|
||||
<cass:template />
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<?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:cass="http://www.springframework.org/schema/data/cassandra"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
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/util http://www.springframework.org/schema/util/spring-util-3.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">
|
||||
|
||||
<!-- this is needed just so it runs correctly as part of the build, so ignore it & the port attribute of the cluster below -->
|
||||
<context:property-placeholder
|
||||
location="classpath:/spring-data-cassandra-build.properties" />
|
||||
|
||||
<cass:cluster port="${cassandra.native_transport_port}" />
|
||||
|
||||
<cass:session keyspace-name="system" />
|
||||
|
||||
<cass:repositories
|
||||
base-package="org.springframework.data.cassandra.test.integration.minimal.config" />
|
||||
</beans>
|
||||
@@ -1,7 +1,8 @@
|
||||
<?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" xmlns:util="http://www.springframework.org/schema/util"
|
||||
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"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
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
|
||||
@@ -11,25 +12,24 @@
|
||||
|
||||
<import resource="classpath:/spring-data-cassandra-basic.xml" />
|
||||
|
||||
<cassandra:cluster id="cassandra-cluster"
|
||||
port="${cassandra.native_transport_port}">
|
||||
<cass:mapping
|
||||
entity-base-packages="org.springframework.data.cassandra.test.integration.repository">
|
||||
<cass:entity
|
||||
class="org.springframework.data.cassandra.test.integration.repository.User">
|
||||
<cass:table name="users_x" />
|
||||
</cass:entity>
|
||||
</cass:mapping>
|
||||
|
||||
<cassandra:keyspace name="UserRepositoryXmlConfigIntegrationTests"
|
||||
<cass:cluster port="${cassandra.native_transport_port}">
|
||||
<cass:keyspace name="UserRepositoryXmlConfigIntegrationTests"
|
||||
action="CREATE" durable-writes="true">
|
||||
</cassandra:keyspace>
|
||||
</cassandra:cluster>
|
||||
</cass:keyspace>
|
||||
</cass:cluster>
|
||||
|
||||
<cassandra:session id="cassandra-session"
|
||||
cluster-ref="cassandra-cluster" keyspace-name="UserRepositoryXmlConfigIntegrationTests"
|
||||
cassandra-converter-ref="cassandra-converter" schema-action="CREATE">
|
||||
<cassandra:mapping>
|
||||
<cassandra:entity
|
||||
class="org.springframework.data.cassandra.test.integration.repository.User">
|
||||
<cassandra:table name="users_x" />
|
||||
</cassandra:entity>
|
||||
</cassandra:mapping>
|
||||
</cassandra:session>
|
||||
<cass:session keyspace-name="UserRepositoryXmlConfigIntegrationTests"
|
||||
schema-action="CREATE">
|
||||
</cass:session>
|
||||
|
||||
<cassandra:repositories
|
||||
<cass:repositories
|
||||
base-package="org.springframework.data.cassandra.test.integration.repository" />
|
||||
</beans>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?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: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
|
||||
@@ -10,15 +10,8 @@
|
||||
<context:property-placeholder
|
||||
location="classpath:/spring-data-cassandra-build.properties" />
|
||||
|
||||
<bean id="cassandra-mapping"
|
||||
class="org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext" />
|
||||
<cass:converter mapping-ref="cassandraMapping"/>
|
||||
|
||||
<bean id="cassandra-converter"
|
||||
class="org.springframework.data.cassandra.convert.MappingCassandraConverter">
|
||||
<constructor-arg ref="cassandra-mapping" />
|
||||
</bean>
|
||||
|
||||
<cassandra:template id="cassandra-template"
|
||||
cassandra-converter-ref="cassandra-converter" session-ref="cassandra-session" />
|
||||
<cass:template />
|
||||
|
||||
</beans>
|
||||
|
||||
Reference in New Issue
Block a user