Upgrade to Jedis 4.2.

The upgrade also allows to enable support for GEOSEARCH, GEOSEARCHSTORE, XCLAIMJUSTID and XPENDING.

Closes: #2212
Original Pull Request: #2287
This commit is contained in:
Mark Paluch
2022-03-08 10:15:37 +01:00
committed by Christoph Strobl
parent d3a70f8f22
commit 1e4cd6f341
43 changed files with 1182 additions and 1505 deletions

View File

@@ -24,7 +24,7 @@
<xstream>1.4.19</xstream>
<pool>2.11.1</pool>
<lettuce>6.1.8.RELEASE</lettuce>
<jedis>3.8.0</jedis>
<jedis>4.2.0</jedis>
<multithreadedtc>1.01</multithreadedtc>
<netty>4.1.72.Final</netty>
<java-module-name>spring.data.redis</java-module-name>

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.redis.connection.convert;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.stream.Collectors;
@@ -48,4 +49,8 @@ public class SetConverter<S, T> implements Converter<Set<S>, Set<T>> {
return source.stream().map(itemConverter::convert).collect(Collectors.toCollection(LinkedHashSet::new));
}
public Set<T> convert(Collection<S> source) {
return source.stream().map(itemConverter::convert).collect(Collectors.toCollection(LinkedHashSet::new));
}
}

View File

