DATAREDIS-716 - Polishing.
Add OBJECT command support for Jedis Cluster. Original pull request: #337.
This commit is contained in:
@@ -24,6 +24,7 @@ import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
@@ -493,6 +494,22 @@ public class ClusterCommandExecutor implements DisposableBean {
|
||||
public byte[] getKey() {
|
||||
return key.getArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the {@link Function mapper function} to the value and return the mapped value.
|
||||
*
|
||||
* @param mapper must not be {@literal null}.
|
||||
* @param <U> type of the mapped value.
|
||||
* @return the mapped value.
|
||||
* @since 2.1
|
||||
*/
|
||||
@Nullable
|
||||
public <U> U mapValue(Function<? super T, ? extends U> mapper) {
|
||||
|
||||
Assert.notNull(mapper, "Mapper function must not be null!");
|
||||
|
||||
return mapper.apply(getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -568,7 +568,13 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
|
||||
@Nullable
|
||||
@Override
|
||||
public ValueEncoding encodingOf(byte[] key) {
|
||||
throw new UnsupportedOperationException("Jedis does not support OBJECT ENCODING in cluster!");
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return connection.getClusterCommandExecutor()
|
||||
.executeCommandOnSingleNode((JedisClusterCommandCallback<byte[]>) client -> client.objectEncoding(key),
|
||||
connection.clusterGetNodeForKey(key))
|
||||
.mapValue(JedisConverters::toEncoding);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -578,7 +584,13 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
|
||||
@Nullable
|
||||
@Override
|
||||
public Duration idletime(byte[] key) {
|
||||
throw new UnsupportedOperationException("Jedis does not support OBJECT IDLETIME in cluster!");
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return connection.getClusterCommandExecutor()
|
||||
.executeCommandOnSingleNode((JedisClusterCommandCallback<Long>) client -> client.objectIdletime(key),
|
||||
connection.clusterGetNodeForKey(key))
|
||||
.mapValue(Converters::secondsToDuration);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -588,7 +600,14 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
|
||||
@Nullable
|
||||
@Override
|
||||
public Long refcount(byte[] key) {
|
||||
throw new UnsupportedOperationException("Jedis does not support OBJECT REFCOUNT in cluster!");
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return connection.getClusterCommandExecutor()
|
||||
.executeCommandOnSingleNode((JedisClusterCommandCallback<Long>) client -> client.objectRefcount(key),
|
||||
connection.clusterGetNodeForKey(key))
|
||||
.getValue();
|
||||
|
||||
}
|
||||
|
||||
private DataAccessException convertJedisAccessException(Exception ex) {
|
||||
|
||||
@@ -28,6 +28,7 @@ import redis.clients.jedis.JedisPool;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -57,6 +58,7 @@ import org.springframework.data.redis.connection.RedisStringCommands.BitOperatio
|
||||
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.ValueEncoding.RedisValueEncoding;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.ScanOptions;
|
||||
import org.springframework.data.redis.core.types.Expiration;
|
||||
@@ -2292,4 +2294,43 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
|
||||
org.springframework.data.domain.Range.of(Bound.inclusive(2L), Bound.unbounded())), is(16L));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-716
|
||||
public void encodingReturnsCorrectly() {
|
||||
|
||||
nativeConnection.set(KEY_1_BYTES, "1000".getBytes());
|
||||
|
||||
assertThat(clusterConnection.keyCommands().encodingOf(KEY_1_BYTES), is(RedisValueEncoding.INT));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-716
|
||||
public void encodingReturnsVacantWhenKeyDoesNotExist() {
|
||||
assertThat(clusterConnection.keyCommands().encodingOf(KEY_2_BYTES), is(RedisValueEncoding.VACANT));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-716
|
||||
public void idletimeReturnsCorrectly() {
|
||||
|
||||
nativeConnection.set(KEY_1_BYTES, VALUE_1_BYTES);
|
||||
nativeConnection.get(KEY_1_BYTES);
|
||||
|
||||
assertThat(clusterConnection.keyCommands().idletime(KEY_1_BYTES), is(Duration.ofSeconds(0)));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-716
|
||||
public void idldetimeReturnsNullWhenKeyDoesNotExist() {
|
||||
assertThat(clusterConnection.keyCommands().idletime(KEY_3_BYTES), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-716
|
||||
public void refcountReturnsCorrectly() {
|
||||
|
||||
nativeConnection.lpush(KEY_1_BYTES, VALUE_1_BYTES);
|
||||
|
||||
assertThat(clusterConnection.keyCommands().refcount(KEY_1_BYTES), is(1L));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-716
|
||||
public void refcountReturnsNullWhenKeyDoesNotExist() {
|
||||
assertThat(clusterConnection.keyCommands().refcount(KEY_3_BYTES), is(nullValue()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ import org.springframework.data.redis.connection.RedisStringCommands.BitOperatio
|
||||
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.ValueEncoding.RedisValueEncoding;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConverters;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.ScanOptions;
|
||||
@@ -2317,4 +2318,44 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests {
|
||||
assertThat(clusterConnection.stringCommands().bitPos(KEY_1_BYTES, true,
|
||||
org.springframework.data.domain.Range.of(Bound.inclusive(2L), Bound.unbounded())), is(16L));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-716
|
||||
public void encodingReturnsCorrectly() {
|
||||
|
||||
nativeConnection.set(KEY_1, "1000");
|
||||
|
||||
assertThat(clusterConnection.keyCommands().encodingOf(KEY_1_BYTES), is(RedisValueEncoding.INT));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-716
|
||||
public void encodingReturnsVacantWhenKeyDoesNotExist() {
|
||||
assertThat(clusterConnection.keyCommands().encodingOf(KEY_2_BYTES), is(RedisValueEncoding.VACANT));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-716
|
||||
public void idletimeReturnsCorrectly() {
|
||||
|
||||
nativeConnection.set(KEY_1, VALUE_1);
|
||||
nativeConnection.get(KEY_1);
|
||||
|
||||
assertThat(clusterConnection.keyCommands().idletime(KEY_1_BYTES), is(Duration.ofSeconds(0)));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-716
|
||||
public void idldetimeReturnsNullWhenKeyDoesNotExist() {
|
||||
assertThat(clusterConnection.keyCommands().idletime(KEY_3_BYTES), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-716
|
||||
public void refcountReturnsCorrectly() {
|
||||
|
||||
nativeConnection.lpush(KEY_1, VALUE_1);
|
||||
|
||||
assertThat(clusterConnection.keyCommands().refcount(KEY_1_BYTES), is(1L));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-716
|
||||
public void refcountReturnsNullWhenKeyDoesNotExist() {
|
||||
assertThat(clusterConnection.keyCommands().refcount(KEY_3_BYTES), is(nullValue()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user