Add support for GETEX and GETDEL through getAndExpire(…), getAndPersist(…) and getAndDelete(…) methods.

We now support Redis 6.2 GETEX and GETDEL commands through the Template API and on the connection level for all drivers.

Closes: #2050
Original Pull Request: #2086
This commit is contained in:
Mark Paluch
2021-06-14 15:24:13 +02:00
committed by Christoph Strobl
parent 72055de59f
commit a53193946f
25 changed files with 851 additions and 8 deletions

View File

@@ -1135,6 +1135,28 @@ public abstract class AbstractConnectionIntegrationTests {
verifyResults(Arrays.asList(true, DataType.STRING));
}
@Test // GH-2050
@EnabledOnCommand("GETEX")
void testGetEx() {
actual.add(connection.set("testGS", "1"));
actual.add(connection.getEx("testGS", Expiration.seconds(10)));
actual.add(connection.ttl("testGS"));
Long ttl = (Long) getResults().get(2);
assertThat(ttl).isGreaterThan(1);
}
@Test // GH-2050
@EnabledOnCommand("GETDEL")
void testGetDel() {
actual.add(connection.set("testGS", "1"));
actual.add(connection.getDel("testGS"));
actual.add(connection.exists("testGS"));
verifyResults(Arrays.asList(true, "1", false));
}
@Test
void testGetSet() {
actual.add(connection.set("testGS", "1"));

View File

@@ -186,6 +186,12 @@ public interface ClusterConnectionTests {
// DATAREDIS-315
void getRangeShouldReturnValueCorrectly();
// GH-2050
void getExShouldWorkCorrectly();
// GH-2050
void getDelShouldWorkCorrectly();
// DATAREDIS-315
void getSetShouldWorkCorrectly();

View File

@@ -696,6 +696,26 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
assertThat(clusterConnection.getRange(KEY_1_BYTES, 0, 2)).isEqualTo(JedisConverters.toBytes("val"));
}
@Test // GH-2050
@EnabledOnCommand("GETEX")
public void getExShouldWorkCorrectly() {
nativeConnection.set(KEY_1, VALUE_1);
assertThat(clusterConnection.getEx(KEY_1_BYTES, Expiration.seconds(10))).isEqualTo(VALUE_1_BYTES);
assertThat(clusterConnection.ttl(KEY_1_BYTES)).isGreaterThan(1);
}
@Test // GH-2050
@EnabledOnCommand("GETDEL")
public void getDelShouldWorkCorrectly() {
nativeConnection.set(KEY_1, VALUE_1);
assertThat(clusterConnection.getDel(KEY_1_BYTES)).isEqualTo(VALUE_1_BYTES);
assertThat(clusterConnection.exists(KEY_1_BYTES)).isFalse();
}
@Test // DATAREDIS-315
public void getSetShouldWorkCorrectly() {

View File

@@ -58,6 +58,7 @@ import org.springframework.data.redis.connection.ValueEncoding.RedisValueEncodin
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.test.condition.EnabledOnCommand;
import org.springframework.data.redis.test.condition.EnabledOnRedisClusterAvailable;
import org.springframework.data.redis.test.extension.LettuceExtension;
import org.springframework.data.redis.test.extension.LettuceTestClientResources;
@@ -727,6 +728,26 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests {
assertThat(clusterConnection.getRange(KEY_1_BYTES, 0, 2)).isEqualTo(LettuceConverters.toBytes("val"));
}
@Test // GH-2050
@EnabledOnCommand("GETEX")
public void getExShouldWorkCorrectly() {
nativeConnection.set(KEY_1, VALUE_1);
assertThat(clusterConnection.getEx(KEY_1_BYTES, Expiration.seconds(10))).isEqualTo(VALUE_1_BYTES);
assertThat(clusterConnection.ttl(KEY_1_BYTES)).isGreaterThan(1);
}
@Test // GH-2050
@EnabledOnCommand("GETDEL")
public void getDelShouldWorkCorrectly() {
nativeConnection.set(KEY_1, VALUE_1);
assertThat(clusterConnection.getDel(KEY_1_BYTES)).isEqualTo(VALUE_1_BYTES);
assertThat(clusterConnection.exists(KEY_1_BYTES)).isFalse();
}
@Test // DATAREDIS-315
public void getSetShouldWorkCorrectly() {

View File

@@ -51,6 +51,7 @@ import org.springframework.data.redis.connection.ReactiveStringCommands.SetComma
import org.springframework.data.redis.connection.RedisStringCommands.BitOperation;
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.test.condition.EnabledOnCommand;
import org.springframework.data.redis.test.extension.parametrized.ParameterizedRedisTest;
import org.springframework.data.redis.test.util.HexStringUtils;
import org.springframework.data.redis.util.ByteUtils;
@@ -66,6 +67,32 @@ public class LettuceReactiveStringCommandsIntegrationTests extends LettuceReacti
super(fixture);
}
@ParameterizedRedisTest // GH-2050
@EnabledOnCommand("GETEX")
void getExShouldWorkCorrectly() {
nativeCommands.set(KEY_1, VALUE_1);
connection.stringCommands().getEx(KEY_1_BBUFFER, Expiration.seconds(10)).as(StepVerifier::create) //
.expectNext(VALUE_1_BBUFFER) //
.verifyComplete();
assertThat(nativeCommands.ttl(KEY_1)).isGreaterThan(1L);
}
@ParameterizedRedisTest // GH-2050
@EnabledOnCommand("GETDEL")
void getDelShouldWorkCorrectly() {
nativeCommands.set(KEY_1, VALUE_1);
connection.stringCommands().getDel(KEY_1_BBUFFER).as(StepVerifier::create) //
.expectNext(VALUE_1_BBUFFER) //
.verifyComplete();
assertThat(nativeCommands.exists(KEY_1)).isZero();
}
@ParameterizedRedisTest // DATAREDIS-525
void getSetShouldReturnPreviousValueCorrectly() {

View File

@@ -40,6 +40,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.ReactiveOperationsTestParams.Fixture;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.data.redis.test.condition.EnabledOnCommand;
import org.springframework.data.redis.test.extension.parametrized.MethodSource;
import org.springframework.data.redis.test.extension.parametrized.ParameterizedRedisTest;
@@ -235,6 +236,50 @@ public class DefaultReactiveValueOperationsIntegrationTests<K, V> {
valueOperations.get(key).as(StepVerifier::create).expectNext(value).verifyComplete();
}
@ParameterizedRedisTest // GH-2050
@EnabledOnCommand("GETEX")
void getAndExpire() {
K key = keyFactory.instance();
V value = valueFactory.instance();
valueOperations.set(key, value).as(StepVerifier::create).expectNext(true).verifyComplete();
valueOperations.getAndExpire(key, Duration.ofSeconds(10)).as(StepVerifier::create).expectNext(value)
.verifyComplete();
redisTemplate.getExpire(key).as(StepVerifier::create)
.assertNext(actual -> assertThat(actual).isGreaterThan(Duration.ZERO)).verifyComplete();
}
@ParameterizedRedisTest // GH-2050
@EnabledOnCommand("GETDEL")
void getAndDelete() {
K key = keyFactory.instance();
V value = valueFactory.instance();
valueOperations.set(key, value).as(StepVerifier::create).expectNext(true).verifyComplete();
valueOperations.getAndDelete(key).as(StepVerifier::create).expectNext(value).verifyComplete();
redisTemplate.hasKey(key).as(StepVerifier::create).expectNext(false).verifyComplete();
}
@ParameterizedRedisTest // GH-2050
@EnabledOnCommand("GETEX")
void getAndPersist() {
K key = keyFactory.instance();
V value = valueFactory.instance();
valueOperations.set(key, value, Duration.ofSeconds(10)).as(StepVerifier::create).expectNext(true).verifyComplete();
valueOperations.getAndPersist(key).as(StepVerifier::create).expectNext(value).verifyComplete();
redisTemplate.getExpire(key).as(StepVerifier::create).expectNext(Duration.ZERO).verifyComplete();
}
@ParameterizedRedisTest // DATAREDIS-602
void getAndSet() {

View File

@@ -32,6 +32,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.springframework.data.redis.ObjectFactory;
import org.springframework.data.redis.test.condition.EnabledIfLongRunningTest;
import org.springframework.data.redis.test.condition.EnabledOnCommand;
import org.springframework.data.redis.test.extension.parametrized.MethodSource;
import org.springframework.data.redis.test.extension.parametrized.ParameterizedRedisTest;
@@ -214,6 +215,46 @@ public class DefaultValueOperationsIntegrationTests<K, V> {
assertThat(valueOps.get(key)).isEqualTo(value);
}
@ParameterizedRedisTest // GH-2050
@EnabledOnCommand("GETEX")
void testGetAndExpire() {
K key = keyFactory.instance();
V value1 = valueFactory.instance();
V value2 = valueFactory.instance();
valueOps.set(key, value1);
assertThat(valueOps.getAndExpire(key, Duration.ofSeconds(10))).isEqualTo(value1);
assertThat(redisTemplate.getExpire(key)).isGreaterThan(1);
}
@ParameterizedRedisTest // GH-2050
@EnabledOnCommand("GETEX")
void testGetAndPersist() {
K key = keyFactory.instance();
V value1 = valueFactory.instance();
valueOps.set(key, value1, Duration.ofSeconds(10));
assertThat(valueOps.getAndPersist(key)).isEqualTo(value1);
assertThat(redisTemplate.getExpire(key)).isEqualTo(-1);
}
@ParameterizedRedisTest // GH-2050
@EnabledOnCommand("GETDEL")
void testGetAndDelete() {
K key = keyFactory.instance();
V value1 = valueFactory.instance();
valueOps.set(key, value1);
assertThat(valueOps.getAndDelete(key)).isEqualTo(value1);
assertThat(redisTemplate.hasKey(key)).isFalse();
}
@ParameterizedRedisTest
void testGetAndSet() {