@@ -15,15 +15,13 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.Builder;
import redis.clients.jedis.Client;
import redis.clients.jedis.Connection;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Protocol.Command;
import redis.clients.jedis.Queable;
import redis.clients.jedis.Response;
import redis.clients.jedis.util.SafeEncoder;
import redis.clients.jedis.Protocol;
import redis.clients.jedis.Transaction;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Set;
import java.util.function.Function;
@@ -43,26 +41,15 @@ import org.springframework.util.ReflectionUtils;
@SuppressWarnings({ "unchecked", "ConstantConditions" })
class JedisClientUtils {
private static final Method GET_RESPONSE;
private static final Field TRANSACTION;
private static final Set<String> KNOWN_COMMANDS;
private static final Builder<Object> OBJECT_BUILDER;
static {
GET_RESPONSE = ReflectionUtils.findMethod(Queable.class, "getResponse", Builder.class);
ReflectionUtils.makeAccessible(GET_RESPONSE);
TRANSACTION = ReflectionUtils.findField(Jedis.class, "transaction");
ReflectionUtils.makeAccessible(TRANSACTION);
KNOWN_COMMANDS = Arrays.stream(Command.values()).map(Enum::name).collect(Collectors.toSet());
OBJECT_BUILDER = new Builder<Object>() {
public Object build(Object data) {
return data;
}
public String toString() {
return "Object";
}
};
KNOWN_COMMANDS = Arrays.stream(Protocol.Command.values()).map(Enum::name).collect(Collectors.toSet());
}
/**
@@ -72,7 +59,7 @@ class JedisClientUtils {
* @param keys must not be {@literal null}, may be empty.
* @param args must not be {@literal null}, may be empty.
* @param jedis must not be {@literal null}.
* @return the response, can be be {@literal null}.
* @return the response, can be {@literal null}.
*/
static <T> T execute(String command, byte[][] keys, byte[][] args, Supplier<Jedis> jedis) {
return execute(command, keys, args, jedis, it -> (T) it.getOne());
@@ -86,42 +73,42 @@ class JedisClientUtils {
* @param args must not be {@literal null}, may be empty.
* @param jedis must not be {@literal null}.
* @param responseMapper must not be {@literal null}.
* @return the response, can be be {@literal null}.
* @return the response, can be {@literal null}.
* @since 2.1
*/
static <T> T execute(String command, byte[][] keys, byte[][] args, Supplier<Jedis> jedis,
Function<Client, T> responseMapper) {
Function<Connection, T> responseMapper) {
byte[][] commandArgs = getCommandArguments(keys, args);
Client client = sendCommand(command, commandArgs, jedis.get());
Connection Connection = sendCommand(command, commandArgs, jedis.get());
return responseMapper.apply(client);
return responseMapper.apply(Connection);
}
/**
* Send a Redis command and retrieve the {@link Client} for response retrieval.
* Send a Redis command and retrieve the {@link Connection} for response retrieval.
*
* @param command the command.
* @param args must not be {@literal null}, may be empty.
* @param jedis must not be {@literal null}.
* @return the {@link Client} instance used to send the command.
* @return the {@link Connection} instance used to send the command.
*/
static Client sendCommand(String command, byte[][] args, Jedis jedis) {
static Connection sendCommand(String command, byte[][] args, Jedis jedis) {
Client client = jedis.getClient();
Connection Connection = jedis.getConnection();
sendCommand(client, command, args);
sendCommand(Connection, command, args);
return client;
return Connection;
}
private static void sendCommand(Client client, String command, byte[][] args) {
private static void sendCommand(Connection Connection, String command, byte[][] args) {
if (isKnownCommand(command)) {
client.sendCommand(Command.valueOf(command.trim().toUpperCase()), args);
Connection.sendCommand(Protocol.Command.valueOf(command.trim().toUpperCase()), args);
} else {
client.sendCommand(() -> SafeEncoder.encode(command.trim().toUpperCase()), args);
Connection.sendCommand(() -> command.trim().toUpperCase().getBytes(StandardCharsets.UTF_8), args);
}
}
@@ -148,23 +135,13 @@ class JedisClientUtils {
}
/**
* @param jedis the client instance.
* @param jedis the Connection instance.
* @return {@literal true} if the connection has entered {@literal MULTI} state.
*/
static boolean isInMulti(Jedis jedis) {
return jedis.getClient().isInMulti();
}
/**
* Retrieve the {@link Response} object from a {@link redis.clients.jedis.Transaction} or a
* {@link redis.clients.jedis.Pipeline} for response synchronization.
*
* @param target a {@link redis.clients.jedis.Transaction} or {@link redis.clients.jedis.Pipeline}, must not be
* {@literal null}.
* @return the {@link Response} wrapper object.
*/
static Response<Object> getResponse(Object target) {
return (Response<Object>) ReflectionUtils.invokeMethod(GET_RESPONSE, target, OBJECT_BUILDER);
}
Object field = ReflectionUtils.getField(TRANSACTION, jedis);
return field instanceof Transaction;
}
}

View File

@@ -15,13 +15,12 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.Client;
import redis.clients.jedis.Connection;
import redis.clients.jedis.ConnectionPool;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisClusterConnectionHandler;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.providers.ClusterConnectionProvider;
import java.time.Duration;
import java.util.ArrayList;
@@ -33,7 +32,6 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Function;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -119,9 +117,13 @@ public class JedisClusterConnection implements RedisClusterConnection {
new JedisClusterNodeResourceProvider(cluster, topologyProvider), EXCEPTION_TRANSLATION);
disposeClusterCommandExecutorOnClose = true;
try {
DirectFieldAccessor dfa = new DirectFieldAccessor(cluster);
clusterCommandExecutor.setMaxRedirects((Integer) dfa.getPropertyValue("maxRedirections"));
DirectFieldAccessor executorDfa = new DirectFieldAccessor(cluster);
Object custerCommandExecutor = executorDfa.getPropertyValue("executor");
DirectFieldAccessor dfa = new DirectFieldAccessor(custerCommandExecutor);
clusterCommandExecutor.setMaxRedirects((Integer) dfa.getPropertyValue("maxRedirects"));
} catch (Exception e) {
// ignore it and work with the executor default
}
@@ -177,11 +179,6 @@ public class JedisClusterConnection implements RedisClusterConnection {
@Nullable
@Override
public <T> T execute(String command, byte[] key, Collection<byte[]> args) {
return execute(command, key, args, it -> (T) it.getOne());
}
@Nullable
<T> T execute(String command, byte[] key, Collection<byte[]> args, Function<Client, T> responseMapper) {
Assert.notNull(command, "Command must not be null!");
Assert.notNull(key, "Key must not be null!");
@@ -191,8 +188,9 @@ public class JedisClusterConnection implements RedisClusterConnection {
RedisClusterNode keyMaster = topologyProvider.getTopology().getKeyServingMasterNode(key);
return clusterCommandExecutor.executeCommandOnSingleNode((JedisClusterCommandCallback<T>) client -> JedisClientUtils
.execute(command, EMPTY_2D_BYTE_ARRAY, commandArgs, () -> client, responseMapper), keyMaster).getValue();
return clusterCommandExecutor.executeCommandOnSingleNode((JedisClusterCommandCallback<T>) client -> {
return (T) client.sendCommand(() -> JedisConverters.toBytes(command), commandArgs);
}, keyMaster).getValue();
}
private static byte[][] getCommandArguments(byte[] key, Collection<byte[]> args) {
@@ -409,18 +407,13 @@ public class JedisClusterConnection implements RedisClusterConnection {
@Override
public byte[] echo(byte[] message) {
try {
return cluster.echo(message);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
throw new InvalidDataAccessApiUsageException("Echo not supported in cluster mode.");
}
@Override
public String ping() {
return !clusterCommandExecutor.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) BinaryJedis::ping)
return !clusterCommandExecutor.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) Jedis::ping)
.resultsAsList().isEmpty() ? "PONG" : null;
}
@@ -429,7 +422,7 @@ public class JedisClusterConnection implements RedisClusterConnection {
public String ping(RedisClusterNode node) {
return clusterCommandExecutor
.executeCommandOnSingleNode((JedisClusterCommandCallback<String>) BinaryJedis::ping, node).getValue();
.executeCommandOnSingleNode((JedisClusterCommandCallback<String>) Jedis::ping, node).getValue();
}
/*
@@ -552,8 +545,10 @@ public class JedisClusterConnection implements RedisClusterConnection {
@Override
public Integer clusterGetSlotForKey(byte[] key) {
return clusterCommandExecutor.executeCommandOnArbitraryNode((JedisClusterCommandCallback<Integer>) client -> client
.clusterKeySlot(JedisConverters.toString(key)).intValue()).getValue();
return clusterCommandExecutor
.executeCommandOnArbitraryNode(
(JedisClusterCommandCallback<Integer>) client -> (int) client.clusterKeySlot(JedisConverters.toString(key)))
.getValue();
}
@Override
@@ -709,7 +704,7 @@ public class JedisClusterConnection implements RedisClusterConnection {
private final JedisCluster cluster;
private final ClusterTopologyProvider topologyProvider;
private final JedisClusterConnectionHandler connectionHandler;
private final ClusterConnectionProvider connectionHandler;
/**
* Creates new {@link JedisClusterNodeResourceProvider}.
@@ -726,7 +721,7 @@ public class JedisClusterConnection implements RedisClusterConnection {
PropertyAccessor accessor = new DirectFieldAccessFallbackBeanWrapper(cluster);
this.connectionHandler = accessor.isReadableProperty("connectionHandler")
? (JedisClusterConnectionHandler) accessor.getPropertyValue("connectionHandler")
? (ClusterConnectionProvider) accessor.getPropertyValue("connectionHandler")
: null;
} else {
this.connectionHandler = null;
@@ -739,23 +734,23 @@ public class JedisClusterConnection implements RedisClusterConnection {
Assert.notNull(node, "Cannot get Pool for 'null' node!");
JedisPool pool = getResourcePoolForSpecificNode(node);
ConnectionPool pool = getResourcePoolForSpecificNode(node);
if (pool != null) {
return pool.getResource();
return new Jedis(pool.getResource());
}
Jedis connection = getConnectionForSpecificNode(node);
Connection connection = getConnectionForSpecificNode(node);
if (connection != null) {
return connection;
return new Jedis(connection);
}
throw new DataAccessResourceFailureException(String.format("Node %s is unknown to cluster", node));
}
private JedisPool getResourcePoolForSpecificNode(RedisClusterNode node) {
private ConnectionPool getResourcePoolForSpecificNode(RedisClusterNode node) {
Map<String, JedisPool> clusterNodes = cluster.getClusterNodes();
Map<String, ConnectionPool> clusterNodes = cluster.getClusterNodes();
if (clusterNodes.containsKey(node.asString())) {
return clusterNodes.get(node.asString());
}
@@ -763,7 +758,7 @@ public class JedisClusterConnection implements RedisClusterConnection {
return null;
}
private Jedis getConnectionForSpecificNode(RedisClusterNode node) {
private Connection getConnectionForSpecificNode(RedisClusterNode node) {
RedisClusterNode member = topologyProvider.getTopology().lookup(node);
@@ -773,7 +768,7 @@ public class JedisClusterConnection implements RedisClusterConnection {
}
if (member != null && connectionHandler != null) {
return connectionHandler.getConnectionFromNode(new HostAndPort(member.getHost(), member.getPort()));
return connectionHandler.getConnection(new HostAndPort(member.getHost(), member.getPort()));
}
return null;
@@ -835,15 +830,15 @@ public class JedisClusterConnection implements RedisClusterConnection {
Map<String, Exception> errors = new LinkedHashMap<>();
List<Entry<String, JedisPool>> list = new ArrayList<>(cluster.getClusterNodes().entrySet());
List<Entry<String, ConnectionPool>> list = new ArrayList<>(cluster.getClusterNodes().entrySet());
Collections.shuffle(list);
for (Entry<String, JedisPool> entry : list) {
for (Entry<String, ConnectionPool> entry : list) {
try (Jedis jedis = entry.getValue().getResource()) {
try (Connection connection = entry.getValue().getResource()) {
time = System.currentTimeMillis();
Set<RedisClusterNode> nodes = Converters.toSetOfRedisClusterNodes(jedis.clusterNodes());
Set<RedisClusterNode> nodes = Converters.toSetOfRedisClusterNodes(new Jedis(connection).clusterNodes());
synchronized (lock) {
cached = new ClusterTopology(nodes);

View File

@@ -16,8 +16,9 @@
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.GeoCoordinate;
import redis.clients.jedis.GeoUnit;
import redis.clients.jedis.args.GeoUnit;
import redis.clients.jedis.params.GeoRadiusParam;
import redis.clients.jedis.params.GeoSearchParam;
import java.util.HashMap;
import java.util.List;
@@ -238,13 +239,37 @@ class JedisClusterGeoCommands implements RedisGeoCommands {
@Override
public GeoResults<GeoLocation<byte[]>> geoSearch(byte[] key, GeoReference<byte[]> reference, GeoShape predicate,
GeoSearchCommandArgs args) {
throw new UnsupportedOperationException("GEOSEARCH not supported through Jedis");
Assert.notNull(key, "Key must not be null!");
GeoSearchParam params = JedisConverters.toGeoSearchParams(reference, predicate, args);
try {
return JedisConverters.geoRadiusResponseToGeoResultsConverter(predicate.getMetric())
.convert(connection.getCluster().geosearch(key, params));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
@Override
public Long geoSearchStore(byte[] destKey, byte[] key, GeoReference<byte[]> reference, GeoShape predicate,
GeoSearchStoreCommandArgs args) {
throw new UnsupportedOperationException("GEOSEARCHSTORE not supported through Jedis");
Assert.notNull(destKey, "Destination Key must not be null!");
Assert.notNull(key, "Key must not be null!");
GeoSearchParam params = JedisConverters.toGeoSearchParams(reference, predicate, args);
try {
if (args.isStoreDistance()) {
return connection.getCluster().geosearchStoreStoreDist(destKey, key, params);
}
return connection.getCluster().geosearchStore(destKey, key, params);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
private DataAccessException convertJedisAccessException(Exception ex) {

View File

@@ -15,7 +15,8 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.params.ScanParams;
import redis.clients.jedis.resps.ScanResult;
import java.util.ArrayList;
import java.util.Collections;
@@ -278,7 +279,7 @@ class JedisClusterHashCommands implements RedisHashCommands {
ScanParams params = JedisConverters.toScanParams(options);
redis.clients.jedis.ScanResult<Map.Entry<byte[], byte[]>> result = connection.getCluster().hscan(key,
ScanResult<Entry<byte[], byte[]>> result = connection.getCluster().hscan(key,
JedisConverters.toBytes(cursorId), params);
return new ScanIteration<>(Long.valueOf(result.getCursor()), result.getResult());
}

View File

@@ -15,8 +15,9 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.ScanParams;
import redis.clients.jedis.resps.ScanResult;
import java.time.Duration;
import java.util.ArrayList;
@@ -179,7 +180,7 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
protected ScanIteration<byte[]> doScan(long cursorId, ScanOptions options) {
ScanParams params = JedisConverters.toScanParams(options);
redis.clients.jedis.ScanResult<String> result = client.scan(Long.toString(cursorId), params);
ScanResult<String> result = client.scan(Long.toString(cursorId), params);
return new ScanIteration<>(Long.valueOf(result.getCursor()),
JedisConverters.stringListToByteList().convert(result.getResult()));
}
@@ -277,11 +278,8 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
Assert.notNull(key, "Key must not be null!");
if (seconds > Integer.MAX_VALUE) {
throw new UnsupportedOperationException("Jedis does not support seconds exceeding Integer.MAX_VALUE.");
}
try {
return JedisConverters.toBoolean(connection.getCluster().expire(key, Long.valueOf(seconds).intValue()));
return JedisConverters.toBoolean(connection.getCluster().expire(key, seconds));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -404,14 +402,10 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(serializedValue, "Serialized value must not be null!");
if (ttlInMillis > Integer.MAX_VALUE) {
throw new UnsupportedOperationException("Jedis does not support ttlInMillis exceeding Integer.MAX_VALUE.");
}
connection.getClusterCommandExecutor().executeCommandOnSingleNode((JedisClusterCommandCallback<String>) client -> {
if (!replace) {
return client.restore(key, Long.valueOf(ttlInMillis).intValue(), serializedValue);
return client.restore(key, ttlInMillis, serializedValue);
}
return JedisConverters.toString(this.connection.execute("RESTORE", key,
@@ -472,7 +466,7 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
}
return connection.getClusterCommandExecutor()
.executeMultiKeyCommand((JedisMultiKeyClusterCommandCallback<Boolean>) BinaryJedis::exists, Arrays.asList(keys))
.executeMultiKeyCommand((JedisMultiKeyClusterCommandCallback<Boolean>) Jedis::exists, Arrays.asList(keys))
.resultsAsList().stream().mapToLong(val -> ObjectUtils.nullSafeEquals(val, Boolean.TRUE) ? 1 : 0).sum();
}

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import java.util.List;
@@ -44,7 +44,7 @@ class JedisClusterScriptingCommands implements RedisScriptingCommands {
try {
connection.getClusterCommandExecutor().executeCommandOnAllNodes(
(JedisClusterConnection.JedisClusterCommandCallback<String>) BinaryJedis::scriptFlush);
(JedisClusterConnection.JedisClusterCommandCallback<String>) Jedis::scriptFlush);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -55,7 +55,7 @@ class JedisClusterScriptingCommands implements RedisScriptingCommands {
try {
connection.getClusterCommandExecutor().executeCommandOnAllNodes(
(JedisClusterConnection.JedisClusterCommandCallback<String>) BinaryJedis::scriptKill);
(JedisClusterConnection.JedisClusterCommandCallback<String>) Jedis::scriptKill);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -90,7 +90,7 @@ class JedisClusterScriptingCommands implements RedisScriptingCommands {
try {
return (T) new JedisScriptReturnConverter(returnType)
.convert(getCluster().eval(script, JedisConverters.toBytes(numKeys), keysAndArgs));
.convert(getCluster().eval(script, numKeys, keysAndArgs));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}

View File

@@ -15,7 +15,6 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
@@ -54,30 +53,30 @@ class JedisClusterServerCommands implements RedisClusterServerCommands {
@Override
public void bgReWriteAof(RedisClusterNode node) {
executeCommandOnSingleNode(BinaryJedis::bgrewriteaof, node);
executeCommandOnSingleNode(Jedis::bgrewriteaof, node);
}
@Override
public void bgReWriteAof() {
connection.getClusterCommandExecutor()
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) BinaryJedis::bgrewriteaof);
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) Jedis::bgrewriteaof);
}
@Override
public void bgSave() {
connection.getClusterCommandExecutor()
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) BinaryJedis::bgsave);
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) Jedis::bgsave);
}
@Override
public void bgSave(RedisClusterNode node) {
executeCommandOnSingleNode(BinaryJedis::bgsave, node);
executeCommandOnSingleNode(Jedis::bgsave, node);
}
@Override
public Long lastSave() {
List<Long> result = new ArrayList<>(executeCommandOnAllNodes(BinaryJedis::lastsave).resultsAsList());
List<Long> result = new ArrayList<>(executeCommandOnAllNodes(Jedis::lastsave).resultsAsList());
if (CollectionUtils.isEmpty(result)) {
return null;
@@ -89,23 +88,23 @@ class JedisClusterServerCommands implements RedisClusterServerCommands {
@Override
public Long lastSave(RedisClusterNode node) {
return executeCommandOnSingleNode(BinaryJedis::lastsave, node).getValue();
return executeCommandOnSingleNode(Jedis::lastsave, node).getValue();
}
@Override
public void save() {
executeCommandOnAllNodes(BinaryJedis::save);
executeCommandOnAllNodes(Jedis::save);
}
@Override
public void save(RedisClusterNode node) {
executeCommandOnSingleNode(BinaryJedis::save, node);
executeCommandOnSingleNode(Jedis::save, node);
}
@Override
public Long dbSize() {
Collection<Long> dbSizes = executeCommandOnAllNodes(BinaryJedis::dbSize).resultsAsList();
Collection<Long> dbSizes = executeCommandOnAllNodes(Jedis::dbSize).resultsAsList();
if (CollectionUtils.isEmpty(dbSizes)) {
return 0L;
@@ -120,12 +119,12 @@ class JedisClusterServerCommands implements RedisClusterServerCommands {
@Override
public Long dbSize(RedisClusterNode node) {
return executeCommandOnSingleNode(BinaryJedis::dbSize, node).getValue();
return executeCommandOnSingleNode(Jedis::dbSize, node).getValue();
}
@Override
public void flushDb() {
executeCommandOnAllNodes(BinaryJedis::flushDB);
executeCommandOnAllNodes(Jedis::flushDB);
}
@Override
@@ -135,7 +134,7 @@ class JedisClusterServerCommands implements RedisClusterServerCommands {
@Override
public void flushDb(RedisClusterNode node) {
executeCommandOnSingleNode(BinaryJedis::flushDB, node);
executeCommandOnSingleNode(Jedis::flushDB, node);
}
@Override
@@ -146,7 +145,7 @@ class JedisClusterServerCommands implements RedisClusterServerCommands {
@Override
public void flushAll() {
connection.getClusterCommandExecutor()
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) BinaryJedis::flushAll);
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) Jedis::flushAll);
}
@Override
@@ -158,7 +157,7 @@ class JedisClusterServerCommands implements RedisClusterServerCommands {
@Override
public void flushAll(RedisClusterNode node) {
executeCommandOnSingleNode(BinaryJedis::flushAll, node);
executeCommandOnSingleNode(Jedis::flushAll, node);
}
@Override
@@ -187,7 +186,7 @@ class JedisClusterServerCommands implements RedisClusterServerCommands {
@Override
public Properties info(RedisClusterNode node) {
return JedisConverters.toProperties(executeCommandOnSingleNode(BinaryJedis::info, node).getValue());
return JedisConverters.toProperties(executeCommandOnSingleNode(Jedis::info, node).getValue());
}
@Override
@@ -222,12 +221,18 @@ class JedisClusterServerCommands implements RedisClusterServerCommands {
@Override
public void shutdown() {
connection.getClusterCommandExecutor()
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) BinaryJedis::shutdown);
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) jedis -> {
jedis.shutdown();
return null;
});
}
@Override
public void shutdown(RedisClusterNode node) {
executeCommandOnSingleNode(BinaryJedis::shutdown, node);
executeCommandOnSingleNode(jedis -> {
jedis.shutdown();
return null;
}, node);
}
@Override
@@ -297,23 +302,23 @@ class JedisClusterServerCommands implements RedisClusterServerCommands {
@Override
public void resetConfigStats() {
connection.getClusterCommandExecutor()
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) BinaryJedis::configResetStat);
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) Jedis::configResetStat);
}
@Override
public void rewriteConfig() {
connection.getClusterCommandExecutor()
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) BinaryJedis::configRewrite);
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) Jedis::configRewrite);
}
@Override
public void resetConfigStats(RedisClusterNode node) {
executeCommandOnSingleNode(BinaryJedis::configResetStat, node);
executeCommandOnSingleNode(Jedis::configResetStat, node);
}
@Override
public void rewriteConfig(RedisClusterNode node) {
executeCommandOnSingleNode(BinaryJedis::configRewrite, node);
executeCommandOnSingleNode(Jedis::configRewrite, node);
}
@Override
@@ -321,7 +326,7 @@ class JedisClusterServerCommands implements RedisClusterServerCommands {
return convertListOfStringToTime(
connection.getClusterCommandExecutor()
.executeCommandOnArbitraryNode((JedisClusterCommandCallback<List<String>>) BinaryJedis::time).getValue(),
.executeCommandOnArbitraryNode((JedisClusterCommandCallback<List<String>>) Jedis::time).getValue(),
timeUnit);
}
@@ -330,7 +335,7 @@ class JedisClusterServerCommands implements RedisClusterServerCommands {
return convertListOfStringToTime(
connection.getClusterCommandExecutor()
.executeCommandOnSingleNode((JedisClusterCommandCallback<List<String>>) BinaryJedis::time, node).getValue(),
.executeCommandOnSingleNode((JedisClusterCommandCallback<List<String>>) Jedis::time, node).getValue(),
timeUnit);
}

View File

@@ -15,7 +15,8 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.params.ScanParams;
import redis.clients.jedis.resps.ScanResult;
import java.util.ArrayList;
import java.util.Arrays;
@@ -396,7 +397,7 @@ class JedisClusterSetCommands implements RedisSetCommands {
protected ScanIteration<byte[]> doScan(long cursorId, ScanOptions options) {
ScanParams params = JedisConverters.toScanParams(options);
redis.clients.jedis.ScanResult<byte[]> result = connection.getCluster().sscan(key,
ScanResult<byte[]> result = connection.getCluster().sscan(key,
JedisConverters.toBytes(cursorId), params);
return new ScanIteration<>(Long.parseLong(result.getCursor()), result.getResult());
}

View File

@@ -19,7 +19,11 @@ import static org.springframework.data.redis.connection.jedis.StreamConverters.*
import redis.clients.jedis.BuilderFactory;
import redis.clients.jedis.params.XAddParams;
import redis.clients.jedis.params.XClaimParams;
import redis.clients.jedis.params.XReadGroupParams;
import redis.clients.jedis.params.XReadParams;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -85,7 +89,26 @@ class JedisClusterStreamCommands implements RedisStreamCommands {
@Override
public List<RecordId> xClaimJustId(byte[] key, String group, String newOwner, XClaimOptions options) {
throw new UnsupportedOperationException("JedisCluster does not support xClaimJustId.");
Assert.notNull(key, "Key must not be null!");
Assert.notNull(group, "Group must not be null!");
Assert.notNull(newOwner, "NewOwner must not be null!");
long minIdleTime = options.getMinIdleTime() == null ? -1L : options.getMinIdleTime().toMillis();
XClaimParams xClaimParams = StreamConverters.toXClaimParams(options);
try {
List<byte[]> ids = connection.getCluster().xclaimJustId(key, JedisConverters.toBytes(group),
JedisConverters.toBytes(newOwner), minIdleTime, xClaimParams, entryIdsToBytes(options.getIds()));
List<RecordId> recordIds = new ArrayList<>(ids.size());
ids.forEach(it -> recordIds.add(RecordId.of(JedisConverters.toString(it))));
return recordIds;
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
@Override
@@ -96,13 +119,12 @@ class JedisClusterStreamCommands implements RedisStreamCommands {
Assert.notNull(newOwner, "NewOwner must not be null!");
long minIdleTime = options.getMinIdleTime() == null ? -1L : options.getMinIdleTime().toMillis();
int retryCount = options.getRetryCount() == null ? -1 : options.getRetryCount().intValue();
long unixTime = options.getUnixTime() == null ? -1L : options.getUnixTime().toEpochMilli();
XClaimParams xClaimParams = StreamConverters.toXClaimParams(options);
try {
return convertToByteRecord(key,
connection.getCluster().xclaim(key, JedisConverters.toBytes(group), JedisConverters.toBytes(newOwner),
minIdleTime, unixTime, retryCount, options.isForce(), entryIdsToBytes(options.getIds())));
minIdleTime, xClaimParams, entryIdsToBytes(options.getIds())));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -170,17 +192,40 @@ class JedisClusterStreamCommands implements RedisStreamCommands {
@Override
public StreamInfo.XInfoStream xInfo(byte[] key) {
throw new UnsupportedOperationException("JedisCluster does not support XINFO.");
Assert.notNull(key, "Key must not be null!");
try {
return StreamInfo.XInfoStream.fromList((List) connection.getCluster().xinfoStream(key));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
@Override
public StreamInfo.XInfoGroups xInfoGroups(byte[] key) {
throw new UnsupportedOperationException("JedisCluster does not support XINFO.");
Assert.notNull(key, "Key must not be null!");
try {
return StreamInfo.XInfoGroups.fromList(connection.getCluster().xinfoGroups(key));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
@Override
public StreamInfo.XInfoConsumers xInfoConsumers(byte[] key, String groupName) {
throw new UnsupportedOperationException("JedisCluster does not support XINFO.");
Assert.notNull(key, "Key must not be null!");
Assert.notNull(groupName, "GroupName must not be null!");
try {
return StreamInfo.XInfoConsumers.fromList(groupName,
connection.getCluster().xinfoConsumers(key, JedisConverters.toBytes(groupName)));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
@Override
@@ -197,7 +242,21 @@ class JedisClusterStreamCommands implements RedisStreamCommands {
@Override
public PendingMessagesSummary xPending(byte[] key, String groupName) {
throw new UnsupportedOperationException("Jedis does not support returning PendingMessagesSummary.");
Assert.notNull(key, "Key must not be null!");
Assert.notNull(groupName, "GroupName must not be null!");
byte[] group = JedisConverters.toBytes(groupName);
try {
Object response = connection.getCluster().xpending(key, group);
return StreamConverters.toPendingMessagesSummary(groupName, response);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
@Override
@@ -245,12 +304,11 @@ class JedisClusterStreamCommands implements RedisStreamCommands {
Assert.notNull(readOptions, "StreamReadOptions must not be null!");
Assert.notNull(streams, "StreamOffsets must not be null!");
long block = readOptions.getBlock() == null ? -1L : readOptions.getBlock();
int count = readOptions.getCount() != null ? readOptions.getCount().intValue() : Integer.MAX_VALUE;
XReadParams xReadParams = StreamConverters.toXReadParams(readOptions);
try {
List<byte[]> xread = connection.getCluster().xread(count, block, toStreamOffsets(streams));
List<byte[]> xread = connection.getCluster().xread(xReadParams, toStreamOffsets(streams));
if (xread == null) {
return Collections.emptyList();
@@ -270,13 +328,12 @@ class JedisClusterStreamCommands implements RedisStreamCommands {
Assert.notNull(readOptions, "StreamReadOptions must not be null!");
Assert.notNull(streams, "StreamOffsets must not be null!");
long block = readOptions.getBlock() == null ? -1L : readOptions.getBlock();
int count = readOptions.getCount() == null ? -1 : readOptions.getCount().intValue();
XReadGroupParams xReadParams = StreamConverters.toXReadGroupParams(readOptions);
try {
List<byte[]> xread = connection.getCluster().xreadGroup(JedisConverters.toBytes(consumer.getGroup()),
JedisConverters.toBytes(consumer.getName()), count, block, readOptions.isNoack(), toStreamOffsets(streams));
JedisConverters.toBytes(consumer.getName()), xReadParams, toStreamOffsets(streams));
if (xread == null) {
return Collections.emptyList();

View File

@@ -15,8 +15,7 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.Connection;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;
import java.util.ArrayList;
@@ -116,7 +115,7 @@ class JedisClusterStringCommands implements RedisStringCommands {
}
return connection.getClusterCommandExecutor()
.executeMultiKeyCommand((JedisMultiKeyClusterCommandCallback<byte[]>) BinaryJedis::get, Arrays.asList(keys))
.executeMultiKeyCommand((JedisMultiKeyClusterCommandCallback<byte[]>) Jedis::get, Arrays.asList(keys))
.resultsAsListSortBy(keys);
}
@@ -393,7 +392,7 @@ class JedisClusterStringCommands implements RedisStringCommands {
byte[][] args = JedisConverters.toBitfieldCommandArguments(subCommands);
try {
return connection.execute("BITFIELD", key, Arrays.asList(args), Connection::getIntegerMultiBulkReply);
return connection.getCluster().bitfield(key, args);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}

View File

@@ -15,10 +15,12 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ZParams;
import redis.clients.jedis.params.ScanParams;
import redis.clients.jedis.params.ZParams;
import redis.clients.jedis.resps.ScanResult;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -49,7 +51,7 @@ import org.springframework.util.Assert;
*/
class JedisClusterZSetCommands implements RedisZSetCommands {
private static final SetConverter<redis.clients.jedis.Tuple, Tuple> TUPLE_SET_CONVERTER = new SetConverter<>(
private static final SetConverter<redis.clients.jedis.resps.Tuple, Tuple> TUPLE_SET_CONVERTER = new SetConverter<>(
JedisConverters::toTuple);
private final JedisClusterConnection connection;
@@ -142,7 +144,7 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
try {
Set<redis.clients.jedis.Tuple> tuples = connection.getCluster().zrandmemberWithScores(key, 1);
List<redis.clients.jedis.resps.Tuple> tuples = connection.getCluster().zrandmemberWithScores(key, 1);
return tuples.isEmpty() ? null : JedisConverters.toTuple(tuples.iterator().next());
} catch (Exception ex) {
@@ -156,7 +158,7 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
try {
Set<redis.clients.jedis.Tuple> tuples = connection.getCluster().zrandmemberWithScores(key, count);
List<redis.clients.jedis.resps.Tuple> tuples = connection.getCluster().zrandmemberWithScores(key, count);
return tuples.stream().map(JedisConverters::toTuple).collect(Collectors.toList());
} catch (Exception ex) {
@@ -196,7 +198,7 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
try {
return connection.getCluster().zrange(key, start, end);
return new LinkedHashSet<>(connection.getCluster().zrange(key, start, end));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -234,9 +236,10 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
try {
if (limit.isUnlimited()) {
return connection.getCluster().zrevrangeByScore(key, max, min);
return new LinkedHashSet<>(connection.getCluster().zrevrangeByScore(key, max, min));
}
return connection.getCluster().zrevrangeByScore(key, max, min, limit.getOffset(), limit.getCount());
return new LinkedHashSet<>(
connection.getCluster().zrevrangeByScore(key, max, min, limit.getOffset(), limit.getCount()));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -302,7 +305,7 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
try {
redis.clients.jedis.Tuple tuple = connection.getCluster().zpopmin(key);
redis.clients.jedis.resps.Tuple tuple = connection.getCluster().zpopmin(key);
return tuple != null ? JedisConverters.toTuple(tuple) : null;
} catch (Exception ex) {
throw convertJedisAccessException(ex);
@@ -343,7 +346,7 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
try {
redis.clients.jedis.Tuple tuple = connection.getCluster().zpopmax(key);
redis.clients.jedis.resps.Tuple tuple = connection.getCluster().zpopmax(key);
return tuple != null ? JedisConverters.toTuple(tuple) : null;
} catch (Exception ex) {
throw convertJedisAccessException(ex);
@@ -405,9 +408,10 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
try {
if (limit.isUnlimited()) {
return connection.getCluster().zrangeByScore(key, min, max);
return new LinkedHashSet<>(connection.getCluster().zrangeByScore(key, min, max));
}
return connection.getCluster().zrangeByScore(key, min, max, limit.getOffset(), limit.getCount());
return new LinkedHashSet<>(
connection.getCluster().zrangeByScore(key, min, max, limit.getOffset(), limit.getCount()));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -425,9 +429,10 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
try {
if (limit.isUnlimited()) {
return connection.getCluster().zrangeByLex(key, min, max);
return new LinkedHashSet<>(connection.getCluster().zrangeByLex(key, min, max));
}
return connection.getCluster().zrangeByLex(key, min, max, limit.getOffset(), limit.getCount());
return new LinkedHashSet<>(
connection.getCluster().zrangeByLex(key, min, max, limit.getOffset(), limit.getCount()));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -461,9 +466,10 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
try {
if (limit.isUnlimited()) {
return connection.getCluster().zrevrangeByLex(key, max, min);
return new LinkedHashSet<>(connection.getCluster().zrevrangeByLex(key, max, min));
}
return connection.getCluster().zrevrangeByLex(key, max, min, limit.getOffset(), limit.getCount());
return new LinkedHashSet<>(
connection.getCluster().zrevrangeByLex(key, max, min, limit.getOffset(), limit.getCount()));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -487,7 +493,7 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
try {
return connection.getCluster().zrangeByScore(key, min, max);
return new LinkedHashSet<>(connection.getCluster().zrangeByScore(key, min, max));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -515,8 +521,8 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
}
try {
return connection.getCluster().zrangeByScore(key, min, max, Long.valueOf(offset).intValue(),
Long.valueOf(count).intValue());
return new LinkedHashSet<>(connection.getCluster().zrangeByScore(key, min, max, Long.valueOf(offset).intValue(),
Long.valueOf(count).intValue()));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -545,7 +551,7 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
try {
return connection.getCluster().zrevrange(key, start, end);
return new LinkedHashSet<>(connection.getCluster().zrevrange(key, start, end));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -569,7 +575,7 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
try {
return connection.getCluster().zrevrangeByScore(key, max, min);
return new LinkedHashSet<>(connection.getCluster().zrevrangeByScore(key, max, min));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -597,8 +603,8 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
}
try {
return connection.getCluster().zrevrangeByScore(key, max, min, Long.valueOf(offset).intValue(),
Long.valueOf(count).intValue());
return new LinkedHashSet<>(connection.getCluster().zrevrangeByScore(key, max, min,
Long.valueOf(offset).intValue(), Long.valueOf(count).intValue()));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -961,7 +967,7 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
ScanParams params = JedisConverters.toScanParams(options);
redis.clients.jedis.ScanResult<redis.clients.jedis.Tuple> result = connection.getCluster().zscan(key,
ScanResult<redis.clients.jedis.resps.Tuple> result = connection.getCluster().zscan(key,
JedisConverters.toBytes(cursorId), params);
return new ScanIteration<>(Long.valueOf(result.getCursor()),
JedisConverters.tuplesToTuples().convert(result.getResult()));
@@ -975,7 +981,8 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
try {
return connection.getCluster().zrangeByScore(key, JedisConverters.toBytes(min), JedisConverters.toBytes(max));
return new LinkedHashSet<>(
connection.getCluster().zrangeByScore(key, JedisConverters.toBytes(min), JedisConverters.toBytes(max)));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -991,8 +998,8 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
}
try {
return connection.getCluster().zrangeByScore(key, JedisConverters.toBytes(min), JedisConverters.toBytes(max),
Long.valueOf(offset).intValue(), Long.valueOf(count).intValue());
return new LinkedHashSet<>(connection.getCluster().zrangeByScore(key, JedisConverters.toBytes(min),
JedisConverters.toBytes(max), Long.valueOf(offset).intValue(), Long.valueOf(count).intValue()));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -1002,7 +1009,7 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
return connection.convertJedisAccessException(ex);
}
private static Set<Tuple> toTupleSet(Set<redis.clients.jedis.Tuple> source) {
private static Set<Tuple> toTupleSet(List<redis.clients.jedis.resps.Tuple> source) {
return TUPLE_SET_CONVERTER.convert(source);
}

View File

@@ -15,7 +15,18 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.*;
import redis.clients.jedis.BuilderFactory;
import redis.clients.jedis.CommandArguments;
import redis.clients.jedis.CommandObject;
import redis.clients.jedis.DefaultJedisClientConfig;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisClientConfig;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Response;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.commands.ProtocolCommand;
import redis.clients.jedis.commands.ServerCommands;
import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.util.Pool;
@@ -36,6 +47,7 @@ import org.springframework.data.redis.FallbackExceptionTranslationStrategy;
import org.springframework.data.redis.RedisSystemException;
import org.springframework.data.redis.connection.*;
import org.springframework.data.redis.connection.convert.TransactionResultConverter;
import org.springframework.data.redis.connection.jedis.JedisInvoker.ResponseCommands;
import org.springframework.data.redis.connection.jedis.JedisResult.JedisResultBuilder;
import org.springframework.data.redis.connection.jedis.JedisResult.JedisStatusResult;
import org.springframework.lang.Nullable;
@@ -83,8 +95,6 @@ public class JedisConnection extends AbstractRedisConnection {
private final JedisZSetCommands zSetCommands = new JedisZSetCommands(this);
private final @Nullable Pool<Jedis> pool;
private final String clientName;
private final JedisClientConfig nodeConfig;
private final JedisClientConfig sentinelConfig;
@@ -148,8 +158,6 @@ public class JedisConnection extends AbstractRedisConnection {
this.jedis = jedis;
this.pool = pool;
this.clientName = nodeConfig.getClientName();
this.nodeConfig = nodeConfig;
this.sentinelConfig = sentinelConfig;
// select the db
@@ -167,22 +175,22 @@ public class JedisConnection extends AbstractRedisConnection {
@Nullable
private Object doInvoke(boolean status, Function<Jedis, Object> directFunction,
Function<MultiKeyPipelineBase, Response<Object>> pipelineFunction, Converter<Object, Object> converter,
Function<ResponseCommands, Response<Object>> pipelineFunction, Converter<Object, Object> converter,
Supplier<Object> nullDefault) {
return doWithJedis(it -> {
if (isPipelined()) {
if (isQueueing()) {
Response<Object> response = pipelineFunction.apply(getRequiredPipeline());
pipeline(status ? newStatusResult(response) : newJedisResult(response, converter, nullDefault));
Response<Object> response = pipelineFunction.apply(JedisInvoker.createCommands(getRequiredTransaction()));
transaction(status ? newStatusResult(response) : newJedisResult(response, converter, nullDefault));
return null;
}
if (isQueueing()) {
if (isPipelined()) {
Response<Object> response = pipelineFunction.apply(getRequiredTransaction());
transaction(status ? newStatusResult(response) : newJedisResult(response, converter, nullDefault));
Response<Object> response = pipelineFunction.apply(JedisInvoker.createCommands(getRequiredPipeline()));
pipeline(status ? newStatusResult(response) : newJedisResult(response, converter, nullDefault));
return null;
}
@@ -263,32 +271,28 @@ public class JedisConnection extends AbstractRedisConnection {
@Override
public Object execute(String command, byte[]... args) {
return execute(command, args, Connection::getOne, JedisClientUtils::getResponse);
}
@Nullable
<T> T execute(String command, byte[][] args, Function<Client, T> resultMapper,
Function<Object, Response<?>> pipelineResponseMapper) {
Assert.hasText(command, "A valid command needs to be specified!");
Assert.notNull(args, "Arguments must not be null!");
return doWithJedis(it -> {
Client client = JedisClientUtils.sendCommand(command, args, it);
ProtocolCommand protocolCommand = () -> JedisConverters.toBytes(command);
if (isQueueing() || isPipelined()) {
Response<?> result = pipelineResponseMapper
.apply(isPipelined() ? getRequiredPipeline() : getRequiredTransaction());
CommandArguments arguments = new CommandArguments(protocolCommand).addObjects(args);
CommandObject<Object> commandObject = new CommandObject<>(arguments, BuilderFactory.RAW_OBJECT);
if (isPipelined()) {
pipeline(newJedisResult(result));
pipeline(newJedisResult(getRequiredPipeline().executeCommand(commandObject)));
} else {
transaction(newJedisResult(result));
transaction(newJedisResult(getRequiredTransaction().executeCommand(commandObject)));
}
return null;
}
return resultMapper.apply(client);
return it.sendCommand(protocolCommand, args);
});
}
@@ -330,16 +334,21 @@ public class JedisConnection extends AbstractRedisConnection {
@Override
public boolean isQueueing() {
return JedisClientUtils.isInMulti(jedis);
return transaction != null;
}
@Override
public boolean isPipelined() {
return (pipeline != null);
return pipeline != null;
}
@Override
public void openPipeline() {
if (isQueueing()) {
throw new InvalidDataAccessApiUsageException("Cannot use Pipelining while a transaction is active");
}
if (pipeline == null) {
pipeline = jedis.pipelined();
}
@@ -406,21 +415,17 @@ public class JedisConnection extends AbstractRedisConnection {
Assert.notNull(message, "Message must not be null");
return invoke().just(BinaryJedis::echo, MultiKeyPipelineBase::echo, message);
return invoke().just(j -> j.echo(message));
}
@Override
public String ping() {
return invoke().just(BinaryJedis::ping, MultiKeyPipelineBase::ping);
return invoke().just(ServerCommands::ping);
}
@Override
public void discard() {
try {
if (isPipelined()) {
pipeline(newStatusResult(getRequiredPipeline().discard()));
return;
}
getRequiredTransaction().discard();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
@@ -433,11 +438,6 @@ public class JedisConnection extends AbstractRedisConnection {
@Override
public List<Object> exec() {
try {
if (isPipelined()) {
pipeline(newJedisResult(getRequiredPipeline().exec(),
new TransactionResultConverter<>(new LinkedList<>(txResults), JedisExceptionConverter.INSTANCE)));
return null;
}
if (transaction == null) {
throw new InvalidDataAccessApiUsageException("No ongoing transaction. Did you forget to call multi?");
@@ -539,24 +539,23 @@ public class JedisConnection extends AbstractRedisConnection {
return;
}
doWithJedis(it -> {
if (isPipelined()) {
throw new InvalidDataAccessApiUsageException("Cannot use Transaction while a pipeline is open");
}
if (isPipelined()) {
getRequiredPipeline().multi();
return;
}
doWithJedis(it -> {
this.transaction = it.multi();
});
}
@Override
public void select(int dbIndex) {
invokeStatus().just(BinaryJedis::select, MultiKeyPipelineBase::select, dbIndex);
getJedis().select(dbIndex);
}
@Override
public void unwatch() {
doWithJedis((Consumer<Jedis>) BinaryJedis::unwatch);
doWithJedis((Consumer<Jedis>) Jedis::unwatch);
}
@Override
@@ -567,11 +566,7 @@ public class JedisConnection extends AbstractRedisConnection {
doWithJedis(it -> {
for (byte[] key : keys) {
if (isPipelined()) {
pipeline(newStatusResult(getRequiredPipeline().watch(key)));
} else {
it.watch(key);
}
}
});
}
@@ -582,7 +577,7 @@ public class JedisConnection extends AbstractRedisConnection {
@Override
public Long publish(byte[] channel, byte[] message) {
return invoke().just(BinaryJedis::publish, MultiKeyPipelineBase::publish, channel, message);
return invoke().just(j -> j.publish(channel, message));
}
@Override

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.Connection;
import redis.clients.jedis.DefaultJedisClientConfig;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
@@ -23,7 +24,6 @@ import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.Protocol;
import redis.clients.jedis.util.Pool;
@@ -401,7 +401,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
* @since 1.7
*/
protected JedisCluster createCluster(RedisClusterConfiguration clusterConfig,
GenericObjectPoolConfig<Jedis> poolConfig) {
GenericObjectPoolConfig<Connection> poolConfig) {
Assert.notNull(clusterConfig, "Cluster configuration must not be null!");
@@ -649,7 +649,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
* @return the poolConfig
*/
@Nullable
public GenericObjectPoolConfig<Jedis> getPoolConfig() {
public <T> GenericObjectPoolConfig<T> getPoolConfig() {
return clientConfiguration.getPoolConfig().orElse(null);
}
@@ -890,12 +890,6 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
private Duration readTimeout = Duration.ofMillis(Protocol.DEFAULT_TIMEOUT);
private Duration connectTimeout = Duration.ofMillis(Protocol.DEFAULT_TIMEOUT);
public static JedisClientConfiguration create(JedisShardInfo shardInfo) {
MutableJedisClientConfiguration configuration = new MutableJedisClientConfiguration();
return configuration;
}
public static JedisClientConfiguration create(GenericObjectPoolConfig jedisPoolConfig) {
MutableJedisClientConfiguration configuration = new MutableJedisClientConfiguration();

View File

@@ -15,7 +15,6 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.BitOP;
import redis.clients.jedis.GeoCoordinate;
import redis.clients.jedis.GeoRadiusResponse;
import redis.clients.jedis.GeoUnit;
@@ -23,10 +22,17 @@ import redis.clients.jedis.ListPosition;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.SortingParams;
import redis.clients.jedis.args.FlushMode;
import redis.clients.jedis.args.BitOP;
import redis.clients.jedis.args.GeoUnit;
import redis.clients.jedis.args.ListPosition;
import redis.clients.jedis.params.GeoRadiusParam;
import redis.clients.jedis.params.GeoSearchParam;
import redis.clients.jedis.params.GetExParams;
import redis.clients.jedis.params.ScanParams;
import redis.clients.jedis.params.SetParams;
import redis.clients.jedis.params.SortingParams;
import redis.clients.jedis.params.ZAddParams;
import redis.clients.jedis.resps.GeoRadiusResponse;
import redis.clients.jedis.util.SafeEncoder;
import java.nio.ByteBuffer;
@@ -41,6 +47,7 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.domain.Sort;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResult;
import org.springframework.data.geo.GeoResults;
@@ -52,6 +59,7 @@ import org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldInc
import org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldSet;
import org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldSubCommand;
import org.springframework.data.redis.connection.RedisClusterNode;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit;
import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation;
import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs;
@@ -76,6 +84,11 @@ import org.springframework.data.redis.connection.zset.Tuple;
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.data.redis.domain.geo.BoundingBox;
import org.springframework.data.redis.domain.geo.BoxShape;
import org.springframework.data.redis.domain.geo.GeoReference;
import org.springframework.data.redis.domain.geo.GeoShape;
import org.springframework.data.redis.domain.geo.RadiusShape;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -114,12 +127,12 @@ public abstract class JedisConverters extends Converters {
}
/**
* {@link ListConverter} converting jedis {@link redis.clients.jedis.Tuple} to {@link Tuple}.
* {@link ListConverter} converting jedis {@link redis.clients.jedis.resps.Tuple} to {@link Tuple}.
*
* @return
* @since 1.4
*/
static ListConverter<redis.clients.jedis.Tuple, Tuple> tuplesToTuples() {
static ListConverter<redis.clients.jedis.resps.Tuple, Tuple> tuplesToTuples() {
return new ListConverter<>(JedisConverters::toTuple);
}
@@ -130,11 +143,11 @@ public abstract class JedisConverters extends Converters {
/**
* @deprecated since 2.5
*/
static Set<Tuple> toTupleSet(Set<redis.clients.jedis.Tuple> source) {
static Set<Tuple> toTupleSet(Set<redis.clients.jedis.resps.Tuple> source) {
return new SetConverter<>(JedisConverters::toTuple).convert(source);
}
public static Tuple toTuple(redis.clients.jedis.Tuple source) {
public static Tuple toTuple(redis.clients.jedis.resps.Tuple source) {
return new DefaultTuple(source.getBinaryElement(), source.getScore());
}
@@ -586,7 +599,7 @@ public abstract class JedisConverters extends Converters {
* @return
* @since 1.8
*/
public static Converter<List<redis.clients.jedis.GeoRadiusResponse>, GeoResults<GeoLocation<byte[]>>> geoRadiusResponseToGeoResultsConverter(
public static Converter<List<GeoRadiusResponse>, GeoResults<GeoLocation<byte[]>>> geoRadiusResponseToGeoResultsConverter(
Metric metric) {
return GeoResultsConverterFactory.INSTANCE.forMetric(metric);
}
@@ -759,6 +772,86 @@ public abstract class JedisConverters extends Converters {
}
}
static GeoSearchParam toGeoSearchParams(GeoReference<byte[]> reference, GeoShape predicate,
RedisGeoCommands.GeoCommandArgs args) {
Assert.notNull(reference, "GeoReference must not be null!");
Assert.notNull(predicate, "GeoShape must not be null!");
Assert.notNull(args, "GeoSearchCommandArgs must not be null!");
GeoSearchParam param = GeoSearchParam.geoSearchParam();
configureGeoReference(reference, param);
if (args.getLimit() != null) {
boolean hasAnyLimit = args.getFlags().contains(Flag.ANY);
param.count(Math.toIntExact(args.getLimit()), hasAnyLimit);
}
if (args.getSortDirection() != null) {
if (args.getSortDirection() == Sort.Direction.ASC) {
param.asc();
} else {
param.desc();
}
}
if (args.getFlags().contains(Flag.WITHDIST)) {
param.withDist();
}
if (args.getFlags().contains(Flag.WITHCOORD)) {
param.withCoord();
}
return getGeoSearchParam(predicate, param);
}
private static GeoSearchParam getGeoSearchParam(GeoShape predicate, GeoSearchParam param) {
if (predicate instanceof RadiusShape) {
Distance radius = ((RadiusShape) predicate).getRadius();
param.byRadius(radius.getValue(), toGeoUnit(radius.getMetric()));
return param;
}
if (predicate instanceof BoxShape) {
BoxShape boxPredicate = (BoxShape) predicate;
BoundingBox boundingBox = boxPredicate.getBoundingBox();
param.byBox(boundingBox.getWidth().getValue(), boundingBox.getHeight().getValue(),
toGeoUnit(boxPredicate.getMetric()));
return param;
}
throw new IllegalArgumentException(String.format("Cannot convert %s to Jedis GeoSearchParam", predicate));
}
private static void configureGeoReference(GeoReference<byte[]> reference, GeoSearchParam param) {
if (reference instanceof GeoReference.GeoMemberReference) {
param.fromMember(toString(((GeoReference.GeoMemberReference<byte[]>) reference).getMember()));
return;
}
if (reference instanceof GeoReference.GeoCoordinateReference) {
GeoReference.GeoCoordinateReference<?> coordinates = (GeoReference.GeoCoordinateReference<?>) reference;
param.fromLonLat(coordinates.getLongitude(), coordinates.getLatitude());
return;
}
throw new IllegalArgumentException(String.format("Cannot extract Geo Reference from %s", reference));
}
/**
* @author Christoph Strobl
* @since 1.8
@@ -767,13 +860,13 @@ public abstract class JedisConverters extends Converters {
INSTANCE;
Converter<List<redis.clients.jedis.GeoRadiusResponse>, GeoResults<GeoLocation<byte[]>>> forMetric(Metric metric) {
Converter<List<GeoRadiusResponse>, GeoResults<GeoLocation<byte[]>>> forMetric(Metric metric) {
return new GeoResultsConverter(
ObjectUtils.nullSafeEquals(Metrics.NEUTRAL, metric) ? DistanceUnit.METERS : metric);
}
private static class GeoResultsConverter
implements Converter<List<redis.clients.jedis.GeoRadiusResponse>, GeoResults<GeoLocation<byte[]>>> {
implements Converter<List<GeoRadiusResponse>, GeoResults<GeoLocation<byte[]>>> {
private final Metric metric;
@@ -786,7 +879,7 @@ public abstract class JedisConverters extends Converters {
List<GeoResult<GeoLocation<byte[]>>> results = new ArrayList<>(source.size());
Converter<redis.clients.jedis.GeoRadiusResponse, GeoResult<GeoLocation<byte[]>>> converter = GeoResultConverterFactory.INSTANCE
Converter<GeoRadiusResponse, GeoResult<GeoLocation<byte[]>>> converter = GeoResultConverterFactory.INSTANCE
.forMetric(metric);
for (GeoRadiusResponse result : source) {
results.add(converter.convert(result));
@@ -805,12 +898,12 @@ public abstract class JedisConverters extends Converters {
INSTANCE;
Converter<redis.clients.jedis.GeoRadiusResponse, GeoResult<GeoLocation<byte[]>>> forMetric(Metric metric) {
Converter<GeoRadiusResponse, GeoResult<GeoLocation<byte[]>>> forMetric(Metric metric) {
return new GeoResultConverter(metric);
}
private static class GeoResultConverter
implements Converter<redis.clients.jedis.GeoRadiusResponse, GeoResult<GeoLocation<byte[]>>> {
implements Converter<GeoRadiusResponse, GeoResult<GeoLocation<byte[]>>> {
private final Metric metric;
@@ -819,7 +912,7 @@ public abstract class JedisConverters extends Converters {
}
@Override
public GeoResult<GeoLocation<byte[]>> convert(redis.clients.jedis.GeoRadiusResponse source) {
public GeoResult<GeoLocation<byte[]>> convert(GeoRadiusResponse source) {
Point point = JedisConverters.toPoint(source.getCoordinate());

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.exceptions.JedisClusterMaxAttemptsException;
import redis.clients.jedis.exceptions.JedisClusterOperationException;
import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisException;
import redis.clients.jedis.exceptions.JedisRedirectionException;
@@ -49,7 +49,11 @@ public class JedisExceptionConverter implements Converter<Exception, DataAccessE
return (DataAccessException) ex;
}
if (ex instanceof JedisClusterMaxAttemptsException) {
if (ex instanceof UnsupportedOperationException) {
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
}
if (ex instanceof JedisClusterOperationException && "No more cluster attempts left.".equals(ex.getMessage())) {
return new TooManyClusterRedirectionsException(ex.getMessage(), ex);
}

View File

@@ -15,12 +15,11 @@
*/
package org.springframework.data.redis.connection.jedis;
import org.springframework.data.redis.domain.geo.GeoReference;
import org.springframework.data.redis.domain.geo.GeoShape;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.GeoCoordinate;
import redis.clients.jedis.GeoUnit;
import redis.clients.jedis.MultiKeyPipelineBase;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.args.GeoUnit;
import redis.clients.jedis.commands.PipelineBinaryCommands;
import redis.clients.jedis.params.GeoSearchParam;
import java.util.HashMap;
import java.util.List;
@@ -33,6 +32,8 @@ import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Metric;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.domain.geo.GeoReference;
import org.springframework.data.redis.domain.geo.GeoShape;
import org.springframework.util.Assert;
/**
@@ -55,7 +56,7 @@ class JedisGeoCommands implements RedisGeoCommands {
Assert.notNull(point, "Point must not be null!");
Assert.notNull(member, "Member must not be null!");
return connection.invoke().just(BinaryJedis::geoadd, MultiKeyPipelineBase::geoadd, key, point.getX(), point.getY(),
return connection.invoke().just(Jedis::geoadd, PipelineBinaryCommands::geoadd, key, point.getX(), point.getY(),
member);
}
@@ -71,7 +72,7 @@ class JedisGeoCommands implements RedisGeoCommands {
redisGeoCoordinateMap.put(mapKey, JedisConverters.toGeoCoordinate(memberCoordinateMap.get(mapKey)));
}
return connection.invoke().just(BinaryJedis::geoadd, MultiKeyPipelineBase::geoadd, key, redisGeoCoordinateMap);
return connection.invoke().just(Jedis::geoadd, PipelineBinaryCommands::geoadd, key, redisGeoCoordinateMap);
}
@Override
@@ -86,7 +87,7 @@ class JedisGeoCommands implements RedisGeoCommands {
redisGeoCoordinateMap.put(location.getName(), JedisConverters.toGeoCoordinate(location.getPoint()));
}
return connection.invoke().just(BinaryJedis::geoadd, MultiKeyPipelineBase::geoadd, key, redisGeoCoordinateMap);
return connection.invoke().just(Jedis::geoadd, PipelineBinaryCommands::geoadd, key, redisGeoCoordinateMap);
}
@Override
@@ -98,7 +99,7 @@ class JedisGeoCommands implements RedisGeoCommands {
Converter<Double, Distance> distanceConverter = JedisConverters.distanceConverterForMetric(DistanceUnit.METERS);
return connection.invoke().from(BinaryJedis::geodist, MultiKeyPipelineBase::geodist, key, member1, member2)
return connection.invoke().from(Jedis::geodist, PipelineBinaryCommands::geodist, key, member1, member2)
.get(distanceConverter);
}
@@ -113,7 +114,7 @@ class JedisGeoCommands implements RedisGeoCommands {
GeoUnit geoUnit = JedisConverters.toGeoUnit(metric);
Converter<Double, Distance> distanceConverter = JedisConverters.distanceConverterForMetric(metric);
return connection.invoke().from(BinaryJedis::geodist, MultiKeyPipelineBase::geodist, key, member1, member2, geoUnit)
return connection.invoke().from(Jedis::geodist, PipelineBinaryCommands::geodist, key, member1, member2, geoUnit)
.get(distanceConverter);
}
@@ -124,7 +125,7 @@ class JedisGeoCommands implements RedisGeoCommands {
Assert.notNull(members, "Members must not be null!");
Assert.noNullElements(members, "Members must not contain null!");
return connection.invoke().fromMany(BinaryJedis::geohash, MultiKeyPipelineBase::geohash, key, members)
return connection.invoke().fromMany(Jedis::geohash, PipelineBinaryCommands::geohash, key, members)
.toList(JedisConverters::toString);
}
@@ -135,7 +136,7 @@ class JedisGeoCommands implements RedisGeoCommands {
Assert.notNull(members, "Members must not be null!");
Assert.noNullElements(members, "Members must not contain null!");
return connection.invoke().fromMany(BinaryJedis::geopos, MultiKeyPipelineBase::geopos, key, members)
return connection.invoke().fromMany(Jedis::geopos, PipelineBinaryCommands::geopos, key, members)
.toList(JedisConverters::toPoint);
}
@@ -145,11 +146,11 @@ class JedisGeoCommands implements RedisGeoCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(within, "Within must not be null!");
Converter<List<redis.clients.jedis.GeoRadiusResponse>, GeoResults<GeoLocation<byte[]>>> converter = JedisConverters
Converter<List<redis.clients.jedis.resps.GeoRadiusResponse>, GeoResults<GeoLocation<byte[]>>> converter = JedisConverters
.geoRadiusResponseToGeoResultsConverter(within.getRadius().getMetric());
return connection.invoke()
.from(BinaryJedis::georadius, MultiKeyPipelineBase::georadius, key, within.getCenter().getX(),
.from(Jedis::georadius, PipelineBinaryCommands::georadius, key, within.getCenter().getX(),
within.getCenter().getY(), within.getRadius().getValue(),
JedisConverters.toGeoUnit(within.getRadius().getMetric()))
.get(converter);
@@ -163,10 +164,10 @@ class JedisGeoCommands implements RedisGeoCommands {
Assert.notNull(args, "Args must not be null!");
redis.clients.jedis.params.GeoRadiusParam geoRadiusParam = JedisConverters.toGeoRadiusParam(args);
Converter<List<redis.clients.jedis.GeoRadiusResponse>, GeoResults<GeoLocation<byte[]>>> converter = JedisConverters
Converter<List<redis.clients.jedis.resps.GeoRadiusResponse>, GeoResults<GeoLocation<byte[]>>> converter = JedisConverters
.geoRadiusResponseToGeoResultsConverter(within.getRadius().getMetric());
return connection.invoke().from(BinaryJedis::georadius, MultiKeyPipelineBase::georadius, key,
return connection.invoke().from(Jedis::georadius, PipelineBinaryCommands::georadius, key,
within.getCenter().getX(),
within.getCenter().getY(), within.getRadius().getValue(),
JedisConverters.toGeoUnit(within.getRadius().getMetric()), geoRadiusParam)
@@ -181,10 +182,10 @@ class JedisGeoCommands implements RedisGeoCommands {
Assert.notNull(radius, "Radius must not be null!");
GeoUnit geoUnit = JedisConverters.toGeoUnit(radius.getMetric());
Converter<List<redis.clients.jedis.GeoRadiusResponse>, GeoResults<GeoLocation<byte[]>>> converter = JedisConverters
Converter<List<redis.clients.jedis.resps.GeoRadiusResponse>, GeoResults<GeoLocation<byte[]>>> converter = JedisConverters
.geoRadiusResponseToGeoResultsConverter(radius.getMetric());
return connection.invoke().from(BinaryJedis::georadiusByMember, MultiKeyPipelineBase::georadiusByMember, key,
return connection.invoke().from(Jedis::georadiusByMember, PipelineBinaryCommands::georadiusByMember, key,
member, radius.getValue(), geoUnit).get(converter);
}
@@ -198,11 +199,11 @@ class JedisGeoCommands implements RedisGeoCommands {
Assert.notNull(args, "Args must not be null!");
GeoUnit geoUnit = JedisConverters.toGeoUnit(radius.getMetric());
Converter<List<redis.clients.jedis.GeoRadiusResponse>, GeoResults<GeoLocation<byte[]>>> converter = JedisConverters
Converter<List<redis.clients.jedis.resps.GeoRadiusResponse>, GeoResults<GeoLocation<byte[]>>> converter = JedisConverters
.geoRadiusResponseToGeoResultsConverter(radius.getMetric());
redis.clients.jedis.params.GeoRadiusParam geoRadiusParam = JedisConverters.toGeoRadiusParam(args);
return connection.invoke().from(BinaryJedis::georadiusByMember, MultiKeyPipelineBase::georadiusByMember, key,
return connection.invoke().from(Jedis::georadiusByMember, PipelineBinaryCommands::georadiusByMember, key,
member, radius.getValue(), geoUnit, geoRadiusParam).get(converter);
}
@@ -214,12 +215,30 @@ class JedisGeoCommands implements RedisGeoCommands {
@Override
public GeoResults<GeoLocation<byte[]>> geoSearch(byte[] key, GeoReference<byte[]> reference, GeoShape predicate,
GeoSearchCommandArgs args) {
throw new UnsupportedOperationException("GEOSEARCH not supported through Jedis");
Assert.notNull(key, "Key must not be null!");
GeoSearchParam param = JedisConverters.toGeoSearchParams(reference, predicate, args);
Converter<List<redis.clients.jedis.resps.GeoRadiusResponse>, GeoResults<GeoLocation<byte[]>>> converter = JedisConverters
.geoRadiusResponseToGeoResultsConverter(predicate.getMetric());
return connection.invoke().from(Jedis::geosearch, PipelineBinaryCommands::geosearch, key, param).get(converter);
}
@Override
public Long geoSearchStore(byte[] destKey, byte[] key, GeoReference<byte[]> reference, GeoShape predicate,
GeoSearchStoreCommandArgs args) {
throw new UnsupportedOperationException("GEOSEARCHSTORE not supported through Jedis");
Assert.notNull(destKey, "Destination Key must not be null!");
Assert.notNull(key, "Key must not be null!");
GeoSearchParam param = JedisConverters.toGeoSearchParams(reference, predicate, args);
if (args.isStoreDistance()) {
return connection.invoke().just(Jedis::geosearchStoreStoreDist, PipelineBinaryCommands::geosearchStoreStoreDist,
destKey, key, param);
}
return connection.invoke().just(Jedis::geosearchStore, PipelineBinaryCommands::geosearchStore, destKey, key, param);
}
}

View File

@@ -15,10 +15,10 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.MultiKeyPipelineBase;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.commands.PipelineBinaryCommands;
import redis.clients.jedis.params.ScanParams;
import redis.clients.jedis.resps.ScanResult;
import java.util.ArrayList;
import java.util.List;
@@ -26,6 +26,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.redis.connection.RedisHashCommands;
import org.springframework.data.redis.connection.convert.Converters;
import org.springframework.data.redis.core.Cursor;
@@ -55,7 +56,7 @@ class JedisHashCommands implements RedisHashCommands {
Assert.notNull(field, "Field must not be null!");
Assert.notNull(value, "Value must not be null!");
return connection.invoke().from(BinaryJedis::hset, MultiKeyPipelineBase::hset, key, field, value)
return connection.invoke().from(Jedis::hset, PipelineBinaryCommands::hset, key, field, value)
.get(JedisConverters.longToBoolean());
}
@@ -66,7 +67,7 @@ class JedisHashCommands implements RedisHashCommands {
Assert.notNull(field, "Field must not be null!");
Assert.notNull(value, "Value must not be null!");
return connection.invoke().from(BinaryJedis::hsetnx, MultiKeyPipelineBase::hsetnx, key, field, value)
return connection.invoke().from(Jedis::hsetnx, PipelineBinaryCommands::hsetnx, key, field, value)
.get(JedisConverters.longToBoolean());
}
@@ -76,7 +77,7 @@ class JedisHashCommands implements RedisHashCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(fields, "Fields must not be null!");
return connection.invoke().just(BinaryJedis::hdel, MultiKeyPipelineBase::hdel, key, fields);
return connection.invoke().just(Jedis::hdel, PipelineBinaryCommands::hdel, key, fields);
}
@Override
@@ -85,7 +86,7 @@ class JedisHashCommands implements RedisHashCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(field, "Fields must not be null!");
return connection.invoke().just(BinaryJedis::hexists, MultiKeyPipelineBase::hexists, key, field);
return connection.invoke().just(Jedis::hexists, PipelineBinaryCommands::hexists, key, field);
}
@Override
@@ -94,7 +95,7 @@ class JedisHashCommands implements RedisHashCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(field, "Field must not be null!");
return connection.invoke().just(BinaryJedis::hget, MultiKeyPipelineBase::hget, key, field);
return connection.invoke().just(Jedis::hget, PipelineBinaryCommands::hget, key, field);
}
@Override
@@ -102,7 +103,7 @@ class JedisHashCommands implements RedisHashCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::hgetAll, MultiKeyPipelineBase::hgetAll, key);
return connection.invoke().just(Jedis::hgetAll, PipelineBinaryCommands::hgetAll, key);
}
@Nullable
@@ -111,7 +112,7 @@ class JedisHashCommands implements RedisHashCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::hrandfield, MultiKeyPipelineBase::hrandfield, key);
return connection.invoke().just(Jedis::hrandfield, PipelineBinaryCommands::hrandfield, key);
}
@Nullable
@@ -121,7 +122,7 @@ class JedisHashCommands implements RedisHashCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke()
.from(BinaryJedis::hrandfieldWithValues, MultiKeyPipelineBase::hrandfieldWithValues, key, 1L)
.from(Jedis::hrandfieldWithValues, PipelineBinaryCommands::hrandfieldWithValues, key, 1L)
.get(it -> it.isEmpty() ? null : it.entrySet().iterator().next());
}
@@ -131,7 +132,7 @@ class JedisHashCommands implements RedisHashCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::hrandfield, MultiKeyPipelineBase::hrandfield, key, count);
return connection.invoke().just(Jedis::hrandfield, PipelineBinaryCommands::hrandfield, key, count);
}
@Nullable
@@ -141,7 +142,7 @@ class JedisHashCommands implements RedisHashCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke()
.from(BinaryJedis::hrandfieldWithValues, MultiKeyPipelineBase::hrandfieldWithValues, key, count).get(it -> {
.from(Jedis::hrandfieldWithValues, PipelineBinaryCommands::hrandfieldWithValues, key, count).get(it -> {
List<Entry<byte[], byte[]>> entries = new ArrayList<>(it.size());
it.forEach((k, v) -> entries.add(Converters.entryOf(k, v)));
@@ -156,7 +157,7 @@ class JedisHashCommands implements RedisHashCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(field, "Field must not be null!");
return connection.invoke().just(BinaryJedis::hincrBy, MultiKeyPipelineBase::hincrBy, key, field, delta);
return connection.invoke().just(Jedis::hincrBy, PipelineBinaryCommands::hincrBy, key, field, delta);
}
@Override
@@ -165,7 +166,7 @@ class JedisHashCommands implements RedisHashCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(field, "Field must not be null!");
return connection.invoke().just(BinaryJedis::hincrByFloat, MultiKeyPipelineBase::hincrByFloat, key, field, delta);
return connection.invoke().just(Jedis::hincrByFloat, PipelineBinaryCommands::hincrByFloat, key, field, delta);
}
@Override
@@ -173,7 +174,7 @@ class JedisHashCommands implements RedisHashCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::hkeys, MultiKeyPipelineBase::hkeys, key);
return connection.invoke().just(Jedis::hkeys, PipelineBinaryCommands::hkeys, key);
}
@Override
@@ -181,7 +182,7 @@ class JedisHashCommands implements RedisHashCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::hlen, MultiKeyPipelineBase::hlen, key);
return connection.invoke().just(Jedis::hlen, PipelineBinaryCommands::hlen, key);
}
@Override
@@ -190,7 +191,7 @@ class JedisHashCommands implements RedisHashCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(fields, "Fields must not be null!");
return connection.invoke().just(BinaryJedis::hmget, MultiKeyPipelineBase::hmget, key, fields);
return connection.invoke().just(Jedis::hmget, PipelineBinaryCommands::hmget, key, fields);
}
@Override
@@ -199,7 +200,7 @@ class JedisHashCommands implements RedisHashCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(hashes, "Hashes must not be null!");
connection.invokeStatus().just(BinaryJedis::hmset, MultiKeyPipelineBase::hmset, key, hashes);
connection.invokeStatus().just(Jedis::hmset, PipelineBinaryCommands::hmset, key, hashes);
}
@Override
@@ -207,7 +208,7 @@ class JedisHashCommands implements RedisHashCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::hvals, MultiKeyPipelineBase::hvals, key);
return connection.invoke().just(Jedis::hvals, PipelineBinaryCommands::hvals, key);
}
@Override
@@ -232,7 +233,7 @@ class JedisHashCommands implements RedisHashCommands {
protected ScanIteration<Entry<byte[], byte[]>> doScan(byte[] key, long cursorId, ScanOptions options) {
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'HSCAN' cannot be called in pipeline / transaction mode.");
throw new InvalidDataAccessApiUsageException("'HSCAN' cannot be called in pipeline / transaction mode.");
}
ScanParams params = JedisConverters.toScanParams(options);
@@ -257,7 +258,7 @@ class JedisHashCommands implements RedisHashCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(field, "Field must not be null!");
return connection.invoke().just(BinaryJedis::hstrlen, MultiKeyPipelineBase::hstrlen, key, field);
return connection.invoke().just(Jedis::hstrlen, PipelineBinaryCommands::hstrlen, key, field);
}
private boolean isPipelined() {

View File

@@ -15,8 +15,8 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.MultiKeyPipelineBase;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.commands.PipelineBinaryCommands;
import org.springframework.data.redis.connection.RedisHyperLogLogCommands;
import org.springframework.util.Assert;
@@ -40,7 +40,7 @@ class JedisHyperLogLogCommands implements RedisHyperLogLogCommands {
Assert.notEmpty(values, "PFADD requires at least one non 'null' value.");
Assert.noNullElements(values, "Values for PFADD must not contain 'null'.");
return connection.invoke().just(BinaryJedis::pfadd, MultiKeyPipelineBase::pfadd, key, values);
return connection.invoke().just(Jedis::pfadd, PipelineBinaryCommands::pfadd, key, values);
}
@Override
@@ -49,7 +49,7 @@ class JedisHyperLogLogCommands implements RedisHyperLogLogCommands {
Assert.notEmpty(keys, "PFCOUNT requires at least one non 'null' key.");
Assert.noNullElements(keys, "Keys for PFCOUNT must not contain 'null'.");
return connection.invoke().just(BinaryJedis::pfcount, MultiKeyPipelineBase::pfcount, keys);
return connection.invoke().just(Jedis::pfcount, PipelineBinaryCommands::pfcount, keys);
}
@Override
@@ -59,7 +59,7 @@ class JedisHyperLogLogCommands implements RedisHyperLogLogCommands {
Assert.notNull(sourceKeys, "Source keys must not be null");
Assert.noNullElements(sourceKeys, "Keys for PFMERGE must not contain 'null'.");
connection.invoke().just(BinaryJedis::pfmerge, MultiKeyPipelineBase::pfmerge, destinationKey, sourceKeys);
connection.invoke().just(Jedis::pfmerge, PipelineBinaryCommands::pfmerge, destinationKey, sourceKeys);
}
}

View File

@@ -16,8 +16,11 @@
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.MultiKeyPipelineBase;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Response;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.commands.DatabasePipelineCommands;
import redis.clients.jedis.commands.PipelineBinaryCommands;
import java.util.ArrayList;
import java.util.Collection;
@@ -28,6 +31,7 @@ import java.util.Set;
import java.util.function.Function;
import java.util.function.Supplier;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.redis.connection.convert.Converters;
import org.springframework.lang.Nullable;
@@ -77,7 +81,7 @@ class JedisInvoker {
Assert.notNull(function, "ConnectionFunction must not be null!");
return synchronizer.invoke(function::apply, it -> {
throw new UnsupportedOperationException("Operation not supported in pipelining/transaction mode");
throw new UnsupportedOperationException("Operation not supported by Jedis in pipelining/transaction mode");
}, Converters.identityConverter(), () -> null);
}
@@ -762,7 +766,7 @@ class JedisInvoker {
}
/**
* A function accepting {@link MultiKeyPipelineBase} with 0 arguments.
* A function accepting {@link ResponseCommands} with 0 arguments.
*
* @param <R>
*/
@@ -774,11 +778,11 @@ class JedisInvoker {
*
* @param connection the connection in use. Never {@literal null}.
*/
Response<R> apply(MultiKeyPipelineBase connection);
Response<R> apply(ResponseCommands connection);
}
/**
* A function accepting {@link MultiKeyPipelineBase} with 1 argument.
* A function accepting {@link ResponseCommands} with 1 argument.
*
* @param <T1>
* @param <R>
@@ -792,11 +796,11 @@ class JedisInvoker {
* @param connection the connection in use. Never {@literal null}.
* @param t1 first argument.
*/
Response<R> apply(MultiKeyPipelineBase connection, T1 t1);
Response<R> apply(ResponseCommands connection, T1 t1);
}
/**
* A function accepting {@link MultiKeyPipelineBase} with 2 arguments.
* A function accepting {@link ResponseCommands} with 2 arguments.
*
* @param <T1>
* @param <T2>
@@ -812,11 +816,11 @@ class JedisInvoker {
* @param t1 first argument.
* @param t2 second argument.
*/
Response<R> apply(MultiKeyPipelineBase connection, T1 t1, T2 t2);
Response<R> apply(ResponseCommands connection, T1 t1, T2 t2);
}
/**
* A function accepting {@link MultiKeyPipelineBase} with 3 arguments.
* A function accepting {@link ResponseCommands} with 3 arguments.
*
* @param <T1>
* @param <T2>
@@ -834,11 +838,11 @@ class JedisInvoker {
* @param t2 second argument.
* @param t3 third argument.
*/
Response<R> apply(MultiKeyPipelineBase connection, T1 t1, T2 t2, T3 t3);
Response<R> apply(ResponseCommands connection, T1 t1, T2 t2, T3 t3);
}
/**
* A function accepting {@link MultiKeyPipelineBase} with 4 arguments.
* A function accepting {@link ResponseCommands} with 4 arguments.
*
* @param <T1>
* @param <T2>
@@ -858,11 +862,11 @@ class JedisInvoker {
* @param t3 third argument.
* @param t4 fourth argument.
*/
Response<R> apply(MultiKeyPipelineBase connection, T1 t1, T2 t2, T3 t3, T4 t4);
Response<R> apply(ResponseCommands connection, T1 t1, T2 t2, T3 t3, T4 t4);
}
/**
* A function accepting {@link MultiKeyPipelineBase} with 5 arguments.
* A function accepting {@link ResponseCommands} with 5 arguments.
*
* @param <T1>
* @param <T2>
@@ -884,11 +888,11 @@ class JedisInvoker {
* @param t4 fourth argument.
* @param t5 fifth argument.
*/
Response<R> apply(MultiKeyPipelineBase connection, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5);
Response<R> apply(ResponseCommands connection, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5);
}
/**
* A function accepting {@link MultiKeyPipelineBase} with 6 arguments.
* A function accepting {@link ResponseCommands} with 6 arguments.
*
* @param <T1>
* @param <T2>
@@ -912,17 +916,17 @@ class JedisInvoker {
* @param t5 fifth argument.
* @param t6 sixth argument.
*/
Response<R> apply(MultiKeyPipelineBase connection, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6);
Response<R> apply(ResponseCommands connection, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6);
}
static class DefaultSingleInvocationSpec<S> implements SingleInvocationSpec<S> {
private final Function<Jedis, S> parentFunction;
private final Function<MultiKeyPipelineBase, Response<S>> parentPipelineFunction;
private final Function<ResponseCommands, Response<S>> parentPipelineFunction;
private final Synchronizer synchronizer;
DefaultSingleInvocationSpec(Function<Jedis, S> parentFunction,
Function<MultiKeyPipelineBase, Response<S>> parentPipelineFunction, Synchronizer synchronizer) {
Function<ResponseCommands, Response<S>> parentPipelineFunction, Synchronizer synchronizer) {
this.parentFunction = parentFunction;
this.parentPipelineFunction = parentPipelineFunction;
@@ -950,11 +954,11 @@ class JedisInvoker {
static class DefaultManyInvocationSpec<S> implements ManyInvocationSpec<S> {
private final Function<Jedis, Collection<S>> parentFunction;
private final Function<MultiKeyPipelineBase, Response<Collection<S>>> parentPipelineFunction;
private final Function<ResponseCommands, Response<Collection<S>>> parentPipelineFunction;
private final Synchronizer synchronizer;
DefaultManyInvocationSpec(Function<Jedis, ? extends Collection<S>> parentFunction,
Function<MultiKeyPipelineBase, Response<? extends Collection<S>>> parentPipelineFunction,
Function<ResponseCommands, Response<? extends Collection<S>>> parentPipelineFunction,
Synchronizer synchronizer) {
this.parentFunction = (Function) parentFunction;
@@ -1014,14 +1018,14 @@ class JedisInvoker {
@Nullable
@SuppressWarnings({ "unchecked", "rawtypes" })
default <I, T> T invoke(Function<Jedis, I> callFunction,
Function<MultiKeyPipelineBase, Response<I>> pipelineFunction) {
Function<ResponseCommands, Response<I>> pipelineFunction) {
return (T) doInvoke((Function) callFunction, (Function) pipelineFunction, Converters.identityConverter(), () -> null);
}
@Nullable
@SuppressWarnings({ "unchecked", "rawtypes" })
default <I, T> T invoke(Function<Jedis, I> callFunction,
Function<MultiKeyPipelineBase, Response<I>> pipelineFunction, Converter<I, T> converter,
Function<ResponseCommands, Response<I>> pipelineFunction, Converter<I, T> converter,
Supplier<T> nullDefault) {
return (T) doInvoke((Function) callFunction, (Function) pipelineFunction, (Converter<Object, Object>) converter,
@@ -1030,7 +1034,27 @@ class JedisInvoker {
@Nullable
Object doInvoke(Function<Jedis, Object> callFunction,
Function<MultiKeyPipelineBase, Response<Object>> pipelineFunction, Converter<Object, Object> converter,
Function<ResponseCommands, Response<Object>> pipelineFunction, Converter<Object, Object> converter,
Supplier<Object> nullDefault);
}
interface ResponseCommands extends PipelineBinaryCommands, DatabasePipelineCommands {
Response<Long> publish(String channel, String message);
}
static ResponseCommands createCommands(Transaction transaction) {
ProxyFactory proxyFactory = new ProxyFactory(transaction);
proxyFactory.addInterface(ResponseCommands.class);
return (ResponseCommands) proxyFactory.getProxy(JedisInvoker.class.getClassLoader());
}
static ResponseCommands createCommands(Pipeline pipeline) {
ProxyFactory proxyFactory = new ProxyFactory(pipeline);
proxyFactory.addInterface(ResponseCommands.class);
return (ResponseCommands) proxyFactory.getProxy(JedisInvoker.class.getClassLoader());
}
}

View File

@@ -15,11 +15,12 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.MultiKeyPipelineBase;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import redis.clients.jedis.SortingParams;
import redis.clients.jedis.commands.JedisBinaryCommands;
import redis.clients.jedis.commands.PipelineBinaryCommands;
import redis.clients.jedis.params.RestoreParams;
import redis.clients.jedis.params.ScanParams;
import redis.clients.jedis.params.SortingParams;
import redis.clients.jedis.resps.ScanResult;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
@@ -27,6 +28,7 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.connection.RedisKeyCommands;
import org.springframework.data.redis.connection.SortParameters;
@@ -61,7 +63,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::exists, MultiKeyPipelineBase::exists, key);
return connection.invoke().just(JedisBinaryCommands::exists, PipelineBinaryCommands::exists, key);
}
@Nullable
@@ -71,7 +73,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(keys, "Keys must not be null!");
Assert.noNullElements(keys, "Keys must not contain null elements!");
return connection.invoke().just(BinaryJedis::exists, MultiKeyPipelineBase::exists, keys);
return connection.invoke().just(JedisBinaryCommands::exists, PipelineBinaryCommands::exists, keys);
}
@Override
@@ -80,7 +82,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(keys, "Keys must not be null!");
Assert.noNullElements(keys, "Keys must not contain null elements!");
return connection.invoke().just(BinaryJedis::del, MultiKeyPipelineBase::del, keys);
return connection.invoke().just(JedisBinaryCommands::del, PipelineBinaryCommands::del, keys);
}
public Boolean copy(byte[] sourceKey, byte[] targetKey, boolean replace) {
@@ -88,7 +90,8 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(sourceKey, "source key must not be null!");
Assert.notNull(targetKey, "target key must not be null!");
return connection.invoke().just(BinaryJedis::copy, MultiKeyPipelineBase::copy, sourceKey, targetKey, replace);
return connection.invoke().just(JedisBinaryCommands::copy, PipelineBinaryCommands::copy, sourceKey, targetKey,
replace);
}
@Nullable
@@ -97,7 +100,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(keys, "Keys must not be null!");
return connection.invoke().just(BinaryJedis::unlink, MultiKeyPipelineBase::unlink, keys);
return connection.invoke().just(JedisBinaryCommands::unlink, PipelineBinaryCommands::unlink, keys);
}
@Override
@@ -105,7 +108,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().from(BinaryJedis::type, MultiKeyPipelineBase::type, key)
return connection.invoke().from(JedisBinaryCommands::type, PipelineBinaryCommands::type, key)
.get(JedisConverters.stringToDataType());
}
@@ -115,7 +118,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(keys, "Keys must not be null!");
return connection.invoke().just(BinaryJedis::touch, MultiKeyPipelineBase::touch, keys);
return connection.invoke().just(JedisBinaryCommands::touch, PipelineBinaryCommands::touch, keys);
}
@Override
@@ -123,7 +126,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(pattern, "Pattern must not be null!");
return connection.invoke().just(BinaryJedis::keys, MultiKeyPipelineBase::keys, pattern);
return connection.invoke().just(JedisBinaryCommands::keys, PipelineBinaryCommands::keys, pattern);
}
@Override
@@ -145,7 +148,7 @@ class JedisKeyCommands implements RedisKeyCommands {
protected ScanIteration<byte[]> doScan(long cursorId, ScanOptions options) {
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'SCAN' cannot be called in pipeline / transaction mode.");
throw new InvalidDataAccessApiUsageException("'SCAN' cannot be called in pipeline / transaction mode.");
}
ScanParams params = JedisConverters.toScanParams(options);
@@ -180,7 +183,7 @@ class JedisKeyCommands implements RedisKeyCommands {
@Override
public byte[] randomKey() {
return connection.invoke().just(BinaryJedis::randomBinaryKey, MultiKeyPipelineBase::randomKeyBinary);
return connection.invoke().just(JedisBinaryCommands::randomBinaryKey, PipelineBinaryCommands::randomBinaryKey);
}
@Override
@@ -189,7 +192,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(oldKey, "Old key must not be null!");
Assert.notNull(newKey, "New key must not be null!");
connection.invokeStatus().just(BinaryJedis::rename, MultiKeyPipelineBase::rename, oldKey, newKey);
connection.invokeStatus().just(JedisBinaryCommands::rename, PipelineBinaryCommands::rename, oldKey, newKey);
}
@Override
@@ -198,7 +201,8 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(sourceKey, "Source key must not be null!");
Assert.notNull(targetKey, "Target key must not be null!");
return connection.invoke().from(BinaryJedis::renamenx, MultiKeyPipelineBase::renamenx, sourceKey, targetKey)
return connection.invoke()
.from(JedisBinaryCommands::renamenx, PipelineBinaryCommands::renamenx, sourceKey, targetKey)
.get(JedisConverters.longToBoolean());
}
@@ -211,7 +215,7 @@ class JedisKeyCommands implements RedisKeyCommands {
return pExpire(key, TimeUnit.SECONDS.toMillis(seconds));
}
return connection.invoke().from(BinaryJedis::expire, MultiKeyPipelineBase::expire, key, (int) seconds)
return connection.invoke().from(JedisBinaryCommands::expire, PipelineBinaryCommands::expire, key, seconds)
.get(JedisConverters.longToBoolean());
}
@@ -220,7 +224,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().from(BinaryJedis::pexpire, MultiKeyPipelineBase::pexpire, key, millis)
return connection.invoke().from(JedisBinaryCommands::pexpire, PipelineBinaryCommands::pexpire, key, millis)
.get(JedisConverters.longToBoolean());
}
@@ -229,7 +233,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().from(BinaryJedis::expireAt, MultiKeyPipelineBase::expireAt, key, unixTime)
return connection.invoke().from(JedisBinaryCommands::expireAt, PipelineBinaryCommands::expireAt, key, unixTime)
.get(JedisConverters.longToBoolean());
}
@@ -238,7 +242,8 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().from(BinaryJedis::pexpireAt, MultiKeyPipelineBase::pexpireAt, key, unixTimeInMillis)
return connection.invoke()
.from(JedisBinaryCommands::pexpireAt, PipelineBinaryCommands::pexpireAt, key, unixTimeInMillis)
.get(JedisConverters.longToBoolean());
}
@@ -247,7 +252,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().from(BinaryJedis::persist, MultiKeyPipelineBase::persist, key)
return connection.invoke().from(JedisBinaryCommands::persist, PipelineBinaryCommands::persist, key)
.get(JedisConverters.longToBoolean());
}
@@ -256,7 +261,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().from(BinaryJedis::move, MultiKeyPipelineBase::move, key, dbIndex)
return connection.invoke().from(j -> j.move(key, dbIndex))
.get(JedisConverters.longToBoolean());
}
@@ -265,7 +270,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::ttl, MultiKeyPipelineBase::ttl, key);
return connection.invoke().just(JedisBinaryCommands::ttl, PipelineBinaryCommands::ttl, key);
}
@Override
@@ -273,7 +278,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().from(BinaryJedis::ttl, MultiKeyPipelineBase::ttl, key)
return connection.invoke().from(JedisBinaryCommands::ttl, PipelineBinaryCommands::ttl, key)
.get(Converters.secondsToTimeUnit(timeUnit));
}
@@ -282,7 +287,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::pttl, MultiKeyPipelineBase::pttl, key);
return connection.invoke().just(JedisBinaryCommands::pttl, PipelineBinaryCommands::pttl, key);
}
@Override
@@ -290,7 +295,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().from(BinaryJedis::pttl, MultiKeyPipelineBase::pttl, key)
return connection.invoke().from(JedisBinaryCommands::pttl, PipelineBinaryCommands::pttl, key)
.get(Converters.millisecondsToTimeUnit(timeUnit));
}
@@ -302,10 +307,10 @@ class JedisKeyCommands implements RedisKeyCommands {
SortingParams sortParams = JedisConverters.toSortingParams(params);
if (sortParams != null) {
return connection.invoke().just(BinaryJedis::sort, MultiKeyPipelineBase::sort, key, sortParams);
return connection.invoke().just(JedisBinaryCommands::sort, PipelineBinaryCommands::sort, key, sortParams);
}
return connection.invoke().just(BinaryJedis::sort, MultiKeyPipelineBase::sort, key);
return connection.invoke().just(JedisBinaryCommands::sort, PipelineBinaryCommands::sort, key);
}
@Override
@@ -316,10 +321,11 @@ class JedisKeyCommands implements RedisKeyCommands {
SortingParams sortParams = JedisConverters.toSortingParams(params);
if (sortParams != null) {
return connection.invoke().just(BinaryJedis::sort, MultiKeyPipelineBase::sort, key, sortParams, storeKey);
return connection.invoke().just(JedisBinaryCommands::sort, PipelineBinaryCommands::sort, key, sortParams,
storeKey);
}
return connection.invoke().just(BinaryJedis::sort, MultiKeyPipelineBase::sort, key, storeKey);
return connection.invoke().just(JedisBinaryCommands::sort, PipelineBinaryCommands::sort, key, storeKey);
}
@Override
@@ -327,7 +333,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::dump, MultiKeyPipelineBase::dump, key);
return connection.invoke().just(JedisBinaryCommands::dump, PipelineBinaryCommands::dump, key);
}
@Override
@@ -338,8 +344,8 @@ class JedisKeyCommands implements RedisKeyCommands {
if (replace) {
connection.invokeStatus().just(BinaryJedis::restoreReplace, MultiKeyPipelineBase::restoreReplace, key,
(int) ttlInMillis, serializedValue);
connection.invokeStatus().just(JedisBinaryCommands::restore, PipelineBinaryCommands::restore, key,
(int) ttlInMillis, serializedValue, RestoreParams.restoreParams().replace());
return;
}
@@ -347,7 +353,8 @@ class JedisKeyCommands implements RedisKeyCommands {
throw new IllegalArgumentException("TtlInMillis must be less than Integer.MAX_VALUE for restore in Jedis.");
}
connection.invokeStatus().just(BinaryJedis::restore, MultiKeyPipelineBase::restore, key, (int) ttlInMillis,
connection.invokeStatus().just(JedisBinaryCommands::restore, PipelineBinaryCommands::restore, key,
(int) ttlInMillis,
serializedValue);
}
@@ -357,7 +364,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().from(BinaryJedis::objectEncoding, MultiKeyPipelineBase::objectEncoding, key)
return connection.invoke().from(JedisBinaryCommands::objectEncoding, PipelineBinaryCommands::objectEncoding, key)
.getOrElse(JedisConverters::toEncoding, () -> RedisValueEncoding.VACANT);
}
@@ -367,7 +374,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().from(BinaryJedis::objectIdletime, MultiKeyPipelineBase::objectIdletime, key)
return connection.invoke().from(JedisBinaryCommands::objectIdletime, PipelineBinaryCommands::objectIdletime, key)
.get(Converters::secondsToDuration);
}
@@ -377,7 +384,7 @@ class JedisKeyCommands implements RedisKeyCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::objectRefcount, MultiKeyPipelineBase::objectRefcount, key);
return connection.invoke().just(JedisBinaryCommands::objectRefcount, PipelineBinaryCommands::objectRefcount, key);
}
private boolean isPipelined() {

View File

@@ -15,10 +15,9 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.MultiKeyPipelineBase;
import redis.clients.jedis.Protocol;
import redis.clients.jedis.args.ListDirection;
import redis.clients.jedis.commands.JedisBinaryCommands;
import redis.clients.jedis.commands.PipelineBinaryCommands;
import redis.clients.jedis.params.LPosParams;
import java.util.Collections;
@@ -47,7 +46,7 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::rpush, MultiKeyPipelineBase::rpush, key, values);
return connection.invoke().just(JedisBinaryCommands::rpush, PipelineBinaryCommands::rpush, key, values);
}
@Override
@@ -62,10 +61,11 @@ class JedisListCommands implements RedisListCommands {
}
if (count != null) {
return connection.invoke().just(BinaryJedis::lpos, MultiKeyPipelineBase::lpos, key, element, params, count);
return connection.invoke().just(JedisBinaryCommands::lpos, PipelineBinaryCommands::lpos, key, element, params,
count);
}
return connection.invoke().from(BinaryJedis::lpos, MultiKeyPipelineBase::lpos, key, element, params)
return connection.invoke().from(JedisBinaryCommands::lpos, PipelineBinaryCommands::lpos, key, element, params)
.getOrElse(Collections::singletonList, Collections::emptyList);
}
@@ -76,7 +76,7 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(values, "Values must not be null!");
Assert.noNullElements(values, "Values must not contain null elements!");
return connection.invoke().just(BinaryJedis::lpush, MultiKeyPipelineBase::lpush, key, values);
return connection.invoke().just(JedisBinaryCommands::lpush, PipelineBinaryCommands::lpush, key, values);
}
@Override
@@ -85,7 +85,7 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
return connection.invoke().just(BinaryJedis::rpushx, MultiKeyPipelineBase::rpushx, key, value);
return connection.invoke().just(JedisBinaryCommands::rpushx, PipelineBinaryCommands::rpushx, key, value);
}
@Override
@@ -94,7 +94,7 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
return connection.invoke().just(BinaryJedis::lpushx, MultiKeyPipelineBase::lpushx, key, value);
return connection.invoke().just(JedisBinaryCommands::lpushx, PipelineBinaryCommands::lpushx, key, value);
}
@Override
@@ -102,7 +102,7 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::llen, MultiKeyPipelineBase::llen, key);
return connection.invoke().just(JedisBinaryCommands::llen, PipelineBinaryCommands::llen, key);
}
@Override
@@ -110,7 +110,7 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::lrange, MultiKeyPipelineBase::lrange, key, start, end);
return connection.invoke().just(JedisBinaryCommands::lrange, PipelineBinaryCommands::lrange, key, start, end);
}
@Override
@@ -118,7 +118,7 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(key, "Key must not be null!");
connection.invokeStatus().just(BinaryJedis::ltrim, MultiKeyPipelineBase::ltrim, key, start, end);
connection.invokeStatus().just(JedisBinaryCommands::ltrim, PipelineBinaryCommands::ltrim, key, start, end);
}
@Override
@@ -126,7 +126,7 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::lindex, MultiKeyPipelineBase::lindex, key, index);
return connection.invoke().just(JedisBinaryCommands::lindex, PipelineBinaryCommands::lindex, key, index);
}
@Override
@@ -134,7 +134,7 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::linsert, MultiKeyPipelineBase::linsert, key,
return connection.invoke().just(JedisBinaryCommands::linsert, PipelineBinaryCommands::linsert, key,
JedisConverters.toListPosition(where), pivot, value);
}
@@ -146,7 +146,8 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(from, "From direction must not be null!");
Assert.notNull(to, "To direction must not be null!");
return connection.invoke().just(BinaryJedis::lmove, MultiKeyPipelineBase::lmove, sourceKey, destinationKey,
return connection.invoke().just(JedisBinaryCommands::lmove, PipelineBinaryCommands::lmove, sourceKey,
destinationKey,
ListDirection.valueOf(from.name()), ListDirection.valueOf(to.name()));
}
@@ -158,7 +159,8 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(from, "From direction must not be null!");
Assert.notNull(to, "To direction must not be null!");
return connection.invoke().just(BinaryJedis::blmove, MultiKeyPipelineBase::blmove, sourceKey, destinationKey,
return connection.invoke().just(JedisBinaryCommands::blmove, PipelineBinaryCommands::blmove, sourceKey,
destinationKey,
ListDirection.valueOf(from.name()), ListDirection.valueOf(to.name()), timeout);
}
@@ -168,7 +170,7 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
connection.invokeStatus().just(BinaryJedis::lset, MultiKeyPipelineBase::lset, key, index, value);
connection.invokeStatus().just(JedisBinaryCommands::lset, PipelineBinaryCommands::lset, key, index, value);
}
@Override
@@ -177,7 +179,7 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
return connection.invoke().just(BinaryJedis::lrem, MultiKeyPipelineBase::lrem, key, count, value);
return connection.invoke().just(JedisBinaryCommands::lrem, PipelineBinaryCommands::lrem, key, count, value);
}
@Override
@@ -185,7 +187,7 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::lpop, MultiKeyPipelineBase::lpop, key);
return connection.invoke().just(JedisBinaryCommands::lpop, PipelineBinaryCommands::lpop, key);
}
@Override
@@ -193,7 +195,7 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::lpop, MultiKeyPipelineBase::lpop, key, (int) count);
return connection.invoke().just(JedisBinaryCommands::lpop, PipelineBinaryCommands::lpop, key, (int) count);
}
@Override
@@ -201,7 +203,7 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::rpop, MultiKeyPipelineBase::rpop, key);
return connection.invoke().just(JedisBinaryCommands::rpop, PipelineBinaryCommands::rpop, key);
}
@Override
@@ -209,7 +211,7 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::rpop, MultiKeyPipelineBase::rpop, key, (int) count);
return connection.invoke().just(JedisBinaryCommands::rpop, PipelineBinaryCommands::rpop, key, (int) count);
}
@Override
@@ -218,7 +220,7 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(keys, "Key must not be null!");
Assert.noNullElements(keys, "Keys must not contain null elements!");
return connection.invoke().just(BinaryJedis::blpop, MultiKeyPipelineBase::blpop, bXPopArgs(timeout, keys));
return connection.invoke().just(j -> j.blpop(timeout, keys), j -> j.blpop(timeout, keys));
}
@Override
@@ -227,7 +229,7 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(keys, "Key must not be null!");
Assert.noNullElements(keys, "Keys must not contain null elements!");
return connection.invoke().just(BinaryJedis::brpop, MultiKeyPipelineBase::brpop, bXPopArgs(timeout, keys));
return connection.invoke().just(j -> j.brpop(timeout, keys), j -> j.brpop(timeout, keys));
}
@Override
@@ -236,7 +238,7 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(srcKey, "Source key must not be null!");
Assert.notNull(dstKey, "Destination key must not be null!");
return connection.invoke().just(BinaryJedis::rpoplpush, MultiKeyPipelineBase::rpoplpush, srcKey, dstKey);
return connection.invoke().just(JedisBinaryCommands::rpoplpush, PipelineBinaryCommands::rpoplpush, srcKey, dstKey);
}
@Override
@@ -245,16 +247,8 @@ class JedisListCommands implements RedisListCommands {
Assert.notNull(srcKey, "Source key must not be null!");
Assert.notNull(dstKey, "Destination key must not be null!");
return connection.invoke().just(BinaryJedis::brpoplpush, MultiKeyPipelineBase::brpoplpush, srcKey, dstKey, timeout);
}
private static byte[][] bXPopArgs(int timeout, byte[]... keys) {
byte[][] args = new byte[keys.length + 1][];
System.arraycopy(keys, 0, args, 0, keys.length);
args[args.length - 1] = Protocol.toByteArray(timeout);
return args;
return connection.invoke().just(JedisBinaryCommands::brpoplpush, PipelineBinaryCommands::brpoplpush, srcKey, dstKey,
timeout);
}
}

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.Jedis;
import java.util.List;
@@ -40,7 +40,7 @@ class JedisScriptingCommands implements RedisScriptingCommands {
assertDirectMode();
connection.invoke().just(BinaryJedis::scriptFlush);
connection.invoke().just(Jedis::scriptFlush);
}
@Override
@@ -48,7 +48,7 @@ class JedisScriptingCommands implements RedisScriptingCommands {
assertDirectMode();
connection.invoke().just(BinaryJedis::scriptKill);
connection.invoke().just(Jedis::scriptKill);
}
@Override
@@ -78,7 +78,7 @@ class JedisScriptingCommands implements RedisScriptingCommands {
assertDirectMode();
JedisScriptReturnConverter converter = new JedisScriptReturnConverter(returnType);
return (T) connection.invoke().from(it -> it.eval(script, JedisConverters.toBytes(numKeys), keysAndArgs))
return (T) connection.invoke().from(it -> it.eval(script, numKeys, keysAndArgs))
.getOrElse(converter, () -> converter.convert(null));
}

