diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfiguration.java index 0a85a34cc7d..22e8ef33331 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfiguration.java @@ -16,6 +16,7 @@ package org.springframework.boot.autoconfigure.data.cassandra; +import java.util.Collections; import java.util.List; import com.datastax.driver.core.Cluster; @@ -41,6 +42,7 @@ import org.springframework.data.cassandra.config.SchemaAction; import org.springframework.data.cassandra.core.CassandraAdminOperations; import org.springframework.data.cassandra.core.CassandraTemplate; import org.springframework.data.cassandra.core.convert.CassandraConverter; +import org.springframework.data.cassandra.core.convert.CassandraCustomConversions; import org.springframework.data.cassandra.core.convert.MappingCassandraConverter; import org.springframework.data.cassandra.core.mapping.CassandraMappingContext; import org.springframework.data.cassandra.core.mapping.SimpleUserTypeResolver; @@ -79,7 +81,8 @@ public class CassandraDataAutoConfiguration { @Bean @ConditionalOnMissingBean - public CassandraMappingContext cassandraMapping() throws ClassNotFoundException { + public CassandraMappingContext cassandraMapping( + CassandraCustomConversions conversions) throws ClassNotFoundException { CassandraMappingContext context = new CassandraMappingContext(); List packages = EntityScanPackages.get(this.beanFactory) .getPackageNames(); @@ -93,13 +96,17 @@ public class CassandraDataAutoConfiguration { context.setUserTypeResolver(new SimpleUserTypeResolver(this.cluster, this.properties.getKeyspaceName())); } + context.setCustomConversions(conversions); return context; } @Bean @ConditionalOnMissingBean - public CassandraConverter cassandraConverter(CassandraMappingContext mapping) { - return new MappingCassandraConverter(mapping); + public CassandraConverter cassandraConverter(CassandraMappingContext mapping, + CassandraCustomConversions conversions) { + MappingCassandraConverter converter = new MappingCassandraConverter(mapping); + converter.setCustomConversions(conversions); + return converter; } @Bean @@ -123,4 +130,10 @@ public class CassandraDataAutoConfiguration { return new CassandraTemplate(session, converter); } + @Bean + @ConditionalOnMissingBean + public CassandraCustomConversions cassandraCustomConversions() { + return new CassandraCustomConversions(Collections.emptyList()); + } + } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfigurationTests.java index 3a1670fd3f9..bff272d4626 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfigurationTests.java @@ -16,6 +16,7 @@ package org.springframework.boot.autoconfigure.data.cassandra; +import java.util.Collections; import java.util.Set; import com.datastax.driver.core.Session; @@ -23,7 +24,6 @@ import org.junit.After; import org.junit.Test; import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.data.cassandra.city.City; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.boot.test.util.TestPropertyValues; @@ -32,19 +32,23 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; +import org.springframework.core.convert.converter.Converter; import org.springframework.data.cassandra.core.CassandraTemplate; +import org.springframework.data.cassandra.core.convert.CassandraCustomConversions; import org.springframework.data.cassandra.core.mapping.CassandraMappingContext; import org.springframework.data.cassandra.core.mapping.SimpleUserTypeResolver; import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.util.ObjectUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; /** - * Tests for {@link CassandraDataAutoConfiguration} + * Tests for {@link CassandraDataAutoConfiguration}. * * @author EddĂș MelĂ©ndez * @author Mark Paluch + * @author Stephane Nicoll */ public class CassandraDataAutoConfigurationTests { @@ -59,13 +63,7 @@ public class CassandraDataAutoConfigurationTests { @Test public void templateExists() { - this.context = new AnnotationConfigApplicationContext(); - TestPropertyValues.of("spring.data.cassandra.keyspaceName:boot_test") - .applyTo(this.context); - this.context.register(TestExcludeConfiguration.class, TestConfiguration.class, - PropertyPlaceholderAutoConfiguration.class, - CassandraAutoConfiguration.class, CassandraDataAutoConfiguration.class); - this.context.refresh(); + load(TestExcludeConfiguration.class); assertThat(this.context.getBeanNamesForType(CassandraTemplate.class).length) .isEqualTo(1); } @@ -73,12 +71,7 @@ public class CassandraDataAutoConfigurationTests { @Test @SuppressWarnings("unchecked") public void entityScanShouldSetInitialEntitySet() throws Exception { - this.context = new AnnotationConfigApplicationContext(); - TestPropertyValues.of("spring.data.cassandra.keyspaceName:boot_test"); - this.context.register(TestConfiguration.class, EntityScanConfig.class, - PropertyPlaceholderAutoConfiguration.class, - CassandraAutoConfiguration.class, CassandraDataAutoConfiguration.class); - this.context.refresh(); + load(EntityScanConfig.class); CassandraMappingContext mappingContext = this.context .getBean(CassandraMappingContext.class); Set> initialEntitySet = (Set>) ReflectionTestUtils @@ -88,19 +81,43 @@ public class CassandraDataAutoConfigurationTests { @Test public void userTypeResolverShouldBeSet() throws Exception { - this.context = new AnnotationConfigApplicationContext(); - TestPropertyValues.of("spring.data.cassandra.keyspaceName:boot_test") - .applyTo(this.context); - this.context.register(TestConfiguration.class, - PropertyPlaceholderAutoConfiguration.class, - CassandraAutoConfiguration.class, CassandraDataAutoConfiguration.class); - this.context.refresh(); + load(); CassandraMappingContext mappingContext = this.context .getBean(CassandraMappingContext.class); assertThat(ReflectionTestUtils.getField(mappingContext, "userTypeResolver")) .isInstanceOf(SimpleUserTypeResolver.class); } + @Test + public void defaultConversions() { + load(); + CassandraTemplate template = this.context.getBean(CassandraTemplate.class); + assertThat(template.getConverter().getConversionService().canConvert(Person.class, + String.class)).isFalse(); + } + + @Test + public void customConversions() { + load(CustomConversionConfig.class); + CassandraTemplate template = this.context.getBean(CassandraTemplate.class); + assertThat(template.getConverter().getConversionService().canConvert(Person.class, + String.class)).isTrue(); + + } + + public void load(Class... config) { + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); + TestPropertyValues.of("spring.data.cassandra.keyspaceName:boot_test") + .applyTo(ctx); + if (!ObjectUtils.isEmpty(config)) { + ctx.register(config); + } + ctx.register(TestConfiguration.class, CassandraAutoConfiguration.class, + CassandraDataAutoConfiguration.class); + ctx.refresh(); + this.context = ctx; + } + @Configuration @ComponentScan(excludeFilters = @ComponentScan.Filter(classes = { Session.class }, type = FilterType.ASSIGNABLE_TYPE)) @@ -124,4 +141,27 @@ public class CassandraDataAutoConfigurationTests { } + @Configuration + static class CustomConversionConfig { + + @Bean + public CassandraCustomConversions myCassandraCustomConversions() { + return new CassandraCustomConversions(Collections.singletonList( + new MyConverter())); + } + + } + + private static class MyConverter implements Converter { + + @Override + public String convert(Person o) { + return null; + } + } + + private static class Person { + + } + }