diff --git a/src/main/java/org/springframework/data/redis/serializer/DefaultRedisSerializationContext.java b/src/main/java/org/springframework/data/redis/serializer/DefaultRedisSerializationContext.java index 9662fedd5..75648685b 100644 --- a/src/main/java/org/springframework/data/redis/serializer/DefaultRedisSerializationContext.java +++ b/src/main/java/org/springframework/data/redis/serializer/DefaultRedisSerializationContext.java @@ -24,7 +24,7 @@ import org.springframework.util.Assert; * @author Mark Paluch * @author Christoph Strobl * @author Shyngys Sapraliyev - * @author Zhou KQ + * @author John Blum * @since 2.0 */ class DefaultRedisSerializationContext implements RedisSerializationContext { @@ -36,7 +36,8 @@ class DefaultRedisSerializationContext implements RedisSerializationContex private final SerializationPair stringTuple; private DefaultRedisSerializationContext(SerializationPair keyTuple, SerializationPair valueTuple, - SerializationPair hashKeyTuple, SerializationPair hashValueTuple, SerializationPair stringTuple) { + SerializationPair hashKeyTuple, SerializationPair hashValueTuple, + SerializationPair stringTuple) { this.keyTuple = keyTuple; this.valueTuple = valueTuple; @@ -47,29 +48,29 @@ class DefaultRedisSerializationContext implements RedisSerializationContex @Override public SerializationPair getKeySerializationPair() { - return keyTuple; + return this.keyTuple; } @Override public SerializationPair getValueSerializationPair() { - return valueTuple; + return this.valueTuple; } @Override @SuppressWarnings("unchecked") public SerializationPair getHashKeySerializationPair() { - return (SerializationPair) hashKeyTuple; + return (SerializationPair) this.hashKeyTuple; } @Override @SuppressWarnings("unchecked") public SerializationPair getHashValueSerializationPair() { - return (SerializationPair) hashValueTuple; + return (SerializationPair) this.hashValueTuple; } @Override public SerializationPair getStringSerializationPair() { - return stringTuple; + return this.stringTuple; } /** @@ -77,6 +78,7 @@ class DefaultRedisSerializationContext implements RedisSerializationContex * * @author Mark Paluch * @author Christoph Strobl + * @author Zhou KQ * @since 2.0 */ static class DefaultRedisSerializationContextBuilder implements RedisSerializationContextBuilder { @@ -85,6 +87,7 @@ class DefaultRedisSerializationContext implements RedisSerializationContex private @Nullable SerializationPair valueTuple; private @Nullable SerializationPair hashKeyTuple; private @Nullable SerializationPair hashValueTuple; + private SerializationPair stringTuple = SerializationPair.fromSerializer(RedisSerializer.string()); @Override @@ -93,6 +96,7 @@ class DefaultRedisSerializationContext implements RedisSerializationContex Assert.notNull(tuple, "SerializationPair must not be null"); this.keyTuple = tuple; + return this; } @@ -102,6 +106,7 @@ class DefaultRedisSerializationContext implements RedisSerializationContex Assert.notNull(tuple, "SerializationPair must not be null"); this.valueTuple = tuple; + return this; } @@ -111,6 +116,7 @@ class DefaultRedisSerializationContext implements RedisSerializationContex Assert.notNull(tuple, "SerializationPair must not be null"); this.hashKeyTuple = tuple; + return this; } @@ -120,6 +126,7 @@ class DefaultRedisSerializationContext implements RedisSerializationContex Assert.notNull(tuple, "SerializationPair must not be null"); this.hashValueTuple = tuple; + return this; } @@ -129,19 +136,20 @@ class DefaultRedisSerializationContext implements RedisSerializationContex Assert.notNull(tuple, "SerializationPair must not be null"); this.stringTuple = tuple; + return this; } @Override public RedisSerializationContext build() { - Assert.notNull(keyTuple, "Key SerializationPair must not be null!"); - Assert.notNull(valueTuple, "Value SerializationPair must not be null!"); - Assert.notNull(hashKeyTuple, "HashKey SerializationPair must not be null!"); - Assert.notNull(hashValueTuple, "HashValue SerializationPair must not be null!"); + Assert.notNull(this.keyTuple, "Key SerializationPair must not be null"); + Assert.notNull(this.valueTuple, "Value SerializationPair must not be null"); + Assert.notNull(this.hashKeyTuple, "HashKey SerializationPair must not be null"); + Assert.notNull(this.hashValueTuple, "HashValue SerializationPair must not be null"); - return new DefaultRedisSerializationContext<>(keyTuple, valueTuple, hashKeyTuple, hashValueTuple, - stringTuple); + return new DefaultRedisSerializationContext<>(this.keyTuple, this.valueTuple, + this.hashKeyTuple, this.hashValueTuple, this.stringTuple); } } } diff --git a/src/main/java/org/springframework/data/redis/serializer/RedisSerializationContext.java b/src/main/java/org/springframework/data/redis/serializer/RedisSerializationContext.java index d76b5bb7e..b0b75dfc3 100644 --- a/src/main/java/org/springframework/data/redis/serializer/RedisSerializationContext.java +++ b/src/main/java/org/springframework/data/redis/serializer/RedisSerializationContext.java @@ -27,6 +27,7 @@ import org.springframework.util.Assert; * * @author Mark Paluch * @author Christoph Strobl + * @author John Blum * @since 2.0 * @see RedisElementWriter * @see RedisElementReader @@ -40,9 +41,8 @@ public interface RedisSerializationContext { * @param expected value type. * @return a new {@link RedisSerializationContextBuilder}. */ - @SuppressWarnings("unchecked") static RedisSerializationContextBuilder newSerializationContext() { - return new DefaultRedisSerializationContext.DefaultRedisSerializationContextBuilder(); + return new DefaultRedisSerializationContext.DefaultRedisSerializationContextBuilder<>(); } /** @@ -68,7 +68,7 @@ public interface RedisSerializationContext { * @param expected value type. * @return a new {@link RedisSerializationContextBuilder}. */ - @SuppressWarnings("unchecked") + @SuppressWarnings({ "rawtypes", "unchecked" }) static RedisSerializationContextBuilder newSerializationContext(SerializationPair serializationPair) { Assert.notNull(serializationPair, "SerializationPair must not be null"); @@ -114,7 +114,7 @@ public interface RedisSerializationContext { /** * Creates a new {@link RedisSerializationContext} using a {@link JdkSerializationRedisSerializer}. * - * @return new instance of {@link RedisSerializationContext}. + * @return a new {@link RedisSerializationContext} using JDK Serializaton. * @since 2.1 */ static RedisSerializationContext java() { @@ -123,10 +123,11 @@ public interface RedisSerializationContext { /** * Creates a new {@link RedisSerializationContext} using a {@link JdkSerializationRedisSerializer} with given - * {@link ClassLoader}. + * {@link ClassLoader} to resolves {@link Class type} of the keys and values stored in Redis. * - * @param classLoader the {@link ClassLoader} to use for deserialization. Can be {@literal null}. - * @return new instance of {@link RedisSerializationContext}. + * @param classLoader {@link ClassLoader} used to resolve {@link Class types} of keys and value stored in Redis + * during deserialization; can be {@literal null}. + * @return a new {@link RedisSerializationContext} using JDK Serializaton. * @since 2.1 */ static RedisSerializationContext java(ClassLoader classLoader) { @@ -136,7 +137,7 @@ public interface RedisSerializationContext { /** * Creates a new {@link RedisSerializationContext} using a {@link StringRedisSerializer}. * - * @return + * @return a new {@link RedisSerializationContext} using a {@link StringRedisSerializer}. */ static RedisSerializationContext string() { return fromSerializer(RedisSerializer.string()); @@ -145,9 +146,10 @@ public interface RedisSerializationContext { /** * Creates a new {@link RedisSerializationContext} using the given {@link RedisSerializer}. * - * @param serializer must not be {@literal null}. - * @param - * @return + * @param {@link Class Type} of {@link Object} being de/serialized by the {@link RedisSerializer}. + * @param serializer {@link RedisSerializer} used to de/serialize keys and value stored in Redis; + * must not be {@literal null}. + * @return a new {@link RedisSerializationContext} using the given {@link RedisSerializer}. */ static RedisSerializationContext fromSerializer(RedisSerializer serializer) { return just(SerializationPair.fromSerializer(serializer)); @@ -156,9 +158,10 @@ public interface RedisSerializationContext { /** * Creates a new {@link RedisSerializationContext} using the given {@link SerializationPair}. * - * @param serializationPair - * @param - * @return + * @param {@link Class Type} of {@link Object} de/serialized by the {@link SerializationPair}. + * @param serializationPair {@link SerializationPair} used to de/serialize keys and values stored in Redis; + * must not be {@literal null}. + * @return a new {@link RedisSerializationContext} using the given {@link SerializationPair}. */ static RedisSerializationContext just(SerializationPair serializationPair) { return RedisSerializationContext. newSerializationContext(serializationPair).build(); @@ -278,10 +281,10 @@ public interface RedisSerializationContext { RedisElementWriter getWriter(); /** - * Serialize a {@code element} to its {@link ByteBuffer} representation. + * Serialize the given {@code element} to its {@link ByteBuffer} representation. * - * @param element - * @return the {@link ByteBuffer} representing {@code element} in its binary form. + * @param element {@link Object} to write (serialize) as a stream of bytes. + * @return the {@link ByteBuffer} representing the given {@code element} in binary form. */ default ByteBuffer write(T element) { return getWriter().write(element); @@ -314,6 +317,7 @@ public interface RedisSerializationContext { default RedisSerializationContextBuilder key(RedisElementReader reader, RedisElementWriter writer) { key(SerializationPair.just(reader, writer)); + return this; } @@ -326,6 +330,7 @@ public interface RedisSerializationContext { default RedisSerializationContextBuilder key(RedisSerializer serializer) { key(SerializationPair.fromSerializer(serializer)); + return this; } @@ -347,6 +352,7 @@ public interface RedisSerializationContext { default RedisSerializationContextBuilder value(RedisElementReader reader, RedisElementWriter writer) { value(SerializationPair.just(reader, writer)); + return this; } @@ -359,6 +365,7 @@ public interface RedisSerializationContext { default RedisSerializationContextBuilder value(RedisSerializer serializer) { value(SerializationPair.fromSerializer(serializer)); + return this; } @@ -377,10 +384,11 @@ public interface RedisSerializationContext { * @param writer must not be {@literal null}. * @return {@literal this} builder. */ - default RedisSerializationContextBuilder hashKey(RedisElementReader reader, - RedisElementWriter writer) { + default RedisSerializationContextBuilder hashKey(RedisElementReader reader, + RedisElementWriter writer) { hashKey(SerializationPair.just(reader, writer)); + return this; } @@ -390,9 +398,10 @@ public interface RedisSerializationContext { * @param serializer must not be {@literal null}. * @return {@literal this} builder. */ - default RedisSerializationContextBuilder hashKey(RedisSerializer serializer) { + default RedisSerializationContextBuilder hashKey(RedisSerializer serializer) { hashKey(SerializationPair.fromSerializer(serializer)); + return this; } @@ -411,10 +420,11 @@ public interface RedisSerializationContext { * @param writer must not be {@literal null}. * @return {@literal this} builder. */ - default RedisSerializationContextBuilder hashValue(RedisElementReader reader, - RedisElementWriter writer) { + default RedisSerializationContextBuilder hashValue(RedisElementReader reader, + RedisElementWriter writer) { hashValue(SerializationPair.just(reader, writer)); + return this; } @@ -424,9 +434,10 @@ public interface RedisSerializationContext { * @param serializer must not be {@literal null}. * @return {@literal this} builder. */ - default RedisSerializationContextBuilder hashValue(RedisSerializer serializer) { + default RedisSerializationContextBuilder hashValue(RedisSerializer serializer) { hashValue(SerializationPair.fromSerializer(serializer)); + return this; } @@ -449,6 +460,7 @@ public interface RedisSerializationContext { RedisElementWriter writer) { string(SerializationPair.just(reader, writer)); + return this; } @@ -461,6 +473,7 @@ public interface RedisSerializationContext { default RedisSerializationContextBuilder string(RedisSerializer serializer) { string(SerializationPair.fromSerializer(serializer)); + return this; } @@ -470,5 +483,6 @@ public interface RedisSerializationContext { * @return the {@link RedisSerializationContext}. */ RedisSerializationContext build(); + } } diff --git a/src/test/java/org/springframework/data/redis/serializer/RedisSerializationContextUnitTests.java b/src/test/java/org/springframework/data/redis/serializer/RedisSerializationContextUnitTests.java index 61a80c72a..add9744c4 100644 --- a/src/test/java/org/springframework/data/redis/serializer/RedisSerializationContextUnitTests.java +++ b/src/test/java/org/springframework/data/redis/serializer/RedisSerializationContextUnitTests.java @@ -15,12 +15,13 @@ */ package org.springframework.data.redis.serializer; -import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -import static org.assertj.core.api.Assertions.*; +import org.junit.jupiter.api.Test; /** * Unit tests for {@link RedisSerializationContext}. @@ -33,6 +34,7 @@ class RedisSerializationContextUnitTests { @Test // DATAREDIS-602 void shouldRejectBuildIfKeySerializerIsNotSet() { + assertThatIllegalArgumentException() .isThrownBy(() -> RedisSerializationContext. newSerializationContext() // .value(StringRedisSerializer.UTF_8) // @@ -43,6 +45,7 @@ class RedisSerializationContextUnitTests { @Test // DATAREDIS-602 void shouldRejectBuildIfValueSerializerIsNotSet() { + assertThatIllegalArgumentException() .isThrownBy(() -> RedisSerializationContext. newSerializationContext() // .key(StringRedisSerializer.UTF_8) // @@ -53,6 +56,7 @@ class RedisSerializationContextUnitTests { @Test // DATAREDIS-602 void shouldRejectBuildIfHashKeySerializerIsNotSet() { + assertThatIllegalArgumentException() .isThrownBy(() -> RedisSerializationContext. newSerializationContext() // .key(StringRedisSerializer.UTF_8) // @@ -63,6 +67,7 @@ class RedisSerializationContextUnitTests { @Test // DATAREDIS-602 void shouldRejectBuildIfHashValueSerializerIsNotSet() { + assertThatIllegalArgumentException() .isThrownBy(() -> RedisSerializationContext. newSerializationContext() // .key(StringRedisSerializer.UTF_8) // @@ -72,10 +77,11 @@ class RedisSerializationContextUnitTests { } @Test // DATAREDIS-602 + @SuppressWarnings({ "rawtypes", "unchecked" }) void shouldUseDefaultIfSet() { - RedisSerializationContext. newSerializationContext(StringRedisSerializer.UTF_8) - .key(new GenericToStringSerializer(Long.class))// + RedisSerializationContext.newSerializationContext(StringRedisSerializer.UTF_8) + .key(new GenericToStringSerializer(Long.class)) // .build(); } @@ -116,8 +122,7 @@ class RedisSerializationContextUnitTests { @Test // DATAREDIS-1000 void shouldEncodeAndDecodeRawByteBufferValue() { - RedisSerializationContext serializationContext = RedisSerializationContext - .byteBuffer(); + RedisSerializationContext serializationContext = RedisSerializationContext.byteBuffer(); ByteBuffer deserialized = serializationContext.getValueSerializationPair() .read(serializationContext.getValueSerializationPair() @@ -129,8 +134,7 @@ class RedisSerializationContextUnitTests { @Test // DATAREDIS-1000 void shouldEncodeAndDecodeByteArrayValue() { - RedisSerializationContext serializationContext = RedisSerializationContext - .byteArray(); + RedisSerializationContext serializationContext = RedisSerializationContext.byteArray(); byte[] deserialized = serializationContext.getValueSerializationPair() .read(serializationContext.getValueSerializationPair() @@ -139,55 +143,51 @@ class RedisSerializationContextUnitTests { assertThat(deserialized).isEqualTo("hello".getBytes()); } - @Test + @Test // GH-2651 void shouldEncodeAndDecodeUtf8StringValue() { - RedisSerializationContext serializationContext = RedisSerializationContext - .newSerializationContext(StringRedisSerializer.UTF_8) - .string(StringRedisSerializer.UTF_8) - .build(); - RedisSerializationContext.SerializationPair serializationPair = serializationContext.getStringSerializationPair(); - assertThat(serializationPair.write("üߨ")) - .isEqualTo(ByteBuffer.wrap("üߨ".getBytes(StandardCharsets.UTF_8))); - assertThat(serializationPair.read(ByteBuffer.wrap("üߨ".getBytes(StandardCharsets.UTF_8)))) - .isEqualTo("üߨ"); + RedisSerializationContext.SerializationPair serializationPair = + buildStringSerializationContext(StringRedisSerializer.UTF_8).getStringSerializationPair(); + + assertThat(serializationPair.write("üߨ")).isEqualTo(StandardCharsets.UTF_8.encode("üߨ")); + assertThat(serializationPair.read(StandardCharsets.UTF_8.encode("üߨ"))).isEqualTo("üߨ"); } - @Test + @Test // GH-2651 void shouldEncodeAndDecodeAsciiStringValue() { - RedisSerializationContext serializationContext = RedisSerializationContext - .newSerializationContext(StringRedisSerializer.US_ASCII) - .string(StringRedisSerializer.US_ASCII) - .build(); - RedisSerializationContext.SerializationPair serializationPair = serializationContext.getStringSerializationPair(); - assertThat(serializationPair.write("üߨ")) - .isEqualTo(ByteBuffer.wrap("???".getBytes(StandardCharsets.US_ASCII))); - assertThat(serializationPair.read(ByteBuffer.wrap("üߨ".getBytes(StandardCharsets.US_ASCII)))) - .isEqualTo("???"); + RedisSerializationContext.SerializationPair serializationPair = + buildStringSerializationContext(StringRedisSerializer.US_ASCII).getStringSerializationPair(); + + assertThat(serializationPair.write("üߨ")).isEqualTo(StandardCharsets.US_ASCII.encode("???")); + assertThat(serializationPair.read(StandardCharsets.US_ASCII.encode("üߨ"))).isEqualTo("???"); } - @Test + @Test // GH-2651 void shouldEncodeAndDecodeIso88591StringValue() { - RedisSerializationContext serializationContext = RedisSerializationContext - .newSerializationContext(StringRedisSerializer.ISO_8859_1) - .string(StringRedisSerializer.ISO_8859_1) - .build(); - RedisSerializationContext.SerializationPair serializationPair = serializationContext.getStringSerializationPair(); - assertThat(serializationPair.write("üߨ")) - .isEqualTo(ByteBuffer.wrap("üߨ".getBytes(StandardCharsets.ISO_8859_1))); - assertThat(serializationPair.read(ByteBuffer.wrap("üߨ".getBytes(StandardCharsets.ISO_8859_1)))) - .isEqualTo("üߨ"); + RedisSerializationContext.SerializationPair serializationPair = + buildStringSerializationContext(StringRedisSerializer.ISO_8859_1).getStringSerializationPair(); + + assertThat(serializationPair.write("üߨ")).isEqualTo(StandardCharsets.ISO_8859_1.encode("üߨ")); + assertThat(serializationPair.read(StandardCharsets.ISO_8859_1.encode("üߨ"))).isEqualTo("üߨ"); } private RedisSerializationContext createSerializationContext() { return RedisSerializationContext. newSerializationContext() // .key(StringRedisSerializer.UTF_8) // - .value(ByteBuffer::getLong, value -> (ByteBuffer) ByteBuffer.allocate(8).putLong(value).flip()) // + .value(ByteBuffer::getLong, value -> ByteBuffer.allocate(8).putLong(value).flip()) // .hashKey(StringRedisSerializer.UTF_8) // .hashValue(StringRedisSerializer.UTF_8) // .build(); } + + private RedisSerializationContext buildStringSerializationContext( + RedisSerializer stringSerializer) { + + return RedisSerializationContext.newSerializationContext(stringSerializer) + .string(stringSerializer) + .build(); + } }