View File

@@ -15,9 +15,7 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.MultiKeyPipelineBase;
import redis.clients.jedis.args.SaveMode;
import java.util.List;
@@ -46,32 +44,32 @@ class JedisServerCommands implements RedisServerCommands {
@Override
public void bgReWriteAof() {
connection.invoke().just(BinaryJedis::bgrewriteaof, MultiKeyPipelineBase::bgrewriteaof);
connection.invoke().just(Jedis::bgrewriteaof);
}
@Override
public void bgSave() {
connection.invokeStatus().just(BinaryJedis::bgsave, MultiKeyPipelineBase::bgsave);
connection.invokeStatus().just(Jedis::bgsave);
}
@Override
public Long lastSave() {
return connection.invoke().just(BinaryJedis::lastsave, MultiKeyPipelineBase::lastsave);
return connection.invoke().just(Jedis::lastsave);
}
@Override
public void save() {
connection.invokeStatus().just(BinaryJedis::save, MultiKeyPipelineBase::save);
connection.invokeStatus().just(Jedis::save);
}
@Override
public Long dbSize() {
return connection.invoke().just(BinaryJedis::dbSize, MultiKeyPipelineBase::dbSize);
return connection.invoke().just(Jedis::dbSize);
}
@Override
public void flushDb() {
connection.invokeStatus().just(BinaryJedis::flushDB, MultiKeyPipelineBase::flushDB);
connection.invokeStatus().just(Jedis::flushDB);
}
@Override
@@ -82,7 +80,7 @@ class JedisServerCommands implements RedisServerCommands {
@Override
public void flushAll() {
connection.invokeStatus().just(BinaryJedis::flushAll, MultiKeyPipelineBase::flushAll);
connection.invokeStatus().just(Jedis::flushAll);
}
@Override
@@ -93,7 +91,7 @@ class JedisServerCommands implements RedisServerCommands {
@Override
public Properties info() {
return connection.invoke().from(BinaryJedis::info, MultiKeyPipelineBase::info).get(JedisConverters::toProperties);
return connection.invoke().from(Jedis::info).get(JedisConverters::toProperties);
}
@Override
@@ -101,13 +99,16 @@ class JedisServerCommands implements RedisServerCommands {
Assert.notNull(section, "Section must not be null!");
return connection.invoke().from(BinaryJedis::info, MultiKeyPipelineBase::info, section)
return connection.invoke().from(j -> j.info(section))
.get(JedisConverters::toProperties);
}
@Override
public void shutdown() {
connection.invokeStatus().just(BinaryJedis::shutdown, MultiKeyPipelineBase::shutdown);
connection.invokeStatus().just(jedis -> {
jedis.shutdown();
return null;
});
}
@Override
@@ -128,7 +129,7 @@ class JedisServerCommands implements RedisServerCommands {
Assert.notNull(pattern, "Pattern must not be null!");
return connection.invoke().from(Jedis::configGet, MultiKeyPipelineBase::configGet, pattern)
return connection.invoke().from(j -> j.configGet(pattern))
.get(Converters::toProperties);
}
@@ -138,12 +139,12 @@ class JedisServerCommands implements RedisServerCommands {
Assert.notNull(param, "Parameter must not be null!");
Assert.notNull(value, "Value must not be null!");
connection.invokeStatus().just(Jedis::configSet, MultiKeyPipelineBase::configSet, param, value);
connection.invokeStatus().just(j -> j.configSet(param, value));
}
@Override
public void resetConfigStats() {
connection.invokeStatus().just(BinaryJedis::configResetStat, MultiKeyPipelineBase::configResetStat);
connection.invokeStatus().just(Jedis::configResetStat);
}
@Override
@@ -156,7 +157,7 @@ class JedisServerCommands implements RedisServerCommands {
Assert.notNull(timeUnit, "TimeUnit must not be null.");
return connection.invoke().from(BinaryJedis::time, MultiKeyPipelineBase::time)
return connection.invoke().from(Jedis::time)
.get((List<String> source) -> JedisConverters.toTime(source, timeUnit));
}
@@ -223,7 +224,7 @@ class JedisServerCommands implements RedisServerCommands {
throw new UnsupportedOperationException("'REPLICAOF' cannot be called in pipeline / transaction mode.");
}
connection.invokeStatus().just(BinaryJedis::slaveofNoOne);
connection.invokeStatus().just(Jedis::slaveofNoOne);
}
@Override
@@ -239,8 +240,7 @@ class JedisServerCommands implements RedisServerCommands {
int timeoutToUse = timeout <= Integer.MAX_VALUE ? (int) timeout : Integer.MAX_VALUE;
connection.invokeStatus().just(BinaryJedis::migrate, MultiKeyPipelineBase::migrate, target.getHost(),
target.getPort(), key, dbIndex, timeoutToUse);
connection.invokeStatus().just(j -> j.migrate(target.getHost(), target.getPort(), key, dbIndex, timeoutToUse));
}
private boolean isPipelined() {

View File

@@ -15,14 +15,16 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.MultiKeyPipelineBase;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.commands.PipelineBinaryCommands;
import redis.clients.jedis.params.ScanParams;
import redis.clients.jedis.resps.ScanResult;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.redis.connection.RedisSetCommands;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.KeyBoundCursor;
@@ -50,7 +52,7 @@ class JedisSetCommands implements RedisSetCommands {
Assert.notNull(values, "Values must not be null!");
Assert.noNullElements(values, "Values must not contain null elements!");
return connection.invoke().just(BinaryJedis::sadd, MultiKeyPipelineBase::sadd, key, values);
return connection.invoke().just(Jedis::sadd, PipelineBinaryCommands::sadd, key, values);
}
@Override
@@ -58,7 +60,7 @@ class JedisSetCommands implements RedisSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::scard, MultiKeyPipelineBase::scard, key);
return connection.invoke().just(Jedis::scard, PipelineBinaryCommands::scard, key);
}
@Override
@@ -67,7 +69,7 @@ class JedisSetCommands implements RedisSetCommands {
Assert.notNull(keys, "Keys must not be null!");
Assert.noNullElements(keys, "Keys must not contain null elements!");
return connection.invoke().just(BinaryJedis::sdiff, MultiKeyPipelineBase::sdiff, keys);
return connection.invoke().just(Jedis::sdiff, PipelineBinaryCommands::sdiff, keys);
}
@Override
@@ -77,7 +79,7 @@ class JedisSetCommands implements RedisSetCommands {
Assert.notNull(keys, "Source keys must not be null!");
Assert.noNullElements(keys, "Source keys must not contain null elements!");
return connection.invoke().just(BinaryJedis::sdiffstore, MultiKeyPipelineBase::sdiffstore, destKey, keys);
return connection.invoke().just(Jedis::sdiffstore, PipelineBinaryCommands::sdiffstore, destKey, keys);
}
@Override
@@ -86,7 +88,7 @@ class JedisSetCommands implements RedisSetCommands {
Assert.notNull(keys, "Keys must not be null!");
Assert.noNullElements(keys, "Keys must not contain null elements!");
return connection.invoke().just(BinaryJedis::sinter, MultiKeyPipelineBase::sinter, keys);
return connection.invoke().just(Jedis::sinter, PipelineBinaryCommands::sinter, keys);
}
@Override
@@ -96,7 +98,7 @@ class JedisSetCommands implements RedisSetCommands {
Assert.notNull(keys, "Source keys must not be null!");
Assert.noNullElements(keys, "Source keys must not contain null elements!");
return connection.invoke().just(BinaryJedis::sinterstore, MultiKeyPipelineBase::sinterstore, destKey, keys);
return connection.invoke().just(Jedis::sinterstore, PipelineBinaryCommands::sinterstore, destKey, keys);
}
@Override
@@ -105,7 +107,7 @@ class JedisSetCommands implements RedisSetCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
return connection.invoke().just(BinaryJedis::sismember, MultiKeyPipelineBase::sismember, key, value);
return connection.invoke().just(Jedis::sismember, PipelineBinaryCommands::sismember, key, value);
}
@Override
@@ -115,7 +117,7 @@ class JedisSetCommands implements RedisSetCommands {
Assert.notNull(values, "Values must not be null!");
Assert.noNullElements(values, "Values must not contain null elements!");
return connection.invoke().just(BinaryJedis::smismember, MultiKeyPipelineBase::smismember, key, values);
return connection.invoke().just(Jedis::smismember, PipelineBinaryCommands::smismember, key, values);
}
@Override
@@ -123,7 +125,7 @@ class JedisSetCommands implements RedisSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::smembers, MultiKeyPipelineBase::smembers, key);
return connection.invoke().just(Jedis::smembers, PipelineBinaryCommands::smembers, key);
}
@Override
@@ -133,7 +135,7 @@ class JedisSetCommands implements RedisSetCommands {
Assert.notNull(destKey, "Destination key must not be null!");
Assert.notNull(value, "Value must not be null!");
return connection.invoke().from(BinaryJedis::smove, MultiKeyPipelineBase::smove, srcKey, destKey, value)
return connection.invoke().from(Jedis::smove, PipelineBinaryCommands::smove, srcKey, destKey, value)
.get(JedisConverters::toBoolean);
}
@@ -142,7 +144,7 @@ class JedisSetCommands implements RedisSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::spop, MultiKeyPipelineBase::spop, key);
return connection.invoke().just(Jedis::spop, PipelineBinaryCommands::spop, key);
}
@Override
@@ -150,7 +152,7 @@ class JedisSetCommands implements RedisSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().from(BinaryJedis::spop, MultiKeyPipelineBase::spop, key, count).get(ArrayList::new);
return connection.invoke().from(Jedis::spop, PipelineBinaryCommands::spop, key, count).get(ArrayList::new);
}
@Override
@@ -158,7 +160,7 @@ class JedisSetCommands implements RedisSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::srandmember, MultiKeyPipelineBase::srandmember, key);
return connection.invoke().just(Jedis::srandmember, PipelineBinaryCommands::srandmember, key);
}
@Override
@@ -170,7 +172,7 @@ class JedisSetCommands implements RedisSetCommands {
throw new IllegalArgumentException("Count must be less than Integer.MAX_VALUE for sRandMember in Jedis.");
}
return connection.invoke().just(BinaryJedis::srandmember, MultiKeyPipelineBase::srandmember, key, (int) count);
return connection.invoke().just(Jedis::srandmember, PipelineBinaryCommands::srandmember, key, (int) count);
}
@Override
@@ -180,7 +182,7 @@ class JedisSetCommands implements RedisSetCommands {
Assert.notNull(values, "Values must not be null!");
Assert.noNullElements(values, "Values must not contain null elements!");
return connection.invoke().just(BinaryJedis::srem, MultiKeyPipelineBase::srem, key, values);
return connection.invoke().just(Jedis::srem, PipelineBinaryCommands::srem, key, values);
}
@Override
@@ -189,7 +191,7 @@ class JedisSetCommands implements RedisSetCommands {
Assert.notNull(keys, "Keys must not be null!");
Assert.noNullElements(keys, "Keys must not contain null elements!");
return connection.invoke().just(BinaryJedis::sunion, MultiKeyPipelineBase::sunion, keys);
return connection.invoke().just(Jedis::sunion, PipelineBinaryCommands::sunion, keys);
}
@Override
@@ -199,7 +201,7 @@ class JedisSetCommands implements RedisSetCommands {
Assert.notNull(keys, "Source keys must not be null!");
Assert.noNullElements(keys, "Source keys must not contain null elements!");
return connection.invoke().just(BinaryJedis::sunionstore, MultiKeyPipelineBase::sunionstore, destKey, keys);
return connection.invoke().just(Jedis::sunionstore, PipelineBinaryCommands::sunionstore, destKey, keys);
}
@Override
@@ -224,12 +226,12 @@ class JedisSetCommands implements RedisSetCommands {
protected ScanIteration<byte[]> doScan(byte[] key, long cursorId, ScanOptions options) {
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'SSCAN' cannot be called in pipeline / transaction mode.");
throw new InvalidDataAccessApiUsageException("'SSCAN' cannot be called in pipeline / transaction mode.");
}
ScanParams params = JedisConverters.toScanParams(options);
redis.clients.jedis.ScanResult<byte[]> result = connection.getJedis().sscan(key,
ScanResult<byte[]> result = connection.getJedis().sscan(key,
JedisConverters.toBytes(cursorId), params);
return new ScanIteration<>(Long.valueOf(result.getCursor()), result.getResult());
}

View File

@@ -15,12 +15,17 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.BuilderFactory;
import redis.clients.jedis.MultiKeyPipelineBase;
import redis.clients.jedis.StreamConsumersInfo;
import redis.clients.jedis.StreamGroupInfo;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.commands.PipelineBinaryCommands;
import redis.clients.jedis.commands.StreamPipelineBinaryCommands;
import redis.clients.jedis.params.XAddParams;
import redis.clients.jedis.params.XClaimParams;
import redis.clients.jedis.params.XPendingParams;
import redis.clients.jedis.params.XReadGroupParams;
import redis.clients.jedis.params.XReadParams;
import redis.clients.jedis.resps.StreamConsumersInfo;
import redis.clients.jedis.resps.StreamGroupInfo;
import java.util.ArrayList;
import java.util.Arrays;
@@ -30,6 +35,7 @@ import java.util.List;
import org.springframework.data.domain.Range;
import org.springframework.data.redis.connection.Limit;
import org.springframework.data.redis.connection.RedisStreamCommands;
import org.springframework.data.redis.connection.jedis.JedisInvoker.ResponseCommands;
import org.springframework.data.redis.connection.stream.ByteRecord;
import org.springframework.data.redis.connection.stream.Consumer;
import org.springframework.data.redis.connection.stream.MapRecord;
@@ -61,7 +67,7 @@ class JedisStreamCommands implements RedisStreamCommands {
Assert.hasText(group, "Group name must not be null or empty!");
Assert.notNull(recordIds, "recordIds must not be null!");
return connection.invoke().just(BinaryJedis::xack, MultiKeyPipelineBase::xack, key, JedisConverters.toBytes(group),
return connection.invoke().just(Jedis::xack, PipelineBinaryCommands::xack, key, JedisConverters.toBytes(group),
StreamConverters.entryIdsToBytes(Arrays.asList(recordIds)));
}
@@ -74,13 +80,24 @@ class JedisStreamCommands implements RedisStreamCommands {
XAddParams params = StreamConverters.toXAddParams(record, options);
return connection.invoke()
.from(BinaryJedis::xadd, MultiKeyPipelineBase::xadd, record.getStream(), record.getValue(), params)
.from(Jedis::xadd, PipelineBinaryCommands::xadd, record.getStream(), record.getValue(), params)
.get(it -> RecordId.of(JedisConverters.toString(it)));
}
@Override
public List<RecordId> xClaimJustId(byte[] key, String group, String newOwner, XClaimOptions options) {
throw new UnsupportedOperationException("Jedis does not support xClaimJustId.");
Assert.notNull(key, "Key must not be null!");
Assert.notNull(group, "Group must not be null!");
Assert.notNull(newOwner, "NewOwner must not be null!");
XClaimParams params = StreamConverters.toXClaimParams(options);
return connection.invoke()
.fromMany(Jedis::xclaimJustId, ResponseCommands::xclaimJustId, key, JedisConverters.toBytes(group),
JedisConverters.toBytes(newOwner), options.getMinIdleTime().toMillis(), params,
StreamConverters.entryIdsToBytes(options.getIds()))
.toList(it -> RecordId.of(JedisConverters.toString(it)));
}
@Override
@@ -90,16 +107,13 @@ class JedisStreamCommands implements RedisStreamCommands {
Assert.notNull(group, "Group must not be null!");
Assert.notNull(newOwner, "NewOwner must not be null!");
long minIdleTime = options.getMinIdleTime() == null ? -1L : options.getMinIdleTime().toMillis();
int retryCount = options.getRetryCount() == null ? -1 : options.getRetryCount().intValue();
long unixTime = options.getUnixTime() == null ? -1L : options.getUnixTime().toEpochMilli();
XClaimParams params = StreamConverters.toXClaimParams(options);
return connection.invoke()
.from(
it -> it.xclaim(key, JedisConverters.toBytes(group), JedisConverters.toBytes(newOwner), minIdleTime,
unixTime, retryCount, options.isForce(), StreamConverters.entryIdsToBytes(options.getIds())),
it -> it.xclaim(key, JedisConverters.toBytes(group), JedisConverters.toBytes(newOwner), minIdleTime,
unixTime, retryCount, options.isForce(), StreamConverters.entryIdsToBytes(options.getIds())))
Jedis::xclaim, ResponseCommands::xclaim, key, JedisConverters.toBytes(group),
JedisConverters.toBytes(newOwner), options.getMinIdleTime().toMillis(), params,
StreamConverters.entryIdsToBytes(options.getIds()))
.get(r -> StreamConverters.convertToByteRecord(key, r));
}
@@ -109,7 +123,7 @@ class JedisStreamCommands implements RedisStreamCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(recordIds, "recordIds must not be null!");
return connection.invoke().just(BinaryJedis::xdel, MultiKeyPipelineBase::xdel, key,
return connection.invoke().just(Jedis::xdel, PipelineBinaryCommands::xdel, key,
StreamConverters.entryIdsToBytes(Arrays.asList(recordIds)));
}
@@ -125,7 +139,7 @@ class JedisStreamCommands implements RedisStreamCommands {
Assert.hasText(groupName, "Group name must not be null or empty!");
Assert.notNull(readOffset, "ReadOffset must not be null!");
return connection.invoke().just(BinaryJedis::xgroupCreate, MultiKeyPipelineBase::xgroupCreate, key,
return connection.invoke().just(Jedis::xgroupCreate, PipelineBinaryCommands::xgroupCreate, key,
JedisConverters.toBytes(groupName), JedisConverters.toBytes(readOffset.getOffset()), mkStream);
}
@@ -135,7 +149,7 @@ class JedisStreamCommands implements RedisStreamCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(consumer, "Consumer must not be null!");
return connection.invoke().from(BinaryJedis::xgroupDelConsumer, MultiKeyPipelineBase::xgroupDelConsumer, key,
return connection.invoke().from(Jedis::xgroupDelConsumer, PipelineBinaryCommands::xgroupDelConsumer, key,
JedisConverters.toBytes(consumer.getGroup()), JedisConverters.toBytes(consumer.getName())).get(r -> r > 0);
}
@@ -146,7 +160,7 @@ class JedisStreamCommands implements RedisStreamCommands {
Assert.hasText(groupName, "Group name must not be null or empty!");
return connection.invoke()
.from(BinaryJedis::xgroupDestroy, MultiKeyPipelineBase::xgroupDestroy, key, JedisConverters.toBytes(groupName))
.from(Jedis::xgroupDestroy, PipelineBinaryCommands::xgroupDestroy, key, JedisConverters.toBytes(groupName))
.get(r -> r > 0);
}
@@ -155,12 +169,8 @@ class JedisStreamCommands implements RedisStreamCommands {
Assert.notNull(key, "Key must not be null!");
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'XINFO' cannot be called in pipeline / transaction mode.");
}
return connection.invoke().just(it -> {
redis.clients.jedis.StreamInfo streamInfo = it.xinfoStream(key);
return connection.invoke().from(Jedis::xinfoStream, ResponseCommands::xinfoStream, key).get(it -> {
redis.clients.jedis.resps.StreamInfo streamInfo = BuilderFactory.STREAM_INFO.build(it);
return StreamInfo.XInfoStream.fromList(StreamConverters.mapToList(streamInfo.getStreamInfo()));
});
}
@@ -170,12 +180,8 @@ class JedisStreamCommands implements RedisStreamCommands {
Assert.notNull(key, "Key must not be null!");
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'XINFO GROUPS' cannot be called in pipeline / transaction mode.");
}
return connection.invoke().just(it -> {
List<StreamGroupInfo> streamGroupInfos = it.xinfoGroup(key);
return connection.invoke().from(Jedis::xinfoGroups, StreamPipelineBinaryCommands::xinfoGroups, key).get(it -> {
List<StreamGroupInfo> streamGroupInfos = BuilderFactory.STREAM_GROUP_INFO_LIST.build(it);
List<Object> sources = new ArrayList<>();
streamGroupInfos
.forEach(streamGroupInfo -> sources.add(StreamConverters.mapToList(streamGroupInfo.getGroupInfo())));
@@ -189,12 +195,11 @@ class JedisStreamCommands implements RedisStreamCommands {
Assert.notNull(key, "Key must not be null!");
Assert.hasText(groupName, "Group name must not be null or empty!");
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'XINFO CONSUMERS' cannot be called in pipeline / transaction mode.");
}
return connection.invoke().just(it -> {
List<StreamConsumersInfo> streamConsumersInfos = it.xinfoConsumers(key, JedisConverters.toBytes(groupName));
return connection.invoke()
.from(Jedis::xinfoConsumers, ResponseCommands::xinfoConsumers, key, JedisConverters.toBytes(groupName))
.get(it -> {
List<StreamConsumersInfo> streamConsumersInfos = BuilderFactory.STREAM_CONSUMERS_INFO_LIST
.build(it);
List<Object> sources = new ArrayList<>();
streamConsumersInfos
.forEach(
@@ -208,12 +213,17 @@ class JedisStreamCommands implements RedisStreamCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::xlen, MultiKeyPipelineBase::xlen, key);
return connection.invoke().just(Jedis::xlen, PipelineBinaryCommands::xlen, key);
}
@Override
public PendingMessagesSummary xPending(byte[] key, String groupName) {
throw new UnsupportedOperationException("Jedis does not support returning PendingMessagesSummary.");
Assert.notNull(key, "Key must not be null!");
return connection.invoke()
.from(Jedis::xpending, PipelineBinaryCommands::xpending, key, JedisConverters.toBytes(groupName))
.get(it -> StreamConverters.toPendingMessagesSummary(groupName, it));
}
@Override
@@ -223,16 +233,12 @@ class JedisStreamCommands implements RedisStreamCommands {
Assert.notNull(groupName, "GroupName must not be null!");
Range<String> range = (Range<String>) options.getRange();
byte[] group = JedisConverters.toBytes(groupName);
XPendingParams xPendingParams = StreamConverters.toXPendingParams(options);
return connection.invoke().from((it, t1, t2, t3, t4, t5, t6) -> {
Object r = it.xpending(t1, t2, t3, t4, t5, t6);
return BuilderFactory.STREAM_PENDING_ENTRY_LIST.build(r);
}, MultiKeyPipelineBase::xpending, key, group, JedisConverters.toBytes(StreamConverters.getLowerValue(range)),
JedisConverters.toBytes(StreamConverters.getUpperValue(range)), options.getCount().intValue(),
JedisConverters.toBytes(options.getConsumerName()))
.get(r -> StreamConverters.toPendingMessages(groupName, range, r));
return connection.invoke()
.from(Jedis::xpending, ResponseCommands::xpending, key, JedisConverters.toBytes(groupName), xPendingParams)
.get(r -> StreamConverters.toPendingMessages(groupName, range,
BuilderFactory.STREAM_PENDING_ENTRY_LIST.build(r)));
}
@Override
@@ -245,11 +251,9 @@ class JedisStreamCommands implements RedisStreamCommands {
int count = limit.isUnlimited() ? Integer.MAX_VALUE : limit.getCount();
return connection.invoke()
.from(
it -> it.xrange(key, JedisConverters.toBytes(StreamConverters.getLowerValue(range)),
JedisConverters.toBytes(StreamConverters.getUpperValue(range)), count),
it -> it.xrange(key, JedisConverters.toBytes(StreamConverters.getLowerValue(range)),
JedisConverters.toBytes(StreamConverters.getUpperValue(range)), count))
.from(Jedis::xrange, ResponseCommands::xrange, key,
JedisConverters.toBytes(StreamConverters.getLowerValue(range)),
JedisConverters.toBytes(StreamConverters.getUpperValue(range)), count)
.get(r -> StreamConverters.convertToByteRecord(key, r));
}
@@ -259,14 +263,10 @@ class JedisStreamCommands implements RedisStreamCommands {
Assert.notNull(readOptions, "StreamReadOptions must not be null!");
Assert.notNull(streams, "StreamOffsets must not be null!");
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'XREAD' cannot be called in pipeline / transaction mode.");
}
XReadParams params = StreamConverters.toXReadParams(readOptions);
long block = readOptions.getBlock() == null ? -1L : readOptions.getBlock();
int count = readOptions.getCount() != null ? readOptions.getCount().intValue() : Integer.MAX_VALUE;
return connection.invoke().from(it -> it.xread(count, block, StreamConverters.toStreamOffsets(streams)))
return connection.invoke()
.from(Jedis::xread, ResponseCommands::xread, params, StreamConverters.toStreamOffsets(streams))
.getOrElse(StreamConverters::convertToByteRecords, Collections::emptyList);
}
@@ -278,18 +278,12 @@ class JedisStreamCommands implements RedisStreamCommands {
Assert.notNull(readOptions, "StreamReadOptions must not be null!");
Assert.notNull(streams, "StreamOffsets must not be null!");
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'XREADGROUP' cannot be called in pipeline / transaction mode.");
}
XReadGroupParams params = StreamConverters.toXReadGroupParams(readOptions);
long block = readOptions.getBlock() == null ? -1L : readOptions.getBlock();
int count = readOptions.getCount() == null ? -1 : readOptions.getCount().intValue();
return connection.invoke().from(it -> {
return it.xreadGroup(JedisConverters.toBytes(consumer.getGroup()), JedisConverters.toBytes(consumer.getName()),
count, block, readOptions.isNoack(), StreamConverters.toStreamOffsets(streams));
}).getOrElse(StreamConverters::convertToByteRecords, Collections::emptyList);
return connection.invoke()
.from(Jedis::xreadGroup, ResponseCommands::xreadGroup, JedisConverters.toBytes(consumer.getGroup()),
JedisConverters.toBytes(consumer.getName()), params, StreamConverters.toStreamOffsets(streams))
.getOrElse(StreamConverters::convertToByteRecords, Collections::emptyList);
}
@Override
@@ -301,7 +295,7 @@ class JedisStreamCommands implements RedisStreamCommands {
int count = limit.isUnlimited() ? Integer.MAX_VALUE : limit.getCount();
return connection.invoke()
.from(BinaryJedis::xrevrange, MultiKeyPipelineBase::xrevrange, key,
.from(Jedis::xrevrange, ResponseCommands::xrevrange, key,
JedisConverters.toBytes(StreamConverters.getUpperValue(range)),
JedisConverters.toBytes(StreamConverters.getLowerValue(range)), count)
.get(it -> StreamConverters.convertToByteRecord(key, it));
@@ -317,7 +311,7 @@ class JedisStreamCommands implements RedisStreamCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::xtrim, MultiKeyPipelineBase::xtrim, key, count, approximateTrimming);
return connection.invoke().just(Jedis::xtrim, PipelineBinaryCommands::xtrim, key, count, approximateTrimming);
}
private boolean isPipelined() {

View File

@@ -15,9 +15,9 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.BitPosParams;
import redis.clients.jedis.MultiKeyPipelineBase;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.commands.PipelineBinaryCommands;
import redis.clients.jedis.params.BitPosParams;
import redis.clients.jedis.params.SetParams;
import java.util.List;
@@ -50,7 +50,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::get, MultiKeyPipelineBase::get, key);
return connection.invoke().just(Jedis::get, PipelineBinaryCommands::get, key);
}
@Nullable
@@ -59,7 +59,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::getDel, MultiKeyPipelineBase::getDel, key);
return connection.invoke().just(Jedis::getDel, PipelineBinaryCommands::getDel, key);
}
@Nullable
@@ -69,7 +69,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(expiration, "Expiration must not be null!");
return connection.invoke().just(BinaryJedis::getEx, MultiKeyPipelineBase::getEx, key,
return connection.invoke().just(Jedis::getEx, PipelineBinaryCommands::getEx, key,
JedisConverters.toGetExParams(expiration));
}
@@ -79,7 +79,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
return connection.invoke().just(BinaryJedis::getSet, MultiKeyPipelineBase::getSet, key, value);
return connection.invoke().just(Jedis::getSet, PipelineBinaryCommands::getSet, key, value);
}
@Override
@@ -88,7 +88,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(keys, "Keys must not be null!");
Assert.noNullElements(keys, "Keys must not contain null elements!");
return connection.invoke().just(BinaryJedis::mget, MultiKeyPipelineBase::mget, keys);
return connection.invoke().just(Jedis::mget, PipelineBinaryCommands::mget, keys);
}
@Override
@@ -97,7 +97,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
return connection.invoke().from(BinaryJedis::set, MultiKeyPipelineBase::set, key, value)
return connection.invoke().from(Jedis::set, PipelineBinaryCommands::set, key, value)
.get(Converters.stringToBooleanConverter());
}
@@ -112,7 +112,7 @@ class JedisStringCommands implements RedisStringCommands {
SetParams params = JedisConverters.toSetCommandExPxArgument(expiration,
JedisConverters.toSetCommandNxXxArgument(option));
return connection.invoke().from(BinaryJedis::set, MultiKeyPipelineBase::set, key, value, params)
return connection.invoke().from(Jedis::set, PipelineBinaryCommands::set, key, value, params)
.getOrElse(Converters.stringToBooleanConverter(), () -> false);
}
@@ -122,7 +122,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
return connection.invoke().from(BinaryJedis::setnx, MultiKeyPipelineBase::setnx, key, value)
return connection.invoke().from(Jedis::setnx, PipelineBinaryCommands::setnx, key, value)
.get(Converters.longToBoolean());
}
@@ -136,7 +136,7 @@ class JedisStringCommands implements RedisStringCommands {
throw new IllegalArgumentException("Time must be less than Integer.MAX_VALUE for setEx in Jedis.");
}
return connection.invoke().from(BinaryJedis::setex, MultiKeyPipelineBase::setex, key, (int) seconds, value)
return connection.invoke().from(Jedis::setex, PipelineBinaryCommands::setex, key, seconds, value)
.getOrElse(Converters.stringToBooleanConverter(), () -> false);
}
@@ -146,7 +146,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
return connection.invoke().from(BinaryJedis::psetex, MultiKeyPipelineBase::psetex, key, milliseconds, value)
return connection.invoke().from(Jedis::psetex, PipelineBinaryCommands::psetex, key, milliseconds, value)
.getOrElse(Converters.stringToBooleanConverter(), () -> false);
}
@@ -155,7 +155,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(tuples, "Tuples must not be null!");
return connection.invoke().from(BinaryJedis::mset, MultiKeyPipelineBase::mset, JedisConverters.toByteArrays(tuples))
return connection.invoke().from(Jedis::mset, PipelineBinaryCommands::mset, JedisConverters.toByteArrays(tuples))
.get(Converters.stringToBooleanConverter());
}
@@ -165,7 +165,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(tuples, "Tuples must not be null!");
return connection.invoke()
.from(BinaryJedis::msetnx, MultiKeyPipelineBase::msetnx, JedisConverters.toByteArrays(tuples))
.from(Jedis::msetnx, PipelineBinaryCommands::msetnx, JedisConverters.toByteArrays(tuples))
.get(Converters.longToBoolean());
}
@@ -174,7 +174,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::incr, MultiKeyPipelineBase::incr, key);
return connection.invoke().just(Jedis::incr, PipelineBinaryCommands::incr, key);
}
@Override
@@ -182,7 +182,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::incrBy, MultiKeyPipelineBase::incrBy, key, value);
return connection.invoke().just(Jedis::incrBy, PipelineBinaryCommands::incrBy, key, value);
}
@Override
@@ -190,7 +190,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::incrByFloat, MultiKeyPipelineBase::incrByFloat, key, value);
return connection.invoke().just(Jedis::incrByFloat, PipelineBinaryCommands::incrByFloat, key, value);
}
@Override
@@ -198,7 +198,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::decr, MultiKeyPipelineBase::decr, key);
return connection.invoke().just(Jedis::decr, PipelineBinaryCommands::decr, key);
}
@Override
@@ -206,7 +206,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::decrBy, MultiKeyPipelineBase::decrBy, key, value);
return connection.invoke().just(Jedis::decrBy, PipelineBinaryCommands::decrBy, key, value);
}
@Override
@@ -215,7 +215,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
return connection.invoke().just(BinaryJedis::append, MultiKeyPipelineBase::append, key, value);
return connection.invoke().just(Jedis::append, PipelineBinaryCommands::append, key, value);
}
@Override
@@ -223,7 +223,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::getrange, MultiKeyPipelineBase::getrange, key, start, end);
return connection.invoke().just(Jedis::getrange, PipelineBinaryCommands::getrange, key, start, end);
}
@Override
@@ -232,7 +232,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
connection.invokeStatus().just(BinaryJedis::setrange, MultiKeyPipelineBase::setrange, key, offset, value);
connection.invokeStatus().just(Jedis::setrange, PipelineBinaryCommands::setrange, key, offset, value);
}
@Override
@@ -240,7 +240,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::getbit, MultiKeyPipelineBase::getbit, key, offset);
return connection.invoke().just(Jedis::getbit, PipelineBinaryCommands::getbit, key, offset);
}
@Override
@@ -248,8 +248,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::setbit, MultiKeyPipelineBase::setbit, key, offset,
JedisConverters.toBit(value));
return connection.invoke().just(Jedis::setbit, PipelineBinaryCommands::setbit, key, offset, value);
}
@Override
@@ -257,7 +256,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::bitcount, MultiKeyPipelineBase::bitcount, key);
return connection.invoke().just(Jedis::bitcount, PipelineBinaryCommands::bitcount, key);
}
@Override
@@ -265,7 +264,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::bitcount, MultiKeyPipelineBase::bitcount, key, start, end);
return connection.invoke().just(Jedis::bitcount, PipelineBinaryCommands::bitcount, key, start, end);
}
@Override
@@ -274,7 +273,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(subCommands, "Command must not be null!");
return connection.invoke().just(BinaryJedis::bitfield, MultiKeyPipelineBase::bitfield, key,
return connection.invoke().just(Jedis::bitfield, PipelineBinaryCommands::bitfield, key,
JedisConverters.toBitfieldCommandArguments(subCommands));
}
@@ -288,7 +287,7 @@ class JedisStringCommands implements RedisStringCommands {
throw new UnsupportedOperationException("Bitop NOT should only be performed against one key");
}
return connection.invoke().just(BinaryJedis::bitop, MultiKeyPipelineBase::bitop, JedisConverters.toBitOp(op),
return connection.invoke().just(Jedis::bitop, PipelineBinaryCommands::bitop, JedisConverters.toBitOp(op),
destination, keys);
}
@@ -305,10 +304,10 @@ class JedisStringCommands implements RedisStringCommands {
? new BitPosParams(range.getLowerBound().getValue().get(), range.getUpperBound().getValue().get())
: new BitPosParams(range.getLowerBound().getValue().get());
return connection.invoke().just(BinaryJedis::bitpos, MultiKeyPipelineBase::bitpos, key, bit, params);
return connection.invoke().just(Jedis::bitpos, PipelineBinaryCommands::bitpos, key, bit, params);
}
return connection.invoke().just(BinaryJedis::bitpos, MultiKeyPipelineBase::bitpos, key, bit);
return connection.invoke().just(Jedis::bitpos, PipelineBinaryCommands::bitpos, key, bit);
}
@Override
@@ -316,7 +315,7 @@ class JedisStringCommands implements RedisStringCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::strlen, MultiKeyPipelineBase::strlen, key);
return connection.invoke().just(Jedis::strlen, PipelineBinaryCommands::strlen, key);
}
}

