DATAREDIS-1005 - Add support for scripting commands for Jedis Cluster.
Original pull request: #460.
This commit is contained in:
committed by
Mark Paluch
parent
011ae5cda4
commit
988a7e71b7
@@ -326,7 +326,7 @@ public class JedisClusterConnection implements DefaultedRedisClusterConnection {
|
||||
*/
|
||||
@Override
|
||||
public RedisScriptingCommands scriptingCommands() {
|
||||
return JedisClusterScriptingCommands.INSTANCE;
|
||||
return new JedisClusterScriptingCommands(this);
|
||||
}
|
||||
|
||||
private JedisClusterKeyCommands doGetKeyCommands() {
|
||||
|
||||
@@ -17,17 +17,22 @@ package org.springframework.data.redis.connection.jedis;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.redis.connection.RedisScriptingCommands;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import redis.clients.jedis.JedisCluster;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
* @since 2.0
|
||||
*/
|
||||
enum JedisClusterScriptingCommands implements RedisScriptingCommands {
|
||||
@RequiredArgsConstructor
|
||||
class JedisClusterScriptingCommands implements RedisScriptingCommands {
|
||||
|
||||
INSTANCE;
|
||||
private final @NonNull JedisClusterConnection clusterConnection;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -70,8 +75,15 @@ enum JedisClusterScriptingCommands implements RedisScriptingCommands {
|
||||
* @see org.springframework.data.redis.connection.RedisScriptingCommands#eval(byte[], org.springframework.data.redis.connection.ReturnType, int, byte[][])
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
|
||||
throw new InvalidDataAccessApiUsageException("Eval is not supported in cluster environment.");
|
||||
checkConnection();
|
||||
try {
|
||||
return (T) new JedisScriptReturnConverter(returnType)
|
||||
.convert(getCluster().eval(script, JedisConverters.toBytes(numKeys), keysAndArgs));
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -80,7 +92,7 @@ enum JedisClusterScriptingCommands implements RedisScriptingCommands {
|
||||
*/
|
||||
@Override
|
||||
public <T> T evalSha(String scriptSha, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
|
||||
throw new InvalidDataAccessApiUsageException("EvalSha is not supported in cluster environment.");
|
||||
return evalSha(JedisConverters.toBytes(scriptSha), returnType, numKeys, keysAndArgs);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -88,7 +100,43 @@ enum JedisClusterScriptingCommands implements RedisScriptingCommands {
|
||||
* @see org.springframework.data.redis.connection.RedisScriptingCommands#evalSha(byte[], org.springframework.data.redis.connection.ReturnType, int, byte[][])
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T evalSha(byte[] scriptSha, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
|
||||
throw new InvalidDataAccessApiUsageException("EvalSha is not supported in cluster environment.");
|
||||
checkConnection();
|
||||
try {
|
||||
return (T) new JedisScriptReturnConverter(returnType)
|
||||
.convert(getCluster().evalsha(scriptSha, numKeys, keysAndArgs));
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public JedisClusterConnection getClusterConnection() {
|
||||
return clusterConnection;
|
||||
}
|
||||
|
||||
protected RuntimeException convertJedisAccessException(Exception ex) {
|
||||
return clusterConnection.convertJedisAccessException(ex);
|
||||
}
|
||||
|
||||
private JedisCluster getCluster() {
|
||||
return clusterConnection.getCluster();
|
||||
}
|
||||
|
||||
protected void checkConnection() {
|
||||
if (isQueueing()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (isPipelined()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPipelined() {
|
||||
return clusterConnection.isPipelined();
|
||||
}
|
||||
|
||||
private boolean isQueueing() {
|
||||
return clusterConnection.isQueueing();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.redis.connection.ClusterConnectionTests;
|
||||
import org.springframework.data.redis.connection.ClusterSlotHashUtil;
|
||||
import org.springframework.data.redis.connection.DataType;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import org.springframework.data.redis.connection.DefaultSortParameters;
|
||||
import org.springframework.data.redis.connection.DefaultTuple;
|
||||
import org.springframework.data.redis.connection.RedisClusterNode;
|
||||
@@ -70,6 +71,7 @@ import org.springframework.data.redis.test.util.HexStringUtils;
|
||||
import org.springframework.data.redis.test.util.MinimumRedisVersionRule;
|
||||
import org.springframework.data.redis.test.util.RedisClusterRule;
|
||||
import org.springframework.test.annotation.IfProfileValue;
|
||||
import org.springframework.data.redis.core.script.DigestUtils;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
@@ -2421,4 +2423,28 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests {
|
||||
.valueAt(offset(0L).multipliedByTypeLength())
|
||||
.get(INT_8).valueAt(offset(1L).multipliedByTypeLength())), contains(100L, -56L));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-1005
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6+")
|
||||
public void evalOK() {
|
||||
byte[] keyAndArgs = JedisConverters.toBytes("FOO");
|
||||
|
||||
String luaScript = "return redis.call(\"INCR\", KEYS[1])";
|
||||
byte[] luaScriptBin = JedisConverters.toBytes(luaScript);
|
||||
Long result = clusterConnection.scriptingCommands().eval(luaScriptBin, ReturnType.VALUE, 1, keyAndArgs);
|
||||
assertThat(result, is(1L));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-1005
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6+")
|
||||
public void evalShaOK() {
|
||||
byte[] keyAndArgs = JedisConverters.toBytes("FOO");
|
||||
|
||||
String luaScript = "return redis.call(\"INCR\", KEYS[1])";
|
||||
String digest = DigestUtils.sha1DigestAsHex(luaScript);
|
||||
byte[] luaScriptBin = JedisConverters.toBytes(digest);
|
||||
Long result = clusterConnection.scriptingCommands().evalSha(luaScriptBin, ReturnType.VALUE, 1, keyAndArgs);
|
||||
assertThat(result, is(1L));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user