DATAREDIS-316 - Add EX/PX, NX/XX options to SET command.

We now support EX/PX and NX/XX arguments along with the SET command for both xetorthio/jedis and mp911de/lettuce.

Jedis 2.8 does not support all combinations of EX/PX and NX/XX. To work around those limitations we delegate to the according set methods to execute related commands or fail fast if there is no way for delegation.

Original pull request: #170.
This commit is contained in:
Christoph Strobl
2016-02-15 15:25:05 +01:00
committed by Mark Paluch
parent 68da4a4ee5
commit 0c6c127b5e
18 changed files with 1239 additions and 16 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2016 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.
@@ -16,6 +16,7 @@
package org.springframework.data.redis.connection;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.number.IsCloseTo.*;
import static org.junit.Assert.*;
import static org.junit.Assume.*;
import static org.springframework.data.redis.SpinBarrier.*;
@@ -52,6 +53,7 @@ import org.springframework.data.redis.RedisVersionUtils;
import org.springframework.data.redis.TestCondition;
import org.springframework.data.redis.connection.RedisListCommands.Position;
import org.springframework.data.redis.connection.RedisStringCommands.BitOperation;
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
import org.springframework.data.redis.connection.RedisZSetCommands.Aggregate;
import org.springframework.data.redis.connection.RedisZSetCommands.Range;
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
@@ -60,6 +62,7 @@ import org.springframework.data.redis.connection.StringRedisConnection.StringTup
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.core.types.RedisClientInfo;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
@@ -2220,6 +2223,282 @@ public abstract class AbstractConnectionIntegrationTests {
assertThat(values, not(hasItems("a", "b", "c", "d")));
}
/**
* @see DATAREDIS-316
*/
@Test
@WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE })
public void setWithExpirationAndNullOpionShouldSetTtlWhenKeyDoesNotExist() {
String key = "exp-" + UUID.randomUUID();
connection.set(key, "foo", Expiration.milliseconds(500), null);
actual.add(connection.exists(key));
actual.add(connection.pTtl(key));
List<Object> result = getResults();
assertThat((Boolean) result.get(0), is(Boolean.TRUE));
assertThat(((Long) result.get(1)).doubleValue(), is(closeTo(500d, 499d)));
}
/**
* @see DATAREDIS-316
*/
@Test
@WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE })
public void setWithExpirationAndUpsertOpionShouldSetTtlWhenKeyDoesNotExist() {
String key = "exp-" + UUID.randomUUID();
connection.set(key, "foo", Expiration.milliseconds(500), SetOption.upsert());
actual.add(connection.exists(key));
actual.add(connection.pTtl(key));
List<Object> result = getResults();
assertThat((Boolean) result.get(0), is(Boolean.TRUE));
assertThat(((Long) result.get(1)).doubleValue(), is(closeTo(500d, 499d)));
}
/**
* @see DATAREDIS-316
*/
@Test
@WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE })
public void setWithExpirationAndUpsertOpionShouldSetTtlWhenKeyDoesExist() {
String key = "exp-" + UUID.randomUUID();
connection.set(key, "spring");
connection.set(key, "data", Expiration.milliseconds(500), SetOption.upsert());
actual.add(connection.exists(key));
actual.add(connection.pTtl(key));
actual.add(connection.get(key));
List<Object> result = getResults();
assertThat((Boolean) result.get(0), is(Boolean.TRUE));
assertThat(((Long) result.get(1)).doubleValue(), is(closeTo(500d, 499d)));
assertThat(((String) result.get(2)), is(equalTo("data")));
}
/**
* @see DATAREDIS-316
*/
@Test
@WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE })
public void setWithExpirationAndAbsentOptionShouldSetTtlWhenKeyDoesExist() {
String key = "exp-" + UUID.randomUUID();
connection.set(key, "spring");
connection.set(key, "data", Expiration.milliseconds(500), SetOption.ifAbsent());
actual.add(connection.exists(key));
actual.add(connection.pTtl(key));
actual.add(connection.get(key));
List<Object> result = getResults();
assertThat((Boolean) result.get(0), is(Boolean.TRUE));
assertThat(((Long) result.get(1)).doubleValue(), is(closeTo(-1, 0)));
assertThat(((String) result.get(2)), is(equalTo("spring")));
}
/**
* @see DATAREDIS-316
*/
@Test
@WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE })
public void setWithExpirationAndAbsentOptionShouldSetTtlWhenKeyDoesNotExist() {
String key = "exp-" + UUID.randomUUID();
connection.set(key, "data", Expiration.milliseconds(500), SetOption.ifAbsent());
actual.add(connection.exists(key));
actual.add(connection.pTtl(key));
actual.add(connection.get(key));
List<Object> result = getResults();
assertThat((Boolean) result.get(0), is(Boolean.TRUE));
assertThat(((Long) result.get(1)).doubleValue(), is(closeTo(500d, 499d)));
assertThat(((String) result.get(2)), is(equalTo("data")));
}
/**
* @see DATAREDIS-316
*/
@Test
@WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE })
public void setWithExpirationAndPresentOptionShouldSetTtlWhenKeyDoesExist() {
String key = "exp-" + UUID.randomUUID();
connection.set(key, "spring");
connection.set(key, "data", Expiration.milliseconds(500), SetOption.ifPresent());
actual.add(connection.exists(key));
actual.add(connection.pTtl(key));
actual.add(connection.get(key));
List<Object> result = getResults();
assertThat((Boolean) result.get(0), is(Boolean.TRUE));
assertThat(((Long) result.get(1)).doubleValue(), is(closeTo(500, 499)));
assertThat(((String) result.get(2)), is(equalTo("data")));
}
/**
* @see DATAREDIS-316
*/
@Test
@WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE })
public void setWithExpirationAndPresentOptionShouldSetTtlWhenKeyDoesNotExist() {
String key = "exp-" + UUID.randomUUID();
connection.set(key, "data", Expiration.milliseconds(500), SetOption.ifPresent());
actual.add(connection.exists(key));
actual.add(connection.pTtl(key));
actual.add(connection.get(key));
List<Object> result = getResults();
assertThat((Boolean) result.get(0), is(Boolean.FALSE));
assertThat(((Long) result.get(1)).doubleValue(), is(closeTo(-2, 0)));
}
/**
* @see DATAREDIS-316
*/
@Test
@WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE })
public void setWithNullExpirationAndUpsertOpionShouldSetTtlWhenKeyDoesNotExist() {
String key = "exp-" + UUID.randomUUID();
connection.set(key, "foo", null, SetOption.upsert());
actual.add(connection.exists(key));
actual.add(connection.pTtl(key));
List<Object> result = getResults();
assertThat((Boolean) result.get(0), is(Boolean.TRUE));
assertThat(((Long) result.get(1)).doubleValue(), is(closeTo(-1, 0)));
}
/**
* @see DATAREDIS-316
*/
@Test
@WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE })
public void setWithoutExpirationAndUpsertOpionShouldSetTtlWhenKeyDoesNotExist() {
String key = "exp-" + UUID.randomUUID();
connection.set(key, "foo", Expiration.persistent(), SetOption.upsert());
actual.add(connection.exists(key));
actual.add(connection.pTtl(key));
List<Object> result = getResults();
assertThat((Boolean) result.get(0), is(Boolean.TRUE));
assertThat(((Long) result.get(1)).doubleValue(), is(closeTo(-1, 0)));
}
/**
* @see DATAREDIS-316
*/
@Test
@WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE })
public void setWithoutExpirationAndUpsertOpionShouldSetTtlWhenKeyDoesExist() {
String key = "exp-" + UUID.randomUUID();
connection.set(key, "spring");
connection.set(key, "data", Expiration.persistent(), SetOption.upsert());
actual.add(connection.exists(key));
actual.add(connection.pTtl(key));
actual.add(connection.get(key));
List<Object> result = getResults();
assertThat((Boolean) result.get(0), is(Boolean.TRUE));
assertThat(((Long) result.get(1)).doubleValue(), is(closeTo(-1, 0)));
assertThat(((String) result.get(2)), is(equalTo("data")));
}
/**
* @see DATAREDIS-316
*/
@Test
@WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE })
public void setWithoutExpirationAndAbsentOptionShouldSetTtlWhenKeyDoesExist() {
String key = "exp-" + UUID.randomUUID();
connection.set(key, "spring");
connection.set(key, "data", Expiration.persistent(), SetOption.ifAbsent());
actual.add(connection.exists(key));
actual.add(connection.pTtl(key));
actual.add(connection.get(key));
List<Object> result = getResults();
assertThat((Boolean) result.get(0), is(Boolean.TRUE));
assertThat(((Long) result.get(1)).doubleValue(), is(closeTo(-1, 0)));
assertThat(((String) result.get(2)), is(equalTo("spring")));
}
/**
* @see DATAREDIS-316
*/
@Test
@WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE })
public void setWithoutExpirationAndAbsentOptionShouldSetTtlWhenKeyDoesNotExist() {
String key = "exp-" + UUID.randomUUID();
connection.set(key, "data", Expiration.persistent(), SetOption.ifAbsent());
actual.add(connection.exists(key));
actual.add(connection.pTtl(key));
actual.add(connection.get(key));
List<Object> result = getResults();
assertThat((Boolean) result.get(0), is(Boolean.TRUE));
assertThat(((Long) result.get(1)).doubleValue(), is(closeTo(-1, 0)));
assertThat(((String) result.get(2)), is(equalTo("data")));
}
/**
* @see DATAREDIS-316
*/
@Test
@WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE })
public void setWithoutExpirationAndPresentOptionShouldSetTtlWhenKeyDoesExist() {
String key = "exp-" + UUID.randomUUID();
connection.set(key, "spring");
connection.set(key, "data", Expiration.persistent(), SetOption.ifPresent());
actual.add(connection.exists(key));
actual.add(connection.pTtl(key));
actual.add(connection.get(key));
List<Object> result = getResults();
assertThat((Boolean) result.get(0), is(Boolean.TRUE));
assertThat(((Long) result.get(1)).doubleValue(), is(closeTo(-1, 0)));
assertThat(((String) result.get(2)), is(equalTo("data")));
}
/**
* @see DATAREDIS-316
*/
@Test
@WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE })
public void setWithoutExpirationAndPresentOptionShouldSetTtlWhenKeyDoesNotExist() {
String key = "exp-" + UUID.randomUUID();
connection.set(key, "data", Expiration.persistent(), SetOption.ifPresent());
actual.add(connection.exists(key));
actual.add(connection.pTtl(key));
actual.add(connection.get(key));
List<Object> result = getResults();
assertThat((Boolean) result.get(0), is(Boolean.FALSE));
assertThat(((Long) result.get(1)).doubleValue(), is(closeTo(-2, 0)));
}
protected void verifyResults(List<Object> expected) {
assertEquals(expected, getResults());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 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.
@@ -15,6 +15,9 @@
*/
package org.springframework.data.redis.connection;
/**
* @author Christoph Strobl
*/
public interface ClusterConnectionTests {
/**
@@ -893,4 +896,44 @@ public interface ClusterConnectionTests {
*/
void clusterGetMasterSlaveMapShouldListMastersAndSlavesCorrectly();
/**
* @see DATAREDIS-316
*/
void setWithExpirationInSecondsShouldWorkCorrectly();
/**
* @see DATAREDIS-316
*/
void setWithExpirationInMillisecondsShouldWorkCorrectly();
/**
* @see DATAREDIS-316
*/
void setWithOptionIfPresentShouldWorkCorrectly();
/**
* @see DATAREDIS-316
*/
void setWithOptionIfAbsentShouldWorkCorrectly();
/**
* @see DATAREDIS-316
*/
void setWithExpirationAndIfAbsentShouldWorkCorrectly();
/**
* @see DATAREDIS-316
*/
void setWithExpirationAndIfAbsentShouldNotBeAppliedWhenKeyExists();
/**
* @see DATAREDIS-316
*/
void setWithExpirationAndIfPresentShouldWorkCorrectly();
/**
* @see DATAREDIS-316
*/
void setWithExpirationAndIfPresentShouldNotBeAppliedWhenKeyDoesNotExists();
}

View File

@@ -30,6 +30,7 @@ import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisNode.RedisNodeBuilder;
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.core.types.RedisClientInfo;
import org.springframework.util.ObjectUtils;
@@ -891,5 +892,10 @@ public class RedisConnectionUnitTests {
public void migrate(byte[] key, RedisNode target, int dbIndex, MigrateOption option, long timeout) {
delegate.migrate(key, target, dbIndex, option, timeout);
}
@Override
public void set(byte[] key, byte[] value, Expiration expiration, SetOption options) {
delegate.set(key, value, expiration, options);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 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.
@@ -16,6 +16,7 @@
package org.springframework.data.redis.connection.jedis;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.number.IsCloseTo.*;
import static org.junit.Assert.*;
import static org.springframework.data.redis.connection.ClusterTestVariables.*;
@@ -46,10 +47,12 @@ import org.springframework.data.redis.connection.RedisClusterNode;
import org.springframework.data.redis.connection.RedisListCommands.Position;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisStringCommands.BitOperation;
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
import org.springframework.data.redis.connection.RedisZSetCommands.Range;
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
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.util.RedisClusterRule;
import redis.clients.jedis.HostAndPort;
@@ -2308,4 +2311,103 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
assertThat(masterSlaveMap.get(new RedisClusterNode(CLUSTER_HOST, MASTER_NODE_2_PORT)).isEmpty(), is(true));
assertThat(masterSlaveMap.get(new RedisClusterNode(CLUSTER_HOST, MASTER_NODE_3_PORT)).isEmpty(), is(true));
}
/**
* @see DATAREDIS-316
*/
@Test
public void setWithExpirationInSecondsShouldWorkCorrectly() {
clusterConnection.set(KEY_1_BYTES, VALUE_1_BYTES, Expiration.seconds(1), SetOption.upsert());
assertThat(nativeConnection.exists(KEY_1_BYTES), is(true));
assertThat(nativeConnection.ttl(KEY_1_BYTES), is(1L));
}
/**
* @see DATAREDIS-316
*/
@Test
public void setWithExpirationInMillisecondsShouldWorkCorrectly() {
clusterConnection.set(KEY_1_BYTES, VALUE_1_BYTES, Expiration.milliseconds(500), SetOption.upsert());
assertThat(nativeConnection.exists(KEY_1_BYTES), is(true));
assertThat(nativeConnection.pttl(KEY_1).doubleValue(), is(closeTo(500d, 499d)));
}
/**
* @see DATAREDIS-316
*/
@Test(expected = UnsupportedOperationException.class)
public void setWithOptionIfPresentShouldWorkCorrectly() {
nativeConnection.set(KEY_1_BYTES, VALUE_1_BYTES);
clusterConnection.set(KEY_1_BYTES, VALUE_2_BYTES, Expiration.persistent(), SetOption.ifPresent());
}
/**
* @see DATAREDIS-316
*/
@Test
public void setWithOptionIfAbsentShouldWorkCorrectly() {
clusterConnection.set(KEY_1_BYTES, VALUE_1_BYTES, Expiration.persistent(), SetOption.ifAbsent());
assertThat(nativeConnection.exists(KEY_1_BYTES), is(true));
assertThat(nativeConnection.ttl(KEY_1_BYTES), is(-1L));
}
/**
* @see DATAREDIS-316
*/
@Test
public void setWithExpirationAndIfAbsentShouldWorkCorrectly() {
clusterConnection.set(KEY_1_BYTES, VALUE_1_BYTES, Expiration.seconds(1), SetOption.ifAbsent());
assertThat(nativeConnection.exists(KEY_1_BYTES), is(true));
assertThat(nativeConnection.ttl(KEY_1_BYTES), is(1L));
}
/**
* @see DATAREDIS-316
*/
@Test
public void setWithExpirationAndIfAbsentShouldNotBeAppliedWhenKeyExists() {
nativeConnection.set(KEY_1_BYTES, VALUE_1_BYTES);
clusterConnection.set(KEY_1_BYTES, VALUE_2_BYTES, Expiration.seconds(1), SetOption.ifAbsent());
assertThat(nativeConnection.exists(KEY_1_BYTES), is(true));
assertThat(nativeConnection.ttl(KEY_1_BYTES), is(-1L));
assertThat(nativeConnection.get(KEY_1_BYTES), is(equalTo(VALUE_1_BYTES)));
}
/**
* @see DATAREDIS-316
*/
@Test
public void setWithExpirationAndIfPresentShouldWorkCorrectly() {
nativeConnection.set(KEY_1_BYTES, VALUE_1_BYTES);
clusterConnection.set(KEY_1_BYTES, VALUE_2_BYTES, Expiration.seconds(1), SetOption.ifPresent());
assertThat(nativeConnection.exists(KEY_1_BYTES), is(true));
assertThat(nativeConnection.ttl(KEY_1_BYTES), is(1L));
assertThat(nativeConnection.get(KEY_1_BYTES), is(equalTo(VALUE_2_BYTES)));
}
/**
* @see DATAREDIS-316
*/
@Test
public void setWithExpirationAndIfPresentShouldNotBeAppliedWhenKeyDoesNotExists() {
clusterConnection.set(KEY_1_BYTES, VALUE_1_BYTES, Expiration.seconds(1), SetOption.ifPresent());
assertThat(nativeConnection.exists(KEY_1_BYTES), is(false));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 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.
@@ -29,7 +29,9 @@ import java.util.Map;
import org.junit.Test;
import org.springframework.data.redis.connection.RedisServer;
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
import org.springframework.data.redis.connection.RedisZSetCommands.Range;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.core.types.RedisClientInfo;
/**
@@ -257,6 +259,56 @@ public class JedisConvertersUnitTests {
JedisConverters.boundaryToBytesForZRange(Range.range().gt(new Date()).getMin(), null);
}
/**
* @see DATAREDIS-316
*/
@Test
public void toSetCommandExPxOptionShouldReturnEXforSeconds() {
assertThat(JedisConverters.toSetCommandExPxArgument(Expiration.seconds(100)), equalTo(JedisConverters.toBytes("EX")));
}
/**
* @see DATAREDIS-316
*/
@Test
public void toSetCommandExPxOptionShouldReturnEXforMilliseconds() {
assertThat(JedisConverters.toSetCommandExPxArgument(Expiration.milliseconds(100)),
equalTo(JedisConverters.toBytes("PX")));
}
/**
* @see DATAREDIS-316
*/
@Test
public void toSetCommandExPxOptionShouldReturnEmptyArrayForNull() {
assertThat(JedisConverters.toSetCommandExPxArgument(null), equalTo(new byte[] {}));
}
/**
* @see DATAREDIS-316
*/
@Test
public void toSetCommandNxXxOptionShouldReturnNXforAbsent() {
assertThat(JedisConverters.toSetCommandNxXxArgument(SetOption.ifAbsent()), equalTo(JedisConverters.toBytes("NX")));
}
/**
* @see DATAREDIS-316
*/
@Test
public void toSetCommandNxXxOptionShouldReturnXXforAbsent() {
assertThat(JedisConverters.toSetCommandNxXxArgument(SetOption.ifPresent()), equalTo(JedisConverters.toBytes("XX")));
}
/**
* @see DATAREDIS-316
*/
@Test
public void toSetCommandNxXxOptionShouldReturnEmptyArrayforUpsert() {
assertThat(JedisConverters.toSetCommandNxXxArgument(SetOption.upsert()), equalTo(new byte[] {}));
}
private void verifyRedisServerInfo(RedisServer server, Map<String, String> values) {
for (Map.Entry<String, String> entry : values.entrySet()) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 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.
@@ -16,6 +16,7 @@
package org.springframework.data.redis.connection.lettuce;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.number.IsCloseTo.*;
import static org.junit.Assert.*;
import static org.springframework.data.redis.connection.ClusterTestVariables.*;
@@ -44,11 +45,13 @@ import org.springframework.data.redis.connection.RedisClusterNode;
import org.springframework.data.redis.connection.RedisListCommands.Position;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisStringCommands.BitOperation;
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
import org.springframework.data.redis.connection.RedisZSetCommands.Range;
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
import org.springframework.data.redis.connection.jedis.JedisConverters;
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.util.RedisClusterRule;
import com.lambdaworks.redis.RedisURI.Builder;
@@ -2298,4 +2301,105 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests {
assertThat(masterSlaveMap.get(new RedisClusterNode(CLUSTER_HOST, MASTER_NODE_2_PORT)).isEmpty(), is(true));
assertThat(masterSlaveMap.get(new RedisClusterNode(CLUSTER_HOST, MASTER_NODE_3_PORT)).isEmpty(), is(true));
}
/**
* @see DATAREDIS-316
*/
@Test
public void setWithExpirationInSecondsShouldWorkCorrectly() {
clusterConnection.set(KEY_1_BYTES, VALUE_1_BYTES, Expiration.seconds(1), SetOption.upsert());
assertThat(nativeConnection.exists(KEY_1), is(true));
assertThat(nativeConnection.ttl(KEY_1), is(1L));
}
/**
* @see DATAREDIS-316
*/
@Test
public void setWithExpirationInMillisecondsShouldWorkCorrectly() {
clusterConnection.set(KEY_1_BYTES, VALUE_1_BYTES, Expiration.milliseconds(500), SetOption.upsert());
assertThat(nativeConnection.exists(KEY_1), is(true));
assertThat(nativeConnection.pttl(KEY_1).doubleValue(), is(closeTo(500d, 499d)));
}
/**
* @see DATAREDIS-316
*/
@Test
public void setWithOptionIfPresentShouldWorkCorrectly() {
nativeConnection.set(KEY_1, VALUE_1);
clusterConnection.set(KEY_1_BYTES, VALUE_2_BYTES, Expiration.persistent(), SetOption.ifPresent());
}
/**
* @see DATAREDIS-316
*/
@Test
public void setWithOptionIfAbsentShouldWorkCorrectly() {
clusterConnection.set(KEY_1_BYTES, VALUE_1_BYTES, Expiration.persistent(), SetOption.ifAbsent());
assertThat(nativeConnection.exists(KEY_1), is(true));
assertThat(nativeConnection.ttl(KEY_1), is(-1L));
}
/**
* @see DATAREDIS-316
*/
@Test
public void setWithExpirationAndIfAbsentShouldWorkCorrectly() {
clusterConnection.set(KEY_1_BYTES, VALUE_1_BYTES, Expiration.seconds(1), SetOption.ifAbsent());
assertThat(nativeConnection.exists(KEY_1), is(true));
assertThat(nativeConnection.ttl(KEY_1), is(1L));
}
/**
* @see DATAREDIS-316
*/
@Test
public void setWithExpirationAndIfAbsentShouldNotBeAppliedWhenKeyExists() {
nativeConnection.set(KEY_1, VALUE_1);
clusterConnection.set(KEY_1_BYTES, VALUE_2_BYTES, Expiration.seconds(1), SetOption.ifAbsent());
assertThat(nativeConnection.exists(KEY_1), is(true));
assertThat(nativeConnection.ttl(KEY_1), is(-1L));
assertThat(nativeConnection.get(KEY_1), is(equalTo(VALUE_1)));
}
/**
* @see DATAREDIS-316
*/
@Test
public void setWithExpirationAndIfPresentShouldWorkCorrectly() {
nativeConnection.set(KEY_1, VALUE_1);
clusterConnection.set(KEY_1_BYTES, VALUE_2_BYTES, Expiration.seconds(1), SetOption.ifPresent());
assertThat(nativeConnection.exists(KEY_1), is(true));
assertThat(nativeConnection.ttl(KEY_1), is(1L));
assertThat(nativeConnection.get(KEY_1), is(equalTo(VALUE_2)));
}
/**
* @see DATAREDIS-316
*/
@Test
public void setWithExpirationAndIfPresentShouldNotBeAppliedWhenKeyDoesNotExists() {
clusterConnection.set(KEY_1_BYTES, VALUE_1_BYTES, Expiration.seconds(1), SetOption.ifPresent());
assertThat(nativeConnection.exists(KEY_1), is(false));
}
}

View File

@@ -21,6 +21,7 @@ import static org.hamcrest.core.IsEqual.*;
import static org.hamcrest.core.IsNull.*;
import static org.junit.Assert.*;
import static org.springframework.data.redis.connection.ClusterTestVariables.*;
import static org.springframework.test.util.ReflectionTestUtils.*;
import java.util.Arrays;
import java.util.Collections;
@@ -31,11 +32,14 @@ import org.junit.Test;
import org.springframework.data.redis.connection.RedisClusterNode;
import org.springframework.data.redis.connection.RedisClusterNode.Flag;
import org.springframework.data.redis.connection.RedisClusterNode.LinkState;
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.core.types.RedisClientInfo;
import com.lambdaworks.redis.RedisURI;
import com.lambdaworks.redis.cluster.models.partitions.Partitions;
import com.lambdaworks.redis.cluster.models.partitions.RedisClusterNode.NodeFlag;
import com.lambdaworks.redis.protocol.SetArgs;
/**
* @author Christoph Strobl
@@ -111,4 +115,102 @@ public class LettuceConvertersUnitTests {
assertThat(node.getLinkState(), is(LinkState.CONNECTED));
assertThat(node.getSlotRange().getSlots(), hasItems(1, 2, 3, 4, 5));
}
/**
* @see DATAREDIS-316
*/
@Test
public void toSetArgsShouldReturnEmptyArgsForNullValues() {
SetArgs args = LettuceConverters.toSetArgs(null, null);
assertThat(getField(args, "ex"), is(nullValue()));
assertThat(getField(args, "px"), is(nullValue()));
assertThat((Boolean) getField(args, "nx"), is(Boolean.FALSE));
assertThat((Boolean) getField(args, "xx"), is(Boolean.FALSE));
}
/**
* @see DATAREDIS-316
*/
@Test
public void toSetArgsShouldNotSetExOrPxForPersistent() {
SetArgs args = LettuceConverters.toSetArgs(Expiration.persistent(), null);
assertThat(getField(args, "ex"), is(nullValue()));
assertThat(getField(args, "px"), is(nullValue()));
assertThat((Boolean) getField(args, "nx"), is(Boolean.FALSE));
assertThat((Boolean) getField(args, "xx"), is(Boolean.FALSE));
}
/**
* @see DATAREDIS-316
*/
@Test
public void toSetArgsShouldSetExForSeconds() {
SetArgs args = LettuceConverters.toSetArgs(Expiration.seconds(10), null);
assertThat((Long) getField(args, "ex"), is(10L));
assertThat(getField(args, "px"), is(nullValue()));
assertThat((Boolean) getField(args, "nx"), is(Boolean.FALSE));
assertThat((Boolean) getField(args, "xx"), is(Boolean.FALSE));
}
/**
* @see DATAREDIS-316
*/
@Test
public void toSetArgsShouldSetPxForMilliseconds() {
SetArgs args = LettuceConverters.toSetArgs(Expiration.milliseconds(100), null);
assertThat(getField(args, "ex"), is(nullValue()));
assertThat((Long) getField(args, "px"), is(100L));
assertThat((Boolean) getField(args, "nx"), is(Boolean.FALSE));
assertThat((Boolean) getField(args, "xx"), is(Boolean.FALSE));
}
/**
* @see DATAREDIS-316
*/
@Test
public void toSetArgsShouldSetNxForAbsent() {
SetArgs args = LettuceConverters.toSetArgs(null, SetOption.ifAbsent());
assertThat(getField(args, "ex"), is(nullValue()));
assertThat(getField(args, "px"), is(nullValue()));
assertThat((Boolean) getField(args, "nx"), is(Boolean.TRUE));
assertThat((Boolean) getField(args, "xx"), is(Boolean.FALSE));
}
/**
* @see DATAREDIS-316
*/
@Test
public void toSetArgsShouldSetXxForPresent() {
SetArgs args = LettuceConverters.toSetArgs(null, SetOption.ifPresent());
assertThat(getField(args, "ex"), is(nullValue()));
assertThat(getField(args, "px"), is(nullValue()));
assertThat((Boolean) getField(args, "nx"), is(Boolean.FALSE));
assertThat((Boolean) getField(args, "xx"), is(Boolean.TRUE));
}
/**
* @see DATAREDIS-316
*/
@Test
public void toSetArgsShouldNotSetNxOrXxForUpsert() {
SetArgs args = LettuceConverters.toSetArgs(null, SetOption.upsert());
assertThat(getField(args, "ex"), is(nullValue()));
assertThat(getField(args, "px"), is(nullValue()));
assertThat((Boolean) getField(args, "nx"), is(Boolean.FALSE));
assertThat((Boolean) getField(args, "xx"), is(Boolean.FALSE));
}
}