View File

@@ -15,19 +15,18 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.MultiKeyPipelineBase;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import redis.clients.jedis.ZParams;
import redis.clients.jedis.commands.PipelineBinaryCommands;
import redis.clients.jedis.params.ScanParams;
import redis.clients.jedis.params.ZParams;
import redis.clients.jedis.resps.ScanResult;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.redis.connection.RedisZSetCommands;
import org.springframework.data.redis.connection.zset.DefaultTuple;
import org.springframework.data.redis.connection.zset.Tuple;
@@ -61,7 +60,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(value, "Value must not be null!");
return connection.invoke()
.from(BinaryJedis::zadd, MultiKeyPipelineBase::zadd, key, score, value, JedisConverters.toZAddParams(args))
.from(Jedis::zadd, PipelineBinaryCommands::zadd, key, score, value, JedisConverters.toZAddParams(args))
.get(JedisConverters::toBoolean);
}
@@ -71,7 +70,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(tuples, "Tuples must not be null!");
return connection.invoke().just(BinaryJedis::zadd, MultiKeyPipelineBase::zadd, key,
return connection.invoke().just(Jedis::zadd, PipelineBinaryCommands::zadd, key,
JedisConverters.toTupleMap(tuples), JedisConverters.toZAddParams(args));
}
@@ -82,7 +81,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(values, "Values must not be null!");
Assert.noNullElements(values, "Values must not contain null elements!");
return connection.invoke().just(BinaryJedis::zrem, MultiKeyPipelineBase::zrem, key, values);
return connection.invoke().just(Jedis::zrem, PipelineBinaryCommands::zrem, key, values);
}
@Override
@@ -91,7 +90,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
return connection.invoke().just(BinaryJedis::zincrby, MultiKeyPipelineBase::zincrby, key, increment, value);
return connection.invoke().just(Jedis::zincrby, PipelineBinaryCommands::zincrby, key, increment, value);
}
@Override
@@ -99,7 +98,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::zrandmember, MultiKeyPipelineBase::zrandmember, key);
return connection.invoke().just(Jedis::zrandmember, PipelineBinaryCommands::zrandmember, key);
}
@Override
@@ -107,7 +106,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().fromMany(BinaryJedis::zrandmember, MultiKeyPipelineBase::zrandmember, key, count)
return connection.invoke().fromMany(Jedis::zrandmember, PipelineBinaryCommands::zrandmember, key, count)
.toList();
}
@@ -117,7 +116,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke()
.from(BinaryJedis::zrandmemberWithScores, MultiKeyPipelineBase::zrandmemberWithScores, key, 1L).get(it -> {
.from(Jedis::zrandmemberWithScores, PipelineBinaryCommands::zrandmemberWithScores, key, 1L).get(it -> {
if (it.isEmpty()) {
return null;
@@ -133,7 +132,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke()
.fromMany(BinaryJedis::zrandmemberWithScores, MultiKeyPipelineBase::zrandmemberWithScores, key, count)
.fromMany(Jedis::zrandmemberWithScores, PipelineBinaryCommands::zrandmemberWithScores, key, count)
.toList(JedisConverters::toTuple);
}
@@ -143,7 +142,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
return connection.invoke().just(BinaryJedis::zrank, MultiKeyPipelineBase::zrank, key, value);
return connection.invoke().just(Jedis::zrank, PipelineBinaryCommands::zrank, key, value);
}
@Override
@@ -151,7 +150,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::zrevrank, MultiKeyPipelineBase::zrevrank, key, value);
return connection.invoke().just(Jedis::zrevrank, PipelineBinaryCommands::zrevrank, key, value);
}
@Override
@@ -159,7 +158,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::zrange, MultiKeyPipelineBase::zrange, key, start, end);
return connection.invoke().fromMany(Jedis::zrange, PipelineBinaryCommands::zrange, key, start, end).toSet();
}
@Override
@@ -168,7 +167,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke()
.fromMany(BinaryJedis::zrangeWithScores, MultiKeyPipelineBase::zrangeWithScores, key, start, end)
.fromMany(Jedis::zrangeWithScores, PipelineBinaryCommands::zrangeWithScores, key, start, end)
.toSet(JedisConverters::toTuple);
}
@@ -184,13 +183,13 @@ class JedisZSetCommands implements RedisZSetCommands {
byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES);
if (!limit.isUnlimited()) {
return connection.invoke().fromMany(BinaryJedis::zrangeByScoreWithScores,
MultiKeyPipelineBase::zrangeByScoreWithScores, key, min, max, limit.getOffset(), limit.getCount())
return connection.invoke().fromMany(Jedis::zrangeByScoreWithScores,
PipelineBinaryCommands::zrangeByScoreWithScores, key, min, max, limit.getOffset(), limit.getCount())
.toSet(JedisConverters::toTuple);
}
return connection.invoke()
.fromMany(BinaryJedis::zrangeByScoreWithScores, MultiKeyPipelineBase::zrangeByScoreWithScores, key, min, max)
.fromMany(Jedis::zrangeByScoreWithScores, PipelineBinaryCommands::zrangeByScoreWithScores, key, min, max)
.toSet(JedisConverters::toTuple);
}
@@ -199,7 +198,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::zrevrange, MultiKeyPipelineBase::zrevrange, key, start, end);
return connection.invoke().fromMany(Jedis::zrevrange, PipelineBinaryCommands::zrevrange, key, start, end).toSet();
}
@Override
@@ -208,7 +207,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke()
.fromMany(BinaryJedis::zrevrangeWithScores, MultiKeyPipelineBase::zrevrangeWithScores, key, start, end)
.fromMany(Jedis::zrevrangeWithScores, PipelineBinaryCommands::zrevrangeWithScores, key, start, end)
.toSet(JedisConverters::toTuple);
}
@@ -223,12 +222,12 @@ class JedisZSetCommands implements RedisZSetCommands {
byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES);
if (!limit.isUnlimited()) {
return connection.invoke().just(BinaryJedis::zrevrangeByScore, MultiKeyPipelineBase::zrevrangeByScore, key, max,
min, limit.getOffset(), limit.getCount());
return connection.invoke().fromMany(Jedis::zrevrangeByScore, PipelineBinaryCommands::zrevrangeByScore, key, max,
min, limit.getOffset(), limit.getCount()).toSet();
}
return connection.invoke().just(BinaryJedis::zrevrangeByScore, MultiKeyPipelineBase::zrevrangeByScore, key, max,
min);
return connection.invoke()
.fromMany(Jedis::zrevrangeByScore, PipelineBinaryCommands::zrevrangeByScore, key, max, min).toSet();
}
@Override
@@ -243,13 +242,14 @@ class JedisZSetCommands implements RedisZSetCommands {
byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES);
if (!limit.isUnlimited()) {
return connection.invoke().fromMany(BinaryJedis::zrevrangeByScoreWithScores,
MultiKeyPipelineBase::zrevrangeByScoreWithScores, key, max, min, limit.getOffset(), limit.getCount())
return connection.invoke().fromMany(Jedis::zrevrangeByScoreWithScores,
PipelineBinaryCommands::zrevrangeByScoreWithScores, key, max, min, limit.getOffset(), limit.getCount())
.toSet(JedisConverters::toTuple);
}
return connection.invoke().fromMany(BinaryJedis::zrevrangeByScoreWithScores,
MultiKeyPipelineBase::zrevrangeByScoreWithScores, key, max, min).toSet(JedisConverters::toTuple);
return connection.invoke()
.fromMany(Jedis::zrevrangeByScoreWithScores, PipelineBinaryCommands::zrevrangeByScoreWithScores, key, max, min)
.toSet(JedisConverters::toTuple);
}
@Override
@@ -257,7 +257,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::zcount, MultiKeyPipelineBase::zcount, key, min, max);
return connection.invoke().just(Jedis::zcount, PipelineBinaryCommands::zcount, key, min, max);
}
@Override
@@ -269,7 +269,7 @@ class JedisZSetCommands implements RedisZSetCommands {
byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES);
byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES);
return connection.invoke().just(BinaryJedis::zcount, MultiKeyPipelineBase::zcount, key, min, max);
return connection.invoke().just(Jedis::zcount, PipelineBinaryCommands::zcount, key, min, max);
}
@Override
@@ -281,7 +281,7 @@ class JedisZSetCommands implements RedisZSetCommands {
byte[] min = JedisConverters.boundaryToBytesForZRangeByLex(range.getMin(), JedisConverters.MINUS_BYTES);
byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getMax(), JedisConverters.PLUS_BYTES);
return connection.invoke().just(BinaryJedis::zlexcount, MultiKeyPipelineBase::zlexcount, key, min, max);
return connection.invoke().just(Jedis::zlexcount, PipelineBinaryCommands::zlexcount, key, min, max);
}
@Nullable
@@ -290,7 +290,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().from(BinaryJedis::zpopmin, MultiKeyPipelineBase::zpopmin, key)
return connection.invoke().from(Jedis::zpopmin, PipelineBinaryCommands::zpopmin, key)
.get(JedisConverters::toTuple);
}
@@ -301,7 +301,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke()
.fromMany(BinaryJedis::zpopmin, MultiKeyPipelineBase::zpopmin, key, Math.toIntExact(count))
.fromMany(Jedis::zpopmin, PipelineBinaryCommands::zpopmin, key, Math.toIntExact(count))
.toSet(JedisConverters::toTuple);
}
@@ -313,7 +313,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(unit, "TimeUnit must not be null!");
return connection.invoke()
.from(BinaryJedis::bzpopmin, MultiKeyPipelineBase::bzpopmin, JedisConverters.toSeconds(timeout, unit), key)
.from(Jedis::bzpopmin, PipelineBinaryCommands::bzpopmin, JedisConverters.toSeconds(timeout, unit), key)
.get(JedisZSetCommands::toTuple);
}
@@ -323,7 +323,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().from(BinaryJedis::zpopmax, MultiKeyPipelineBase::zpopmax, key)
return connection.invoke().from(Jedis::zpopmax, PipelineBinaryCommands::zpopmax, key)
.get(JedisConverters::toTuple);
}
@@ -334,7 +334,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke()
.fromMany(BinaryJedis::zpopmax, MultiKeyPipelineBase::zpopmax, key, Math.toIntExact(count))
.fromMany(Jedis::zpopmax, PipelineBinaryCommands::zpopmax, key, Math.toIntExact(count))
.toSet(JedisConverters::toTuple);
}
@@ -346,7 +346,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(unit, "TimeUnit must not be null!");
return connection.invoke()
.from(BinaryJedis::bzpopmax, MultiKeyPipelineBase::bzpopmax, JedisConverters.toSeconds(timeout, unit), key)
.from(Jedis::bzpopmax, PipelineBinaryCommands::bzpopmax, JedisConverters.toSeconds(timeout, unit), key)
.get(JedisZSetCommands::toTuple);
}
@@ -355,7 +355,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::zcard, MultiKeyPipelineBase::zcard, key);
return connection.invoke().just(Jedis::zcard, PipelineBinaryCommands::zcard, key);
}
@Override
@@ -364,7 +364,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
return connection.invoke().just(BinaryJedis::zscore, MultiKeyPipelineBase::zscore, key, value);
return connection.invoke().just(Jedis::zscore, PipelineBinaryCommands::zscore, key, value);
}
@Override
@@ -373,7 +373,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(values, "Value must not be null!");
return connection.invoke().just(BinaryJedis::zmscore, MultiKeyPipelineBase::zmscore, key, values);
return connection.invoke().just(Jedis::zmscore, PipelineBinaryCommands::zmscore, key, values);
}
@Override
@@ -381,7 +381,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
return connection.invoke().just(BinaryJedis::zremrangeByRank, MultiKeyPipelineBase::zremrangeByRank, key, start,
return connection.invoke().just(Jedis::zremrangeByRank, PipelineBinaryCommands::zremrangeByRank, key, start,
end);
}
@@ -394,7 +394,7 @@ class JedisZSetCommands implements RedisZSetCommands {
byte[] min = JedisConverters.boundaryToBytesForZRangeByLex(range.getMin(), JedisConverters.MINUS_BYTES);
byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getMax(), JedisConverters.PLUS_BYTES);
return connection.invoke().just(BinaryJedis::zremrangeByLex, MultiKeyPipelineBase::zremrangeByLex, key, min, max);
return connection.invoke().just(Jedis::zremrangeByLex, PipelineBinaryCommands::zremrangeByLex, key, min, max);
}
@Override
@@ -406,7 +406,7 @@ class JedisZSetCommands implements RedisZSetCommands {
byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES);
byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES);
return connection.invoke().just(BinaryJedis::zremrangeByScore, MultiKeyPipelineBase::zremrangeByScore, key, min,
return connection.invoke().just(Jedis::zremrangeByScore, PipelineBinaryCommands::zremrangeByScore, key, min,
max);
}
@@ -415,7 +415,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(sets, "Sets must not be null!");
return connection.invoke().just(BinaryJedis::zdiff, MultiKeyPipelineBase::zdiff, sets);
return connection.invoke().just(Jedis::zdiff, PipelineBinaryCommands::zdiff, sets);
}
@Override
@@ -423,7 +423,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(sets, "Sets must not be null!");
return connection.invoke().fromMany(BinaryJedis::zdiffWithScores, MultiKeyPipelineBase::zdiffWithScores, sets)
return connection.invoke().fromMany(Jedis::zdiffWithScores, PipelineBinaryCommands::zdiffWithScores, sets)
.toSet(JedisConverters::toTuple);
}
@@ -433,7 +433,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(destKey, "Destination key must not be null!");
Assert.notNull(sets, "Source sets must not be null!");
return connection.invoke().just(BinaryJedis::zdiffStore, MultiKeyPipelineBase::zdiffStore, destKey, sets);
return connection.invoke().just(Jedis::zdiffStore, PipelineBinaryCommands::zdiffStore, destKey, sets);
}
@Override
@@ -441,7 +441,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(sets, "Sets must not be null!");
return connection.invoke().just(BinaryJedis::zinter, MultiKeyPipelineBase::zinter, new ZParams(), sets);
return connection.invoke().just(Jedis::zinter, PipelineBinaryCommands::zinter, new ZParams(), sets);
}
@Override
@@ -450,7 +450,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(sets, "Sets must not be null!");
return connection.invoke()
.fromMany(BinaryJedis::zinterWithScores, MultiKeyPipelineBase::zinterWithScores, new ZParams(), sets)
.fromMany(Jedis::zinterWithScores, PipelineBinaryCommands::zinterWithScores, new ZParams(), sets)
.toSet(JedisConverters::toTuple);
}
@@ -462,7 +462,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.isTrue(weights.size() == sets.length, () -> String
.format("The number of weights (%d) must match the number of source sets (%d)!", weights.size(), sets.length));
return connection.invoke().fromMany(BinaryJedis::zinterWithScores, MultiKeyPipelineBase::zinterWithScores,
return connection.invoke().fromMany(Jedis::zinterWithScores, PipelineBinaryCommands::zinterWithScores,
toZParams(aggregate, weights), sets).toSet(JedisConverters::toTuple);
}
@@ -477,7 +477,7 @@ class JedisZSetCommands implements RedisZSetCommands {
ZParams zparams = toZParams(aggregate, weights);
return connection.invoke().just(BinaryJedis::zinterstore, MultiKeyPipelineBase::zinterstore, destKey, zparams,
return connection.invoke().just(Jedis::zinterstore, PipelineBinaryCommands::zinterstore, destKey, zparams,
sets);
}
@@ -488,7 +488,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(sets, "Source sets must not be null!");
Assert.noNullElements(sets, "Source sets must not contain null elements!");
return connection.invoke().just(BinaryJedis::zinterstore, MultiKeyPipelineBase::zinterstore, destKey, sets);
return connection.invoke().just(Jedis::zinterstore, PipelineBinaryCommands::zinterstore, destKey, sets);
}
@Override
@@ -496,7 +496,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(sets, "Sets must not be null!");
return connection.invoke().just(BinaryJedis::zunion, MultiKeyPipelineBase::zunion, new ZParams(), sets);
return connection.invoke().just(Jedis::zunion, PipelineBinaryCommands::zunion, new ZParams(), sets);
}
@Override
@@ -505,7 +505,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(sets, "Sets must not be null!");
return connection.invoke()
.fromMany(BinaryJedis::zunionWithScores, MultiKeyPipelineBase::zunionWithScores, new ZParams(), sets)
.fromMany(Jedis::zunionWithScores, PipelineBinaryCommands::zunionWithScores, new ZParams(), sets)
.toSet(JedisConverters::toTuple);
}
@@ -517,7 +517,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.isTrue(weights.size() == sets.length, () -> String
.format("The number of weights (%d) must match the number of source sets (%d)!", weights.size(), sets.length));
return connection.invoke().fromMany(BinaryJedis::zunionWithScores, MultiKeyPipelineBase::zunionWithScores,
return connection.invoke().fromMany(Jedis::zunionWithScores, PipelineBinaryCommands::zunionWithScores,
toZParams(aggregate, weights), sets).toSet(JedisConverters::toTuple);
}
@@ -533,7 +533,7 @@ class JedisZSetCommands implements RedisZSetCommands {
ZParams zparams = toZParams(aggregate, weights);
return connection.invoke().just(BinaryJedis::zunionstore, MultiKeyPipelineBase::zunionstore, destKey, zparams,
return connection.invoke().just(Jedis::zunionstore, PipelineBinaryCommands::zunionstore, destKey, zparams,
sets);
}
@@ -544,7 +544,7 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(sets, "Source sets must not be null!");
Assert.noNullElements(sets, "Source sets must not contain null elements!");
return connection.invoke().just(BinaryJedis::zunionstore, MultiKeyPipelineBase::zunionstore, destKey, sets);
return connection.invoke().just(Jedis::zunionstore, PipelineBinaryCommands::zunionstore, destKey, sets);
}
@Override
@@ -569,12 +569,12 @@ class JedisZSetCommands implements RedisZSetCommands {
protected ScanIteration<Tuple> doScan(byte[] key, long cursorId, ScanOptions options) {
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'ZSCAN' cannot be called in pipeline / transaction mode.");
throw new InvalidDataAccessApiUsageException("'ZSCAN' cannot be called in pipeline / transaction mode.");
}
ScanParams params = JedisConverters.toScanParams(options);
ScanResult<redis.clients.jedis.Tuple> result = connection.getJedis().zscan(key,
ScanResult<redis.clients.jedis.resps.Tuple> result = connection.getJedis().zscan(key,
JedisConverters.toBytes(cursorId), params);
return new ScanIteration<>(Long.valueOf(result.getCursor()),
JedisConverters.tuplesToTuples().convert(result.getResult()));
@@ -593,9 +593,8 @@ class JedisZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null!");
String keyStr = new String(key, StandardCharsets.UTF_8);
return connection.invoke().fromMany(Jedis::zrangeByScore, MultiKeyPipelineBase::zrangeByScore, keyStr, min, max)
.toSet(JedisConverters::toBytes);
return connection.invoke().fromMany(Jedis::zrangeByScore, PipelineBinaryCommands::zrangeByScore, key,
JedisConverters.toBytes(min), JedisConverters.toBytes(max)).toSet();
}
@Override
@@ -608,10 +607,9 @@ class JedisZSetCommands implements RedisZSetCommands {
throw new IllegalArgumentException(
"Offset and count must be less than Integer.MAX_VALUE for zRangeByScore in Jedis.");
}
String keyStr = new String(key, StandardCharsets.UTF_8);
return connection.invoke().fromMany(Jedis::zrangeByScore, MultiKeyPipelineBase::zrangeByScore, keyStr, min, max,
(int) offset, (int) count).toSet(JedisConverters::toBytes);
return connection.invoke().fromMany(Jedis::zrangeByScore, PipelineBinaryCommands::zrangeByScore, key,
JedisConverters.toBytes(min), JedisConverters.toBytes(max), (int) offset, (int) count).toSet();
}
@Override
@@ -625,11 +623,12 @@ class JedisZSetCommands implements RedisZSetCommands {
byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES);
if (!limit.isUnlimited()) {
return connection.invoke().just(BinaryJedis::zrangeByScore, MultiKeyPipelineBase::zrangeByScore, key, min, max,
limit.getOffset(), limit.getCount());
return connection.invoke().fromMany(Jedis::zrangeByScore, PipelineBinaryCommands::zrangeByScore, key, min, max,
limit.getOffset(), limit.getCount()).toSet();
}
return connection.invoke().just(BinaryJedis::zrangeByScore, MultiKeyPipelineBase::zrangeByScore, key, min, max);
return connection.invoke().fromMany(Jedis::zrangeByScore, PipelineBinaryCommands::zrangeByScore, key, min, max)
.toSet();
}
@Override
@@ -643,11 +642,11 @@ class JedisZSetCommands implements RedisZSetCommands {
byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getMax(), JedisConverters.PLUS_BYTES);
if (!limit.isUnlimited()) {
return connection.invoke().just(BinaryJedis::zrangeByLex, MultiKeyPipelineBase::zrangeByLex, key, min, max,
limit.getOffset(), limit.getCount());
return connection.invoke().fromMany(Jedis::zrangeByLex, PipelineBinaryCommands::zrangeByLex, key, min, max,
limit.getOffset(), limit.getCount()).toSet();
}
return connection.invoke().just(BinaryJedis::zrangeByLex, MultiKeyPipelineBase::zrangeByLex, key, min, max);
return connection.invoke().fromMany(Jedis::zrangeByLex, PipelineBinaryCommands::zrangeByLex, key, min, max).toSet();
}
@Override
@@ -661,11 +660,11 @@ class JedisZSetCommands implements RedisZSetCommands {
byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getMax(), JedisConverters.PLUS_BYTES);
if (!limit.isUnlimited()) {
return connection.invoke().from(BinaryJedis::zrevrangeByLex, MultiKeyPipelineBase::zrevrangeByLex, key, max, min,
return connection.invoke().from(Jedis::zrevrangeByLex, PipelineBinaryCommands::zrevrangeByLex, key, max, min,
limit.getOffset(), limit.getCount()).get(LinkedHashSet::new);
}
return connection.invoke().from(BinaryJedis::zrevrangeByLex, MultiKeyPipelineBase::zrevrangeByLex, key, max, min)
return connection.invoke().from(Jedis::zrevrangeByLex, PipelineBinaryCommands::zrevrangeByLex, key, max, min)
.get(LinkedHashSet::new);
}

