Add Redis 2.6 scripting commands to Connections
DATAREDIS-180
This commit is contained in:
@@ -624,6 +624,30 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
|
||||
delegate.restore(key, ttlInMillis, serializedValue);
|
||||
}
|
||||
|
||||
public void scriptFlush() {
|
||||
delegate.scriptFlush();
|
||||
}
|
||||
|
||||
public void scriptKill() {
|
||||
delegate.scriptKill();
|
||||
}
|
||||
|
||||
public String scriptLoad(byte[] script) {
|
||||
return delegate.scriptLoad(script);
|
||||
}
|
||||
|
||||
public List<Boolean> scriptExists(String... scriptSha1) {
|
||||
return delegate.scriptExists(scriptSha1);
|
||||
}
|
||||
|
||||
public <T> T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
|
||||
return delegate.eval(script, returnType, numKeys, keysAndArgs);
|
||||
}
|
||||
|
||||
public <T> T evalSha(String scriptSha1, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
|
||||
return delegate.evalSha(scriptSha1, returnType, numKeys, keysAndArgs);
|
||||
}
|
||||
|
||||
//
|
||||
// String methods
|
||||
//
|
||||
@@ -1235,4 +1259,26 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
|
||||
public Long pTtl(String key) {
|
||||
return pTtl(serialize(key));
|
||||
}
|
||||
|
||||
public String scriptLoad(String script) {
|
||||
return delegate.scriptLoad(serialize(script));
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: This method will not deserialize Strings returned by Lua scripts, as
|
||||
* they may not be encoded with the same serializer used here. They will
|
||||
* be returned as byte[]s
|
||||
*/
|
||||
public <T> T eval(String script, ReturnType returnType, int numKeys, String... keysAndArgs) {
|
||||
return delegate.eval(serialize(script), returnType, numKeys, serializeMulti(keysAndArgs));
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: This method will not deserialize Strings returned by Lua scripts, as
|
||||
* they may not be encoded with the same serializer used here. They will
|
||||
* be returned as byte[]s
|
||||
*/
|
||||
public <T> T evalSha(String scriptSha1, ReturnType returnType, int numKeys, String... keysAndArgs) {
|
||||
return delegate.evalSha(scriptSha1, returnType, numKeys, serializeMulti(keysAndArgs));
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ package org.springframework.data.redis.connection;
|
||||
*/
|
||||
public interface RedisCommands extends RedisKeyCommands, RedisStringCommands, RedisListCommands, RedisSetCommands,
|
||||
RedisZSetCommands, RedisHashCommands, RedisTxCommands, RedisPubSubCommands, RedisConnectionCommands,
|
||||
RedisServerCommands {
|
||||
RedisServerCommands, RedisScriptingCommands {
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Scripting commands.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public interface RedisScriptingCommands {
|
||||
|
||||
void scriptFlush();
|
||||
|
||||
void scriptKill();
|
||||
|
||||
String scriptLoad(byte[] script);
|
||||
|
||||
List<Boolean> scriptExists(String... scriptSha1);
|
||||
|
||||
<T> T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs);
|
||||
|
||||
<T> T evalSha(String scriptSha1, ReturnType returnType, int numKeys, byte[]... keysAndArgs);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2013 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
/**
|
||||
* Represents a data type returned from Redis, currently used to denote the
|
||||
* expected return type of Redis scripting commands
|
||||
*
|
||||
* @author Jennifer Hickey
|
||||
*
|
||||
*/
|
||||
public enum ReturnType {
|
||||
BOOLEAN, INTEGER, MULTI, STATUS, VALUE
|
||||
}
|
||||
@@ -262,4 +262,10 @@ public interface StringRedisConnection extends RedisConnection {
|
||||
void subscribe(MessageListener listener, String... channels);
|
||||
|
||||
void pSubscribe(MessageListener listener, String... patterns);
|
||||
|
||||
String scriptLoad(String script);
|
||||
|
||||
<T> T eval(String script, ReturnType returnType, int numKeys, String... keysAndArgs);
|
||||
|
||||
<T> T evalSha(String scriptSha1, ReturnType returnType, int numKeys, String... keysAndArgs);
|
||||
}
|
||||
@@ -32,6 +32,7 @@ import org.springframework.data.redis.connection.MessageListener;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisPipelineException;
|
||||
import org.springframework.data.redis.connection.RedisSubscribedConnectionException;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import org.springframework.data.redis.connection.SortParameters;
|
||||
import org.springframework.data.redis.connection.Subscription;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -2476,4 +2477,96 @@ public class JedisConnection implements RedisConnection {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Scripting commands
|
||||
//
|
||||
|
||||
public void scriptFlush() {
|
||||
if (isQueueing()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (isPipelined()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
try {
|
||||
jedis.scriptFlush();
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void scriptKill() {
|
||||
if (isQueueing()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (isPipelined()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
try {
|
||||
jedis.scriptKill();
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public String scriptLoad(byte[] script) {
|
||||
if (isQueueing()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (isPipelined()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
try {
|
||||
return JedisUtils.asString(jedis.scriptLoad(script));
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Boolean> scriptExists(String... scriptSha1) {
|
||||
if (isQueueing()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (isPipelined()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
try {
|
||||
return jedis.scriptExists(scriptSha1);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
|
||||
if (isQueueing()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (isPipelined()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
try {
|
||||
return (T) JedisUtils.convertScriptReturn(returnType,
|
||||
jedis.eval(script, JedisUtils.asBytes(numKeys), keysAndArgs));
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T evalSha(String scriptSha1, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
|
||||
if (isQueueing()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (isPipelined()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
try {
|
||||
return (T) JedisUtils.convertScriptReturn(returnType,
|
||||
jedis.evalsha(scriptSha1, numKeys, JedisUtils.convert(keysAndArgs)));
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.springframework.data.redis.RedisConnectionFailureException;
|
||||
import org.springframework.data.redis.RedisSystemException;
|
||||
import org.springframework.data.redis.connection.DefaultTuple;
|
||||
import org.springframework.data.redis.connection.MessageListener;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import org.springframework.data.redis.connection.RedisListCommands.Position;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
|
||||
import org.springframework.data.redis.connection.SortParameters;
|
||||
@@ -48,11 +49,13 @@ import redis.clients.jedis.SortingParams;
|
||||
import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||
import redis.clients.jedis.exceptions.JedisDataException;
|
||||
import redis.clients.jedis.exceptions.JedisException;
|
||||
import redis.clients.util.SafeEncoder;
|
||||
|
||||
/**
|
||||
* Helper class featuring methods for Jedis connection handling, providing support for exception translation.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Jennifer Hickey
|
||||
*/
|
||||
public abstract class JedisUtils {
|
||||
|
||||
@@ -216,7 +219,7 @@ public abstract class JedisUtils {
|
||||
String[] result = new String[raw.length];
|
||||
|
||||
for (int i = 0; i < raw.length; i++) {
|
||||
result[i] = new String(raw[i]);
|
||||
result[i] = SafeEncoder.encode(raw[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -230,4 +233,45 @@ public abstract class JedisUtils {
|
||||
args.add(Protocol.toByteArray(timeout));
|
||||
return args.toArray(new byte[args.size()][]);
|
||||
}
|
||||
|
||||
static byte[] asBytes(int number) {
|
||||
return String.valueOf(number).getBytes();
|
||||
}
|
||||
|
||||
static String asString(byte[] raw) {
|
||||
return SafeEncoder.encode(raw);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static Object convertScriptReturn(ReturnType returnType, Object result) {
|
||||
if(result instanceof String) {
|
||||
//evalsha converts byte[] to String. Convert back for consistency
|
||||
return SafeEncoder.encode((String)result);
|
||||
}
|
||||
if(returnType == ReturnType.STATUS) {
|
||||
return JedisUtils.asString((byte[])result);
|
||||
}
|
||||
if(returnType == ReturnType.BOOLEAN) {
|
||||
// Lua false comes back as a null bulk reply
|
||||
if(result == null) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
return ((Long)result == 1);
|
||||
}
|
||||
if(returnType == ReturnType.MULTI) {
|
||||
List<Object> resultList = (List<Object>) result;
|
||||
List<Object> convertedResults = new ArrayList<Object>();
|
||||
for(Object res: resultList) {
|
||||
if(res instanceof String) {
|
||||
//evalsha converts byte[] to String. Convert back for consistency
|
||||
convertedResults.add(SafeEncoder.encode((String)res));
|
||||
}else {
|
||||
convertedResults.add(res);
|
||||
}
|
||||
}
|
||||
return convertedResults;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,6 +39,7 @@ import org.springframework.data.redis.RedisSystemException;
|
||||
import org.springframework.data.redis.connection.DataType;
|
||||
import org.springframework.data.redis.connection.MessageListener;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import org.springframework.data.redis.connection.SortParameters;
|
||||
import org.springframework.data.redis.connection.Subscription;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -1223,7 +1224,36 @@ public class JredisConnection implements RedisConnection {
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Scripting commands
|
||||
//
|
||||
|
||||
|
||||
public void subscribe(MessageListener listener, byte[]... channels) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void scriptFlush() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void scriptKill() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public String scriptLoad(byte[] script) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public List<Boolean> scriptExists(String... scriptSha1) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public <T> T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public <T> T evalSha(String scriptSha1, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@ import org.springframework.data.redis.connection.MessageListener;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisPipelineException;
|
||||
import org.springframework.data.redis.connection.RedisSubscribedConnectionException;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import org.springframework.data.redis.connection.SortParameters;
|
||||
import org.springframework.data.redis.connection.Subscription;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -1963,6 +1964,92 @@ public class LettuceConnection implements RedisConnection {
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Scripting commands
|
||||
//
|
||||
|
||||
public void scriptFlush() {
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(getAsyncConnection().scriptFlush());
|
||||
return;
|
||||
}
|
||||
getConnection().scriptFlush();
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void scriptKill() {
|
||||
if(isQueueing()) {
|
||||
throw new UnsupportedOperationException("Script kill not permitted in a transaction");
|
||||
}
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(getAsyncConnection().scriptKill());
|
||||
return;
|
||||
}
|
||||
getConnection().scriptKill();
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public String scriptLoad(byte[] script) {
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(getAsyncConnection().scriptLoad(script));
|
||||
return null;
|
||||
}
|
||||
return getConnection().scriptLoad(script);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Boolean> scriptExists(String... scriptSha1) {
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(getAsyncConnection().scriptExists(scriptSha1));
|
||||
return null;
|
||||
}
|
||||
return getConnection().scriptExists(scriptSha1);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
|
||||
try {
|
||||
byte[][] keys = LettuceUtils.extractScriptKeys(numKeys, keysAndArgs);
|
||||
byte[][] args = LettuceUtils.extractScriptArgs(numKeys, keysAndArgs);
|
||||
|
||||
if (isPipelined()) {
|
||||
pipeline(getAsyncConnection().eval(script, LettuceUtils.toScriptOutputType(returnType), keys, args));
|
||||
return null;
|
||||
}
|
||||
return getConnection().eval(script, LettuceUtils.toScriptOutputType(returnType), keys, args);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T evalSha(String scriptSha1, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
|
||||
try {
|
||||
byte[][] keys = LettuceUtils.extractScriptKeys(numKeys, keysAndArgs);
|
||||
byte[][] args = LettuceUtils.extractScriptArgs(numKeys, keysAndArgs);
|
||||
|
||||
if (isPipelined()) {
|
||||
pipeline(getAsyncConnection().evalsha(scriptSha1, LettuceUtils.toScriptOutputType(returnType),
|
||||
keys, args));
|
||||
return null;
|
||||
}
|
||||
return getConnection().evalsha(scriptSha1, LettuceUtils.toScriptOutputType(returnType), keys, args);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Pub/Sub functionality
|
||||
//
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.redis.connection.lettuce;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
@@ -26,6 +27,7 @@ import java.util.Set;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.redis.RedisSystemException;
|
||||
import org.springframework.data.redis.connection.DefaultTuple;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import org.springframework.data.redis.connection.RedisListCommands.Position;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Aggregate;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
|
||||
@@ -37,13 +39,15 @@ import com.lambdaworks.redis.KeyValue;
|
||||
import com.lambdaworks.redis.RedisCommandInterruptedException;
|
||||
import com.lambdaworks.redis.RedisException;
|
||||
import com.lambdaworks.redis.ScoredValue;
|
||||
import com.lambdaworks.redis.ScriptOutputType;
|
||||
import com.lambdaworks.redis.SortArgs;
|
||||
import com.lambdaworks.redis.ZStoreArgs;
|
||||
import com.lambdaworks.redis.codec.RedisCodec;
|
||||
import com.lambdaworks.redis.protocol.Charsets;
|
||||
|
||||
/**
|
||||
* Helper class featuring methods for Lettuce connection handling, providing support for exception translation.
|
||||
* Helper class featuring methods for Lettuce connection handling, providing
|
||||
* support for exception translation.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
@@ -166,4 +170,37 @@ abstract class LettuceUtils {
|
||||
list.add(blpop.value);
|
||||
return list;
|
||||
}
|
||||
|
||||
static ScriptOutputType toScriptOutputType(ReturnType returnType) {
|
||||
switch (returnType) {
|
||||
case BOOLEAN:
|
||||
return ScriptOutputType.BOOLEAN;
|
||||
case MULTI:
|
||||
return ScriptOutputType.MULTI;
|
||||
case VALUE:
|
||||
return ScriptOutputType.VALUE;
|
||||
case INTEGER:
|
||||
return ScriptOutputType.INTEGER;
|
||||
case STATUS:
|
||||
return ScriptOutputType.STATUS;
|
||||
default:
|
||||
throw new IllegalArgumentException("Return type " + returnType
|
||||
+ " is not a supported script output type");
|
||||
}
|
||||
}
|
||||
|
||||
static byte[][] extractScriptKeys(int numKeys, byte[]... keysAndArgs) {
|
||||
if(numKeys > 0) {
|
||||
return Arrays.copyOfRange(keysAndArgs, 0,numKeys);
|
||||
}
|
||||
return new byte[0][0];
|
||||
}
|
||||
|
||||
static byte[][] extractScriptArgs(int numKeys, byte[]... keysAndArgs) {
|
||||
if(keysAndArgs.length > numKeys) {
|
||||
return Arrays.copyOfRange(keysAndArgs, numKeys, keysAndArgs.length);
|
||||
}
|
||||
return new byte[0][0];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,6 +33,7 @@ import org.springframework.data.redis.connection.MessageListener;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisPipelineException;
|
||||
import org.springframework.data.redis.connection.RedisSubscribedConnectionException;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import org.springframework.data.redis.connection.SortParameters;
|
||||
import org.springframework.data.redis.connection.Subscription;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -1921,6 +1922,90 @@ public class SrpConnection implements RedisConnection {
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Scripting commands
|
||||
//
|
||||
|
||||
|
||||
public void scriptFlush() {
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(pipeline.script_flush());
|
||||
return;
|
||||
}
|
||||
client.script_flush();
|
||||
} catch (Exception ex) {
|
||||
throw convertSrpAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void scriptKill() {
|
||||
if(isQueueing()) {
|
||||
throw new UnsupportedOperationException("Script kill not permitted in a transaction");
|
||||
}
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(pipeline.script_kill());
|
||||
return;
|
||||
}
|
||||
client.script_kill();
|
||||
} catch (Exception ex) {
|
||||
throw convertSrpAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public String scriptLoad(byte[] script) {
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(pipeline.script_load(script));
|
||||
return null;
|
||||
}
|
||||
return SrpUtils.asShasum(client.script_load(script));
|
||||
} catch (Exception ex) {
|
||||
throw convertSrpAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Boolean> scriptExists(String... scriptSha1) {
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(pipeline.script_exists((Object[])scriptSha1));
|
||||
return null;
|
||||
}
|
||||
return SrpUtils.asBooleanList(client.script_exists_((Object[])scriptSha1));
|
||||
} catch (Exception ex) {
|
||||
throw convertSrpAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(pipeline.eval(script, numKeys, (Object[])keysAndArgs));
|
||||
return null;
|
||||
}
|
||||
return (T) SrpUtils.convertScriptReturn(returnType, client.eval(script, numKeys,
|
||||
(Object[])keysAndArgs));
|
||||
} catch (Exception ex) {
|
||||
throw convertSrpAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T evalSha(String scriptSha1, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(pipeline.evalsha(scriptSha1, numKeys, (Object[])keysAndArgs));
|
||||
return null;
|
||||
}
|
||||
return (T) SrpUtils.convertScriptReturn(returnType,
|
||||
client.evalsha(scriptSha1, numKeys, (Object[])keysAndArgs));
|
||||
} catch (Exception ex) {
|
||||
throw convertSrpAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Pub/Sub functionality
|
||||
|
||||
@@ -29,9 +29,11 @@ import java.util.Set;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.redis.RedisSystemException;
|
||||
import org.springframework.data.redis.connection.DefaultTuple;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import org.springframework.data.redis.connection.RedisListCommands.Position;
|
||||
import org.springframework.data.redis.connection.RedisStringCommands.BitOperation;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
|
||||
import org.springframework.data.redis.connection.jedis.JedisUtils;
|
||||
import org.springframework.data.redis.connection.SortParameters;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -40,6 +42,7 @@ import redis.reply.BulkReply;
|
||||
import redis.reply.IntegerReply;
|
||||
import redis.reply.MultiBulkReply;
|
||||
import redis.reply.Reply;
|
||||
import redis.reply.StatusReply;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
|
||||
@@ -104,6 +107,14 @@ abstract class SrpUtils {
|
||||
return list;
|
||||
}
|
||||
|
||||
static List<String> asStatusList(Reply[] replies) {
|
||||
List<String> statuses = new ArrayList<String>();
|
||||
for(Reply reply: replies) {
|
||||
statuses.add(((StatusReply)reply).data());
|
||||
}
|
||||
return statuses;
|
||||
}
|
||||
|
||||
static <T> List<T> toList(T[] byteArrays) {
|
||||
return Arrays.asList(byteArrays);
|
||||
}
|
||||
@@ -273,4 +284,51 @@ abstract class SrpUtils {
|
||||
Assert.notNull(op, "The bit operation is required");
|
||||
return op.name().toUpperCase().getBytes(Charsets.UTF_8);
|
||||
}
|
||||
|
||||
static String asShasum(Reply reply) {
|
||||
Object data = reply.data();
|
||||
return (data instanceof String ? (String) data : new String((byte[]) data, Charsets.UTF_8));
|
||||
}
|
||||
|
||||
static List<Boolean> asBooleanList(Reply reply) {
|
||||
if(!(reply instanceof MultiBulkReply)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
List<Boolean> results = new ArrayList<Boolean>();
|
||||
for(Reply r: ((MultiBulkReply)reply).data()) {
|
||||
results.add(SrpUtils.asBoolean((IntegerReply)r));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
static List<Long> asIntegerList(Reply[] replies) {
|
||||
List<Long> results = new ArrayList<Long>();
|
||||
for(Reply reply: replies) {
|
||||
results.add(((IntegerReply)reply).data());
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
static List<Object> asList(MultiBulkReply genericReply) {
|
||||
Reply[] replies = genericReply.data();
|
||||
List<Object> results = new ArrayList<Object>();
|
||||
for(Reply reply: replies) {
|
||||
results.add(reply.data());
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
static Object convertScriptReturn(ReturnType returnType, Reply reply) {
|
||||
if(reply instanceof MultiBulkReply) {
|
||||
return SrpUtils.asList((MultiBulkReply)reply);
|
||||
}
|
||||
if(returnType == ReturnType.BOOLEAN) {
|
||||
// Lua false comes back as a null bulk reply
|
||||
if(reply.data() == null) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
return ((Long)reply.data() == 1);
|
||||
}
|
||||
return reply.data();
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
import static org.springframework.data.redis.SpinBarrier.waitFor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -33,10 +34,12 @@ import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.BlockingDeque;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -47,6 +50,7 @@ import org.springframework.data.redis.Address;
|
||||
import org.springframework.data.redis.Person;
|
||||
import org.springframework.data.redis.RedisSystemException;
|
||||
import org.springframework.data.redis.RedisTestProfileValueSource;
|
||||
import org.springframework.data.redis.RedisVersionUtils;
|
||||
import org.springframework.data.redis.TestCondition;
|
||||
import org.springframework.data.redis.connection.RedisListCommands.Position;
|
||||
import org.springframework.data.redis.connection.RedisStringCommands.BitOperation;
|
||||
@@ -147,6 +151,152 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
assertFalse(connection.pExpireAt("nonexistent", System.currentTimeMillis() + 200));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testScriptLoadEvalSha() {
|
||||
String sha1 = connection.scriptLoad("return KEYS[1]");
|
||||
actual.add(connection.evalSha(sha1, ReturnType.VALUE, 2, "key1", "key2"));
|
||||
verifyResults(Arrays.asList(new Object[] {"key1"}), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalShaArrayStrings() {
|
||||
String sha1 = connection.scriptLoad("return {KEYS[1],ARGV[1]}");
|
||||
actual.add(connection.evalSha(sha1, ReturnType.MULTI, 1, "key1", "arg1"));
|
||||
verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] {"key1", "arg1"} )}), actual);
|
||||
}
|
||||
|
||||
@Test(expected=RedisSystemException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalShaNotFound() {
|
||||
connection.evalSha("somefakesha", ReturnType.VALUE, 2, "key1", "key2");
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnString() {
|
||||
actual.add(connection.eval("return KEYS[1]", ReturnType.VALUE, 1, "foo"));
|
||||
verifyResults(Arrays.asList(new Object[] {"foo"}), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnNumber() {
|
||||
actual.add(connection.eval("return 10", ReturnType.INTEGER, 0));
|
||||
verifyResults(Arrays.asList(new Object[] {10l}), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnSingleOK() {
|
||||
actual.add(connection.eval("return redis.call('set','abc','ghk')", ReturnType.STATUS, 0));
|
||||
assertEquals(Arrays.asList(new Object[] { "OK" }), convertResults(false));
|
||||
}
|
||||
|
||||
@Test(expected=RedisSystemException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnSingleError() {
|
||||
connection.eval("return redis.call('expire','foo')", ReturnType.BOOLEAN, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnFalse() {
|
||||
actual.add(connection.eval("return false", ReturnType.BOOLEAN, 0));
|
||||
verifyResults(Arrays.asList(new Object[] { false }), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnTrue() {
|
||||
actual.add(connection.eval("return true", ReturnType.BOOLEAN, 0));
|
||||
verifyResults(Arrays.asList(new Object[] { true }), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnArrayStrings() {
|
||||
actual.add(connection.eval("return {KEYS[1],ARGV[1]}", ReturnType.MULTI, 1, "foo", "bar"));
|
||||
verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] {"foo", "bar"} )}), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnArrayNumbers() {
|
||||
actual.add(connection.eval("return {1,2}", ReturnType.MULTI, 1, "foo", "bar"));
|
||||
verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] {1l, 2l} )}), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnArrayOKs() {
|
||||
actual.add(connection.eval("return { redis.call('set','abc','ghk'), redis.call('set','abc','lfdf')}",
|
||||
ReturnType.MULTI, 0));
|
||||
assertEquals(Arrays.asList(new Object[] {Arrays.asList(new Object[] {"OK", "OK"} )}), convertResults(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnArrayFalses() {
|
||||
actual.add(connection.eval("return { false, false}", ReturnType.MULTI, 0));
|
||||
verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] {null, null} )}), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnArrayTrues() {
|
||||
actual.add(connection.eval("return { true, true}", ReturnType.MULTI,0));
|
||||
verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] {1l, 1l} )}), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testScriptExists() {
|
||||
String sha1 = connection.scriptLoad("return 'foo'");
|
||||
actual.add(connection.scriptExists(sha1, "98777234"));
|
||||
verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] {true, false})}), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "runLongTests", value = "true")
|
||||
public void testScriptKill() throws Exception{
|
||||
getResults();
|
||||
assumeTrue(RedisVersionUtils.atLeast("2.6", byteConnection));
|
||||
initConnection();
|
||||
final AtomicBoolean scriptDead = new AtomicBoolean(false);
|
||||
Thread th = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection(
|
||||
connectionFactory.getConnection());
|
||||
try {
|
||||
conn2.eval("local time=1 while time < 10000000000 do time=time+1 end", ReturnType.BOOLEAN, 0);
|
||||
}catch(DataAccessException e) {
|
||||
scriptDead.set(true);
|
||||
}
|
||||
conn2.close();
|
||||
}
|
||||
});
|
||||
th.start();
|
||||
Thread.sleep(1000);
|
||||
connection.scriptKill();
|
||||
getResults();
|
||||
assertTrue(waitFor(new TestCondition() {
|
||||
public boolean passes() {
|
||||
return scriptDead.get();
|
||||
}
|
||||
}, 3000l));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testScriptFlush() {
|
||||
String sha1 = connection.scriptLoad("return KEYS[1]");
|
||||
connection.scriptFlush();
|
||||
actual.add(connection.scriptExists(sha1));
|
||||
verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] { false })}), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "runLongTests", value = "true")
|
||||
public void testPersist() throws Exception {
|
||||
@@ -1394,7 +1544,51 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
}
|
||||
|
||||
protected void verifyResults(List<Object> expected, List<Object> actual) {
|
||||
assertEquals(expected, actual);
|
||||
assertEquals(expected, convertResults(true));
|
||||
}
|
||||
|
||||
protected List<Object> convertResults() {
|
||||
return convertResults(true);
|
||||
}
|
||||
|
||||
protected List<Object> convertResults(boolean filterStatus) {
|
||||
List<Object> actual = getResults();
|
||||
List<Object> serializedResults = new ArrayList<Object>();
|
||||
for (Object result : actual) {
|
||||
Object convertedResult = convertResult(result);
|
||||
if (filterStatus) {
|
||||
if(!"OK".equals(convertedResult) && !"QUEUED".equals(convertedResult)) {
|
||||
serializedResults.add(convertedResult);
|
||||
}
|
||||
}else {
|
||||
serializedResults.add(convertedResult);
|
||||
}
|
||||
}
|
||||
return serializedResults;
|
||||
}
|
||||
|
||||
protected List<Object> getResults() {
|
||||
return actual;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
protected Object convertResult(Object result) {
|
||||
if (result instanceof List && !(((List) result).isEmpty())
|
||||
&& ((List) result).get(0) instanceof byte[]) {
|
||||
return (SerializationUtils.deserialize((List<byte[]>) result, stringSerializer));
|
||||
} else if (result instanceof byte[]) {
|
||||
return (stringSerializer.deserialize((byte[]) result));
|
||||
} else if (result instanceof Map
|
||||
&& ((Map) result).keySet().iterator().next() instanceof byte[]) {
|
||||
return (SerializationUtils.deserialize((Map) result, stringSerializer));
|
||||
} else if (result instanceof Set && !(((Set) result).isEmpty())
|
||||
&& ((Set) result).iterator().next() instanceof byte[]) {
|
||||
return (SerializationUtils.deserialize((Set) result, stringSerializer));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void initConnection() {
|
||||
}
|
||||
|
||||
protected class KeyExpired implements TestCondition {
|
||||
|
||||
@@ -31,7 +31,6 @@ import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -42,7 +41,6 @@ import org.springframework.data.redis.connection.RedisStringCommands.BitOperatio
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Aggregate;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
|
||||
import org.springframework.data.redis.connection.StringRedisConnection.StringTuple;
|
||||
import org.springframework.data.redis.serializer.SerializationUtils;
|
||||
import org.springframework.test.annotation.IfProfileValue;
|
||||
|
||||
/**
|
||||
@@ -960,6 +958,79 @@ abstract public class AbstractConnectionPipelineIntegrationTests extends
|
||||
Arrays.asList(new String[] { "foo", "bar" }) }), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testScriptLoadEvalSha() {
|
||||
// close the pipeline to get the return value of script load
|
||||
getResults();
|
||||
String sha1 = connection.scriptLoad("return KEYS[1]");
|
||||
initConnection();
|
||||
actual.add(connection.evalSha(sha1, ReturnType.VALUE, 2, "key1", "key2"));
|
||||
verifyResults(Arrays.asList(new Object[] {"key1"}), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalShaArrayStrings() {
|
||||
// close the pipeline to get the return value of script load
|
||||
getResults();
|
||||
String sha1 = connection.scriptLoad("return {KEYS[1],ARGV[1]}");
|
||||
initConnection();
|
||||
actual.add(connection.evalSha(sha1, ReturnType.MULTI, 1, "key1", "arg1"));
|
||||
verifyResults(Arrays.asList(new Object[] { Arrays.asList(new Object[] {"key1", "arg1"})}), actual);
|
||||
}
|
||||
|
||||
@Test(expected=RedisPipelineException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalShaNotFound() {
|
||||
connection.evalSha("somefakesha", ReturnType.VALUE, 2, "key1", "key2");
|
||||
getResults();
|
||||
}
|
||||
|
||||
@Test(expected=RedisPipelineException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnSingleError() {
|
||||
connection.eval("return redis.call('expire','foo')", ReturnType.BOOLEAN, 0);
|
||||
getResults();
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnFalse() {
|
||||
// pipelined results don't get converted to Booleans
|
||||
actual.add(connection.eval("return false", ReturnType.BOOLEAN, 0));
|
||||
verifyResults(Arrays.asList(new Object[] { null }), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnTrue() {
|
||||
// pipelined results don't get converted to Booleans
|
||||
actual.add(connection.eval("return true", ReturnType.BOOLEAN, 0));
|
||||
verifyResults(Arrays.asList(new Object[] { 1l }), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testScriptExists() {
|
||||
getResults();
|
||||
String sha1 = connection.scriptLoad("return 'foo'");
|
||||
initConnection();
|
||||
actual.add(connection.scriptExists(sha1, "98777234"));
|
||||
verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] {true, false})}), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testScriptFlush() {
|
||||
getResults();
|
||||
String sha1 = connection.scriptLoad("return KEYS[1]");
|
||||
connection.scriptFlush();
|
||||
initConnection();
|
||||
actual.add(connection.scriptExists(sha1));
|
||||
verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] { 0l })}), actual);
|
||||
}
|
||||
|
||||
protected void initConnection() {
|
||||
connection.openPipeline();
|
||||
}
|
||||
@@ -976,33 +1047,4 @@ abstract public class AbstractConnectionPipelineIntegrationTests extends
|
||||
protected List<Object> getResults() {
|
||||
return connection.closePipeline();
|
||||
}
|
||||
|
||||
protected List<Object> convertResults() {
|
||||
List<Object> pipelinedResults = getResults();
|
||||
List<Object> serializedResults = new ArrayList<Object>();
|
||||
for (Object result : pipelinedResults) {
|
||||
Object convertedResult = convertResult(result);
|
||||
if (!"OK".equals(convertedResult) && !"QUEUED".equals(convertedResult)) {
|
||||
serializedResults.add(convertedResult);
|
||||
}
|
||||
}
|
||||
return serializedResults;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
protected Object convertResult(Object result) {
|
||||
if (result instanceof List && !(((List) result).isEmpty())
|
||||
&& ((List) result).get(0) instanceof byte[]) {
|
||||
return (SerializationUtils.deserialize((List<byte[]>) result, stringSerializer));
|
||||
} else if (result instanceof byte[]) {
|
||||
return (stringSerializer.deserialize((byte[]) result));
|
||||
} else if (result instanceof Map
|
||||
&& ((Map) result).keySet().iterator().next() instanceof byte[]) {
|
||||
return (SerializationUtils.deserialize((Map) result, stringSerializer));
|
||||
} else if (result instanceof Set && !(((Set) result).isEmpty())
|
||||
&& ((Set) result).iterator().next() instanceof byte[]) {
|
||||
return (SerializationUtils.deserialize((Set) result, stringSerializer));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,10 @@ import static org.junit.Assert.assertEquals;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.redis.connection.AbstractConnectionIntegrationTests;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import org.springframework.test.annotation.IfProfileValue;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@@ -180,4 +183,16 @@ public class JedisConnectionIntegrationTests extends AbstractConnectionIntegrati
|
||||
connection.hIncrBy(key, hkey, -2 * largeNumber);
|
||||
assertEquals(-largeNumber, Long.valueOf(connection.hGet(key, hkey)).longValue());
|
||||
}
|
||||
|
||||
@Test(expected=InvalidDataAccessApiUsageException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnSingleError() {
|
||||
connection.eval("return redis.call('expire','foo')", ReturnType.BOOLEAN, 0);
|
||||
}
|
||||
|
||||
@Test(expected=InvalidDataAccessApiUsageException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalShaNotFound() {
|
||||
connection.evalSha("somefakesha", ReturnType.VALUE, 2, "key1", "key2");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.springframework.data.redis.RedisSystemException;
|
||||
import org.springframework.data.redis.connection.AbstractConnectionPipelineIntegrationTests;
|
||||
import org.springframework.data.redis.connection.DefaultStringTuple;
|
||||
import org.springframework.data.redis.connection.StringRedisConnection.StringTuple;
|
||||
import org.springframework.test.annotation.IfProfileValue;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@@ -242,6 +243,108 @@ public class JedisConnectionPipelineIntegrationTests extends
|
||||
super.testIncrByDouble();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testScriptLoadEvalSha() {
|
||||
super.testScriptLoadEvalSha();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalShaArrayStrings() {
|
||||
super.testEvalShaArrayStrings();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalShaNotFound() {
|
||||
super.testEvalShaNotFound();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnString() {
|
||||
super.testEvalReturnString();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnNumber() {
|
||||
super.testEvalReturnNumber();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnSingleOK() {
|
||||
super.testEvalReturnSingleOK();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnSingleError() {
|
||||
super.testEvalReturnSingleError();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnFalse() {
|
||||
super.testEvalReturnFalse();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnTrue() {
|
||||
super.testEvalReturnTrue();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnArrayStrings() {
|
||||
super.testEvalReturnArrayStrings();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnArrayNumbers() {
|
||||
super.testEvalReturnArrayNumbers();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnArrayOKs() {
|
||||
super.testEvalReturnArrayOKs();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnArrayFalses() {
|
||||
super.testEvalReturnArrayFalses();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnArrayTrues() {
|
||||
super.testEvalReturnArrayTrues();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testScriptExists() {
|
||||
super.testScriptExists();
|
||||
}
|
||||
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
public void testScriptKill() throws Exception{
|
||||
connection.scriptKill();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testScriptFlush() {
|
||||
super.testScriptFlush();
|
||||
}
|
||||
|
||||
// Overrides, usually due to return values being Long vs Boolean or Set vs
|
||||
// List
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.commons.pool.impl.GenericObjectPool.Config;
|
||||
import org.jredis.JRedis;
|
||||
import org.jredis.protocol.BulkResponse;
|
||||
import org.junit.After;
|
||||
@@ -34,9 +35,9 @@ import org.springframework.data.redis.connection.AbstractConnectionIntegrationTe
|
||||
import org.springframework.data.redis.connection.DefaultSortParameters;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.SortParameters.Order;
|
||||
import org.springframework.test.annotation.IfProfileValue;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.apache.commons.pool.impl.GenericObjectPool.Config;
|
||||
|
||||
/**
|
||||
* Integration test of {@link JredisConnection}
|
||||
@@ -393,6 +394,107 @@ public class JRedisConnectionIntegrationTests extends AbstractConnectionIntegrat
|
||||
super.testIncrByDouble();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testScriptLoadEvalSha() {
|
||||
super.testScriptLoadEvalSha();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalShaArrayStrings() {
|
||||
super.testEvalShaArrayStrings();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalShaNotFound() {
|
||||
super.testEvalShaNotFound();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnString() {
|
||||
super.testEvalReturnString();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnNumber() {
|
||||
super.testEvalReturnNumber();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnSingleOK() {
|
||||
super.testEvalReturnSingleOK();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnSingleError() {
|
||||
super.testEvalReturnSingleError();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnFalse() {
|
||||
super.testEvalReturnFalse();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnTrue() {
|
||||
super.testEvalReturnTrue();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnArrayStrings() {
|
||||
super.testEvalReturnArrayStrings();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnArrayNumbers() {
|
||||
super.testEvalReturnArrayNumbers();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnArrayOKs() {
|
||||
super.testEvalReturnArrayOKs();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnArrayFalses() {
|
||||
super.testEvalReturnArrayFalses();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnArrayTrues() {
|
||||
super.testEvalReturnArrayTrues();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testScriptExists() {
|
||||
super.testScriptExists();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
public void testScriptKill() throws Exception{
|
||||
connection.scriptKill();
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testScriptFlush() {
|
||||
super.testScriptFlush();
|
||||
}
|
||||
|
||||
// Jredis returns null for rPush
|
||||
@Test
|
||||
public void testSort() {
|
||||
|
||||
@@ -16,17 +16,26 @@
|
||||
|
||||
package org.springframework.data.redis.connection.lettuce;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
import static org.springframework.data.redis.SpinBarrier.waitFor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.redis.RedisSystemException;
|
||||
import org.springframework.data.redis.RedisVersionUtils;
|
||||
import org.springframework.data.redis.SettingsUtils;
|
||||
import org.springframework.data.redis.TestCondition;
|
||||
import org.springframework.data.redis.connection.AbstractConnectionIntegrationTests;
|
||||
import org.springframework.data.redis.connection.DefaultStringRedisConnection;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import org.springframework.data.redis.connection.RedisStringCommands.BitOperation;
|
||||
import org.springframework.test.annotation.IfProfileValue;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
@@ -134,4 +143,35 @@ public class LettuceConnectionIntegrationTests extends AbstractConnectionIntegra
|
||||
connection.set("key2", "efgh");
|
||||
actual.add(connection.bitOp(BitOperation.NOT, "key3", "key1", "key2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "runLongTests", value = "true")
|
||||
public void testScriptKill() throws Exception{
|
||||
getResults();
|
||||
assumeTrue(RedisVersionUtils.atLeast("2.6", byteConnection));
|
||||
final AtomicBoolean scriptDead = new AtomicBoolean(false);
|
||||
Thread th = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
final LettuceConnectionFactory factory2 = new LettuceConnectionFactory(SettingsUtils.getHost(),
|
||||
SettingsUtils.getPort());
|
||||
factory2.afterPropertiesSet();
|
||||
DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection(
|
||||
factory2.getConnection());
|
||||
try {
|
||||
conn2.eval("local time=1 while time < 10000000000 do time=time+1 end", ReturnType.BOOLEAN, 0);
|
||||
}catch(DataAccessException e) {
|
||||
scriptDead.set(true);
|
||||
}
|
||||
conn2.close();
|
||||
}
|
||||
});
|
||||
th.start();
|
||||
Thread.sleep(1000);
|
||||
connection.scriptKill();
|
||||
assertTrue(waitFor(new TestCondition() {
|
||||
public boolean passes() {
|
||||
return scriptDead.get();
|
||||
}
|
||||
}, 3000l));
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
import static org.springframework.data.redis.SpinBarrier.waitFor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -29,14 +30,19 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.redis.RedisVersionUtils;
|
||||
import org.springframework.data.redis.SettingsUtils;
|
||||
import org.springframework.data.redis.TestCondition;
|
||||
import org.springframework.data.redis.connection.AbstractConnectionPipelineIntegrationTests;
|
||||
import org.springframework.data.redis.connection.DefaultStringRedisConnection;
|
||||
import org.springframework.data.redis.connection.DefaultStringTuple;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import org.springframework.data.redis.connection.RedisStringCommands.BitOperation;
|
||||
import org.springframework.data.redis.connection.StringRedisConnection.StringTuple;
|
||||
import org.springframework.test.annotation.IfProfileValue;
|
||||
@@ -352,6 +358,67 @@ public class LettuceConnectionPipelineIntegrationTests extends
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnFalse() {
|
||||
// Lettuce actually returns booleans, it's not an SDR conversion
|
||||
actual.add(connection.eval("return false", ReturnType.BOOLEAN, 0));
|
||||
verifyResults(Arrays.asList(new Object[] { false }), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnTrue() {
|
||||
// Lettuce actually returns booleans, it's not an SDR conversion
|
||||
actual.add(connection.eval("return true", ReturnType.BOOLEAN, 0));
|
||||
verifyResults(Arrays.asList(new Object[] { true }), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testScriptFlush() {
|
||||
getResults();
|
||||
String sha1 = connection.scriptLoad("return KEYS[1]");
|
||||
connection.scriptFlush();
|
||||
initConnection();
|
||||
actual.add(connection.scriptExists(sha1));
|
||||
// Lettuce actually returns booleans, it's not an SDR conversion
|
||||
verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] { false })}), actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "runLongTests", value = "true")
|
||||
public void testScriptKill() throws Exception{
|
||||
getResults();
|
||||
assumeTrue(RedisVersionUtils.atLeast("2.6", byteConnection));
|
||||
initConnection();
|
||||
final AtomicBoolean scriptDead = new AtomicBoolean(false);
|
||||
Thread th = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
final LettuceConnectionFactory factory2 = new LettuceConnectionFactory(SettingsUtils.getHost(),
|
||||
SettingsUtils.getPort());
|
||||
factory2.afterPropertiesSet();
|
||||
DefaultStringRedisConnection conn2 = new DefaultStringRedisConnection(
|
||||
factory2.getConnection());
|
||||
try {
|
||||
conn2.eval("local time=1 while time < 10000000000 do time=time+1 end", ReturnType.BOOLEAN, 0);
|
||||
}catch(DataAccessException e) {
|
||||
scriptDead.set(true);
|
||||
}
|
||||
conn2.close();
|
||||
}
|
||||
});
|
||||
th.start();
|
||||
Thread.sleep(1000);
|
||||
getResults();
|
||||
connection.scriptKill();
|
||||
assertTrue(waitFor(new TestCondition() {
|
||||
public boolean passes() {
|
||||
return scriptDead.get();
|
||||
}
|
||||
}, 3000l));
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
protected Object convertResult(Object result) {
|
||||
Object convertedResult = super.convertResult(result);
|
||||
|
||||
@@ -6,11 +6,13 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.redis.connection.RedisPipelineException;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import org.springframework.test.annotation.IfProfileValue;
|
||||
|
||||
/**
|
||||
@@ -71,6 +73,37 @@ public class LettuceConnectionPipelineTxIntegrationTests extends
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=RedisPipelineException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalShaNotFound() {
|
||||
connection.evalSha("somefakesha", ReturnType.VALUE, 2, "key1", "key2");
|
||||
getResults();
|
||||
}
|
||||
|
||||
@Test(expected=RedisPipelineException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnSingleError() {
|
||||
connection.eval("return redis.call('expire','foo')", ReturnType.BOOLEAN, 0);
|
||||
getResults();
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnSingleOK() {
|
||||
actual.add(connection.eval("return redis.call('set','abc','ghk')", ReturnType.STATUS, 0));
|
||||
// We pipeline the result of multi, so add an extra OK here
|
||||
assertEquals(Arrays.asList(new Object[] { "OK", "OK" }), convertResults(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnArrayOKs() {
|
||||
actual.add(connection.eval("return { redis.call('set','abc','ghk'), redis.call('set','abc','lfdf')}",
|
||||
ReturnType.MULTI, 0));
|
||||
// We pipeline the result of multi, so add an extra OK here
|
||||
assertEquals(Arrays.asList(new Object[] {"OK", Arrays.asList(new Object[] {"OK", "OK"} )}), convertResults(false));
|
||||
}
|
||||
|
||||
protected void initConnection() {
|
||||
connection.openPipeline();
|
||||
connection.multi();
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.List;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import org.springframework.test.annotation.IfProfileValue;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
@@ -118,6 +119,30 @@ public class LettuceConnectionTransactionIntegrationTests extends
|
||||
assertTrue(restoreResults.get(0) instanceof RedisException);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalShaNotFound() {
|
||||
connection.evalSha("somefakesha", ReturnType.VALUE, 2, "key1", "key2");
|
||||
List<Object> results = getResults();
|
||||
assertTrue(results.get(0) instanceof RedisException);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnSingleError() {
|
||||
connection.eval("return redis.call('expire','foo')", ReturnType.BOOLEAN, 0);
|
||||
List<Object> results = getResults();
|
||||
assertTrue(results.get(0) instanceof RedisException);
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testScriptKill() {
|
||||
// Impossible to call script kill in a tx because you can't issue the
|
||||
// exec command while Redis is running a script
|
||||
connection.scriptKill();
|
||||
}
|
||||
|
||||
protected void initConnection() {
|
||||
connection.multi();
|
||||
}
|
||||
|
||||
@@ -18,10 +18,14 @@ package org.springframework.data.redis.connection.srp;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.data.redis.connection.AbstractConnectionIntegrationTests;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import org.springframework.test.annotation.IfProfileValue;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
@@ -74,4 +78,18 @@ public class SrpConnectionIntegrationTests extends AbstractConnectionIntegration
|
||||
BulkReply reply = (BulkReply) connection.execute("GET", "foo");
|
||||
assertEquals("bar", stringSerializer.deserialize(reply.data()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnArrayOKs() {
|
||||
// SRP returns the Strings from individual StatusReplys in a MultiBulkReply, while other clients return as byte[]
|
||||
actual.add(connection.eval("return { redis.call('set','abc','ghk'), redis.call('set','abc','lfdf')}",
|
||||
ReturnType.MULTI, 0));
|
||||
verifyResults(Arrays.asList(new Object[] {Arrays.asList(new Object[] {"OK", "OK"} )}), actual);
|
||||
}
|
||||
|
||||
@Ignore("https://github.com/spullara/redis-protocol/issues/25")
|
||||
public void testScriptExists() {
|
||||
//script_exists only returns one result and it's false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.data.redis.connection.AbstractConnectionPipelineIntegrationTests;
|
||||
@@ -42,7 +43,9 @@ import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import redis.reply.BulkReply;
|
||||
import redis.reply.IntegerReply;
|
||||
import redis.reply.Reply;
|
||||
import redis.reply.StatusReply;
|
||||
|
||||
/**
|
||||
* Integration test of {@link SrpConnection} pipeline functionality
|
||||
@@ -190,6 +193,11 @@ public class SrpConnectionPipelineIntegrationTests extends
|
||||
verifyResults(Arrays.asList(new Object[] { 1l, "6.4", "6.4" }), actual);
|
||||
}
|
||||
|
||||
@Ignore("https://github.com/spullara/redis-protocol/issues/25")
|
||||
public void testScriptExists() {
|
||||
// script_exists only returns one result and it's false
|
||||
}
|
||||
|
||||
protected Object convertResult(Object result) {
|
||||
Object convertedResult = super.convertResult(result);
|
||||
if (convertedResult instanceof Reply[]) {
|
||||
@@ -203,7 +211,11 @@ public class SrpConnectionPipelineIntegrationTests extends
|
||||
stringTuples.add(new DefaultStringTuple(tuple, new String(tuple.getValue())));
|
||||
}
|
||||
return stringTuples;
|
||||
} else {
|
||||
} else if(((Reply[]) convertedResult).length > 0 && ((Reply[])convertedResult)[0] instanceof IntegerReply) {
|
||||
return SrpUtils.asIntegerList((Reply[])convertedResult);
|
||||
} else if(((Reply[]) convertedResult).length > 0 && ((Reply[])convertedResult)[0] instanceof StatusReply) {
|
||||
return SrpUtils.asStatusList((Reply[])convertedResult);
|
||||
} else {
|
||||
return SerializationUtils.deserialize(
|
||||
SrpUtils.toBytesList((Reply[]) convertedResult), stringSerializer);
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ package org.springframework.data.redis.connection.srp;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -95,6 +95,22 @@ public class SrpConnectionTransactionIntegrationTests extends SrpConnectionPipel
|
||||
verifyResults(Arrays.asList(new Object[] { "sup", 13l, "suckrcalifrag" }), actual);
|
||||
}
|
||||
|
||||
@Ignore("https://github.com/spullara/redis-protocol/issues/24")
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalReturnSingleError() {
|
||||
// SRP issue exec does not report individual ErrorReplys in a MultiBulkReply
|
||||
// as Exceptions
|
||||
}
|
||||
|
||||
@Ignore("https://github.com/spullara/redis-protocol/issues/24")
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testEvalShaNotFound() {
|
||||
// SRP issue exec does not report individual ErrorReplys in a MultiBulkReply
|
||||
// as Exceptions
|
||||
}
|
||||
|
||||
@Ignore("https://github.com/spullara/redis-protocol/issues/24")
|
||||
@Test
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
@@ -119,6 +135,14 @@ public class SrpConnectionTransactionIntegrationTests extends SrpConnectionPipel
|
||||
// as Exceptions
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
@IfProfileValue(name = "redisVersion", value = "2.6")
|
||||
public void testScriptKill() {
|
||||
// Impossible to call script kill in a tx because you can't issue the
|
||||
// exec command while Redis is running a script
|
||||
connection.scriptKill();
|
||||
}
|
||||
|
||||
protected void initConnection() {
|
||||
connection.multi();
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
reconnect them on next attempted use -->
|
||||
<bean id="jedisConnectionFactory "
|
||||
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
|
||||
p:usePool="false">
|
||||
p:usePool="false" p:timeout="60000">
|
||||
<property name="hostName">
|
||||
<bean class="org.springframework.data.redis.SettingsUtils"
|
||||
factory-method="getHost" />
|
||||
|
||||
Reference in New Issue
Block a user