DATAREDIS-602 - Polishing.

Remove mutable state from `ReactiveRedisTemplate`.
Set up required args constructors for passing `RedisSerializationContext` and `ConnectionFactory` while removing `InitializingBean` and `ClassLoaderAware` interfaces forcing the template to hold mutable state.
Introduced some tiny static helpers for creating `RedisSerializationContext` from Serializers and added defaulting.

Moving forward `RedisTemplate` should also be migrated to using the SerializationContext getting rid of mutable state.

Additionally some minor renames, JavaDoc updates and refactored methods to lambda style.

Original Pull Request: #239
This commit is contained in:
Christoph Strobl
2017-03-23 11:27:18 +01:00
parent 81657c530b
commit 07984271d8
32 changed files with 1347 additions and 1565 deletions

View File

@@ -44,6 +44,7 @@ import org.springframework.data.redis.ObjectFactory;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.test.util.MinimumRedisVersionRule;
import org.springframework.test.annotation.IfProfileValue;
@@ -51,6 +52,7 @@ import org.springframework.test.annotation.IfProfileValue;
* Integration tests for {@link DefaultReactiveGeoOperations}.
*
* @author Mark Paluch
* @author Christoph Strobl
*/
@RunWith(Parameterized.class)
@IfProfileValue(name = "redisVersion", value = "3.2.0+")
@@ -71,7 +73,7 @@ public class DefaultReactiveGeoOperationsIntegrationTests<K, V> {
private final ObjectFactory<K> keyFactory;
private final ObjectFactory<V> valueFactory;
@Parameters(name = "{3}")
@Parameters(name = "{4}")
public static Collection<Object[]> testParams() {
return ReactiveOperationsTestParams.testParams();
}
@@ -88,7 +90,7 @@ public class DefaultReactiveGeoOperationsIntegrationTests<K, V> {
* @param label parameterized test label, no further use besides that.
*/
public DefaultReactiveGeoOperationsIntegrationTests(ReactiveRedisTemplate<K, V> redisTemplate,
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory, String label) {
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory, RedisSerializer serializer, String label) {
this.redisTemplate = redisTemplate;
this.geoOperations = redisTemplate.opsForGeo();

View File

@@ -39,12 +39,14 @@ import org.springframework.data.redis.StringObjectFactory;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* Integration tests for {@link DefaultReactiveHashOperations}.
*
* @author Mark Paluch
* @author Christoph Strobl
*/
@RunWith(Parameterized.class)
@SuppressWarnings("unchecked")
@@ -68,16 +70,13 @@ public class DefaultReactiveHashOperationsIntegrationTests<K, HK, HV> {
lettuceConnectionFactory.setHostName(SettingsUtils.getHost());
lettuceConnectionFactory.afterPropertiesSet();
ReactiveRedisTemplate<String, String> stringTemplate = new ReactiveRedisTemplate<>();
stringTemplate.setConnectionFactory(lettuceConnectionFactory);
stringTemplate.setEnableDefaultSerializer(true);
stringTemplate.setDefaultSerializer(new StringRedisSerializer());
stringTemplate.afterPropertiesSet();
RedisSerializationContext<String, String> serializationContext = RedisSerializationContext
.fromSerializer(new StringRedisSerializer());
ReactiveRedisTemplate<String, String> stringTemplate = new ReactiveRedisTemplate<>(lettuceConnectionFactory,
serializationContext);
ReactiveRedisTemplate<byte[], byte[]> rawTemplate = new ReactiveRedisTemplate<>();
rawTemplate.setConnectionFactory(lettuceConnectionFactory);
rawTemplate.setEnableDefaultSerializer(false);
rawTemplate.afterPropertiesSet();
ReactiveRedisTemplate<byte[], byte[]> rawTemplate = new ReactiveRedisTemplate(lettuceConnectionFactory,
RedisSerializationContext.raw());
return Arrays.asList(new Object[][] { { stringTemplate, stringFactory, stringFactory, stringFactory, "String" },
{ rawTemplate, rawFactory, rawFactory, rawFactory, "raw" } });

View File

@@ -29,11 +29,13 @@ import org.springframework.data.redis.ConnectionFactoryTracker;
import org.springframework.data.redis.ObjectFactory;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.RedisSerializer;
/**
* Integration tests for {@link DefaultReactiveHyperLogLogOperations}.
*
* @author Mark Paluch
* @author Christoph Strobl
*/
@RunWith(Parameterized.class)
@SuppressWarnings("unchecked")
@@ -45,7 +47,7 @@ public class DefaultReactiveHyperLogLogOperationsIntegrationTests<K, V> {
private final ObjectFactory<K> keyFactory;
private final ObjectFactory<V> valueFactory;
@Parameters(name = "{3}")
@Parameters(name = "{4}")
public static Collection<Object[]> testParams() {
return ReactiveOperationsTestParams.testParams();
}
@@ -62,7 +64,7 @@ public class DefaultReactiveHyperLogLogOperationsIntegrationTests<K, V> {
* @param label parameterized test label, no further use besides that.
*/
public DefaultReactiveHyperLogLogOperationsIntegrationTests(ReactiveRedisTemplate<K, V> redisTemplate,
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory, String label) {
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory, RedisSerializer serializer, String label) {
this.redisTemplate = redisTemplate;
this.hyperLogLogOperations = redisTemplate.opsForHyperLogLog();

View File

@@ -34,11 +34,13 @@ import org.springframework.data.redis.ConnectionFactoryTracker;
import org.springframework.data.redis.ObjectFactory;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.RedisSerializer;
/**
* Integration tests for {@link DefaultReactiveListOperations}.
*
* @author Mark Paluch
* @author Christoph Strobl
*/
@RunWith(Parameterized.class)
@SuppressWarnings("unchecked")
@@ -50,7 +52,7 @@ public class DefaultReactiveListOperationsIntegrationTests<K, V> {
private final ObjectFactory<K> keyFactory;
private final ObjectFactory<V> valueFactory;
@Parameters(name = "{3}")
@Parameters(name = "{4}")
public static Collection<Object[]> testParams() {
return ReactiveOperationsTestParams.testParams();
}
@@ -67,7 +69,7 @@ public class DefaultReactiveListOperationsIntegrationTests<K, V> {
* @param label parameterized test label, no further use besides that.
*/
public DefaultReactiveListOperationsIntegrationTests(ReactiveRedisTemplate<K, V> redisTemplate,
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory, String label) {
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory, RedisSerializer serializer, String label) {
this.redisTemplate = redisTemplate;
this.listOperations = redisTemplate.opsForList();

View File

@@ -35,11 +35,13 @@ import org.springframework.data.redis.ConnectionFactoryTracker;
import org.springframework.data.redis.ObjectFactory;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.RedisSerializer;
/**
* Integration tests for {@link DefaultReactiveSetOperations}.
*
* @author Mark Paluch
* @author Christoph Strobl
*/
@RunWith(Parameterized.class)
@SuppressWarnings("unchecked")
@@ -51,7 +53,7 @@ public class DefaultReactiveSetOperationsIntegrationTests<K, V> {
private final ObjectFactory<K> keyFactory;
private final ObjectFactory<V> valueFactory;
@Parameters(name = "{3}")
@Parameters(name = "{4}")
public static Collection<Object[]> testParams() {
return ReactiveOperationsTestParams.testParams();
}
@@ -68,7 +70,7 @@ public class DefaultReactiveSetOperationsIntegrationTests<K, V> {
* @param label parameterized test label, no further use besides that.
*/
public DefaultReactiveSetOperationsIntegrationTests(ReactiveRedisTemplate<K, V> redisTemplate,
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory, String label) {
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory, RedisSerializer serializer, String label) {
this.redisTemplate = redisTemplate;
this.setOperations = redisTemplate.opsForSet();

View File

@@ -37,12 +37,14 @@ import org.springframework.data.redis.ConnectionFactoryTracker;
import org.springframework.data.redis.ObjectFactory;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* Integration tests for {@link DefaultReactiveValueOperations}.
*
* @author Mark Paluch
* @author Christoph Strobl
*/
@RunWith(Parameterized.class)
@SuppressWarnings("unchecked")
@@ -54,7 +56,9 @@ public class DefaultReactiveValueOperationsIntegrationTests<K, V> {
private final ObjectFactory<K> keyFactory;
private final ObjectFactory<V> valueFactory;
@Parameters(name = "{3}")
private final RedisSerializer serializer;
@Parameters(name = "{4}")
public static Collection<Object[]> testParams() {
return ReactiveOperationsTestParams.testParams();
}
@@ -71,12 +75,13 @@ public class DefaultReactiveValueOperationsIntegrationTests<K, V> {
* @param label parameterized test label, no further use besides that.
*/
public DefaultReactiveValueOperationsIntegrationTests(ReactiveRedisTemplate<K, V> redisTemplate,
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory, String label) {
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory, RedisSerializer serializer, String label) {
this.redisTemplate = redisTemplate;
this.valueOperations = redisTemplate.opsForValue();
this.keyFactory = keyFactory;
this.valueFactory = valueFactory;
this.serializer = serializer;
ConnectionFactoryTracker.add(redisTemplate.getConnectionFactory());
}
@@ -219,7 +224,7 @@ public class DefaultReactiveValueOperationsIntegrationTests<K, V> {
V value2 = valueFactory.instance();
V absentValue = null;
if (redisTemplate.getValueSerializer() instanceof StringRedisSerializer) {
if (serializer instanceof StringRedisSerializer) {
absentValue = (V) "";
}
if (value1 instanceof ByteBuffer) {
@@ -239,7 +244,7 @@ public class DefaultReactiveValueOperationsIntegrationTests<K, V> {
@Test // DATAREDIS-602
public void append() {
assumeTrue(redisTemplate.getValueSerializer() instanceof StringRedisSerializer);
assumeTrue(serializer instanceof StringRedisSerializer);
K key = keyFactory.instance();
V value = valueFactory.instance();
@@ -254,7 +259,7 @@ public class DefaultReactiveValueOperationsIntegrationTests<K, V> {
@Test // DATAREDIS-602
public void getRange() {
assumeTrue(redisTemplate.getValueSerializer() instanceof StringRedisSerializer);
assumeTrue(serializer instanceof StringRedisSerializer);
K key = keyFactory.instance();
V value = valueFactory.instance();
@@ -269,7 +274,7 @@ public class DefaultReactiveValueOperationsIntegrationTests<K, V> {
@Test // DATAREDIS-602
public void setRange() {
assumeTrue(redisTemplate.getValueSerializer() instanceof StringRedisSerializer);
assumeTrue(serializer instanceof StringRedisSerializer);
K key = keyFactory.instance();
V value = valueFactory.instance();
@@ -289,7 +294,7 @@ public class DefaultReactiveValueOperationsIntegrationTests<K, V> {
@Test // DATAREDIS-602
public void size() {
assumeTrue(redisTemplate.getValueSerializer() instanceof StringRedisSerializer);
assumeTrue(serializer instanceof StringRedisSerializer);
K key = keyFactory.instance();
V value = valueFactory.instance();

View File

@@ -37,12 +37,14 @@ import org.springframework.data.redis.ObjectFactory;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisZSetCommands.Limit;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* Integration tests for {@link DefaultReactiveZSetOperations}.
*
* @author Mark Paluch
* @author Christoph Strobl
*/
@RunWith(Parameterized.class)
@SuppressWarnings("unchecked")
@@ -54,7 +56,9 @@ public class DefaultReactiveZSetOperationsIntegrationTests<K, V> {
private final ObjectFactory<K> keyFactory;
private final ObjectFactory<V> valueFactory;
@Parameters(name = "{3}")
private final RedisSerializer serializer;
@Parameters(name = "{4}")
public static Collection<Object[]> testParams() {
return ReactiveOperationsTestParams.testParams();
}
@@ -71,12 +75,13 @@ public class DefaultReactiveZSetOperationsIntegrationTests<K, V> {
* @param label parameterized test label, no further use besides that.
*/
public DefaultReactiveZSetOperationsIntegrationTests(ReactiveRedisTemplate<K, V> redisTemplate,
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory, String label) {
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory, RedisSerializer serializer, String label) {
this.redisTemplate = redisTemplate;
this.zSetOperations = redisTemplate.opsForZSet();
this.keyFactory = keyFactory;
this.valueFactory = valueFactory;
this.serializer = serializer;
ConnectionFactoryTracker.add(redisTemplate.getConnectionFactory());
}
@@ -524,7 +529,7 @@ public class DefaultReactiveZSetOperationsIntegrationTests<K, V> {
@Test // DATAREDIS-602
public void rangeByLex() {
assumeTrue(redisTemplate.getValueSerializer() instanceof StringRedisSerializer);
assumeTrue(serializer instanceof StringRedisSerializer);
K key = keyFactory.instance();
V a = (V) "a";
@@ -542,7 +547,7 @@ public class DefaultReactiveZSetOperationsIntegrationTests<K, V> {
@Test // DATAREDIS-602
public void rangeByLexWithLimit() {
assumeTrue(redisTemplate.getValueSerializer() instanceof StringRedisSerializer);
assumeTrue(serializer instanceof StringRedisSerializer);
K key = keyFactory.instance();
V a = (V) "a";
@@ -565,7 +570,7 @@ public class DefaultReactiveZSetOperationsIntegrationTests<K, V> {
@Test // DATAREDIS-602
public void reverseRangeByLex() {
assumeTrue(redisTemplate.getValueSerializer() instanceof StringRedisSerializer);
assumeTrue(serializer instanceof StringRedisSerializer);
K key = keyFactory.instance();
V a = (V) "a";
@@ -582,7 +587,7 @@ public class DefaultReactiveZSetOperationsIntegrationTests<K, V> {
@Test // DATAREDIS-602
public void reverseRangeByLexLimit() {
assumeTrue(redisTemplate.getValueSerializer() instanceof StringRedisSerializer);
assumeTrue(serializer instanceof StringRedisSerializer);
K key = keyFactory.instance();
V a = (V) "a";

View File

@@ -18,9 +18,12 @@ package org.springframework.data.redis.core;
import static org.springframework.data.redis.connection.ClusterTestVariables.*;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.junit.runners.model.Statement;
import org.springframework.data.redis.ByteBufferObjectFactory;
import org.springframework.data.redis.DoubleObjectFactory;
import org.springframework.data.redis.LongObjectFactory;
@@ -36,14 +39,18 @@ import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactor
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.GenericToStringSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.OxmSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.data.redis.test.util.RedisClusterRule;
import org.springframework.oxm.xstream.XStreamMarshaller;
/**
* Parameters for testing implementations of {@link ReactiveRedisTemplate}
*
* @author Mark Paluch
* @author Christoph Strobl
*/
abstract public class ReactiveOperationsTestParams {
@@ -69,85 +76,94 @@ abstract public class ReactiveOperationsTestParams {
lettuceConnectionFactory.setHostName(SettingsUtils.getHost());
lettuceConnectionFactory.afterPropertiesSet();
RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration();
clusterConfiguration.addClusterNode(new RedisClusterNode(CLUSTER_HOST, MASTER_NODE_1_PORT));
JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
ReactiveRedisTemplate<Object, Object> objectTemplate = new ReactiveRedisTemplate<>(lettuceConnectionFactory,
RedisSerializationContext.fromSerializer(jdkSerializationRedisSerializer));
LettuceConnectionFactory lettuceClusterConnectionFactory = new LettuceConnectionFactory(clusterConfiguration);
lettuceClusterConnectionFactory.setPort(SettingsUtils.getPort());
lettuceClusterConnectionFactory.setHostName(SettingsUtils.getHost());
lettuceClusterConnectionFactory.afterPropertiesSet();
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
ReactiveRedisTemplate<String, String> stringTemplate = new ReactiveRedisTemplate<>(lettuceConnectionFactory,
RedisSerializationContext.fromSerializer(stringRedisSerializer));
ReactiveRedisTemplate<Object, Object> objectTemplate = new ReactiveRedisTemplate<>();
objectTemplate.setConnectionFactory(lettuceConnectionFactory);
objectTemplate.afterPropertiesSet();
GenericToStringSerializer<Long> longToStringSerializer = new GenericToStringSerializer(Long.class);
ReactiveRedisTemplate<String, Long> longTemplate = new ReactiveRedisTemplate<>(lettuceConnectionFactory,
RedisSerializationContext.<String, Long> newSerializationContext(jdkSerializationRedisSerializer)
.key(stringRedisSerializer).value(longToStringSerializer).build());
ReactiveRedisTemplate<String, String> clusterStringTemplate = new ReactiveRedisTemplate<>();
clusterStringTemplate.setConnectionFactory(lettuceClusterConnectionFactory);
clusterStringTemplate.setDefaultSerializer(new StringRedisSerializer());
clusterStringTemplate.setEnableDefaultSerializer(true);
clusterStringTemplate.afterPropertiesSet();
GenericToStringSerializer<Double> doubleToStringSerializer = new GenericToStringSerializer(Double.class);
ReactiveRedisTemplate<String, Double> doubleTemplate = new ReactiveRedisTemplate<>(lettuceConnectionFactory,
RedisSerializationContext.<String, Double> newSerializationContext(jdkSerializationRedisSerializer)
.key(stringRedisSerializer).value(doubleToStringSerializer).build());
ReactiveRedisTemplate<String, String> stringTemplate = new ReactiveRedisTemplate<>();
stringTemplate.setDefaultSerializer(new StringRedisSerializer());
stringTemplate.setEnableDefaultSerializer(true);
stringTemplate.setConnectionFactory(lettuceConnectionFactory);
stringTemplate.afterPropertiesSet();
ReactiveRedisTemplate<byte[], byte[]> rawTemplate = new ReactiveRedisTemplate<>(lettuceConnectionFactory,
RedisSerializationContext.raw());
ReactiveRedisTemplate<String, Long> longTemplate = new ReactiveRedisTemplate<>();
longTemplate.setKeySerializer(new StringRedisSerializer());
longTemplate.setValueSerializer(new GenericToStringSerializer<>(Long.class));
longTemplate.setConnectionFactory(lettuceConnectionFactory);
longTemplate.afterPropertiesSet();
ReactiveRedisTemplate<String, Person> personTemplate = new ReactiveRedisTemplate(lettuceConnectionFactory,
RedisSerializationContext.fromSerializer(jdkSerializationRedisSerializer));
ReactiveRedisTemplate<String, Double> doubleTemplate = new ReactiveRedisTemplate<>();
doubleTemplate.setKeySerializer(new StringRedisSerializer());
doubleTemplate.setValueSerializer(new GenericToStringSerializer<>(Double.class));
doubleTemplate.setConnectionFactory(lettuceConnectionFactory);
doubleTemplate.afterPropertiesSet();
OxmSerializer oxmSerializer = new OxmSerializer(xstream, xstream);
ReactiveRedisTemplate<String, String> xstreamStringTemplate = new ReactiveRedisTemplate(lettuceConnectionFactory,
RedisSerializationContext.fromSerializer(oxmSerializer));
ReactiveRedisTemplate<byte[], byte[]> rawTemplate = new ReactiveRedisTemplate<>();
rawTemplate.setEnableDefaultSerializer(false);
rawTemplate.setConnectionFactory(lettuceConnectionFactory);
rawTemplate.afterPropertiesSet();
ReactiveRedisTemplate<String, Person> personTemplate = new ReactiveRedisTemplate<>();
personTemplate.setConnectionFactory(lettuceConnectionFactory);
personTemplate.afterPropertiesSet();
OxmSerializer serializer = new OxmSerializer(xstream, xstream);
ReactiveRedisTemplate<String, String> xstreamStringTemplate = new ReactiveRedisTemplate<>();
xstreamStringTemplate.setConnectionFactory(lettuceConnectionFactory);
xstreamStringTemplate.setDefaultSerializer(serializer);
xstreamStringTemplate.afterPropertiesSet();
ReactiveRedisTemplate<String, Person> xstreamPersonTemplate = new ReactiveRedisTemplate<>();
xstreamPersonTemplate.setConnectionFactory(lettuceConnectionFactory);
xstreamPersonTemplate.setValueSerializer(serializer);
xstreamPersonTemplate.afterPropertiesSet();
ReactiveRedisTemplate<String, Person> xstreamPersonTemplate = new ReactiveRedisTemplate(lettuceConnectionFactory,
RedisSerializationContext.fromSerializer(oxmSerializer));
Jackson2JsonRedisSerializer<Person> jackson2JsonSerializer = new Jackson2JsonRedisSerializer<>(Person.class);
ReactiveRedisTemplate<String, Person> jackson2JsonPersonTemplate = new ReactiveRedisTemplate<>();
jackson2JsonPersonTemplate.setConnectionFactory(lettuceConnectionFactory);
jackson2JsonPersonTemplate.setValueSerializer(jackson2JsonSerializer);
jackson2JsonPersonTemplate.afterPropertiesSet();
ReactiveRedisTemplate<String, Person> jackson2JsonPersonTemplate = new ReactiveRedisTemplate(
lettuceConnectionFactory, RedisSerializationContext.fromSerializer(jackson2JsonSerializer));
GenericJackson2JsonRedisSerializer genericJackson2JsonSerializer = new GenericJackson2JsonRedisSerializer();
ReactiveRedisTemplate<String, Person> genericJackson2JsonPersonTemplate = new ReactiveRedisTemplate<>();
genericJackson2JsonPersonTemplate.setConnectionFactory(lettuceConnectionFactory);
genericJackson2JsonPersonTemplate.setValueSerializer(genericJackson2JsonSerializer);
genericJackson2JsonPersonTemplate.afterPropertiesSet();
ReactiveRedisTemplate<String, Person> genericJackson2JsonPersonTemplate = new ReactiveRedisTemplate(
lettuceConnectionFactory, RedisSerializationContext.fromSerializer(genericJackson2JsonSerializer));
return Arrays.asList(new Object[][] { //
{ stringTemplate, stringFactory, stringFactory , "String"}, //
{ clusterStringTemplate, clusterKeyStringFactory, stringFactory, "Cluster String" }, //
{ objectTemplate, personFactory, personFactory , "Person/JDK"}, //
{ longTemplate, stringFactory, longFactory , "Long"}, //
{ doubleTemplate, stringFactory, doubleFactory , "Double"}, //
{ rawTemplate, rawFactory, rawFactory , "raw"}, //
{ personTemplate, stringFactory, personFactory , "String/Person/JDK"}, //
{ xstreamStringTemplate, stringFactory, stringFactory , "String/OXM"}, //
{ xstreamPersonTemplate, stringFactory, personFactory, "String/Person/OXM"}, //
{ jackson2JsonPersonTemplate, stringFactory, personFactory, "Jackson2"}, //
{ genericJackson2JsonPersonTemplate, stringFactory, personFactory, "Generic Jackson 2" } });
List<Object[]> list = Arrays.asList(new Object[][] { //
{ stringTemplate, stringFactory, stringFactory, stringRedisSerializer, "String" }, //
{ objectTemplate, personFactory, personFactory, jdkSerializationRedisSerializer, "Person/JDK" }, //
{ longTemplate, stringFactory, longFactory, longToStringSerializer, "Long" }, //
{ doubleTemplate, stringFactory, doubleFactory, doubleToStringSerializer, "Double" }, //
{ rawTemplate, rawFactory, rawFactory, null, "raw" }, //
{ personTemplate, stringFactory, personFactory, jdkSerializationRedisSerializer, "String/Person/JDK" }, //
{ xstreamStringTemplate, stringFactory, stringFactory, oxmSerializer, "String/OXM" }, //
{ xstreamPersonTemplate, stringFactory, personFactory, oxmSerializer, "String/Person/OXM" }, //
{ jackson2JsonPersonTemplate, stringFactory, personFactory, jackson2JsonSerializer, "Jackson2" }, //
{ genericJackson2JsonPersonTemplate, stringFactory, personFactory, genericJackson2JsonSerializer,
"Generic Jackson 2" } });
if (clusterAvailable()) {
RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration();
clusterConfiguration.addClusterNode(new RedisClusterNode(CLUSTER_HOST, MASTER_NODE_1_PORT));
ReactiveRedisTemplate<String, String> clusterStringTemplate = null;
LettuceConnectionFactory lettuceClusterConnectionFactory = new LettuceConnectionFactory(clusterConfiguration);
lettuceClusterConnectionFactory.setPort(SettingsUtils.getPort());
lettuceClusterConnectionFactory.setHostName(SettingsUtils.getHost());
lettuceClusterConnectionFactory.afterPropertiesSet();
clusterStringTemplate = new ReactiveRedisTemplate<>(lettuceClusterConnectionFactory,
RedisSerializationContext.string());
list = new ArrayList<>(list);
list.add(new Object[] { clusterStringTemplate, clusterKeyStringFactory, stringFactory, stringRedisSerializer,
"Cluster String" });
}
return list;
}
private static boolean clusterAvailable() {
try {
new RedisClusterRule().apply(new Statement() {
@Override
public void evaluate() throws Throwable {
}
}, null).evaluate();
} catch (Throwable throwable) {
return false;
}
return true;
}
}

View File

@@ -40,13 +40,15 @@ import org.springframework.data.redis.connection.ReactiveRedisClusterConnection;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.ReactiveSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* Integration tests for {@link ReactiveRedisTemplate}.
*
* @author Mark Paluch
* @author Christoph Strobl
*/
@RunWith(Parameterized.class)
public class ReactiveRedisTemplateIntegrationTests<K, V> {
@@ -57,7 +59,7 @@ public class ReactiveRedisTemplateIntegrationTests<K, V> {
private final ObjectFactory<V> valueFactory;
@Parameters(name = "{3}")
@Parameters(name = "{4}")
public static Collection<Object[]> testParams() {
return ReactiveOperationsTestParams.testParams();
}
@@ -74,7 +76,7 @@ public class ReactiveRedisTemplateIntegrationTests<K, V> {
* @param label parameterized test label, no further use besides that.
*/
public ReactiveRedisTemplateIntegrationTests(ReactiveRedisTemplate<K, V> redisTemplate, ObjectFactory<K> keyFactory,
ObjectFactory<V> valueFactory, String label) {
ObjectFactory<V> valueFactory, RedisSerializer serializer, String label) {
this.redisTemplate = redisTemplate;
this.keyFactory = keyFactory;
@@ -269,7 +271,7 @@ public class ReactiveRedisTemplateIntegrationTests<K, V> {
Person value = new PersonObjectFactory().instance();
JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer();
ReactiveSerializationContext<Object, Object> objectSerializers = ReactiveSerializationContext.builder()
RedisSerializationContext<Object, Object> objectSerializers = RedisSerializationContext.newSerializationContext()
.key(jdkSerializer) //
.value(jdkSerializer) //
.hashKey(jdkSerializer) //
@@ -286,18 +288,17 @@ public class ReactiveRedisTemplateIntegrationTests<K, V> {
@Test // DATAREDIS-602
public void shouldApplyCustomSerializationContextToHash() {
ReactiveSerializationContext<K, V> serializationContext = redisTemplate.getSerializationContext();
RedisSerializationContext<K, V> serializationContext = redisTemplate.getSerializationContext();
K key = keyFactory.instance();
String hashField = "foo";
Person hashValue = new PersonObjectFactory().instance();
JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer();
ReactiveSerializationContext<K, V> objectSerializers = ReactiveSerializationContext.<K, V> builder()
.key(serializationContext.key()) //
.value(serializationContext.value()) //
RedisSerializationContext<K, V> objectSerializers = RedisSerializationContext.<K, V> newSerializationContext()
.key(serializationContext.getKeySerializationPair()) //
.value(serializationContext.getValueSerializationPair()) //
.hashKey(new StringRedisSerializer()) //
.hashValue(jdkSerializer) //
.hashValue(new JdkSerializationRedisSerializer()) //
.build();
ReactiveHashOperations<K, String, Object> hashOperations = redisTemplate.opsForHash(objectSerializers);

View File

@@ -29,5 +29,4 @@ public interface PersonRepository extends CrudRepository<Person, String>, Person
List<Person> findAll();
List<Person> findByName(String name);
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.redis.serializer;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import org.junit.Test;
/**
* Unit tests for {@link DefaultRedisElementReader}.
*
* @author Mark Paluch
*/
public class DefaultRedisElementReaderUnitTests {
@Test // DATAREDIS-602
public void shouldDecodeByteBufferCorrectly() {
String input = "123ü?™";
byte[] bytes = input.getBytes(StandardCharsets.UTF_8);
DefaultRedisElementReader<String> reader = new DefaultRedisElementReader<>(
new StringRedisSerializer(StandardCharsets.UTF_8));
String result = reader.read(ByteBuffer.wrap(bytes));
assertThat(result, is(equalTo(input)));
}
@Test // DATAREDIS-602
public void shouldPassThroughByteBufferForAbsentSerializer() {
ByteBuffer input = ByteBuffer.allocate(1);
DefaultRedisElementReader<Object> reader = new DefaultRedisElementReader<>(null);
Object result = reader.read(input);
assertThat(result, is(equalTo(input)));
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.redis.serializer;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import org.junit.Test;
/**
* Unit tests for {@link DefaultRedisElementWriter}.
*
* @author Mark Paluch
*/
public class DefaultRedisElementWriterUnitTests {
@Test // DATAREDIS-602
public void shouldSerializeInputCorrectly() {
String input = "123ü?™";
byte[] bytes = input.getBytes(StandardCharsets.UTF_8);
DefaultRedisElementWriter<String> writer = new DefaultRedisElementWriter<>(
new StringRedisSerializer(StandardCharsets.UTF_8));
ByteBuffer result = writer.write(input);
assertThat(result.array(), is(equalTo(bytes)));
}
@Test // DATAREDIS-602
public void shouldWrapByteArrayForAbsentSerializer() {
DefaultRedisElementWriter<Object> writer = new DefaultRedisElementWriter<>(null);
byte[] input = { 1, 2, 3 };
ByteBuffer result = writer.write(input);
assertThat(result.array(), is(equalTo(input)));
}
@Test // DATAREDIS-602
public void shouldPassThroughByteBufferForAbsentSerializer() {
DefaultRedisElementWriter<Object> writer = new DefaultRedisElementWriter<>(null);
byte[] input = { 1, 2, 3 };
ByteBuffer result = writer.write(ByteBuffer.wrap(input));
assertThat(result.array(), is(equalTo(input)));
}
@Test(expected = IllegalStateException.class) // DATAREDIS-602
public void shouldFailForUnsupportedTypeWithAbsentSerializer() {
DefaultRedisElementWriter<Object> writer = new DefaultRedisElementWriter<>(null);
writer.write(new Object());
}
}

View File

@@ -22,16 +22,17 @@ import java.nio.ByteBuffer;
import org.junit.Test;
/**
* Unit tests for {@link ReactiveSerializationContext}.
* Unit tests for {@link RedisSerializationContext}.
*
* @author Mark Paluch
* @author Christoph Strobl
*/
public class ReactiveSerializationContextUnitTests {
public class RedisSerializationContextUnitTests {
@Test(expected = IllegalArgumentException.class) // DATAREDIS-602
public void shouldRejectBuildIfKeySerializerIsNotSet() {
ReactiveSerializationContext.<String, String> builder() //
RedisSerializationContext.<String, String> newSerializationContext() //
.value(new StringRedisSerializer()) //
.hashKey(new StringRedisSerializer()) //
.hashValue(new StringRedisSerializer()) //
@@ -41,7 +42,7 @@ public class ReactiveSerializationContextUnitTests {
@Test(expected = IllegalArgumentException.class) // DATAREDIS-602
public void shouldRejectBuildIfValueSerializerIsNotSet() {
ReactiveSerializationContext.<String, String> builder() //
RedisSerializationContext.<String, String> newSerializationContext() //
.key(new StringRedisSerializer()) //
.hashKey(new StringRedisSerializer()) //
.hashValue(new StringRedisSerializer()) //
@@ -51,7 +52,7 @@ public class ReactiveSerializationContextUnitTests {
@Test(expected = IllegalArgumentException.class) // DATAREDIS-602
public void shouldRejectBuildIfHashKeySerializerIsNotSet() {
ReactiveSerializationContext.<String, String> builder() //
RedisSerializationContext.<String, String> newSerializationContext() //
.key(new StringRedisSerializer()) //
.value(new StringRedisSerializer()) //
.hashValue(new StringRedisSerializer()) //
@@ -61,31 +62,40 @@ public class ReactiveSerializationContextUnitTests {
@Test(expected = IllegalArgumentException.class) // DATAREDIS-602
public void shouldRejectBuildIfHashValueSerializerIsNotSet() {
ReactiveSerializationContext.<String, String> builder() //
RedisSerializationContext.<String, String> newSerializationContext() //
.key(new StringRedisSerializer()) //
.value(new StringRedisSerializer()) //
.hashKey(new StringRedisSerializer()) //
.build();
}
@Test // DATAREDIS-602
public void shouldUseDefaultIfSet() {
RedisSerializationContext.<String, String> newSerializationContext(new StringRedisSerializer())
.key(new GenericToStringSerializer(Long.class))//
.build();
}
@Test // DATAREDIS-602
public void shouldBuildSerializationContext() {
ReactiveSerializationContext<String, Long> serializationContext = createSerializationContext();
RedisSerializationContext<String, Long> serializationContext = createSerializationContext();
assertThat(serializationContext.key()).isNotNull();
assertThat(serializationContext.value()).isNotNull();
assertThat(serializationContext.hashKey()).isNotNull();
assertThat(serializationContext.hashValue()).isNotNull();
assertThat(serializationContext.string()).isNotNull();
assertThat(serializationContext.getKeySerializationPair()).isNotNull();
assertThat(serializationContext.getValueSerializationPair()).isNotNull();
assertThat(serializationContext.getHashKeySerializationPair()).isNotNull();
assertThat(serializationContext.getHashValueSerializationPair()).isNotNull();
assertThat(serializationContext.getStringSerializationPair()).isNotNull();
}
@Test // DATAREDIS-602
public void shouldEncodeAndDecodeKey() {
ReactiveSerializationContext<String, Long> serializationContext = createSerializationContext();
RedisSerializationContext<String, Long> serializationContext = createSerializationContext();
String deserialized = serializationContext.key().read(serializationContext.key().write("foo"));
String deserialized = serializationContext.getKeySerializationPair()
.read(serializationContext.getKeySerializationPair().write("foo"));
assertThat(deserialized).isEqualTo("foo");
}
@@ -93,16 +103,17 @@ public class ReactiveSerializationContextUnitTests {
@Test // DATAREDIS-602
public void shouldEncodeAndDecodeValue() {
ReactiveSerializationContext<String, Long> serializationContext = createSerializationContext();
RedisSerializationContext<String, Long> serializationContext = createSerializationContext();
long deserialized = serializationContext.value().read(serializationContext.value().write(42L));
long deserialized = serializationContext.getValueSerializationPair()
.read(serializationContext.getValueSerializationPair().write(42L));
assertThat(deserialized).isEqualTo(42);
}
private ReactiveSerializationContext<String, Long> createSerializationContext() {
private RedisSerializationContext<String, Long> createSerializationContext() {
return ReactiveSerializationContext.<String, Long> builder() //
return RedisSerializationContext.<String, Long> newSerializationContext() //
.key(new StringRedisSerializer()) //
.value(ByteBuffer::getLong, value -> (ByteBuffer) ByteBuffer.allocate(8).putLong(value).flip()) //
.hashKey(new StringRedisSerializer()) //