View File

@@ -15,15 +15,22 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.StreamEntry;
import redis.clients.jedis.BuilderFactory;
import redis.clients.jedis.StreamEntryID;
import redis.clients.jedis.StreamPendingEntry;
import redis.clients.jedis.params.XAddParams;
import redis.clients.jedis.params.XClaimParams;
import redis.clients.jedis.params.XPendingParams;
import redis.clients.jedis.params.XReadGroupParams;
import redis.clients.jedis.params.XReadParams;
import redis.clients.jedis.resps.StreamEntry;
import redis.clients.jedis.resps.StreamPendingEntry;
import redis.clients.jedis.params.XAddParams;
import redis.clients.jedis.util.SafeEncoder;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -37,8 +44,10 @@ import org.springframework.data.redis.connection.stream.Consumer;
import org.springframework.data.redis.connection.stream.MapRecord;
import org.springframework.data.redis.connection.stream.PendingMessage;
import org.springframework.data.redis.connection.stream.PendingMessages;
import org.springframework.data.redis.connection.stream.PendingMessagesSummary;
import org.springframework.data.redis.connection.stream.RecordId;
import org.springframework.data.redis.connection.stream.StreamOffset;
import org.springframework.data.redis.connection.stream.StreamReadOptions;
import org.springframework.data.redis.connection.stream.StreamRecords;
/**
@@ -103,9 +112,10 @@ class StreamConverters {
return sources;
}
static Map<byte[], byte[]> toStreamOffsets(StreamOffset<byte[]>[] streams) {
static Map.Entry<byte[], byte[]>[] toStreamOffsets(StreamOffset<byte[]>[] streams) {
return Arrays.stream(streams)
.collect(Collectors.toMap(StreamOffset::getKey, v -> JedisConverters.toBytes(v.getOffset().getOffset())));
.collect(Collectors.toMap(StreamOffset::getKey, v -> JedisConverters.toBytes(v.getOffset().getOffset())))
.entrySet().toArray(new Map.Entry[0]);
}
static List<ByteRecord> convertToByteRecord(byte[] key, Object source) {
@@ -150,6 +160,32 @@ class StreamConverters {
return result;
}
static PendingMessagesSummary toPendingMessagesSummary(String groupName, Object source) {
List<Object> objectList = (List<Object>) source;
long total = BuilderFactory.LONG.build(objectList.get(0));
Range.Bound<String> lower = objectList.get(1) != null
? Range.Bound.inclusive(SafeEncoder.encode((byte[]) objectList.get(1)))
: Range.Bound.unbounded();
Range.Bound<String> upper = objectList.get(2) != null
? Range.Bound.inclusive(SafeEncoder.encode((byte[]) objectList.get(2)))
: Range.Bound.unbounded();
List<List<Object>> consumerObjList = (List<List<Object>>) objectList.get(3);
Map<String, Long> map;
if (consumerObjList != null) {
map = new HashMap<>(consumerObjList.size());
for (List<Object> consumerObj : consumerObjList) {
map.put(SafeEncoder.encode((byte[]) consumerObj.get(0)),
Long.parseLong(SafeEncoder.encode((byte[]) consumerObj.get(1))));
}
} else {
map = Collections.emptyMap();
}
return new PendingMessagesSummary(groupName, total, Range.of(lower, upper), map);
}
/**
* Convert the raw Jedis xpending result to {@link PendingMessages}.
*
@@ -170,10 +206,10 @@ class StreamConverters {
return new PendingMessages(groupName, messages).withinRange(range);
}
static XAddParams toXAddParams(MapRecord<byte[], byte[], byte[]> record, RedisStreamCommands.XAddOptions options) {
public static XAddParams toXAddParams(RedisStreamCommands.XAddOptions options, RecordId recordId) {
XAddParams params = XAddParams.xAddParams();
params.id(record.getId().getValue());
XAddParams params = new XAddParams();
params.id(toStreamEntryId(recordId.getValue()));
if (options.hasMaxlen()) {
params.maxLen(options.getMaxlen());
@@ -193,4 +229,89 @@ class StreamConverters {
return params;
}
private static StreamEntryID toStreamEntryId(String value) {
if ("*".equals(value)) {
return StreamEntryID.NEW_ENTRY;
}
if ("$".equals(value)) {
return StreamEntryID.LAST_ENTRY;
}
if (">".equals(value)) {
return StreamEntryID.UNRECEIVED_ENTRY;
}
return new StreamEntryID(value);
}
public static XClaimParams toXClaimParams(RedisStreamCommands.XClaimOptions options) {
XClaimParams params = XClaimParams.xClaimParams();
if (options.isForce()) {
params.force();
}
if (options.getRetryCount() != null) {
params.retryCount(options.getRetryCount().intValue());
}
if (options.getUnixTime() != null) {
params.time(options.getUnixTime().toEpochMilli());
}
return params;
}
public static XReadParams toXReadParams(StreamReadOptions readOptions) {
XReadParams params = XReadParams.xReadParams();
if (readOptions.isBlocking()) {
params.block(readOptions.getBlock().intValue());
}
if (readOptions.getCount() != null) {
params.count(readOptions.getCount().intValue());
}
return params;
}
public static XReadGroupParams toXReadGroupParams(StreamReadOptions readOptions) {
XReadGroupParams params = XReadGroupParams.xReadGroupParams();
if (readOptions.isBlocking()) {
params.block(readOptions.getBlock().intValue());
}
if (readOptions.getCount() != null) {
params.count(readOptions.getCount().intValue());
}
if (readOptions.isNoack()) {
params.noAck();
}
return params;
}
public static XPendingParams toXPendingParams(RedisStreamCommands.XPendingOptions options) {
Range<String> range = (Range<String>) options.getRange();
XPendingParams xPendingParams = XPendingParams.xPendingParams(StreamConverters.getLowerValue(range),
StreamConverters.getUpperValue(range), options.getCount().intValue());
if (options.hasConsumer()) {
xPendingParams.consumer(options.getConsumerName());
}
return xPendingParams;
}
}

View File

@@ -448,7 +448,7 @@ public abstract class AbstractConnectionIntegrationTests {
}
@Test
void testPingPong() {
public void testPingPong() {
actual.add(connection.ping());
verifyResults(new ArrayList<>(Collections.singletonList("PONG")));
}
@@ -544,7 +544,7 @@ public abstract class AbstractConnectionIntegrationTests {
}
@Test
void testInfo() {
public void testInfo() {
actual.add(connection.info());
List<Object> results = getResults();
@@ -763,7 +763,7 @@ public abstract class AbstractConnectionIntegrationTests {
}
@Test
void testMultiAlreadyInTx() {
public void testMultiAlreadyInTx() {
connection.multi();
// Ensure it's OK to call multi twice
testMultiExec();
@@ -882,7 +882,7 @@ public abstract class AbstractConnectionIntegrationTests {
}
@Test
void testDbSize() {
public void testDbSize() {
actual.add(connection.set("dbparam", "foo"));
actual.add(connection.dbSize());
@@ -890,7 +890,7 @@ public abstract class AbstractConnectionIntegrationTests {
}
@Test
void testFlushDb() {
public void testFlushDb() {
connection.flushDb();
actual.add(connection.dbSize());
verifyResults(Arrays.asList(new Object[] { 0L }));
@@ -905,7 +905,7 @@ public abstract class AbstractConnectionIntegrationTests {
}
@Test
void testEcho() {
public void testEcho() {
actual.add(connection.echo("Hello World"));
verifyResults(Arrays.asList(new Object[] { "Hello World" }));
}
@@ -2525,14 +2525,14 @@ public abstract class AbstractConnectionIntegrationTests {
}
@Test
void testLastSave() {
public void testLastSave() {
actual.add(connection.lastSave());
List<Object> results = getResults();
assertThat(results.get(0)).isNotNull();
}
@Test // DATAREDIS-206, DATAREDIS-513
void testGetTimeShouldRequestServerTime() {
public void testGetTimeShouldRequestServerTime() {
actual.add(connection.time());
@@ -2543,7 +2543,7 @@ public abstract class AbstractConnectionIntegrationTests {
}
@Test // GH-526
void testGetTimeShouldRequestServerTimeAsMicros() {
public void testGetTimeShouldRequestServerTimeAsMicros() {
actual.add(connection.time(TimeUnit.MICROSECONDS));
actual.add(connection.time(TimeUnit.SECONDS));
@@ -2629,21 +2629,17 @@ public abstract class AbstractConnectionIntegrationTests {
connection.lPush("list", "foo");
connection.sAdd("set", "foo");
try (Cursor<byte[]> cursor = connection.scan(KeyScanOptions.scanOptions().type("set").build())) {
assertThat(toList(cursor)).hasSize(1).contains("set");
}
Cursor<byte[]> cursor = connection.scan(KeyScanOptions.scanOptions().type("set").build());
assertThat(toList(cursor)).hasSize(1).contains("set");
try (Cursor<byte[]> cursor = connection.scan(KeyScanOptions.scanOptions().type("string").match("k*").build())) {
assertThat(toList(cursor)).hasSize(1).contains("key");
}
cursor = connection.scan(KeyScanOptions.scanOptions().type("string").match("k*").build());
assertThat(toList(cursor)).hasSize(1).contains("key");
try (Cursor<byte[]> cursor = connection.scan(KeyScanOptions.scanOptions().match("k*").build())) {
assertThat(toList(cursor)).hasSize(1).contains("key");
}
cursor = connection.scan(KeyScanOptions.scanOptions().match("k*").build());
assertThat(toList(cursor)).hasSize(1).contains("key");
try (Cursor<byte[]> cursor = connection.scan(KeyScanOptions.scanOptions().build())) {
assertThat(toList(cursor)).contains("key", "list", "set");
}
cursor = connection.scan(KeyScanOptions.scanOptions().build());
assertThat(toList(cursor)).contains("key", "list", "set");
}
private static List<String> toList(Cursor<byte[]> cursor) {
@@ -2841,7 +2837,7 @@ public abstract class AbstractConnectionIntegrationTests {
@SuppressWarnings("unchecked")
@Test // DATAREDIS-729
void zRevRangeByLexTest() {
public void zRevRangeByLexTest() {
actual.add(connection.zAdd("myzset", 0, "a"));
actual.add(connection.zAdd("myzset", 0, "b"));
@@ -3305,7 +3301,6 @@ public abstract class AbstractConnectionIntegrationTests {
@Test // GH-2043
@EnabledOnCommand("GEOSEARCH")
@EnabledOnRedisDriver(RedisDriver.LETTUCE)
void geoSearchByMemberShouldReturnMembersCorrectly() {
String key = "geo-" + UUID.randomUUID();
@@ -3323,7 +3318,6 @@ public abstract class AbstractConnectionIntegrationTests {
@Test // GH-2043
@EnabledOnCommand("GEOSEARCH")
@EnabledOnRedisDriver(RedisDriver.LETTUCE)
void geoSearchByPointShouldReturnMembersCorrectly() {
String key = "geo-" + UUID.randomUUID();
@@ -3341,7 +3335,6 @@ public abstract class AbstractConnectionIntegrationTests {
@Test // GH-2043
@EnabledOnCommand("GEOSEARCH")
@EnabledOnRedisDriver(RedisDriver.LETTUCE)
void geoSearchShouldConsiderDistanceCorrectly() {
String key = "geo-" + UUID.randomUUID();
@@ -3361,7 +3354,6 @@ public abstract class AbstractConnectionIntegrationTests {
@Test // GH-2043
@EnabledOnCommand("GEOSEARCHSTORE")
@EnabledOnRedisDriver(RedisDriver.LETTUCE)
void geoSearchStoreByMemberShouldStoreResult() {
String key = "geo-" + UUID.randomUUID();
@@ -3381,7 +3373,6 @@ public abstract class AbstractConnectionIntegrationTests {
@Test // GH-2043
@EnabledOnCommand("GEOSEARCHSTORE")
@EnabledOnRedisDriver(RedisDriver.LETTUCE)
void geoSearchStoreByPointShouldStoreResult() {
String key = "geo-" + UUID.randomUUID();
@@ -3763,7 +3754,6 @@ public abstract class AbstractConnectionIntegrationTests {
@Test // DATAREDIS-1084
@EnabledOnCommand("XADD")
@EnabledOnRedisDriver(RedisDriver.LETTUCE)
void xPendingShouldLoadOverviewCorrectly() {
actual.add(connection.xAdd(KEY_1, Collections.singletonMap(KEY_2, VALUE_2)));
@@ -3785,7 +3775,6 @@ public abstract class AbstractConnectionIntegrationTests {
@Test // DATAREDIS-1084
@EnabledOnCommand("XADD")
@EnabledOnRedisDriver(RedisDriver.LETTUCE)
void xPendingShouldLoadEmptyOverviewCorrectly() {
actual.add(connection.xAdd(KEY_1, Collections.singletonMap(KEY_2, VALUE_2)));

View File

@@ -17,9 +17,9 @@ package org.springframework.data.redis.connection;
import static org.assertj.core.api.Assertions.*;
import redis.clients.jedis.ConnectionPool;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;
import java.util.Random;
@@ -47,8 +47,8 @@ public class ClusterSlotHashUtilsTests {
@Test
void localCalculationShouldMatchServers() {
JedisPool pool = cluster.getClusterNodes().values().iterator().next();
Jedis jedis = pool.getResource();
ConnectionPool pool = cluster.getClusterNodes().values().iterator().next();
Jedis jedis = new Jedis(pool.getResource());
for (int i = 0; i < 100; i++) {
String key = randomString();
@@ -66,8 +66,8 @@ public class ClusterSlotHashUtilsTests {
@Test
void localCalculationShoudMatchServersForPrefixedKeys() {
JedisPool pool = cluster.getClusterNodes().values().iterator().next();
Jedis jedis = pool.getResource();
ConnectionPool pool = cluster.getClusterNodes().values().iterator().next();
Jedis jedis = new Jedis(pool.getResource());
for (int i = 0; i < 100; i++) {
String slotPrefix = "{" + randomString() + "}";

View File

@@ -27,10 +27,10 @@ import static org.springframework.data.redis.connection.RedisListCommands.*;
import static org.springframework.data.redis.connection.RedisZSetCommands.*;
import static org.springframework.data.redis.core.ScanOptions.*;
import redis.clients.jedis.ConnectionPool;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;
import java.io.IOException;
import java.nio.charset.Charset;
@@ -121,8 +121,8 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
@BeforeEach
void tearDown() throws IOException {
for (JedisPool pool : nativeConnection.getClusterNodes().values()) {
try (Jedis jedis = pool.getResource()) {
for (ConnectionPool pool : nativeConnection.getClusterNodes().values()) {
try (Jedis jedis = new Jedis(pool.getResource())) {
jedis.flushAll();
} catch (Exception e) {
// ignore this one since we cannot remove data from replicas
@@ -372,7 +372,8 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
@Test // DATAREDIS-315
public void echoShouldReturnInputCorrectly() {
assertThat(clusterConnection.echo(VALUE_1_BYTES)).isEqualTo(VALUE_1_BYTES);
assertThatExceptionOfType(InvalidDataAccessApiUsageException.class)
.isThrownBy(() -> clusterConnection.echo(VALUE_1_BYTES));
}
@Test // DATAREDIS-315
@@ -1986,7 +1987,7 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
clusterConnection.set(KEY_1_BYTES, VALUE_1_BYTES, Expiration.milliseconds(500), SetOption.upsert());
assertThat(nativeConnection.exists(KEY_1_BYTES)).isTrue();
assertThat(nativeConnection.pttl(KEY_1).doubleValue()).isCloseTo(500d, offset(499d));
assertThat(nativeConnection.pttl(KEY_1)).isCloseTo(500L, offset(499L));
}
@Test // DATAREDIS-316

View File

@@ -1,442 +0,0 @@
/*
* Copyright 2015-2022 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.redis.connection.jedis;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import static org.springframework.data.redis.connection.ClusterTestVariables.*;
import static org.springframework.data.redis.test.util.MockitoUtils.*;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisClusterConnectionHandler;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisConnectionException;
import java.io.IOException;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import org.mockito.stubbing.Answer;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.data.redis.ClusterStateFailureException;
import org.springframework.data.redis.RedisSystemException;
import org.springframework.data.redis.connection.ClusterInfo;
import org.springframework.data.redis.connection.RedisClusterCommands.AddSlots;
import org.springframework.data.redis.connection.RedisClusterNode;
import org.springframework.data.redis.connection.jedis.JedisClusterConnection.JedisClusterTopologyProvider;
/**
* @author Christoph Strobl
* @author Mark Paluch
* @author Chen Guanqun
*/
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class JedisClusterConnectionUnitTests {
private static final String CLUSTER_NODES_RESPONSE = "" //
+ MASTER_NODE_1_ID + " " + CLUSTER_HOST + ":" + MASTER_NODE_1_PORT + " myself,master - 0 0 1 connected 0-5460"
+ "\n" + MASTER_NODE_2_ID + " " + CLUSTER_HOST + ":" + MASTER_NODE_2_PORT
+ " master - 0 1427718161587 2 connected 5461-10922" + "\n" + MASTER_NODE_2_ID + " " + CLUSTER_HOST + ":"
+ MASTER_NODE_3_PORT + " master - 0 1427718161587 3 connected 10923-16383";
private static final String CLUSTER_INFO_RESPONSE = "cluster_state:ok" + "\n" + "cluster_slots_assigned:16384" + "\n"
+ "cluster_slots_ok:16384" + "\n" + "cluster_slots_pfail:0" + "\n" + "cluster_slots_fail:0" + "\n"
+ "cluster_known_nodes:4" + "\n" + "cluster_size:3" + "\n" + "cluster_current_epoch:30" + "\n"
+ "cluster_my_epoch:2" + "\n" + "cluster_stats_messages_sent:2560260" + "\n"
+ "cluster_stats_messages_received:2560086";
private JedisClusterConnection connection;
@Spy StubJedisCluster clusterMock;
@Mock JedisClusterConnectionHandler connectionHandlerMock;
@Mock JedisPool node1PoolMock;
@Mock JedisPool node2PoolMock;
@Mock JedisPool node3PoolMock;
@Mock Jedis con1Mock;
@Mock Jedis con2Mock;
@Mock Jedis con3Mock;
private Map<String, JedisPool> nodes = new LinkedHashMap<>();
@BeforeEach
void setUp() {
nodes.put(CLUSTER_HOST + ":" + MASTER_NODE_1_PORT, node1PoolMock);
nodes.put(CLUSTER_HOST + ":" + MASTER_NODE_2_PORT, node2PoolMock);
nodes.put(CLUSTER_HOST + ":" + MASTER_NODE_3_PORT, node3PoolMock);
when(clusterMock.getClusterNodes()).thenReturn(nodes);
when(node1PoolMock.getResource()).thenReturn(con1Mock);
when(node2PoolMock.getResource()).thenReturn(con2Mock);
when(node3PoolMock.getResource()).thenReturn(con3Mock);
when(con1Mock.clusterNodes()).thenReturn(CLUSTER_NODES_RESPONSE);
when(con2Mock.clusterNodes()).thenReturn(CLUSTER_NODES_RESPONSE);
when(con3Mock.clusterNodes()).thenReturn(CLUSTER_NODES_RESPONSE);
clusterMock.setConnectionHandler(connectionHandlerMock);
connection = new JedisClusterConnection(clusterMock);
}
@Test // DATAREDIS-315
void throwsExceptionWhenClusterCommandExecutorIsNull() {
assertThatIllegalArgumentException().isThrownBy(() -> new JedisClusterConnection(clusterMock, null));
}
@Test // DATAREDIS-315
void clusterMeetShouldSendCommandsToExistingNodesCorrectly() {
connection.clusterMeet(UNKNOWN_CLUSTER_NODE);
verify(con1Mock, times(1)).clusterMeet(UNKNOWN_CLUSTER_NODE.getHost(), UNKNOWN_CLUSTER_NODE.getPort());
verify(con2Mock, times(1)).clusterMeet(UNKNOWN_CLUSTER_NODE.getHost(), UNKNOWN_CLUSTER_NODE.getPort());
verify(con2Mock, times(1)).clusterMeet(UNKNOWN_CLUSTER_NODE.getHost(), UNKNOWN_CLUSTER_NODE.getPort());
}
@Test // DATAREDIS-315
void clusterMeetShouldThrowExceptionWhenNodeIsNull() {
assertThatIllegalArgumentException().isThrownBy(() -> connection.clusterMeet(null));
}
@Test // DATAREDIS-315, DATAREDIS-890
void clusterForgetShouldSendCommandsToRemainingNodesCorrectly() {
connection.clusterForget(CLUSTER_NODE_2);
verify(con1Mock, times(1)).clusterForget(CLUSTER_NODE_2.getId());
verify(con3Mock, times(1)).clusterForget(CLUSTER_NODE_2.getId());
}
@Test // DATAREDIS-315, DATAREDIS-890
void clusterReplicateShouldSendCommandsCorrectly() {
connection.clusterReplicate(CLUSTER_NODE_1, CLUSTER_NODE_2);
verify(con2Mock, times(1)).clusterReplicate(CLUSTER_NODE_1.getId());
verify(con1Mock, atMost(1)).clusterNodes();
verify(con1Mock, atMost(1)).close();
verifyNoMoreInteractions(con1Mock);
}
@Test // DATAREDIS-315
void closeShouldNotCloseUnderlyingClusterPool() throws IOException {
connection.close();
verify(clusterMock, never()).close();
}
@Test // DATAREDIS-315
void isClosedShouldReturnConnectionStateCorrectly() {
assertThat(connection.isClosed()).isFalse();
connection.close();
assertThat(connection.isClosed()).isTrue();
}
@Test // DATAREDIS-315
void clusterInfoShouldBeReturnedCorrectly() {
when(con1Mock.clusterInfo()).thenReturn(CLUSTER_INFO_RESPONSE);
when(con2Mock.clusterInfo()).thenReturn(CLUSTER_INFO_RESPONSE);
when(con3Mock.clusterInfo()).thenReturn(CLUSTER_INFO_RESPONSE);
ClusterInfo p = connection.clusterGetClusterInfo();
assertThat(p.getSlotsAssigned()).isEqualTo(16384L);
verifyInvocationsAcross("clusterInfo", times(1), con1Mock, con2Mock, con3Mock);
}
@Test // DATAREDIS-315
void clusterSetSlotImportingShouldBeExecutedCorrectly() {
connection.clusterSetSlot(CLUSTER_NODE_1, 100, AddSlots.IMPORTING);
verify(con1Mock, times(1)).clusterSetSlotImporting(eq(100), eq(CLUSTER_NODE_1.getId()));
}
@Test // DATAREDIS-315
void clusterSetSlotMigratingShouldBeExecutedCorrectly() {
connection.clusterSetSlot(CLUSTER_NODE_1, 100, AddSlots.MIGRATING);
verify(con1Mock, times(1)).clusterSetSlotMigrating(eq(100), eq(CLUSTER_NODE_1.getId()));
}
@Test // DATAREDIS-315
void clusterSetSlotStableShouldBeExecutedCorrectly() {
connection.clusterSetSlot(CLUSTER_NODE_1, 100, AddSlots.STABLE);
verify(con1Mock, times(1)).clusterSetSlotStable(eq(100));
}
@Test // DATAREDIS-315
void clusterSetSlotNodeShouldBeExecutedCorrectly() {
connection.clusterSetSlot(CLUSTER_NODE_1, 100, AddSlots.NODE);
verify(con1Mock, times(1)).clusterSetSlotNode(eq(100), eq(CLUSTER_NODE_1.getId()));
}
@Test // DATAREDIS-315
void clusterSetSlotShouldBeExecutedOnTargetNodeWhenNodeIdNotSet() {
connection.clusterSetSlot(new RedisClusterNode(CLUSTER_HOST, MASTER_NODE_2_PORT), 100, AddSlots.IMPORTING);
verify(con2Mock, times(1)).clusterSetSlotImporting(eq(100), eq(CLUSTER_NODE_2.getId()));
}
@Test // DATAREDIS-315
void clusterSetSlotShouldThrowExceptionWhenModeIsNull() {
assertThatIllegalArgumentException().isThrownBy(() -> connection.clusterSetSlot(CLUSTER_NODE_1, 100, null));
}
@Test // DATAREDIS-315
void clusterDeleteSlotsShouldBeExecutedCorrectly() {
int[] slots = new int[] { 9000, 10000 };
connection.clusterDeleteSlots(CLUSTER_NODE_2, slots);
verify(con2Mock, times(1)).clusterDelSlots((int[]) any());
}
@Test // DATAREDIS-315
void clusterDeleteSlotShouldThrowExceptionWhenNodeIsNull() {
assertThatIllegalArgumentException().isThrownBy(() -> connection.clusterDeleteSlots(null, new int[] { 1 }));
}
@Test // DATAREDIS-315
void timeShouldBeExecutedOnArbitraryNode() {
List<String> values = Arrays.asList("1449655759", "92217");
when(con1Mock.time()).thenReturn(values);
when(con2Mock.time()).thenReturn(values);
when(con3Mock.time()).thenReturn(values);
connection.time();
verifyInvocationsAcross("time", times(1), con1Mock, con2Mock, con3Mock);
}
@Test // DATAREDIS-679
void shouldFailWithUnknownNode() {
try {
connection.serverCommands().dbSize(new RedisClusterNode(CLUSTER_HOST, REPLICAOF_NODE_1_PORT));
} catch (IllegalArgumentException e) {
assertThat(e.getMessage())
.contains("Node " + CLUSTER_HOST + ":" + REPLICAOF_NODE_1_PORT + " is unknown to cluster");
}
}
@Test // DATAREDIS-679
void shouldFailWithAbsentConnection() {
nodes.remove(CLUSTER_HOST + ":" + MASTER_NODE_3_PORT);
assertThatExceptionOfType(DataAccessResourceFailureException.class)
.isThrownBy(() -> connection.serverCommands().dbSize(new RedisClusterNode(CLUSTER_HOST, MASTER_NODE_3_PORT)))
.withMessageContaining("Node " + CLUSTER_HOST + ":" + MASTER_NODE_3_PORT + " is unknown to cluster");
}
@Test // DATAREDIS-679
void shouldReconfigureJedisWithDiscoveredNode() {
nodes.remove(CLUSTER_HOST + ":" + MASTER_NODE_3_PORT);
when(connectionHandlerMock.getConnectionFromNode(new HostAndPort(CLUSTER_HOST, MASTER_NODE_3_PORT)))
.thenReturn(con3Mock);
when(con3Mock.dbSize()).thenAnswer(new Answer<Long>() {
@Override
public Long answer(InvocationOnMock invocation) throws Throwable {
// Required to return the resource properly after invocation.
nodes.put(CLUSTER_HOST + ":" + MASTER_NODE_3_PORT, node3PoolMock);
return 42L;
}
});
Long result = connection.serverCommands().dbSize(new RedisClusterNode(CLUSTER_HOST, MASTER_NODE_3_PORT));
assertThat(result).isEqualTo(42L);
}
@Test // DATAREDIS-315, DATAREDIS-890
void timeShouldBeExecutedOnSingleNode() {
when(con2Mock.time()).thenReturn(Arrays.asList("1449655759", "92217"));
connection.time(CLUSTER_NODE_2);
verify(con2Mock, times(1)).time();
verify(con2Mock, atLeast(1)).close();
verify(con1Mock, atMost(1)).clusterNodes();
verify(con1Mock, atMost(1)).close();
}
@Test // DATAREDIS-315
void resetConfigStatsShouldBeExecutedOnAllNodes() {
connection.resetConfigStats();
verify(con1Mock, times(1)).configResetStat();
verify(con2Mock, times(1)).configResetStat();
verify(con3Mock, times(1)).configResetStat();
}
@Test // DATAREDIS-315, DATAREDIS-890
void resetConfigStatsShouldBeExecutedOnSingleNodeCorrectly() {
connection.resetConfigStats(CLUSTER_NODE_2);
verify(con2Mock, times(1)).configResetStat();
verify(con2Mock, atLeast(1)).close();
verify(con1Mock, never()).configResetStat();
verify(con3Mock, never()).configResetStat();
}
@Test // GH-1992
void rewriteConfigShouldBeExecutedOnAllNodes() {
connection.rewriteConfig();
verify(con1Mock, times(1)).configRewrite();
verify(con2Mock, times(1)).configRewrite();
verify(con3Mock, times(1)).configRewrite();
}
@Test // GH-1992
void rewriteConfigShouldBeExecutedOnSingleNodeCorrectly() {
connection.rewriteConfig(CLUSTER_NODE_2);
verify(con2Mock, times(1)).configRewrite();
verify(con2Mock, atLeast(1)).close();
verify(con1Mock, never()).configRewrite();
verify(con3Mock, never()).configRewrite();
}
@Test // DATAREDIS-315
void clusterTopologyProviderShouldCollectErrorsWhenLoadingNodes() {
when(con1Mock.clusterNodes()).thenThrow(new JedisConnectionException("o.O"));
when(con2Mock.clusterNodes()).thenThrow(new JedisConnectionException("o.1"));
when(con3Mock.clusterNodes()).thenThrow(new JedisConnectionException("o.2"));
assertThatExceptionOfType(ClusterStateFailureException.class)
.isThrownBy(() -> new JedisClusterTopologyProvider(clusterMock).getTopology())
.withMessageContaining("127.0.0.1:7379 failed: o.O").withMessageContaining("127.0.0.1:7380 failed: o.1");
}
@Test // DATAREDIS-603
void translatesUnknownExceptions() {
IllegalArgumentException exception = new IllegalArgumentException("Aw, snap!");
doThrow(exception).when(clusterMock).set("foo".getBytes(), "bar".getBytes());
assertThatExceptionOfType(RedisSystemException.class)
.isThrownBy(() -> connection.set("foo".getBytes(), "bar".getBytes()))
.withMessageContaining(exception.getMessage()).withCause(exception);
}
@Test // DATAREDIS-794
void clusterTopologyProviderShouldUseCachedTopology() {
when(clusterMock.getClusterNodes()).thenReturn(Collections.singletonMap("mock", node1PoolMock));
when(con1Mock.clusterNodes()).thenReturn(CLUSTER_NODES_RESPONSE);
JedisClusterTopologyProvider provider = new JedisClusterTopologyProvider(clusterMock, Duration.ofSeconds(5));
provider.getTopology();
provider.getTopology();
verify(con1Mock).clusterNodes();
}
@Test // DATAREDIS-794
void clusterTopologyProviderShouldRequestTopology() {
when(clusterMock.getClusterNodes()).thenReturn(Collections.singletonMap("mock", node1PoolMock));
when(con1Mock.clusterNodes()).thenReturn(CLUSTER_NODES_RESPONSE);
JedisClusterTopologyProvider provider = new JedisClusterTopologyProvider(clusterMock, Duration.ZERO);
provider.getTopology();
provider.getTopology();
verify(con1Mock, times(2)).clusterNodes();
}
@Test // GH-1985
void nodeWithoutHostShouldRejectConnectionAttempt() {
reset(con1Mock, con2Mock, con3Mock);
when(con1Mock.clusterNodes())
.thenReturn("ef570f86c7b1a953846668debc177a3a16733420 :6379 fail,master - 0 0 1 connected");
when(con2Mock.clusterNodes())
.thenReturn("ef570f86c7b1a953846668debc177a3a16733420 :6379 fail,master - 0 0 1 connected");
when(con3Mock.clusterNodes())
.thenReturn("ef570f86c7b1a953846668debc177a3a16733420 :6379 fail,master - 0 0 1 connected");
JedisClusterConnection connection = new JedisClusterConnection(clusterMock);
assertThatThrownBy(() -> connection.ping(new RedisClusterNode("ef570f86c7b1a953846668debc177a3a16733420")))
.isInstanceOf(DataAccessResourceFailureException.class)
.hasMessageContaining("ef570f86c7b1a953846668debc177a3a16733420");
}
static class StubJedisCluster extends JedisCluster {
JedisClusterConnectionHandler connectionHandler;
public StubJedisCluster() {
super(Collections.emptySet());
}
JedisClusterConnectionHandler getConnectionHandler() {
return connectionHandler;
}
void setConnectionHandler(JedisClusterConnectionHandler connectionHandler) {
this.connectionHandler = connectionHandler;
}
}
}

