DATAREDIS-683 - Polishing.

Rename *Operators -> *Executor and use plain RedisElementReader/Writer instead of SerilaizationPairs. Therefore we’ve introduced new static factory methods creating the required Reader/Writer from a given RedisSerializer.
Additionally some minor Javadoc updates, tests and removal of redundant null checks.

Original Pull Request: #268
This commit is contained in:
Christoph Strobl
2017-08-28 12:27:36 +02:00
parent a3b50ba765
commit 38d9f340c3
18 changed files with 376 additions and 191 deletions

View File

@@ -23,6 +23,7 @@ import io.lettuce.core.ScriptOutputType;
import reactor.test.StepVerifier;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -34,6 +35,7 @@ import org.springframework.data.redis.connection.ReturnType;
/**
* @author Mark Paluch
* @author Christoph Strobl
*/
public class LettuceReactiveScriptingCommandsTests extends LettuceReactiveCommandsTestsBase {
@@ -44,7 +46,7 @@ public class LettuceReactiveScriptingCommandsTests extends LettuceReactiveComman
String sha1 = nativeCommands.scriptLoad("return KEYS[1]");
StepVerifier.create(connection.scriptingCommands().scriptExists("foo", sha1)) //
StepVerifier.create(connection.scriptingCommands().scriptExists(Arrays.asList("foo", sha1))) //
.expectNext(false) //
.expectNext(true) //
.verifyComplete();

View File

@@ -44,6 +44,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisElementReader;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializationContext.SerializationPair;
import org.springframework.data.redis.serializer.RedisSerializer;
@@ -167,7 +168,7 @@ public class ReactiveRedisTemplateIntegrationTests<K, V> {
@Test // DATAREDIS-683
@SuppressWarnings("unchecked")
public void execute() {
public void executeScript() {
K key = keyFactory.instance();
V value = valueFactory.instance();
@@ -184,25 +185,26 @@ public class ReactiveRedisTemplateIntegrationTests<K, V> {
}
@Test // DATAREDIS-683
public void executeWithSerializationPairs() {
public void executeScriptWithElementReaderAndWriter() {
K key = keyFactory.instance();
V value = valueFactory.instance();
SerializationPair<Person> json = SerializationPair.fromSerializer(new Jackson2JsonRedisSerializer<>(Person.class));
SerializationPair<String> string = SerializationPair.fromSerializer(new StringRedisSerializer());
SerializationPair json = SerializationPair.fromSerializer(new Jackson2JsonRedisSerializer<>(Person.class));
RedisElementReader<String> resultReader = RedisElementReader.from(new StringRedisSerializer());
assumeFalse(value instanceof Long);
Person person = new Person("Walter", "White", 51);
StepVerifier.create(
redisTemplate.execute(new DefaultRedisScript<>("return redis.call('set', KEYS[1], ARGV[1])", String.class),
json, string, Collections.singletonList(key), person))
StepVerifier
.create(
redisTemplate.execute(new DefaultRedisScript<>("return redis.call('set', KEYS[1], ARGV[1])", String.class),
Collections.singletonList(key), Collections.singletonList(person), json.getWriter(), resultReader))
.expectNext("OK").verifyComplete();
Flux<Person> execute = redisTemplate.execute(
new DefaultRedisScript<>("return redis.call('get', KEYS[1])", Person.class), json, json,
Collections.singletonList(key));
new DefaultRedisScript<>("return redis.call('get', KEYS[1])", Person.class), Collections.singletonList(key),
Collections.emptyList(), json.getWriter(), json.getReader());
StepVerifier.create(execute).expectNext(person).verifyComplete();
}

View File

@@ -28,6 +28,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.data.redis.Person;
import org.springframework.data.redis.RedisSystemException;
import org.springframework.data.redis.connection.ReactiveRedisConnection;
import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory;
@@ -37,9 +38,10 @@ import org.springframework.data.redis.serializer.RedisSerializationContext;
/**
* @author Mark Paluch
* @author Christoph Strobl
*/
@RunWith(MockitoJUnitRunner.class)
public class DefaultScriptOperatorsUnitTests {
public class DefaultReactiveScriptExecutorUnitTests {
private final DefaultRedisScript<String> SCRIPT = new DefaultRedisScript<>("return KEYS[0]", String.class);
@@ -47,7 +49,7 @@ public class DefaultScriptOperatorsUnitTests {
@Mock ReactiveRedisConnection connectionMock;
@Mock ReactiveScriptingCommands scriptingCommandsMock;
DefaultScriptOperators<String> executor;
DefaultReactiveScriptExecutor<String> executor;
@Before
public void setUp() {
@@ -55,7 +57,7 @@ public class DefaultScriptOperatorsUnitTests {
when(connectionFactoryMock.getReactiveConnection()).thenReturn(connectionMock);
when(connectionMock.scriptingCommands()).thenReturn(scriptingCommandsMock);
executor = new DefaultScriptOperators<>(connectionFactoryMock, RedisSerializationContext.string());
executor = new DefaultReactiveScriptExecutor<>(connectionFactoryMock, RedisSerializationContext.string());
}
@Test // DATAREDIS-683
@@ -64,7 +66,7 @@ public class DefaultScriptOperatorsUnitTests {
when(scriptingCommandsMock.evalSha(anyString(), any(ReturnType.class), anyInt()))
.thenReturn(Flux.just(ByteBuffer.wrap("FOO".getBytes())));
StepVerifier.create(executor.execute(SCRIPT, Collections.emptyList())).expectNext("FOO").verifyComplete();
StepVerifier.create(executor.execute(SCRIPT)).expectNext("FOO").verifyComplete();
verify(scriptingCommandsMock).evalSha(anyString(), any(ReturnType.class), anyInt());
verify(scriptingCommandsMock, never()).eval(any(), any(ReturnType.class), anyInt());
@@ -79,7 +81,7 @@ public class DefaultScriptOperatorsUnitTests {
when(scriptingCommandsMock.eval(any(), any(ReturnType.class), anyInt()))
.thenReturn(Flux.just(ByteBuffer.wrap("FOO".getBytes())));
StepVerifier.create(executor.execute(SCRIPT, Collections.emptyList())).expectNext("FOO").verifyComplete();
StepVerifier.create(executor.execute(SCRIPT)).expectNext("FOO").verifyComplete();
verify(scriptingCommandsMock).evalSha(anyString(), any(ReturnType.class), anyInt());
verify(scriptingCommandsMock).eval(any(), any(ReturnType.class), anyInt());
@@ -91,8 +93,7 @@ public class DefaultScriptOperatorsUnitTests {
when(scriptingCommandsMock.evalSha(anyString(), any(ReturnType.class), anyInt())).thenReturn(Flux
.error(new UnsupportedOperationException("NOSCRIPT No matching script. Please use EVAL.", new Exception())));
StepVerifier.create(executor.execute(SCRIPT, Collections.emptyList()))
.expectError(UnsupportedOperationException.class).verify();
StepVerifier.create(executor.execute(SCRIPT)).expectError(UnsupportedOperationException.class).verify();
}
@Test // DATAREDIS-683
@@ -116,8 +117,19 @@ public class DefaultScriptOperatorsUnitTests {
when(scriptingCommandsMock.evalSha(anyString(), any(ReturnType.class), anyInt()))
.thenReturn(Flux.error(new RuntimeException()));
StepVerifier.create(executor.execute(SCRIPT, Collections.emptyList())).expectError().verify();
StepVerifier.create(executor.execute(SCRIPT)).expectError().verify();
verify(connectionMock).close();
}
@Test // DATAREDIS-683
public void doesNotConvertRawResult() {
Person returnValue = new Person();
when(scriptingCommandsMock.evalSha(anyString(), any(ReturnType.class), anyInt()))
.thenReturn(Flux.just(returnValue));
StepVerifier.create(executor.execute(RedisScript.of("return KEYS[0]"))).expectNext(returnValue).verifyComplete();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-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.
@@ -26,11 +26,13 @@ import org.springframework.scripting.support.StaticScriptSource;
* Test of {@link DefaultRedisScript}
*
* @author Jennifer Hickey
* @author Christoph Strobl
*/
public class DefaultRedisScriptTests {
@Test
public void testGetSha1() {
StaticScriptSource script = new StaticScriptSource("return KEYS[1]");
DefaultRedisScript<String> redisScript = new DefaultRedisScript<>();
redisScript.setScriptSource(script);
@@ -45,6 +47,7 @@ public class DefaultRedisScriptTests {
@Test
public void testGetScriptAsString() {
DefaultRedisScript<String> redisScript = new DefaultRedisScript<>();
redisScript.setScriptText("return ARGS[1]");
redisScript.setResultType(String.class);
@@ -53,14 +56,16 @@ public class DefaultRedisScriptTests {
@Test(expected = ScriptingException.class)
public void testGetScriptAsStringError() {
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("nonexistent")));
redisScript.setResultType(Long.class);
redisScript.getScriptAsString();
}
@Test(expected = IllegalArgumentException.class)
@Test(expected = IllegalStateException.class)
public void initializeWithNoScript() throws Exception {
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
redisScript.afterPropertiesSet();
}