View File

@@ -20,8 +20,6 @@ import static org.mockito.Mockito.*;
import redis.clients.jedis.JedisClientConfig;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisClusterConnectionHandler;
import redis.clients.jedis.JedisClusterInfoCache;
import redis.clients.jedis.JedisPoolConfig;
import java.io.IOException;
@@ -307,50 +305,6 @@ class JedisConnectionFactoryUnitTests {
assertThat(connectionFactory.getClusterConfiguration()).isSameAs(configuration);
}
@Test // DATAREDIS-974, GH-2017
void shouldApplySslConfigWhenCreatingClusterClient() throws NoSuchAlgorithmException {
SSLParameters sslParameters = new SSLParameters();
SSLContext context = SSLContext.getDefault();
SSLSocketFactory socketFactory = context.getSocketFactory();
JedisPoolConfig poolConfig = new JedisPoolConfig();
HostnameVerifier hostNameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
JedisClientConfiguration configuration = JedisClientConfiguration.builder() //
.useSsl() //
.hostnameVerifier(hostNameVerifier) //
.sslParameters(sslParameters) //
.sslSocketFactory(socketFactory).and() //
.clientName("my-client") //
.connectTimeout(Duration.ofMinutes(1)) //
.readTimeout(Duration.ofMinutes(5)) //
.usePooling().poolConfig(poolConfig) //
.build();
connectionFactory = new JedisConnectionFactory(new RedisClusterConfiguration(), configuration);
connectionFactory.afterPropertiesSet();
RedisClusterConnection connection = connectionFactory.getClusterConnection();
assertThat(connection).isInstanceOf(JedisClusterConnection.class);
JedisCluster cluster = ((JedisClusterConnection) connection).getCluster();
JedisClusterConnectionHandler connectionHandler = (JedisClusterConnectionHandler) ReflectionTestUtils
.getField(cluster, "connectionHandler");
JedisClusterInfoCache cache = (JedisClusterInfoCache) ReflectionTestUtils.getField(connectionHandler, "cache");
JedisClientConfig clientConfig = (JedisClientConfig) ReflectionTestUtils.getField(cache, "clientConfig");
assertThat(clientConfig.getConnectionTimeoutMillis()).isEqualTo(60000);
assertThat(clientConfig.getSocketTimeoutMillis()).isEqualTo(300000);
assertThat(clientConfig.getPassword()).isNull();
assertThat(clientConfig.getClientName()).isEqualTo("my-client");
assertThat(clientConfig.isSsl()).isEqualTo(true);
assertThat(clientConfig.getSslSocketFactory()).isEqualTo(socketFactory);
assertThat(clientConfig.getSslParameters()).isEqualTo(sslParameters);
assertThat(clientConfig.getHostnameVerifier()).isEqualTo(hostNameVerifier);
assertThat(clientConfig.getHostAndPortMapper()).isNull();
}
@Test // DATAREDIS-574
void shouldDenyChangesToImmutableClientConfiguration() throws NoSuchAlgorithmException {

View File

@@ -19,9 +19,6 @@ import static org.assertj.core.api.Assertions.*;
import redis.clients.jedis.JedisPoolConfig;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@@ -29,9 +26,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.data.redis.SettingsUtils;
import org.springframework.data.redis.connection.AbstractConnectionPipelineIntegrationTests;
import org.springframework.data.redis.connection.DefaultStringRedisConnection;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.test.condition.EnabledOnCommand;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@@ -61,47 +56,6 @@ public class JedisConnectionPipelineIntegrationTests extends AbstractConnectionP
connection = null;
}
@Test
public void testWatch() {
connection.set("testitnow", "willdo");
connection.watch("testitnow".getBytes());
// Jedis doesn't actually send commands until you close the pipeline
getResults();
DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection(connectionFactory.getConnection());
conn2.set("testitnow", "something");
conn2.close();
// Reopen the pipeline
initConnection();
connection.multi();
connection.set("testitnow", "somethingelse");
actual.add(connection.exec());
actual.add(connection.get("testitnow"));
verifyResults(Arrays.asList(new Object[] { null, "something" }));
}
@SuppressWarnings("unchecked")
@Test
public void testUnwatch() throws Exception {
connection.set("testitnow", "willdo");
connection.watch("testitnow".getBytes());
// Jedis doesn't actually send commands until you close the pipeline
getResults();
initConnection();
connection.unwatch();
// Jedis doesn't actually send commands until you close the pipeline
getResults();
initConnection();
connection.multi();
DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection(connectionFactory.getConnection());
conn2.set("testitnow", "something");
connection.set("testitnow", "somethingelse");
connection.get("testitnow");
actual.add(connection.exec());
List<Object> results = getResults();
List<Object> execResults = (List<Object>) results.get(0);
assertThat(execResults).isEqualTo(Arrays.asList(new Object[] { true, "somethingelse" }));
}
@Test
// DATAREDIS-213 - Verify connection returns to pool after select
public void testClosePoolPipelinedDbSelect() {
@@ -219,108 +173,6 @@ public class JedisConnectionPipelineIntegrationTests extends AbstractConnectionP
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::clientSetNameWorksCorrectly);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xReadShouldReadMessage() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xReadShouldReadMessage);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xReadGroupShouldReadMessage() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xReadGroupShouldReadMessage);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xGroupCreateShouldWorkWithAndWithoutExistingStream() {
assertThatExceptionOfType(UnsupportedOperationException.class)
.isThrownBy(super::xGroupCreateShouldWorkWithAndWithoutExistingStream);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xPendingShouldLoadPendingMessages() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xPendingShouldLoadPendingMessages);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xPendingShouldWorkWithBoundedRange() {
assertThatExceptionOfType(UnsupportedOperationException.class)
.isThrownBy(super::xPendingShouldWorkWithBoundedRange);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xPendingShouldLoadPendingMessagesForConsumer() {
assertThatExceptionOfType(UnsupportedOperationException.class)
.isThrownBy(super::xPendingShouldLoadPendingMessagesForConsumer);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xPendingShouldLoadPendingMessagesForNonExistingConsumer() {
assertThatExceptionOfType(UnsupportedOperationException.class)
.isThrownBy(super::xPendingShouldLoadPendingMessagesForNonExistingConsumer);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xinfo() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xinfo);
}
@Test
@EnabledOnCommand("XADD")
@Override
public void xinfoNoGroup() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xinfoNoGroup);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xinfoGroups() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xinfoGroups);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xinfoGroupsNoGroup() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xinfoGroupsNoGroup);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xinfoGroupsNoConsumer() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xinfoGroupsNoConsumer);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xinfoConsumers() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xinfoConsumers);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xinfoConsumersNoConsumer() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xinfoConsumersNoConsumer);
}
@Test
@Override
// DATAREDIS-268
@@ -332,4 +184,86 @@ public class JedisConnectionPipelineIntegrationTests extends AbstractConnectionP
@Test // DATAREDIS-296
@Disabled
public void testExecWithoutMulti() {}
@Test
@Override
@Disabled
public void testMultiExec() {}
@Test
@Override
@Disabled
public void testMultiDiscard() {}
@Test
@Override
@Disabled
public void testErrorInTx() {}
@Test
@Override
@Disabled
public void testWatch() {}
@Test
@Override
@Disabled
public void testUnwatch() {}
@Test
@Override
@Disabled
public void testMultiAlreadyInTx() {}
@Test
@Override
@Disabled
public void testPingPong() {}
@Test
@Override
@Disabled
public void testFlushDb() {}
@Override
@Disabled
public void testEcho() {}
@Override
@Disabled
public void testInfo() {}
@Override
@Disabled
public void testInfoBySection() {}
@Override
@Disabled
public void testMove() {}
@Test
@Override
@Disabled
public void testGetConfig() {}
@Test
@Override
@Disabled
public void testLastSave() {}
@Test
@Override
@Disabled
public void testGetTimeShouldRequestServerTime() {}
@Test
@Override
@Disabled
public void testGetTimeShouldRequestServerTimeAsMicros() {}
@Test
@Override
@Disabled
public void testDbSize() {}
}

View File

@@ -1,59 +0,0 @@
/*
* Copyright 2013-2022 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.redis.connection.jedis;
import static org.assertj.core.api.Assertions.*;
import java.util.List;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
/**
* @author Jennifer Hickey
* @author Christoph Strobl
*/
public class JedisConnectionPipelineTxIntegrationTests extends JedisConnectionTransactionIntegrationTests {
@Test
@Disabled
public void testRestoreBadData() {}
@Test
@Disabled
public void testRestoreExistingKey() {}
protected void initConnection() {
connection.openPipeline();
connection.multi();
}
@SuppressWarnings("unchecked")
protected List<Object> getResults() {
assertThat(connection.exec()).isNull();
List<Object> pipelined = connection.closePipeline();
// We expect only the results of exec to be in the closed pipeline
assertThat(pipelined.size()).isEqualTo(1);
List<Object> txResults = (List<Object>) pipelined.get(0);
// Return exec results and this test should behave exactly like its superclass
return txResults;
}
@Test
@Disabled
public void testListClientsContainsAtLeastOneElement() {}
}

View File

@@ -24,7 +24,6 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.data.redis.connection.AbstractConnectionTransactionIntegrationTests;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.test.condition.EnabledOnCommand;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@@ -189,106 +188,90 @@ public class JedisConnectionTransactionIntegrationTests extends AbstractConnecti
.isThrownBy(super::testListClientsContainsAtLeastOneElement);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xReadShouldReadMessage() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xReadShouldReadMessage);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xReadGroupShouldReadMessage() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xReadGroupShouldReadMessage);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xGroupCreateShouldWorkWithAndWithoutExistingStream() {
assertThatExceptionOfType(UnsupportedOperationException.class)
.isThrownBy(super::xGroupCreateShouldWorkWithAndWithoutExistingStream);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xPendingShouldLoadPendingMessages() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xPendingShouldLoadPendingMessages);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xPendingShouldWorkWithBoundedRange() {
assertThatExceptionOfType(UnsupportedOperationException.class)
.isThrownBy(super::xPendingShouldWorkWithBoundedRange);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xPendingShouldLoadPendingMessagesForConsumer() {
assertThatExceptionOfType(UnsupportedOperationException.class)
.isThrownBy(super::xPendingShouldLoadPendingMessagesForConsumer);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xPendingShouldLoadPendingMessagesForNonExistingConsumer() {
assertThatExceptionOfType(UnsupportedOperationException.class)
.isThrownBy(super::xPendingShouldLoadPendingMessagesForNonExistingConsumer);
}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Override
public void xinfo() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xinfo);
}
@Test // DATAREDIS-296
@Disabled
public void testExecWithoutMulti() {}
@Test
@EnabledOnCommand("XADD")
@Override
public void xinfoNoGroup() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xinfoNoGroup);
}
@Disabled
public void testMultiExec() {}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Test
@Override
public void xinfoGroups() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xinfoGroups);
}
@Disabled
public void testMultiDiscard() {}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Test
@Override
public void xinfoGroupsNoGroup() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xinfoGroupsNoGroup);
}
@Disabled
public void testErrorInTx() {}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Test
@Override
public void xinfoGroupsNoConsumer() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xinfoGroupsNoConsumer);
}
@Disabled
public void testWatch() {}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Test
@Override
public void xinfoConsumers() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xinfoConsumers);
}
@Disabled
public void testUnwatch() {}
@Test // GH-1711
@EnabledOnCommand("XADD")
@Test
@Override
public void xinfoConsumersNoConsumer() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::xinfoConsumersNoConsumer);
}
@Disabled
public void testMultiAlreadyInTx() {}
@Test
@Override
@Disabled
public void testPingPong() {}
@Test
@Override
@Disabled
public void testFlushDb() {}
@Override
@Disabled
public void testEcho() {}
@Override
@Disabled
public void testInfo() {}
@Override
@Disabled
public void testMove() {}
@Test
@Override
@Disabled
public void testLastSave() {}
@Test
@Override
@Disabled
public void testGetTimeShouldRequestServerTime() {}
@Test
@Override
@Disabled
public void testGetTimeShouldRequestServerTimeAsMicros() {}
@Test
@Override
@Disabled
public void testDbSize() {}
@Test
@Override
@Disabled
public void testSelect() {}
@Test
@Override
@Disabled("Parameter ordering in zrevrangeByLex(byte[] key, byte[] max, byte[] min) is swapped so transactions use inverse parameter order")
public void zRevRangeByLexTest() {}
}

View File

@@ -18,18 +18,19 @@ package org.springframework.data.redis.connection.jedis;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import redis.clients.jedis.Client;
import redis.clients.jedis.Connection;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import redis.clients.jedis.args.SaveMode;
import redis.clients.jedis.exceptions.JedisException;
import redis.clients.jedis.params.ScanParams;
import redis.clients.jedis.resps.ScanResult;
import java.io.IOException;
import java.util.Collections;
import java.util.Map.Entry;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@@ -40,7 +41,6 @@ import org.springframework.data.redis.connection.RedisServerCommands.ShutdownOpt
import org.springframework.data.redis.connection.zset.Tuple;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.test.util.ReflectionTestUtils;
/**
* @author Christoph Strobl
@@ -48,7 +48,7 @@ import org.springframework.test.util.ReflectionTestUtils;
class JedisConnectionUnitTests {
@Nested
public class BasicUnitTests extends AbstractConnectionUnitTestBase<Client> {
public class BasicUnitTests extends AbstractConnectionUnitTestBase<Connection> {
protected JedisConnection connection;
private Jedis jedisSpy;
@@ -56,7 +56,7 @@ class JedisConnectionUnitTests {
@BeforeEach
public void setUp() {
jedisSpy = spy(new MockedClientJedis("http://localhost:1234", getNativeRedisConnectionMock()));
jedisSpy = spy(new Jedis(getNativeRedisConnectionMock()));
connection = new JedisConnection(jedisSpy);
}
@@ -69,7 +69,7 @@ class JedisConnectionUnitTests {
// all good. Sometimes it throws an Exception.
}
verifyNativeConnectionInvocation().shutdown();
verify(jedisSpy).shutdown();
}
@Test // DATAREDIS-184, GH-2153
@@ -77,7 +77,7 @@ class JedisConnectionUnitTests {
assertThatExceptionOfType(JedisException.class).isThrownBy(() -> connection.shutdown(ShutdownOption.NOSAVE));
verifyNativeConnectionInvocation().shutdown(SaveMode.NOSAVE);
verify(jedisSpy).shutdown(SaveMode.NOSAVE);
}
@Test // DATAREDIS-184, GH-2153
@@ -85,21 +85,21 @@ class JedisConnectionUnitTests {
assertThatExceptionOfType(JedisException.class).isThrownBy(() -> connection.shutdown(ShutdownOption.SAVE));
verifyNativeConnectionInvocation().shutdown(SaveMode.SAVE);
verify(jedisSpy).shutdown(SaveMode.SAVE);
}
@Test // DATAREDIS-267
public void killClientShouldDelegateCallCorrectly() {
connection.killClient("127.0.0.1", 1001);
verifyNativeConnectionInvocation().clientKill(eq("127.0.0.1:1001"));
verify(jedisSpy).clientKill(eq("127.0.0.1:1001"));
}
@Test // DATAREDIS-270
public void getClientNameShouldSendRequestCorrectly() {
connection.getClientName();
verifyNativeConnectionInvocation().clientGetname();
verify(jedisSpy).clientGetname();
}
@Test // DATAREDIS-277
@@ -111,14 +111,14 @@ class JedisConnectionUnitTests {
public void replicaOfShouldBeSentCorrectly() {
connection.replicaOf("127.0.0.1", 1001);
verifyNativeConnectionInvocation().slaveof(eq("127.0.0.1"), eq(1001));
verify(jedisSpy).replicaof(eq("127.0.0.1"), eq(1001));
}
@Test // DATAREDIS-277
public void replicaOfNoOneShouldBeSentCorrectly() {
connection.replicaOfNoOne();
verifyNativeConnectionInvocation().slaveofNoOne();
verify(jedisSpy).replicaofNoOne();
}
@Test // DATAREDIS-330
@@ -252,7 +252,7 @@ class JedisConnectionUnitTests {
@Test // DATAREDIS-714
void doesNotSelectDbWhenCurrentDbMatchesDesiredOne() {
Jedis jedisSpy = spy(new MockedClientJedis("http://localhost:1234", getNativeRedisConnectionMock()));
Jedis jedisSpy = spy(new Jedis(getNativeRedisConnectionMock()));
new JedisConnection(jedisSpy);
verify(jedisSpy, never()).select(anyInt());
@@ -261,7 +261,7 @@ class JedisConnectionUnitTests {
@Test // DATAREDIS-714
void doesNotSelectDbWhenCurrentDbDoesNotMatchDesiredOne() {
Jedis jedisSpy = spy(new MockedClientJedis("http://localhost:1234", getNativeRedisConnectionMock()));
Jedis jedisSpy = spy(new Jedis(getNativeRedisConnectionMock()));
when(jedisSpy.getDB()).thenReturn(3);
new JedisConnection(jedisSpy);
@@ -279,9 +279,24 @@ class JedisConnectionUnitTests {
connection.openPipeline();
}
@Test
@Disabled
@Override
void shutdownWithNullShouldDelegateCommandCorrectly() {}
@Test
@Disabled
@Override
void shutdownNosaveShouldBeSentCorrectly() {}
@Test
@Disabled
@Override
void shutdownSaveShouldBeSentCorrectly() {}
@Test // DATAREDIS-267
public void killClientShouldDelegateCallCorrectly() {
assertThatExceptionOfType(UnsupportedOperationException.class)
assertThatExceptionOfType(InvalidDataAccessApiUsageException.class)
.isThrownBy(() -> super.killClientShouldDelegateCallCorrectly());
}
@@ -289,7 +304,7 @@ class JedisConnectionUnitTests {
@Override
// DATAREDIS-270
public void getClientNameShouldSendRequestCorrectly() {
assertThatExceptionOfType(UnsupportedOperationException.class)
assertThatExceptionOfType(InvalidDataAccessApiUsageException.class)
.isThrownBy(() -> super.getClientNameShouldSendRequestCorrectly());
}
@@ -297,74 +312,64 @@ class JedisConnectionUnitTests {
@Override
// DATAREDIS-277
public void replicaOfShouldBeSentCorrectly() {
assertThatExceptionOfType(UnsupportedOperationException.class)
assertThatExceptionOfType(InvalidDataAccessApiUsageException.class)
.isThrownBy(() -> super.replicaOfShouldBeSentCorrectly());
}
@Test // DATAREDIS-277
public void replicaOfNoOneShouldBeSentCorrectly() {
assertThatExceptionOfType(UnsupportedOperationException.class)
assertThatExceptionOfType(InvalidDataAccessApiUsageException.class)
.isThrownBy(() -> super.replicaOfNoOneShouldBeSentCorrectly());
}
@Test // DATAREDIS-531
public void scanShouldKeepTheConnectionOpen() {
assertThatExceptionOfType(UnsupportedOperationException.class)
assertThatExceptionOfType(InvalidDataAccessApiUsageException.class)
.isThrownBy(() -> super.scanShouldKeepTheConnectionOpen());
}
@Test // DATAREDIS-531
public void scanShouldCloseTheConnectionWhenCursorIsClosed() {
assertThatExceptionOfType(UnsupportedOperationException.class)
assertThatExceptionOfType(InvalidDataAccessApiUsageException.class)
.isThrownBy(() -> super.scanShouldCloseTheConnectionWhenCursorIsClosed());
}
@Test // DATAREDIS-531
public void sScanShouldKeepTheConnectionOpen() {
assertThatExceptionOfType(UnsupportedOperationException.class)
assertThatExceptionOfType(InvalidDataAccessApiUsageException.class)
.isThrownBy(() -> super.sScanShouldKeepTheConnectionOpen());
}
@Test // DATAREDIS-531
public void sScanShouldCloseTheConnectionWhenCursorIsClosed() {
assertThatExceptionOfType(UnsupportedOperationException.class)
assertThatExceptionOfType(InvalidDataAccessApiUsageException.class)
.isThrownBy(() -> super.sScanShouldCloseTheConnectionWhenCursorIsClosed());
}
@Test // DATAREDIS-531
public void zScanShouldKeepTheConnectionOpen() {
assertThatExceptionOfType(UnsupportedOperationException.class)
assertThatExceptionOfType(InvalidDataAccessApiUsageException.class)
.isThrownBy(() -> super.zScanShouldKeepTheConnectionOpen());
}
@Test // DATAREDIS-531
public void zScanShouldCloseTheConnectionWhenCursorIsClosed() {
assertThatExceptionOfType(UnsupportedOperationException.class)
assertThatExceptionOfType(InvalidDataAccessApiUsageException.class)
.isThrownBy(() -> super.zScanShouldCloseTheConnectionWhenCursorIsClosed());
}
@Test // DATAREDIS-531
public void hScanShouldKeepTheConnectionOpen() {
assertThatExceptionOfType(UnsupportedOperationException.class)
assertThatExceptionOfType(InvalidDataAccessApiUsageException.class)
.isThrownBy(() -> super.hScanShouldKeepTheConnectionOpen());
}
@Test // DATAREDIS-531
public void hScanShouldCloseTheConnectionWhenCursorIsClosed() {
assertThatExceptionOfType(UnsupportedOperationException.class)
assertThatExceptionOfType(InvalidDataAccessApiUsageException.class)
.isThrownBy(() -> super.hScanShouldCloseTheConnectionWhenCursorIsClosed());
}
}
/**
* {@link Jedis} extension allowing to use mocked object as {@link Client}.
*/
private static class MockedClientJedis extends Jedis {
MockedClientJedis(String host, Client client) {
super(host);
ReflectionTestUtils.setField(this, "client", client);
}
}
}

View File

@@ -19,7 +19,7 @@ import static org.assertj.core.api.Assertions.*;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.exceptions.JedisAskDataException;
import redis.clients.jedis.exceptions.JedisClusterMaxAttemptsException;
import redis.clients.jedis.exceptions.JedisClusterOperationException;
import redis.clients.jedis.exceptions.JedisMovedDataException;
import org.junit.jupiter.api.Test;
@@ -63,7 +63,7 @@ class JedisExceptionConverterUnitTests {
void shouldConvertMaxRedirectException() {
DataAccessException converted = converter
.convert(new JedisClusterMaxAttemptsException("Too many redirections?"));
.convert(new JedisClusterOperationException("No more cluster attempts left."));
assertThat(converted).isInstanceOf(TooManyClusterRedirectionsException.class);
}

View File

@@ -34,11 +34,7 @@ public class TransactionalJedisIntegrationTests extends AbstractTransactionalTes
@Override
@Bean
public JedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName(SettingsUtils.getHost());
factory.setPort(SettingsUtils.getPort());
return factory;
return new JedisConnectionFactory(SettingsUtils.standaloneConfiguration());
}
}
}

View File

@@ -344,6 +344,9 @@ public class RedisTemplateIntegrationTests<K, V> {
@SuppressWarnings({ "rawtypes", "unchecked" })
@ParameterizedRedisTest
public void testExecutePipelinedTx() {
assumeThat(redisTemplate.getConnectionFactory()).isInstanceOf(LettuceConnectionFactory.class);
K key1 = keyFactory.instance();
V value1 = valueFactory.instance();
List<Object> pipelinedResults = redisTemplate.executePipelined(new SessionCallback() {
@@ -371,6 +374,7 @@ public class RedisTemplateIntegrationTests<K, V> {
@SuppressWarnings({ "rawtypes", "unchecked" })
@ParameterizedRedisTest
void testExecutePipelinedTxCustomSerializer() {
assumeThat(redisTemplate.getConnectionFactory()).isInstanceOf(LettuceConnectionFactory.class);
assumeThat(redisTemplate instanceof StringRedisTemplate).isTrue();
List<Object> pipelinedResults = redisTemplate.executePipelined(new SessionCallback() {
public Object execute(RedisOperations operations) throws DataAccessException {
@@ -581,9 +585,6 @@ public class RedisTemplateIntegrationTests<K, V> {
@SuppressWarnings({ "unchecked", "rawtypes" })
public void testGetExpireMillisUsingTransactions() {
assumeThat(redisTemplate.getConnectionFactory() instanceof JedisConnectionFactory
|| redisTemplate.getConnectionFactory() instanceof LettuceConnectionFactory).isTrue();
K key = keyFactory.instance();
List<Object> result = redisTemplate.execute(new SessionCallback<List<Object>>() {
@@ -608,9 +609,6 @@ public class RedisTemplateIntegrationTests<K, V> {
@SuppressWarnings({ "unchecked", "rawtypes" })
public void testGetExpireMillisUsingPipelining() {
assumeThat(redisTemplate.getConnectionFactory() instanceof JedisConnectionFactory
|| redisTemplate.getConnectionFactory() instanceof LettuceConnectionFactory).isTrue();
K key = keyFactory.instance();
List<Object> result = redisTemplate.executePipelined(new SessionCallback<Object>() {

View File

@@ -15,6 +15,8 @@
*/
package org.springframework.data.redis.test.extension;
import redis.clients.jedis.util.IOUtils;
import java.io.Closeable;
import java.util.LinkedList;
@@ -52,4 +54,8 @@ public enum ShutdownQueue {
public static void register(Closeable closeable) {
INSTANCE.closeables.add(closeable);
}
public static void register(AutoCloseable closeable) {
INSTANCE.closeables.add(() -> IOUtils.closeQuietly(closeable));
}
}