Merge branch 'master' into eval-with-nested-lists-and-longs

Conflicts:
	src/main/java/redis/clients/jedis/Jedis.java
	src/test/java/redis/clients/jedis/tests/commands/ScriptingCommandsTest.java
This commit is contained in:
Daniel Josefsson
2014-02-05 22:24:23 +00:00
122 changed files with 10799 additions and 7506 deletions

148
Makefile
View File

@@ -6,6 +6,7 @@ pidfile /tmp/redis1.pid
logfile /tmp/redis1.log logfile /tmp/redis1.log
save "" save ""
appendonly no appendonly no
client-output-buffer-limit pubsub 256k 128k 5
endef endef
define REDIS2_CONF define REDIS2_CONF
@@ -37,6 +38,7 @@ pidfile /tmp/redis4.pid
logfile /tmp/redis4.log logfile /tmp/redis4.log
save "" save ""
appendonly no appendonly no
slaveof localhost 6381
endef endef
define REDIS5_CONF define REDIS5_CONF
@@ -48,8 +50,22 @@ pidfile /tmp/redis5.pid
logfile /tmp/redis5.log logfile /tmp/redis5.log
save "" save ""
appendonly no appendonly no
slaveof localhost 6381
endef endef
define REDIS6_CONF
daemonize yes
port 6384
requirepass foobared
masterauth foobared
pidfile /tmp/redis6.pid
logfile /tmp/redis6.log
save ""
appendonly no
slaveof localhost 6379
endef
# SENTINELS
define REDIS_SENTINEL1 define REDIS_SENTINEL1
port 26379 port 26379
daemonize yes daemonize yes
@@ -57,7 +73,6 @@ sentinel monitor mymaster 127.0.0.1 6379 1
sentinel auth-pass mymaster foobared sentinel auth-pass mymaster foobared
sentinel down-after-milliseconds mymaster 3000 sentinel down-after-milliseconds mymaster 3000
sentinel failover-timeout mymaster 900000 sentinel failover-timeout mymaster 900000
sentinel can-failover mymaster yes
sentinel parallel-syncs mymaster 1 sentinel parallel-syncs mymaster 1
pidfile /tmp/sentinel1.pid pidfile /tmp/sentinel1.pid
logfile /tmp/sentinel1.log logfile /tmp/sentinel1.log
@@ -69,7 +84,6 @@ daemonize yes
sentinel monitor mymaster 127.0.0.1 6381 2 sentinel monitor mymaster 127.0.0.1 6381 2
sentinel auth-pass mymaster foobared sentinel auth-pass mymaster foobared
sentinel down-after-milliseconds mymaster 3000 sentinel down-after-milliseconds mymaster 3000
sentinel can-failover mymaster yes
sentinel parallel-syncs mymaster 1 sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 900000 sentinel failover-timeout mymaster 900000
pidfile /tmp/sentinel2.pid pidfile /tmp/sentinel2.pid
@@ -82,31 +96,78 @@ daemonize yes
sentinel monitor mymaster 127.0.0.1 6381 2 sentinel monitor mymaster 127.0.0.1 6381 2
sentinel auth-pass mymaster foobared sentinel auth-pass mymaster foobared
sentinel down-after-milliseconds mymaster 3000 sentinel down-after-milliseconds mymaster 3000
sentinel can-failover mymaster yes
sentinel parallel-syncs mymaster 1 sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 900000 sentinel failover-timeout mymaster 900000
pidfile /tmp/sentinel3.pid pidfile /tmp/sentinel3.pid
logfile /tmp/sentinel3.log logfile /tmp/sentinel3.log
endef endef
# CLUSTER REDIS NODES
define REDIS_CLUSTER_NODE1_CONF
daemonize yes
port 7379
pidfile /tmp/redis_cluster_node1.pid
logfile /tmp/redis_cluster_node1.log
save ""
appendonly no
cluster-enabled yes
cluster-config-file /tmp/redis_cluster_node1.conf
endef
define REDIS_CLUSTER_NODE2_CONF
daemonize yes
port 7380
pidfile /tmp/redis_cluster_node2.pid
logfile /tmp/redis_cluster_node2.log
save ""
appendonly no
cluster-enabled yes
cluster-config-file /tmp/redis_cluster_node2.conf
endef
define REDIS_CLUSTER_NODE3_CONF
daemonize yes
port 7381
pidfile /tmp/redis_cluster_node3.pid
logfile /tmp/redis_cluster_node3.log
save ""
appendonly no
cluster-enabled yes
cluster-config-file /tmp/redis_cluster_node3.conf
endef
export REDIS1_CONF export REDIS1_CONF
export REDIS2_CONF export REDIS2_CONF
export REDIS3_CONF export REDIS3_CONF
export REDIS4_CONF export REDIS4_CONF
export REDIS5_CONF export REDIS5_CONF
export REDIS6_CONF
export REDIS_SENTINEL1 export REDIS_SENTINEL1
export REDIS_SENTINEL2 export REDIS_SENTINEL2
export REDIS_SENTINEL3 export REDIS_SENTINEL3
export REDIS_CLUSTER_NODE1_CONF
export REDIS_CLUSTER_NODE2_CONF
export REDIS_CLUSTER_NODE3_CONF
start: start: cleanup
echo "$$REDIS1_CONF" | redis-server - echo "$$REDIS1_CONF" | redis-server -
echo "$$REDIS2_CONF" | redis-server - echo "$$REDIS2_CONF" | redis-server -
echo "$$REDIS3_CONF" | redis-server - echo "$$REDIS3_CONF" | redis-server -
echo "$$REDIS4_CONF" | redis-server - echo "$$REDIS4_CONF" | redis-server -
echo "$$REDIS5_CONF" | redis-server - echo "$$REDIS5_CONF" | redis-server -
echo "$$REDIS_SENTINEL1" | redis-server - --sentinel echo "$$REDIS6_CONF" | redis-server -
echo "$$REDIS_SENTINEL2" | redis-server - --sentinel echo "$$REDIS_SENTINEL1" > /tmp/sentinel1.conf && redis-server /tmp/sentinel1.conf --sentinel
echo "$$REDIS_SENTINEL3" | redis-server - --sentinel @sleep 0.5
echo "$$REDIS_SENTINEL2" > /tmp/sentinel2.conf && redis-server /tmp/sentinel2.conf --sentinel
@sleep 0.5
echo "$$REDIS_SENTINEL3" > /tmp/sentinel3.conf && redis-server /tmp/sentinel3.conf --sentinel
echo "$$REDIS_CLUSTER_NODE1_CONF" | redis-server -
echo "$$REDIS_CLUSTER_NODE2_CONF" | redis-server -
echo "$$REDIS_CLUSTER_NODE3_CONF" | redis-server -
cleanup:
- rm -vf /tmp/redis_cluster_node*.conf 2>/dev/null
- rm dump.rdb appendonly.aof - 2>/dev/null
stop: stop:
kill `cat /tmp/redis1.pid` kill `cat /tmp/redis1.pid`
@@ -115,76 +176,33 @@ stop:
kill `cat /tmp/redis3.pid` || true kill `cat /tmp/redis3.pid` || true
kill `cat /tmp/redis4.pid` || true kill `cat /tmp/redis4.pid` || true
kill `cat /tmp/redis5.pid` || true kill `cat /tmp/redis5.pid` || true
kill `cat /tmp/redis6.pid` || true
kill `cat /tmp/sentinel1.pid` kill `cat /tmp/sentinel1.pid`
kill `cat /tmp/sentinel2.pid` kill `cat /tmp/sentinel2.pid`
kill `cat /tmp/sentinel3.pid` kill `cat /tmp/sentinel3.pid`
kill `cat /tmp/redis_cluster_node1.pid` || true
kill `cat /tmp/redis_cluster_node2.pid` || true
kill `cat /tmp/redis_cluster_node3.pid` || true
rm -f /tmp/redis_cluster_node1.conf
rm -f /tmp/redis_cluster_node2.conf
rm -f /tmp/redis_cluster_node3.conf
test: test:
echo "$$REDIS1_CONF" | redis-server - make start
echo "$$REDIS2_CONF" | redis-server - sleep 2
echo "$$REDIS3_CONF" | redis-server - mvn -Dtest=${TEST} clean compile test
echo "$$REDIS4_CONF" | redis-server - make stop
echo "$$REDIS5_CONF" | redis-server -
echo "$$REDIS_SENTINEL1" | redis-server - --sentinel
echo "$$REDIS_SENTINEL2" | redis-server - --sentinel
echo "$$REDIS_SENTINEL3" | redis-server - --sentinel
mvn clean compile test
kill `cat /tmp/redis1.pid`
kill `cat /tmp/redis2.pid`
# this get's segfaulted by the tests
kill `cat /tmp/redis3.pid` || true
kill `cat /tmp/redis4.pid` || true
kill `cat /tmp/redis5.pid` || true
kill `cat /tmp/sentinel1.pid`
kill `cat /tmp/sentinel2.pid`
kill `cat /tmp/sentinel3.pid`
deploy: deploy:
echo "$$REDIS1_CONF" | redis-server - make start
echo "$$REDIS2_CONF" | redis-server -
echo "$$REDIS3_CONF" | redis-server -
echo "$$REDIS4_CONF" | redis-server -
echo "$$REDIS5_CONF" | redis-server -
echo "$$REDIS_SENTINEL1" | redis-server - --sentinel
echo "$$REDIS_SENTINEL2" | redis-server - --sentinel
echo "$$REDIS_SENTINEL3" | redis-server - --sentinel
mvn clean deploy mvn clean deploy
make stop
kill `cat /tmp/redis1.pid`
kill `cat /tmp/redis2.pid`
# this get's segfaulted by the tests
kill `cat /tmp/redis3.pid` || true
kill `cat /tmp/redis4.pid` || true
kill `cat /tmp/redis5.pid` || true
kill `cat /tmp/sentinel1.pid`
kill `cat /tmp/sentinel2.pid`
kill `cat /tmp/sentinel3.pid`
release: release:
echo "$$REDIS1_CONF" | redis-server - make start
echo "$$REDIS2_CONF" | redis-server -
echo "$$REDIS3_CONF" | redis-server -
echo "$$REDIS4_CONF" | redis-server -
echo "$$REDIS5_CONF" | redis-server -
echo "$$REDIS_SENTINEL1" | redis-server - --sentinel
echo "$$REDIS_SENTINEL2" | redis-server - --sentinel
echo "$$REDIS_SENTINEL3" | redis-server - --sentinel
mvn release:clean mvn release:clean
mvn release:prepare mvn release:prepare
mvn release:perform mvn release:perform
make stop
kill `cat /tmp/redis1.pid`
kill `cat /tmp/redis2.pid`
# this get's segfaulted by the tests
kill `cat /tmp/redis3.pid` || true
kill `cat /tmp/redis4.pid` || true
kill `cat /tmp/redis5.pid` || true
kill `cat /tmp/sentinel1.pid`
kill `cat /tmp/sentinel2.pid`
kill `cat /tmp/sentinel3.pid`
.PHONY: test .PHONY: test

View File

@@ -4,7 +4,7 @@ Jedis is a blazingly small and sane [Redis](http://github.com/antirez/redis "Red
Jedis was conceived to be EASY to use. Jedis was conceived to be EASY to use.
Jedis is fully compatible with redis 2.6.14. Jedis is fully compatible with redis 2.8.5.
## Community ## Community
@@ -33,6 +33,7 @@ All of the following redis features are supported:
- Key-tags for sharding - Key-tags for sharding
- Sharding with pipelining - Sharding with pipelining
- Scripting with pipelining - Scripting with pipelining
- Redis Cluster
## How do I use it? ## How do I use it?
@@ -45,7 +46,7 @@ Or use it as a maven dependency:
<dependency> <dependency>
<groupId>redis.clients</groupId> <groupId>redis.clients</groupId>
<artifactId>jedis</artifactId> <artifactId>jedis</artifactId>
<version>2.0.0</version> <version>2.2.1</version>
<type>jar</type> <type>jar</type>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
@@ -65,6 +66,19 @@ Please check the [wiki](http://github.com/xetorthio/jedis/wiki "wiki"). There ar
And you are done! And you are done!
## Jedis Cluster
Redis cluster [specification](http://redis.io/topics/cluster-spec) (still under development) is implemented
```java
Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
//Jedis Cluster will attempt to discover cluster nodes automatically
jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7379));
JedisCluster jc = new JedisCluster(jedisClusterNode);
jc.set("foo", "bar");
String value = jc.get("foo");
```
## I want to contribute! ## I want to contribute!
That is great! Just fork the project in github. Create a topic branch, write some code, and add some tests for your new code. That is great! Just fork the project in github. Create a topic branch, write some code, and add some tests for your new code.

View File

@@ -11,8 +11,8 @@ repositories {
} }
dependencies { dependencies {
testCompile 'junit:junit:4.8.1' testCompile 'junit:junit:4.11'
compile 'commons-pool:commons-pool:1.5.5' compile 'org.apache.commons:commons-pool2:2.0'
} }
@@ -28,6 +28,6 @@ uploadArchives {
*/ */
task createWrapper(type: Wrapper) { task createWrapper(type: Wrapper) {
gradleVersion = '1.0-milestone-6' gradleVersion = '1.8'
} }

Binary file not shown.

View File

@@ -1,6 +1,6 @@
#Fri Dec 23 12:54:50 CST 2011 #Mon Nov 04 18:13:13 EST 2013
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=http\://repo.gradle.org/gradle/distributions/gradle-1.0-milestone-6-bin.zip distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip

94
gradlew vendored
View File

@@ -1,16 +1,16 @@
#!/bin/bash #!/usr/bin/env bash
############################################################################## ##############################################################################
## ## ##
## Gradle wrapper script for UN*X ## ## Gradle start up script for UN*X
## ## ##
############################################################################## ##############################################################################
# Uncomment those lines to set JVM options. GRADLE_OPTS and JAVA_OPTS can be used together. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
# GRADLE_OPTS="$GRADLE_OPTS -Xmx512m" DEFAULT_JVM_OPTS=""
# JAVA_OPTS="$JAVA_OPTS -Xmx512m"
GRADLE_APP_NAME=Gradle APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum" MAX_FD="maximum"
@@ -42,35 +42,32 @@ case "`uname`" in
;; ;;
esac esac
# Attempt to set JAVA_HOME if it's not already set.
if [ -z "$JAVA_HOME" ] ; then
if $darwin ; then
[ -z "$JAVA_HOME" -a -d "/Library/Java/Home" ] && export JAVA_HOME="/Library/Java/Home"
[ -z "$JAVA_HOME" -a -d "/System/Library/Frameworks/JavaVM.framework/Home" ] && export JAVA_HOME="/System/Library/Frameworks/JavaVM.framework/Home"
else
javaExecutable="`which javac`"
[ -z "$javaExecutable" -o "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ] && die "JAVA_HOME not set and cannot find javac to deduce location, please set JAVA_HOME."
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
[ `expr "$readLink" : '\([^ ]*\)'` = "no" ] && die "JAVA_HOME not set and readlink not available, please set JAVA_HOME."
javaExecutable="`readlink -f \"$javaExecutable\"`"
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
export JAVA_HOME="$javaHome"
fi
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched. # For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then if $cygwin ; then
[ -n "$JAVACMD" ] && JAVACMD=`cygpath --unix "$JAVACMD"`
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi fi
STARTER_MAIN_CLASS=org.gradle.wrapper.GradleWrapperMain # Attempt to set APP_HOME
CLASSPATH=`dirname "$0"`/gradle/wrapper/gradle-wrapper.jar # Resolve links: $0 may be a link
WRAPPER_PROPERTIES=`dirname "$0"`/gradle/wrapper/gradle-wrapper.properties PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables # IBM's JDK on AIX uses strange locations for the executables
@@ -78,18 +75,18 @@ if [ -z "$JAVACMD" ] ; then
else else
JAVACMD="$JAVA_HOME/bin/java" JAVACMD="$JAVA_HOME/bin/java"
fi fi
else
JAVACMD="java"
fi
fi
if [ ! -x "$JAVACMD" ] ; then if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi fi
if [ -z "$JAVA_HOME" ] ; then else
warn "JAVA_HOME environment variable is not set" JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
@@ -104,19 +101,18 @@ if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD" warn "Could not set maximum file descriptor limit: $MAX_FD"
fi fi
else else
warn "Could not query businessSystem maximum file descriptor limit: $MAX_FD_LIMIT" warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi fi
fi fi
# For Darwin, add GRADLE_APP_NAME to the JAVA_OPTS as -Xdock:name # For Darwin, add options to specify how the application appears in the dock
if $darwin; then if $darwin; then
JAVA_OPTS="$JAVA_OPTS -Xdock:name=$GRADLE_APP_NAME" GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
# we may also want to set -Xdock:image
fi fi
# For Cygwin, switch paths to Windows format before running java # For Cygwin, switch paths to Windows format before running java
if $cygwin ; then if $cygwin ; then
JAVA_HOME=`cygpath --path --mixed "$JAVA_HOME"` APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath # We build the pattern for arguments to be converted via cygpath
@@ -158,11 +154,11 @@ if $cygwin ; then
esac esac
fi fi
GRADLE_APP_BASE_NAME=`basename "$0"` # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" $JAVA_OPTS $GRADLE_OPTS \ exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
-classpath "$CLASSPATH" \
-Dorg.gradle.appname="$GRADLE_APP_BASE_NAME" \
-Dorg.gradle.wrapper.properties="$WRAPPER_PROPERTIES" \
$STARTER_MAIN_CLASS \
"$@"

52
gradlew.bat vendored
View File

@@ -1,24 +1,37 @@
@if "%DEBUG%" == "" @echo off @if "%DEBUG%" == "" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem ## @rem
@rem Gradle startup script for Windows ## @rem Gradle startup script for Windows
@rem ## @rem
@rem ########################################################################## @rem ##########################################################################
@rem Set local scope for the variables with windows NT shell @rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
@rem Uncomment those lines to set JVM options. GRADLE_OPTS and JAVA_OPTS can be used together. @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
@rem set GRADLE_OPTS=%GRADLE_OPTS% -Xmx512m set DEFAULT_JVM_OPTS=
@rem set JAVA_OPTS=%JAVA_OPTS% -Xmx512m
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.\ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe @rem Find java.exe
set JAVA_EXE=java.exe if defined JAVA_HOME goto findJavaFromJavaHome
if not defined JAVA_HOME goto init
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
@@ -29,14 +42,14 @@ echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo. echo.
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation. echo location of your Java installation.
echo.
goto end goto fail
:init :init
@rem Get command-line arguments, handling Windowz variants @rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args if not "%OS%" == "Windows_NT" goto win9xME_args
if "%eval[2+2]" == "4" goto 4NT_args if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args :win9xME_args
@rem Slurp the command line arguments. @rem Slurp the command line arguments.
@@ -56,25 +69,20 @@ set CMD_LINE_ARGS=%$
:execute :execute
@rem Setup the command line @rem Setup the command line
set STARTER_MAIN_CLASS=org.gradle.wrapper.GradleWrapperMain set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
set CLASSPATH=%DIRNAME%\gradle\wrapper\gradle-wrapper.jar
set WRAPPER_PROPERTIES=%DIRNAME%\gradle\wrapper\gradle-wrapper.properties
set GRADLE_OPTS=%JAVA_OPTS% %GRADLE_OPTS% -Dorg.gradle.wrapper.properties="%WRAPPER_PROPERTIES%"
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %GRADLE_OPTS% -classpath "%CLASSPATH%" %STARTER_MAIN_CLASS% %CMD_LINE_ARGS% "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd if "%ERRORLEVEL%"=="0" goto mainEnd
if not "%OS%"=="Windows_NT" echo 1 > nul | choice /n /c:1 :fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code! rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit "%ERRORLEVEL%" if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b "%ERRORLEVEL%" exit /b 1
:mainEnd :mainEnd
if "%OS%"=="Windows_NT" endlocal if "%OS%"=="Windows_NT" endlocal

17
pom.xml
View File

@@ -9,7 +9,7 @@
<packaging>jar</packaging> <packaging>jar</packaging>
<groupId>redis.clients</groupId> <groupId>redis.clients</groupId>
<artifactId>jedis</artifactId> <artifactId>jedis</artifactId>
<version>2.2.2-SNAPSHOT</version> <version>2.3.2-SNAPSHOT</version>
<name>Jedis</name> <name>Jedis</name>
<description>Jedis is a blazingly small and sane Redis java client.</description> <description>Jedis is a blazingly small and sane Redis java client.</description>
<url>https://github.com/xetorthio/jedis</url> <url>https://github.com/xetorthio/jedis</url>
@@ -45,8 +45,9 @@
</scm> </scm>
<properties> <properties>
<redis-hosts>localhost:6379,localhost:6380,localhost:6381,localhost:6382,localhost:6383</redis-hosts> <redis-hosts>localhost:6379,localhost:6380,localhost:6381,localhost:6382,localhost:6383,localhost:6384</redis-hosts>
<sentinel-hosts>localhost:26379,localhost:26380</sentinel-hosts> <sentinel-hosts>localhost:26379,localhost:26380,localhost:26381</sentinel-hosts>
<cluster-hosts>localhost:7379,localhost:7380,localhost:7381</cluster-hosts>
<github.global.server>github</github.global.server> <github.global.server>github</github.global.server>
</properties> </properties>
@@ -59,9 +60,9 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>commons-pool</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-pool</artifactId> <artifactId>commons-pool2</artifactId>
<version>1.6</version> <version>2.0</version>
<type>jar</type> <type>jar</type>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
@@ -115,11 +116,11 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId> <artifactId>maven-release-plugin</artifactId>
<version>2.4.1</version> <version>2.4.2</version>
</plugin> </plugin>
<plugin> <plugin>
<artifactId>maven-deploy-plugin</artifactId> <artifactId>maven-deploy-plugin</artifactId>
<version>2.7</version> <version>2.8.1</version>
<configuration> <configuration>
<altDeploymentRepository>internal.repo::default::file://${project.build.directory}/mvn-repo</altDeploymentRepository> <altDeploymentRepository>internal.repo::default::file://${project.build.directory}/mvn-repo</altDeploymentRepository>
</configuration> </configuration>

View File

@@ -1,6 +1,5 @@
package redis.clients.jedis; package redis.clients.jedis;
import java.util.List; import java.util.List;
public interface AdvancedBinaryJedisCommands { public interface AdvancedBinaryJedisCommands {

View File

@@ -1,9 +1,8 @@
package redis.clients.jedis; package redis.clients.jedis;
import redis.clients.util.Slowlog;
import java.util.List; import java.util.List;
import redis.clients.util.Slowlog;
public interface AdvancedJedisCommands { public interface AdvancedJedisCommands {
List<String> configGet(String pattern); List<String> configGet(String pattern);

View File

@@ -39,4 +39,6 @@ public interface BasicCommands {
String debug(DebugParams params); String debug(DebugParams params);
String configResetStat(); String configResetStat();
Long waitReplicas(int replicas, long timeout);
} }

View File

@@ -1,8 +1,5 @@
package redis.clients.jedis; package redis.clients.jedis;
import java.util.List;
/** /**
* Pipelined responses for all of the low level, non key related commands * Pipelined responses for all of the low level, non key related commands
*/ */

View File

@@ -1,22 +1,26 @@
package redis.clients.jedis; package redis.clients.jedis;
import redis.clients.jedis.Protocol.Command; import static redis.clients.jedis.Protocol.toByteArray;
import redis.clients.jedis.Protocol.Keyword; import static redis.clients.jedis.Protocol.Command.*;
import redis.clients.util.SafeEncoder; import static redis.clients.jedis.Protocol.Keyword.ENCODING;
import static redis.clients.jedis.Protocol.Keyword.IDLETIME;
import static redis.clients.jedis.Protocol.Keyword.LEN;
import static redis.clients.jedis.Protocol.Keyword.LIMIT;
import static redis.clients.jedis.Protocol.Keyword.NO;
import static redis.clients.jedis.Protocol.Keyword.ONE;
import static redis.clients.jedis.Protocol.Keyword.REFCOUNT;
import static redis.clients.jedis.Protocol.Keyword.RESET;
import static redis.clients.jedis.Protocol.Keyword.STORE;
import static redis.clients.jedis.Protocol.Keyword.WITHSCORES;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import static redis.clients.jedis.Protocol.Command.*; import redis.clients.jedis.Protocol.Command;
import static redis.clients.jedis.Protocol.Command.EXISTS; import redis.clients.jedis.Protocol.Keyword;
import static redis.clients.jedis.Protocol.Command.PSUBSCRIBE; import redis.clients.util.SafeEncoder;
import static redis.clients.jedis.Protocol.Command.PUNSUBSCRIBE;
import static redis.clients.jedis.Protocol.Command.SUBSCRIBE;
import static redis.clients.jedis.Protocol.Command.UNSUBSCRIBE;
import static redis.clients.jedis.Protocol.Keyword.*;
import static redis.clients.jedis.Protocol.toByteArray;
public class BinaryClient extends Connection { public class BinaryClient extends Connection {
public enum LIST_POSITION { public enum LIST_POSITION {
@@ -34,10 +38,16 @@ public class BinaryClient extends Connection {
private long db; private long db;
private boolean isInWatch;
public boolean isInMulti() { public boolean isInMulti() {
return isInMulti; return isInMulti;
} }
public boolean isInWatch() {
return isInWatch;
}
public BinaryClient(final String host) { public BinaryClient(final String host) {
super(host); super(host);
} }
@@ -82,11 +92,11 @@ public class BinaryClient extends Connection {
sendCommand(Command.SET, key, value); sendCommand(Command.SET, key, value);
} }
public void set(final byte[] key, final byte[] value, final byte[] nxxx, final byte[] expx, final long time) { public void set(final byte[] key, final byte[] value, final byte[] nxxx,
final byte[] expx, final long time) {
sendCommand(Command.SET, key, value, nxxx, expx, toByteArray(time)); sendCommand(Command.SET, key, value, nxxx, expx, toByteArray(time));
} }
public void get(final byte[] key) { public void get(final byte[] key) {
sendCommand(Command.GET, key); sendCommand(Command.GET, key);
} }
@@ -377,15 +387,16 @@ public class BinaryClient extends Connection {
sendCommand(ZADD, key, toByteArray(score), member); sendCommand(ZADD, key, toByteArray(score), member);
} }
public void zaddBinary(final byte[] key, Map<Double, byte[]> scoreMembers) { public void zaddBinary(final byte[] key,
final Map<byte[], Double> scoreMembers) {
ArrayList<byte[]> args = new ArrayList<byte[]>( ArrayList<byte[]> args = new ArrayList<byte[]>(
scoreMembers.size() * 2 + 1); scoreMembers.size() * 2 + 1);
args.add(key); args.add(key);
for (Map.Entry<Double, byte[]> entry : scoreMembers.entrySet()) { for (Map.Entry<byte[], Double> entry : scoreMembers.entrySet()) {
args.add(toByteArray(entry.getKey())); args.add(toByteArray(entry.getValue()));
args.add(entry.getValue()); args.add(entry.getKey());
} }
byte[][] argsArray = new byte[args.size()][]; byte[][] argsArray = new byte[args.size()][];
@@ -447,19 +458,23 @@ public class BinaryClient extends Connection {
public void discard() { public void discard() {
sendCommand(DISCARD); sendCommand(DISCARD);
isInMulti = false; isInMulti = false;
isInWatch = false;
} }
public void exec() { public void exec() {
sendCommand(EXEC); sendCommand(EXEC);
isInMulti = false; isInMulti = false;
isInWatch = false;
} }
public void watch(final byte[]... keys) { public void watch(final byte[]... keys) {
sendCommand(WATCH, keys); sendCommand(WATCH, keys);
isInWatch = true;
} }
public void unwatch() { public void unwatch() {
sendCommand(UNWATCH); sendCommand(UNWATCH);
isInWatch = false;
} }
public void sort(final byte[] key) { public void sort(final byte[] key) {
@@ -546,10 +561,15 @@ public class BinaryClient extends Connection {
sendCommand(PUNSUBSCRIBE, patterns); sendCommand(PUNSUBSCRIBE, patterns);
} }
public void pubsub(final byte[]... args) {
sendCommand(PUBSUB, args);
}
public void zcount(final byte[] key, final double min, final double max) { public void zcount(final byte[] key, final double min, final double max) {
byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf".getBytes() : toByteArray(min); byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf"
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf".getBytes() : toByteArray(max); .getBytes() : toByteArray(min);
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf"
.getBytes() : toByteArray(max);
sendCommand(ZCOUNT, key, byteArrayMin, byteArrayMax); sendCommand(ZCOUNT, key, byteArrayMin, byteArrayMax);
} }
@@ -565,8 +585,10 @@ public class BinaryClient extends Connection {
public void zrangeByScore(final byte[] key, final double min, public void zrangeByScore(final byte[] key, final double min,
final double max) { final double max) {
byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf".getBytes() : toByteArray(min); byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf"
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf".getBytes() : toByteArray(max); .getBytes() : toByteArray(min);
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf"
.getBytes() : toByteArray(max);
sendCommand(ZRANGEBYSCORE, key, byteArrayMin, byteArrayMax); sendCommand(ZRANGEBYSCORE, key, byteArrayMin, byteArrayMax);
} }
@@ -584,8 +606,10 @@ public class BinaryClient extends Connection {
public void zrevrangeByScore(final byte[] key, final double max, public void zrevrangeByScore(final byte[] key, final double max,
final double min) { final double min) {
byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf".getBytes() : toByteArray(min); byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf"
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf".getBytes() : toByteArray(max); .getBytes() : toByteArray(min);
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf"
.getBytes() : toByteArray(max);
sendCommand(ZREVRANGEBYSCORE, key, byteArrayMax, byteArrayMin); sendCommand(ZREVRANGEBYSCORE, key, byteArrayMax, byteArrayMin);
} }
@@ -603,11 +627,13 @@ public class BinaryClient extends Connection {
public void zrangeByScore(final byte[] key, final double min, public void zrangeByScore(final byte[] key, final double min,
final double max, final int offset, int count) { final double max, final int offset, int count) {
byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf".getBytes() : toByteArray(min); byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf"
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf".getBytes() : toByteArray(max); .getBytes() : toByteArray(min);
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf"
.getBytes() : toByteArray(max);
sendCommand(ZRANGEBYSCORE, key, byteArrayMin, byteArrayMax, sendCommand(ZRANGEBYSCORE, key, byteArrayMin, byteArrayMax, LIMIT.raw,
LIMIT.raw, toByteArray(offset), toByteArray(count)); toByteArray(offset), toByteArray(count));
} }
public void zrangeByScore(final byte[] key, final String min, public void zrangeByScore(final byte[] key, final String min,
@@ -620,8 +646,10 @@ public class BinaryClient extends Connection {
public void zrevrangeByScore(final byte[] key, final double max, public void zrevrangeByScore(final byte[] key, final double max,
final double min, final int offset, int count) { final double min, final int offset, int count) {
byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf".getBytes() : toByteArray(min); byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf"
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf".getBytes() : toByteArray(max); .getBytes() : toByteArray(min);
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf"
.getBytes() : toByteArray(max);
sendCommand(ZREVRANGEBYSCORE, key, byteArrayMax, byteArrayMin, sendCommand(ZREVRANGEBYSCORE, key, byteArrayMax, byteArrayMin,
LIMIT.raw, toByteArray(offset), toByteArray(count)); LIMIT.raw, toByteArray(offset), toByteArray(count));
@@ -637,8 +665,10 @@ public class BinaryClient extends Connection {
public void zrangeByScoreWithScores(final byte[] key, final double min, public void zrangeByScoreWithScores(final byte[] key, final double min,
final double max) { final double max) {
byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf".getBytes() : toByteArray(min); byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf"
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf".getBytes() : toByteArray(max); .getBytes() : toByteArray(min);
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf"
.getBytes() : toByteArray(max);
sendCommand(ZRANGEBYSCORE, key, byteArrayMin, byteArrayMax, sendCommand(ZRANGEBYSCORE, key, byteArrayMin, byteArrayMax,
WITHSCORES.raw); WITHSCORES.raw);
@@ -654,8 +684,10 @@ public class BinaryClient extends Connection {
public void zrevrangeByScoreWithScores(final byte[] key, final double max, public void zrevrangeByScoreWithScores(final byte[] key, final double max,
final double min) { final double min) {
byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf".getBytes() : toByteArray(min); byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf"
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf".getBytes() : toByteArray(max); .getBytes() : toByteArray(min);
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf"
.getBytes() : toByteArray(max);
sendCommand(ZREVRANGEBYSCORE, key, byteArrayMax, byteArrayMin, sendCommand(ZREVRANGEBYSCORE, key, byteArrayMax, byteArrayMin,
WITHSCORES.raw); WITHSCORES.raw);
@@ -670,12 +702,13 @@ public class BinaryClient extends Connection {
public void zrangeByScoreWithScores(final byte[] key, final double min, public void zrangeByScoreWithScores(final byte[] key, final double min,
final double max, final int offset, final int count) { final double max, final int offset, final int count) {
byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf".getBytes() : toByteArray(min); byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf"
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf".getBytes() : toByteArray(max); .getBytes() : toByteArray(min);
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf"
.getBytes() : toByteArray(max);
sendCommand(ZRANGEBYSCORE, key, byteArrayMin, byteArrayMax, sendCommand(ZRANGEBYSCORE, key, byteArrayMin, byteArrayMax, LIMIT.raw,
LIMIT.raw, toByteArray(offset), toByteArray(count), toByteArray(offset), toByteArray(count), WITHSCORES.raw);
WITHSCORES.raw);
} }
public void zrangeByScoreWithScores(final byte[] key, final String min, public void zrangeByScoreWithScores(final byte[] key, final String min,
@@ -688,8 +721,10 @@ public class BinaryClient extends Connection {
public void zrevrangeByScoreWithScores(final byte[] key, final double max, public void zrevrangeByScoreWithScores(final byte[] key, final double max,
final double min, final int offset, final int count) { final double min, final int offset, final int count) {
byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf".getBytes() : toByteArray(min); byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf"
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf".getBytes() : toByteArray(max); .getBytes() : toByteArray(min);
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf"
.getBytes() : toByteArray(max);
sendCommand(ZREVRANGEBYSCORE, key, byteArrayMax, byteArrayMin, sendCommand(ZREVRANGEBYSCORE, key, byteArrayMax, byteArrayMin,
LIMIT.raw, toByteArray(offset), toByteArray(count), LIMIT.raw, toByteArray(offset), toByteArray(count),
@@ -913,6 +948,14 @@ public class BinaryClient extends Connection {
super.disconnect(); super.disconnect();
} }
public void resetState() {
if (isInMulti())
discard();
if (isInWatch())
unwatch();
}
private void sendEvalCommand(Command command, byte[] script, private void sendEvalCommand(Command command, byte[] script,
byte[] keyCount, byte[][] params) { byte[] keyCount, byte[][] params) {
@@ -1037,7 +1080,8 @@ public class BinaryClient extends Connection {
sendCommand(DUMP, key); sendCommand(DUMP, key);
} }
public void restore(final byte[] key, final int ttl, final byte[] serializedValue) { public void restore(final byte[] key, final int ttl,
final byte[] serializedValue) {
sendCommand(RESTORE, key, toByteArray(ttl), serializedValue); sendCommand(RESTORE, key, toByteArray(ttl), serializedValue);
} }
@@ -1057,7 +1101,8 @@ public class BinaryClient extends Connection {
sendCommand(INCRBYFLOAT, key, toByteArray(increment)); sendCommand(INCRBYFLOAT, key, toByteArray(increment));
} }
public void psetex(final byte[] key, final int milliseconds, final byte[] value) { public void psetex(final byte[] key, final int milliseconds,
final byte[] value) {
sendCommand(PSETEX, key, toByteArray(milliseconds), value); sendCommand(PSETEX, key, toByteArray(milliseconds), value);
} }
@@ -1065,7 +1110,8 @@ public class BinaryClient extends Connection {
sendCommand(Command.SET, key, value, nxxx); sendCommand(Command.SET, key, value, nxxx);
} }
public void set(final byte[] key, final byte[] value, final byte[] nxxx, final byte[] expx, final int time) { public void set(final byte[] key, final byte[] value, final byte[] nxxx,
final byte[] expx, final int time) {
sendCommand(Command.SET, key, value, nxxx, expx, toByteArray(time)); sendCommand(Command.SET, key, value, nxxx, expx, toByteArray(time));
} }
@@ -1093,11 +1139,57 @@ public class BinaryClient extends Connection {
sendCommand(TIME); sendCommand(TIME);
} }
public void migrate(final byte[] host, final int port, final byte[] key, final int destinationDb, final int timeout) { public void migrate(final byte[] host, final int port, final byte[] key,
sendCommand(MIGRATE, host, toByteArray(port), key, toByteArray(destinationDb), toByteArray(timeout)); final int destinationDb, final int timeout) {
sendCommand(MIGRATE, host, toByteArray(port), key,
toByteArray(destinationDb), toByteArray(timeout));
} }
public void hincrByFloat(final byte[] key, final byte[] field, double increment) { public void hincrByFloat(final byte[] key, final byte[] field,
double increment) {
sendCommand(HINCRBYFLOAT, key, field, toByteArray(increment)); sendCommand(HINCRBYFLOAT, key, field, toByteArray(increment));
} }
public void scan(int cursor, final ScanParams params) {
final List<byte[]> args = new ArrayList<byte[]>();
args.add(toByteArray(cursor));
args.addAll(params.getParams());
sendCommand(SCAN, args.toArray(new byte[args.size()][]));
}
public void hscan(final byte[] key, int cursor, final ScanParams params) {
final List<byte[]> args = new ArrayList<byte[]>();
args.add(key);
args.add(toByteArray(cursor));
args.addAll(params.getParams());
sendCommand(HSCAN, args.toArray(new byte[args.size()][]));
}
public void sscan(final byte[] key, int cursor, final ScanParams params) {
final List<byte[]> args = new ArrayList<byte[]>();
args.add(key);
args.add(toByteArray(cursor));
args.addAll(params.getParams());
sendCommand(SSCAN, args.toArray(new byte[args.size()][]));
}
public void zscan(final byte[] key, int cursor, final ScanParams params) {
final List<byte[]> args = new ArrayList<byte[]>();
args.add(key);
args.add(toByteArray(cursor));
args.addAll(params.getParams());
sendCommand(ZSCAN, args.toArray(new byte[args.size()][]));
}
public void waitReplicas(int replicas, long timeout) {
sendCommand(WAIT, toByteArray(replicas), toByteArray(timeout));
}
public void cluster(final byte[]... args) {
sendCommand(CLUSTER, args);
}
public void asking() {
sendCommand(Command.ASKING);
}
} }

View File

@@ -1,17 +1,25 @@
package redis.clients.jedis; package redis.clients.jedis;
import static redis.clients.jedis.Protocol.toByteArray;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import redis.clients.jedis.BinaryClient.LIST_POSITION; import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.exceptions.JedisException; import redis.clients.jedis.exceptions.JedisException;
import redis.clients.util.JedisByteHashMap; import redis.clients.util.JedisByteHashMap;
import redis.clients.util.SafeEncoder; import redis.clients.util.SafeEncoder;
import java.net.URI; public class BinaryJedis implements BasicCommands, BinaryJedisCommands,
import java.util.*; MultiKeyBinaryCommands, AdvancedBinaryJedisCommands,
BinaryScriptingCommands {
import static redis.clients.jedis.Protocol.toByteArray;
public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKeyBinaryCommands, AdvancedBinaryJedisCommands, BinaryScriptingCommands {
protected Client client = null; protected Client client = null;
public BinaryJedis(final String host) { public BinaryJedis(final String host) {
@@ -75,15 +83,20 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
/** /**
* Set the string value as value of the key. The string can't be longer than * Set the string value as value of the key. The string can't be longer than
* 1073741824 bytes (1 GB). * 1073741824 bytes (1 GB).
*
* @param key * @param key
* @param value * @param value
* @param nxxx NX|XX, NX -- Only set the key if it does not already exist. * @param nxxx
* XX -- Only set the key if it already exist. * NX|XX, NX -- Only set the key if it does not already exist. XX
* @param expx EX|PX, expire time units: EX = seconds; PX = milliseconds * -- Only set the key if it already exist.
* @param time expire time in the units of {@param #expx} * @param expx
* EX|PX, expire time units: EX = seconds; PX = milliseconds
* @param time
* expire time in the units of {@param #expx}
* @return Status code reply * @return Status code reply
*/ */
public String set(final byte[] key, final byte[] value, final byte[] nxxx, final byte[] expx, final long time) { public String set(final byte[] key, final byte[] value, final byte[] nxxx,
final byte[] expx, final long time) {
checkIsInMulti(); checkIsInMulti();
client.set(key, value, nxxx, expx, time); client.set(key, value, nxxx, expx, time);
return client.getStatusCodeReply(); return client.getStatusCodeReply();
@@ -1006,7 +1019,8 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
* @return Multi bulk reply, specifically a list of elements in the * @return Multi bulk reply, specifically a list of elements in the
* specified range. * specified range.
*/ */
public List<byte[]> lrange(final byte[] key, final long start, final long end) { public List<byte[]> lrange(final byte[] key, final long start,
final long end) {
checkIsInMulti(); checkIsInMulti();
client.lrange(key, start, end); client.lrange(key, start, end);
return client.getBinaryMultiBulkReply(); return client.getBinaryMultiBulkReply();
@@ -1502,7 +1516,7 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
return client.getIntegerReply(); return client.getIntegerReply();
} }
public Long zadd(final byte[] key, final Map<Double, byte[]> scoreMembers) { public Long zadd(final byte[] key, final Map<byte[], Double> scoreMembers) {
checkIsInMulti(); checkIsInMulti();
client.zaddBinary(key, scoreMembers); client.zaddBinary(key, scoreMembers);
return client.getIntegerReply(); return client.getIntegerReply();
@@ -1685,13 +1699,9 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
public List<Object> multi(final TransactionBlock jedisTransaction) { public List<Object> multi(final TransactionBlock jedisTransaction) {
List<Object> results = null; List<Object> results = null;
jedisTransaction.setClient(client); jedisTransaction.setClient(client);
try {
client.multi(); client.multi();
jedisTransaction.execute(); jedisTransaction.execute();
results = jedisTransaction.exec(); results = jedisTransaction.exec();
} catch (Exception ex) {
jedisTransaction.discard();
}
return results; return results;
} }
@@ -1710,6 +1720,11 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
client.disconnect(); client.disconnect();
} }
public void resetState() {
client.resetState();
client.getAll();
}
public String watch(final byte[]... keys) { public String watch(final byte[]... keys) {
client.watch(keys); client.watch(keys);
return client.getStatusCodeReply(); return client.getStatusCodeReply();
@@ -2261,7 +2276,8 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
*/ */
public Set<byte[]> zrangeByScore(final byte[] key, final double min, public Set<byte[]> zrangeByScore(final byte[] key, final double min,
final double max, final int offset, final int count) { final double max, final int offset, final int count) {
return zrangeByScore(key, toByteArray(min),toByteArray(max),offset, count); return zrangeByScore(key, toByteArray(min), toByteArray(max), offset,
count);
} }
public Set<byte[]> zrangeByScore(final byte[] key, final byte[] min, public Set<byte[]> zrangeByScore(final byte[] key, final byte[] min,
@@ -2399,7 +2415,8 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
public Set<Tuple> zrangeByScoreWithScores(final byte[] key, public Set<Tuple> zrangeByScoreWithScores(final byte[] key,
final double min, final double max, final int offset, final double min, final double max, final int offset,
final int count) { final int count) {
return zrangeByScoreWithScores(key, toByteArray(min), toByteArray(max), offset, count); return zrangeByScoreWithScores(key, toByteArray(min), toByteArray(max),
offset, count);
} }
public Set<Tuple> zrangeByScoreWithScores(final byte[] key, public Set<Tuple> zrangeByScoreWithScores(final byte[] key,
@@ -2437,7 +2454,8 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
public Set<byte[]> zrevrangeByScore(final byte[] key, final double max, public Set<byte[]> zrevrangeByScore(final byte[] key, final double max,
final double min, final int offset, final int count) { final double min, final int offset, final int count) {
return zrevrangeByScore(key, toByteArray(max), toByteArray(min), offset, count); return zrevrangeByScore(key, toByteArray(max), toByteArray(min),
offset, count);
} }
public Set<byte[]> zrevrangeByScore(final byte[] key, final byte[] max, public Set<byte[]> zrevrangeByScore(final byte[] key, final byte[] max,
@@ -2449,13 +2467,15 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key, public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key,
final double max, final double min) { final double max, final double min) {
return zrevrangeByScoreWithScores(key, toByteArray(max), toByteArray(min)); return zrevrangeByScoreWithScores(key, toByteArray(max),
toByteArray(min));
} }
public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key, public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key,
final double max, final double min, final int offset, final double max, final double min, final int offset,
final int count) { final int count) {
return zrevrangeByScoreWithScores(key, toByteArray(max), toByteArray(min), offset, count); return zrevrangeByScoreWithScores(key, toByteArray(max),
toByteArray(min), offset, count);
} }
public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key, public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key,
@@ -2488,7 +2508,8 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
* operation * operation
* *
*/ */
public Long zremrangeByRank(final byte[] key, final long start, final long end) { public Long zremrangeByRank(final byte[] key, final long start,
final long end) {
checkIsInMulti(); checkIsInMulti();
client.zremrangeByRank(key, start, end); client.zremrangeByRank(key, start, end);
return client.getIntegerReply(); return client.getIntegerReply();
@@ -2860,6 +2881,7 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
*/ */
public void monitor(final JedisMonitor jedisMonitor) { public void monitor(final JedisMonitor jedisMonitor) {
client.monitor(); client.monitor();
client.getStatusCodeReply();
jedisMonitor.proceed(client); jedisMonitor.proceed(client);
} }
@@ -3139,12 +3161,13 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
private byte[][] getParams(List<byte[]> keys, List<byte[]> args) { private byte[][] getParams(List<byte[]> keys, List<byte[]> args) {
int keyCount = keys.size(); int keyCount = keys.size();
int argCount = args.size();
byte[][] params = new byte[keyCount + args.size()][]; byte[][] params = new byte[keyCount + args.size()][];
for (int i = 0; i < keyCount; i++) for (int i = 0; i < keyCount; i++)
params[i] = keys.get(i); params[i] = keys.get(i);
for (int i = 0; i < keys.size(); i++) for (int i = 0; i < argCount; i++)
params[keyCount + i] = args.get(i); params[keyCount + i] = args.get(i);
return params; return params;
@@ -3158,7 +3181,8 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
public Object eval(byte[] script, int keyCount, byte[]... params) { public Object eval(byte[] script, int keyCount, byte[]... params) {
client.setTimeoutInfinite(); client.setTimeoutInfinite();
client.eval(script, SafeEncoder.encode(Integer.toString(keyCount)), params); client.eval(script, SafeEncoder.encode(Integer.toString(keyCount)),
params);
return client.getOne(); return client.getOne();
} }
@@ -3187,7 +3211,6 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
for (int i = 0; i < argCount; i++) for (int i = 0; i < argCount; i++)
params[keyCount + i] = args.get(i); params[keyCount + i] = args.get(i);
return evalsha(sha1, keyCount, params); return evalsha(sha1, keyCount, params);
} }
@@ -3273,7 +3296,8 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
return client.getBinaryBulkReply(); return client.getBinaryBulkReply();
} }
public String restore(final byte[] key, final int ttl, final byte[] serializedValue) { public String restore(final byte[] key, final int ttl,
final byte[] serializedValue) {
checkIsInMulti(); checkIsInMulti();
client.restore(key, ttl, serializedValue); client.restore(key, ttl, serializedValue);
return client.getStatusCodeReply(); return client.getStatusCodeReply();
@@ -3304,7 +3328,8 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
return (relpy != null ? new Double(relpy) : null); return (relpy != null ? new Double(relpy) : null);
} }
public String psetex(final byte[] key, final int milliseconds, final byte[] value) { public String psetex(final byte[] key, final int milliseconds,
final byte[] value) {
checkIsInMulti(); checkIsInMulti();
client.psetex(key, milliseconds, value); client.psetex(key, milliseconds, value);
return client.getStatusCodeReply(); return client.getStatusCodeReply();
@@ -3316,7 +3341,8 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
return client.getStatusCodeReply(); return client.getStatusCodeReply();
} }
public String set(final byte[] key, final byte[] value, final byte[] nxxx, final byte[] expx, final int time) { public String set(final byte[] key, final byte[] value, final byte[] nxxx,
final byte[] expx, final int time) {
checkIsInMulti(); checkIsInMulti();
client.set(key, value, nxxx, expx, time); client.set(key, value, nxxx, expx, time);
return client.getStatusCodeReply(); return client.getStatusCodeReply();
@@ -3352,17 +3378,32 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
return client.getMultiBulkReply(); return client.getMultiBulkReply();
} }
public String migrate(final byte[] host, final int port, final byte[] key, final int destinationDb, final int timeout) { public String migrate(final byte[] host, final int port, final byte[] key,
final int destinationDb, final int timeout) {
checkIsInMulti(); checkIsInMulti();
client.migrate(host, port, key, destinationDb, timeout); client.migrate(host, port, key, destinationDb, timeout);
return client.getStatusCodeReply(); return client.getStatusCodeReply();
} }
public Double hincrByFloat(final byte[] key, final byte[] field, double increment) { public Double hincrByFloat(final byte[] key, final byte[] field,
double increment) {
checkIsInMulti(); checkIsInMulti();
client.hincrByFloat(key, field, increment); client.hincrByFloat(key, field, increment);
String relpy = client.getBulkReply(); String relpy = client.getBulkReply();
return (relpy != null ? new Double(relpy) : null); return (relpy != null ? new Double(relpy) : null);
} }
/**
* Syncrhonous replication of Redis as described here:
* http://antirez.com/news/66
*
* Since Java Object class has implemented "wait" method, we cannot use it,
* so I had to change the name of the method. Sorry :S
*/
public Long waitReplicas(int replicas, long timeout) {
checkIsInMulti();
client.waitReplicas(replicas, timeout);
return client.getIntegerReply();
}
} }

View File

@@ -5,8 +5,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import redis.clients.jedis.BinaryClient.LIST_POSITION;
/** /**
* Common interface for sharded and non-sharded BinaryJedis * Common interface for sharded and non-sharded BinaryJedis
*/ */
@@ -117,7 +115,7 @@ public interface BinaryJedisCommands {
Long zadd(byte[] key, double score, byte[] member); Long zadd(byte[] key, double score, byte[] member);
Long zadd(byte[] key, Map<Double, byte[]> scoreMembers); Long zadd(byte[] key, Map<byte[], Double> scoreMembers);
Set<byte[]> zrange(byte[] key, long start, long end); Set<byte[]> zrange(byte[] key, long start, long end);

View File

@@ -117,8 +117,7 @@ public interface BinaryRedisPipeline {
Response<List<byte[]>> sort(byte[] key); Response<List<byte[]>> sort(byte[] key);
Response<List<byte[]>> sort(byte[] key, Response<List<byte[]>> sort(byte[] key, SortingParams sortingParameters);
SortingParams sortingParameters);
Response<byte[]> spop(byte[] key); Response<byte[]> spop(byte[] key);
@@ -144,17 +143,15 @@ public interface BinaryRedisPipeline {
Response<Set<byte[]>> zrange(byte[] key, long start, long end); Response<Set<byte[]>> zrange(byte[] key, long start, long end);
Response<Set<byte[]>> zrangeByScore(byte[] key, double min, Response<Set<byte[]>> zrangeByScore(byte[] key, double min, double max);
double max);
Response<Set<byte[]>> zrangeByScore(byte[] key, byte[] min, Response<Set<byte[]>> zrangeByScore(byte[] key, byte[] min, byte[] max);
byte[] max);
Response<Set<byte[]>> zrangeByScore(byte[] key, double min, Response<Set<byte[]>> zrangeByScore(byte[] key, double min, double max,
double max, int offset, int count); int offset, int count);
Response<Set<byte[]>> zrangeByScore(byte[] key, byte[] min, Response<Set<byte[]>> zrangeByScore(byte[] key, byte[] min, byte[] max,
byte[] max, int offset, int count); int offset, int count);
Response<Set<Tuple>> zrangeByScoreWithScores(byte[] key, double min, Response<Set<Tuple>> zrangeByScoreWithScores(byte[] key, double min,
double max); double max);
@@ -168,30 +165,28 @@ public interface BinaryRedisPipeline {
Response<Set<Tuple>> zrangeByScoreWithScores(byte[] key, byte[] min, Response<Set<Tuple>> zrangeByScoreWithScores(byte[] key, byte[] min,
byte[] max, int offset, int count); byte[] max, int offset, int count);
Response<Set<byte[]>> zrevrangeByScore(byte[] key, double max, Response<Set<byte[]>> zrevrangeByScore(byte[] key, double max, double min);
Response<Set<byte[]>> zrevrangeByScore(byte[] key, byte[] max, byte[] min);
Response<Set<byte[]>> zrevrangeByScore(byte[] key, double max, double min,
int offset, int count);
Response<Set<byte[]>> zrevrangeByScore(byte[] key, byte[] max, byte[] min,
int offset, int count);
Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key, double max,
double min); double min);
Response<Set<byte[]>> zrevrangeByScore(byte[] key, byte[] max, Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key, byte[] max,
byte[] min); byte[] min);
Response<Set<byte[]>> zrevrangeByScore(byte[] key, double max, Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key, double max,
double min, int offset, int count); double min, int offset, int count);
Response<Set<byte[]>> zrevrangeByScore(byte[] key, byte[] max, Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key, byte[] max,
byte[] min, int offset, int count); byte[] min, int offset, int count);
Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key,
double max, double min);
Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key,
byte[] max, byte[] min);
Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key,
double max, double min, int offset, int count);
Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key,
byte[] max, byte[] min, int offset, int count);
Response<Set<Tuple>> zrangeWithScores(byte[] key, long start, long end); Response<Set<Tuple>> zrangeWithScores(byte[] key, long start, long end);
Response<Long> zrank(byte[] key, byte[] member); Response<Long> zrank(byte[] key, byte[] member);
@@ -206,8 +201,7 @@ public interface BinaryRedisPipeline {
Response<Set<byte[]>> zrevrange(byte[] key, long start, long end); Response<Set<byte[]>> zrevrange(byte[] key, long start, long end);
Response<Set<Tuple>> zrevrangeWithScores(byte[] key, long start, Response<Set<Tuple>> zrevrangeWithScores(byte[] key, long start, long end);
long end);
Response<Long> zrevrank(byte[] key, byte[] member); Response<Long> zrevrank(byte[] key, byte[] member);

View File

@@ -1,6 +1,5 @@
package redis.clients.jedis; package redis.clients.jedis;
import java.util.List; import java.util.List;
public interface BinaryScriptingCommands { public interface BinaryScriptingCommands {

View File

@@ -1,16 +1,15 @@
package redis.clients.jedis; package redis.clients.jedis;
import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.util.Hashing;
import redis.clients.util.Sharded;
import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.util.Hashing;
import redis.clients.util.Sharded;
public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo> public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
implements BinaryJedisCommands { implements BinaryJedisCommands {
public BinaryShardedJedis(List<JedisShardInfo> shards) { public BinaryShardedJedis(List<JedisShardInfo> shards) {
@@ -296,7 +295,7 @@ public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
return j.zadd(key, score, member); return j.zadd(key, score, member);
} }
public Long zadd(byte[] key, Map<Double, byte[]> scoreMembers) { public Long zadd(byte[] key, Map<byte[], Double> scoreMembers) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.zadd(key, scoreMembers); return j.zadd(key, scoreMembers);
} }
@@ -409,7 +408,8 @@ public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
return j.zrangeByScoreWithScores(key, min, max, offset, count); return j.zrangeByScoreWithScores(key, min, max, offset, count);
} }
public Set<byte[]> zrangeByScore(byte[] key, byte[] min, byte[] max, int offset, int count) { public Set<byte[]> zrangeByScore(byte[] key, byte[] min, byte[] max,
int offset, int count) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.zrangeByScore(key, min, max, offset, count); return j.zrangeByScore(key, min, max, offset, count);
} }

View File

@@ -1,8 +1,5 @@
package redis.clients.jedis; package redis.clients.jedis;
public enum BitOP { public enum BitOP {
AND, AND, OR, XOR, NOT;
OR,
XOR,
NOT;
} }

View File

@@ -1,8 +1,15 @@
package redis.clients.jedis; package redis.clients.jedis;
import redis.clients.util.SafeEncoder; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*; import redis.clients.util.SafeEncoder;
public class BuilderFactory { public class BuilderFactory {
public static final Builder<Double> DOUBLE = new Builder<Double>() { public static final Builder<Double> DOUBLE = new Builder<Double>() {
@@ -84,8 +91,8 @@ public class BuilderFactory {
final Map<String, String> hash = new HashMap<String, String>(); final Map<String, String> hash = new HashMap<String, String>();
final Iterator<byte[]> iterator = flatHash.iterator(); final Iterator<byte[]> iterator = flatHash.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
hash.put(SafeEncoder.encode(iterator.next()), SafeEncoder hash.put(SafeEncoder.encode(iterator.next()),
.encode(iterator.next())); SafeEncoder.encode(iterator.next()));
} }
return hash; return hash;
@@ -96,6 +103,7 @@ public class BuilderFactory {
} }
}; };
public static final Builder<Set<String>> STRING_SET = new Builder<Set<String>>() { public static final Builder<Set<String>> STRING_SET = new Builder<Set<String>>() {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Set<String> build(Object data) { public Set<String> build(Object data) {

View File

@@ -1,6 +1,6 @@
package redis.clients.jedis; package redis.clients.jedis;
import redis.clients.util.SafeEncoder; import static redis.clients.jedis.Protocol.toByteArray;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@@ -8,7 +8,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import static redis.clients.jedis.Protocol.toByteArray; import redis.clients.util.SafeEncoder;
public class Client extends BinaryClient implements Commands { public class Client extends BinaryClient implements Commands {
public Client(final String host) { public Client(final String host) {
@@ -23,8 +23,10 @@ public class Client extends BinaryClient implements Commands {
set(SafeEncoder.encode(key), SafeEncoder.encode(value)); set(SafeEncoder.encode(key), SafeEncoder.encode(value));
} }
public void set(final String key, final String value, final String nxxx, final String expx, final long time) { public void set(final String key, final String value, final String nxxx,
set(SafeEncoder.encode(key), SafeEncoder.encode(value), SafeEncoder.encode(nxxx), SafeEncoder.encode(expx), time); final String expx, final long time) {
set(SafeEncoder.encode(key), SafeEncoder.encode(value),
SafeEncoder.encode(nxxx), SafeEncoder.encode(expx), time);
} }
public void get(final String key) { public void get(final String key) {
@@ -671,6 +673,18 @@ public class Client extends BinaryClient implements Commands {
subscribe(cs); subscribe(cs);
} }
public void pubsubChannels(String pattern) {
pubsub(Protocol.PUBSUB_CHANNELS, pattern);
}
public void pubsubNumPat() {
pubsub(Protocol.PUBSUB_NUM_PAT);
}
public void pubsubNumSub(String... channels) {
pubsub(Protocol.PUBSUB_NUMSUB, channels);
}
public void configSet(String parameter, String value) { public void configSet(String parameter, String value) {
configSet(SafeEncoder.encode(parameter), SafeEncoder.encode(value)); configSet(SafeEncoder.encode(parameter), SafeEncoder.encode(value));
} }
@@ -709,12 +723,14 @@ public class Client extends BinaryClient implements Commands {
scriptLoad(SafeEncoder.encode(script)); scriptLoad(SafeEncoder.encode(script));
} }
public void zadd(String key, Map<Double, String> scoreMembers) { public void zadd(String key, Map<String, Double> scoreMembers) {
HashMap<Double, byte[]> binaryScoreMembers = new HashMap<Double, byte[]>();
for (Map.Entry<Double, String> entry : scoreMembers.entrySet()) { HashMap<byte[], Double> binaryScoreMembers = new HashMap<byte[], Double>();
binaryScoreMembers.put(entry.getKey(),
SafeEncoder.encode(entry.getValue())); for (Map.Entry<String, Double> entry : scoreMembers.entrySet()) {
binaryScoreMembers.put(SafeEncoder.encode(entry.getKey()),
entry.getValue());
} }
zaddBinary(SafeEncoder.encode(key), binaryScoreMembers); zaddBinary(SafeEncoder.encode(key), binaryScoreMembers);
@@ -752,16 +768,12 @@ public class Client extends BinaryClient implements Commands {
sentinel(arg); sentinel(arg);
} }
public void sentinel(final String cmd, String arg1, int arg2) {
sentinel(SafeEncoder.encode(cmd), SafeEncoder.encode(arg1),
toByteArray(arg2));
}
public void dump(final String key) { public void dump(final String key) {
dump(SafeEncoder.encode(key)); dump(SafeEncoder.encode(key));
} }
public void restore(final String key, final int ttl, final byte[] serializedValue) { public void restore(final String key, final int ttl,
final byte[] serializedValue) {
restore(SafeEncoder.encode(key), ttl, serializedValue); restore(SafeEncoder.encode(key), ttl, serializedValue);
} }
@@ -781,16 +793,20 @@ public class Client extends BinaryClient implements Commands {
incrByFloat(SafeEncoder.encode(key), increment); incrByFloat(SafeEncoder.encode(key), increment);
} }
public void psetex(final String key, final int milliseconds, final String value) { public void psetex(final String key, final int milliseconds,
final String value) {
psetex(SafeEncoder.encode(key), milliseconds, SafeEncoder.encode(value)); psetex(SafeEncoder.encode(key), milliseconds, SafeEncoder.encode(value));
} }
public void set(final String key, final String value, final String nxxx) { public void set(final String key, final String value, final String nxxx) {
set(SafeEncoder.encode(key), SafeEncoder.encode(value), SafeEncoder.encode(nxxx)); set(SafeEncoder.encode(key), SafeEncoder.encode(value),
SafeEncoder.encode(nxxx));
} }
public void set(final String key, final String value, final String nxxx, final String expx, final int time) { public void set(final String key, final String value, final String nxxx,
set(SafeEncoder.encode(key), SafeEncoder.encode(value), SafeEncoder.encode(nxxx), SafeEncoder.encode(expx), time); final String expx, final int time) {
set(SafeEncoder.encode(key), SafeEncoder.encode(value),
SafeEncoder.encode(nxxx), SafeEncoder.encode(expx), time);
} }
public void srandmember(final String key, final int count) { public void srandmember(final String key, final int count) {
@@ -805,11 +821,100 @@ public class Client extends BinaryClient implements Commands {
clientSetname(SafeEncoder.encode(name)); clientSetname(SafeEncoder.encode(name));
} }
public void migrate(final String host, final int port, final String key, final int destinationDb, final int timeout) { public void migrate(final String host, final int port, final String key,
migrate(SafeEncoder.encode(host), port, SafeEncoder.encode(key), destinationDb, timeout); final int destinationDb, final int timeout) {
migrate(SafeEncoder.encode(host), port, SafeEncoder.encode(key),
destinationDb, timeout);
} }
public void hincrByFloat(final String key, final String field, double increment) { public void hincrByFloat(final String key, final String field,
hincrByFloat(SafeEncoder.encode(key), SafeEncoder.encode(field), increment); double increment) {
hincrByFloat(SafeEncoder.encode(key), SafeEncoder.encode(field),
increment);
}
public void hscan(final String key, int cursor, final ScanParams params) {
hscan(SafeEncoder.encode(key), cursor, params);
}
public void sscan(final String key, int cursor, final ScanParams params) {
sscan(SafeEncoder.encode(key), cursor, params);
}
public void zscan(final String key, int cursor, final ScanParams params) {
zscan(SafeEncoder.encode(key), cursor, params);
}
public void cluster(final String subcommand, final int... args) {
final byte[][] arg = new byte[args.length + 1][];
for (int i = 1; i < arg.length; i++) {
arg[i] = toByteArray(args[i - 1]);
}
arg[0] = SafeEncoder.encode(subcommand);
cluster(arg);
}
public void pubsub(final String subcommand, final String... args) {
final byte[][] arg = new byte[args.length+1][];
for (int i = 1; i < arg.length; i++) {
arg[i] = SafeEncoder.encode(args[i-1]);
}
arg[0] = SafeEncoder.encode(subcommand);
pubsub(arg);
}
public void cluster(final String subcommand, final String... args) {
final byte[][] arg = new byte[args.length + 1][];
for (int i = 1; i < arg.length; i++) {
arg[i] = SafeEncoder.encode(args[i - 1]);
}
arg[0] = SafeEncoder.encode(subcommand);
cluster(arg);
}
public void cluster(final String subcommand) {
final byte[][] arg = new byte[1][];
arg[0] = SafeEncoder.encode(subcommand);
cluster(arg);
}
public void clusterNodes() {
cluster(Protocol.CLUSTER_NODES);
}
public void clusterMeet(final String ip, final int port) {
cluster(Protocol.CLUSTER_MEET, ip, String.valueOf(port));
}
public void clusterAddSlots(final int... slots) {
cluster(Protocol.CLUSTER_ADDSLOTS, slots);
}
public void clusterDelSlots(final int... slots) {
cluster(Protocol.CLUSTER_DELSLOTS, slots);
}
public void clusterInfo() {
cluster(Protocol.CLUSTER_INFO);
}
public void clusterGetKeysInSlot(final int slot, final int count) {
final int[] args = new int[] { slot, count };
cluster(Protocol.CLUSTER_GETKEYSINSLOT, args);
}
public void clusterSetSlotNode(final int slot, final String nodeId) {
cluster(Protocol.CLUSTER_SETSLOT, String.valueOf(slot),
Protocol.CLUSTER_SETSLOT_NODE, nodeId);
}
public void clusterSetSlotMigrating(final int slot, final String nodeId) {
cluster(Protocol.CLUSTER_SETSLOT, String.valueOf(slot),
Protocol.CLUSTER_SETSLOT_MIGRATING, nodeId);
}
public void clusterSetSlotImporting(final int slot, final String nodeId) {
cluster(Protocol.CLUSTER_SETSLOT, String.valueOf(slot),
Protocol.CLUSTER_SETSLOT_IMPORTING, nodeId);
} }
} }

View File

@@ -0,0 +1,23 @@
package redis.clients.jedis;
import java.util.List;
public interface ClusterCommands {
String clusterNodes();
String clusterMeet(final String ip, final int port);
String clusterAddSlots(final int... slots);
String clusterDelSlots(final int... slots);
String clusterInfo();
List<String> clusterGetKeysInSlot(final int slot, final int count);
String clusterSetSlotNode(final int slot, final String nodeId);
String clusterSetSlotMigrating(final int slot, final String nodeId);
String clusterSetSlotImporting(final int slot, final String nodeId);
}

View File

@@ -0,0 +1,23 @@
package redis.clients.jedis;
import java.util.List;
public interface ClusterPipeline {
Response<String> clusterNodes();
Response<String> clusterMeet(final String ip, final int port);
Response<String> clusterAddSlots(final int... slots);
Response<String> clusterDelSlots(final int... slots);
Response<String> clusterInfo();
Response<List<String>> clusterGetKeysInSlot(final int slot, final int count);
Response<String> clusterSetSlotNode(final int slot, final String nodeId);
Response<String> clusterSetSlotMigrating(final int slot, final String nodeId);
Response<String> clusterSetSlotImporting(final int slot, final String nodeId);
}

View File

@@ -1,14 +1,15 @@
package redis.clients.jedis; package redis.clients.jedis;
import redis.clients.jedis.BinaryClient.LIST_POSITION;
import java.util.Map; import java.util.Map;
import redis.clients.jedis.BinaryClient.LIST_POSITION;
public interface Commands { public interface Commands {
public void set(final String key, final String value); public void set(final String key, final String value);
public void set(final String key, final String value, final String nxxx, final String expx, final long time); public void set(final String key, final String value, final String nxxx,
final String expx, final long time);
public void get(final String key); public void get(final String key);
@@ -143,7 +144,7 @@ public interface Commands {
public void zadd(final String key, final double score, final String member); public void zadd(final String key, final double score, final String member);
public void zadd(final String key, final Map<Double, String> scoreMembers); public void zadd(final String key, final Map<String, Double> scoreMembers);
public void zrange(final String key, final long start, final long end); public void zrange(final String key, final long start, final long end);
@@ -295,4 +296,14 @@ public interface Commands {
public void bitcount(final String key, long start, long end); public void bitcount(final String key, long start, long end);
public void bitop(BitOP op, final String destKey, String... srcKeys); public void bitop(BitOP op, final String destKey, String... srcKeys);
public void scan(int cursor, final ScanParams params);
public void hscan(final String key, int cursor, final ScanParams params);
public void sscan(final String key, int cursor, final ScanParams params);
public void zscan(final String key, int cursor, final ScanParams params);
public void waitReplicas(int replicas, long timeout);
} }

View File

@@ -124,9 +124,13 @@ public class Connection {
socket = new Socket(); socket = new Socket();
// ->@wjw_add // ->@wjw_add
socket.setReuseAddress(true); socket.setReuseAddress(true);
socket.setKeepAlive(true); //Will monitor the TCP connection is valid socket.setKeepAlive(true); // Will monitor the TCP connection is
socket.setTcpNoDelay(true); //Socket buffer Whetherclosed, to ensure timely delivery of data // valid
socket.setSoLinger(true,0); //Control calls close () method, the underlying socket is closed immediately socket.setTcpNoDelay(true); // Socket buffer Whetherclosed, to
// ensure timely delivery of data
socket.setSoLinger(true, 0); // Control calls close () method,
// the underlying socket is closed
// immediately
// <-@wjw_add // <-@wjw_add
socket.connect(new InetSocketAddress(host, port), timeout); socket.connect(new InetSocketAddress(host, port), timeout);
@@ -202,11 +206,19 @@ public class Connection {
return (List<byte[]>) Protocol.read(inputStream); return (List<byte[]>) Protocol.read(inputStream);
} }
public void resetPipelinedCount() {
pipelinedCommands = 0;
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<Object> getRawObjectMultiBulkReply() {
return (List<Object>) Protocol.read(inputStream);
}
public List<Object> getObjectMultiBulkReply() { public List<Object> getObjectMultiBulkReply() {
flush(); flush();
pipelinedCommands--; pipelinedCommands--;
return (List<Object>) Protocol.read(inputStream); return getRawObjectMultiBulkReply();
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View File

@@ -0,0 +1,49 @@
package redis.clients.jedis;
public class HostAndPort {
public static final String LOCALHOST_STR = "localhost";
private String host;
private int port;
public HostAndPort(String host, int port) {
this.host = host;
this.port = port;
}
public String getHost() {
return host;
}
public int getPort() {
return port;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof HostAndPort) {
HostAndPort hp = (HostAndPort) obj;
String thisHost = convertHost(host);
String hpHost = convertHost(hp.host);
return port == hp.port && thisHost.equals(hpHost);
}
return false;
}
@Override
public String toString() {
return host + ":" + port;
}
private String convertHost(String host) {
if (host.equals("127.0.0.1"))
return LOCALHOST_STR;
else if (host.equals("::1"))
return LOCALHOST_STR;
return host;
}
}

View File

@@ -1,13 +1,22 @@
package redis.clients.jedis; package redis.clients.jedis;
import java.net.URI;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import redis.clients.jedis.BinaryClient.LIST_POSITION; import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.util.SafeEncoder; import redis.clients.util.SafeEncoder;
import redis.clients.util.Slowlog; import redis.clients.util.Slowlog;
import java.net.URI; public class Jedis extends BinaryJedis implements JedisCommands,
import java.util.*; MultiKeyCommands, AdvancedJedisCommands, ScriptingCommands,
BasicCommands, ClusterCommands {
public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommands, AdvancedJedisCommands, ScriptingCommands {
public Jedis(final String host) { public Jedis(final String host) {
super(host); super(host);
} }
@@ -47,24 +56,29 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
/** /**
* Set the string value as value of the key. The string can't be longer than * Set the string value as value of the key. The string can't be longer than
* 1073741824 bytes (1 GB). * 1073741824 bytes (1 GB).
*
* @param key * @param key
* @param value * @param value
* @param nxxx NX|XX, NX -- Only set the key if it does not already exist. * @param nxxx
* XX -- Only set the key if it already exist. * NX|XX, NX -- Only set the key if it does not already exist. XX
* @param expx EX|PX, expire time units: EX = seconds; PX = milliseconds * -- Only set the key if it already exist.
* @param time expire time in the units of {@param #expx} * @param expx
* EX|PX, expire time units: EX = seconds; PX = milliseconds
* @param time
* expire time in the units of {@param #expx}
* @return Status code reply * @return Status code reply
*/ */
public String set(final String key, final String value, final String nxxx, final String expx, final long time) { public String set(final String key, final String value, final String nxxx,
final String expx, final long time) {
checkIsInMulti(); checkIsInMulti();
client.set(key, value, nxxx, expx, time); client.set(key, value, nxxx, expx, time);
return client.getStatusCodeReply(); return client.getStatusCodeReply();
} }
/** /**
* Get the value of the specified key. If the key does not exist the special * Get the value of the specified key. If the key does not exist null is
* value 'nil' is returned. If the value stored at key is not a string an * returned. If the value stored at key is not a string an error is returned
* error is returned because GET can only handle string values. * because GET can only handle string values.
* <p> * <p>
* Time complexity: O(1) * Time complexity: O(1)
* *
@@ -1406,7 +1420,7 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
return client.getIntegerReply(); return client.getIntegerReply();
} }
public Long zadd(final String key, final Map<Double, String> scoreMembers) { public Long zadd(final String key, final Map<String, Double> scoreMembers) {
checkIsInMulti(); checkIsInMulti();
client.zadd(key, scoreMembers); client.zadd(key, scoreMembers);
return client.getIntegerReply(); return client.getIntegerReply();
@@ -1945,8 +1959,6 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
return multiBulkReply; return multiBulkReply;
} }
public Long zcount(final String key, final double min, final double max) { public Long zcount(final String key, final double min, final double max) {
checkIsInMulti(); checkIsInMulti();
client.zcount(key, min, max); client.zcount(key, min, max);
@@ -2011,8 +2023,10 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
* @see #zcount(String, double, double) * @see #zcount(String, double, double)
* *
* @param key * @param key
* @param min a double or Double.MIN_VALUE for "-inf" * @param min
* @param max a double or Double.MAX_VALUE for "+inf" * a double or Double.MIN_VALUE for "-inf"
* @param max
* a double or Double.MAX_VALUE for "+inf"
* @return Multi bulk reply specifically a list of elements in the specified * @return Multi bulk reply specifically a list of elements in the specified
* score range. * score range.
*/ */
@@ -2998,34 +3012,14 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
return slaves; return slaves;
} }
/**
* <pre>
* redis 127.0.0.1:26381> SENTINEL is-master-down-by-addr 127.0.0.1 1
* 1) (integer) 0
* 2) "?"
* redis 127.0.0.1:26381> SENTINEL is-master-down-by-addr 127.0.0.1 6379
* 1) (integer) 0
* 2) "aaef11fbb2712346a386078c7f9834e72ed51e96"
* </pre>
*
* @return Long followed by the String (runid)
*/
@SuppressWarnings("unchecked")
public List<? extends Object> sentinelIsMasterDownByAddr(String host,
int port) {
client.sentinel(Protocol.SENTINEL_IS_MASTER_DOWN_BY_ADDR, host, port);
final List<Object> reply = client.getObjectMultiBulkReply();
return Arrays.asList(BuilderFactory.LONG.build(reply.get(0)),
BuilderFactory.STRING.build(reply.get(1)));
}
public byte[] dump(final String key) { public byte[] dump(final String key) {
checkIsInMulti(); checkIsInMulti();
client.dump(key); client.dump(key);
return client.getBinaryBulkReply(); return client.getBinaryBulkReply();
} }
public String restore(final String key, final int ttl, final byte[] serializedValue) { public String restore(final String key, final int ttl,
final byte[] serializedValue) {
checkIsInMulti(); checkIsInMulti();
client.restore(key, ttl, serializedValue); client.restore(key, ttl, serializedValue);
return client.getStatusCodeReply(); return client.getStatusCodeReply();
@@ -3056,7 +3050,8 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
return (relpy != null ? new Double(relpy) : null); return (relpy != null ? new Double(relpy) : null);
} }
public String psetex(final String key, final int milliseconds, final String value) { public String psetex(final String key, final int milliseconds,
final String value) {
checkIsInMulti(); checkIsInMulti();
client.psetex(key, milliseconds, value); client.psetex(key, milliseconds, value);
return client.getStatusCodeReply(); return client.getStatusCodeReply();
@@ -3068,7 +3063,8 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
return client.getStatusCodeReply(); return client.getStatusCodeReply();
} }
public String set(final String key, final String value, final String nxxx, final String expx, final int time) { public String set(final String key, final String value, final String nxxx,
final String expx, final int time) {
checkIsInMulti(); checkIsInMulti();
client.set(key, value, nxxx, expx, time); client.set(key, value, nxxx, expx, time);
return client.getStatusCodeReply(); return client.getStatusCodeReply();
@@ -3086,16 +3082,174 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
return client.getStatusCodeReply(); return client.getStatusCodeReply();
} }
public String migrate(final String host, final int port, final String key, final int destinationDb, final int timeout) { public String migrate(final String host, final int port, final String key,
final int destinationDb, final int timeout) {
checkIsInMulti(); checkIsInMulti();
client.migrate(host, port, key, destinationDb, timeout); client.migrate(host, port, key, destinationDb, timeout);
return client.getStatusCodeReply(); return client.getStatusCodeReply();
} }
public Double hincrByFloat(final String key, final String field, double increment) { public Double hincrByFloat(final String key, final String field,
double increment) {
checkIsInMulti(); checkIsInMulti();
client.hincrByFloat(key, field, increment); client.hincrByFloat(key, field, increment);
String relpy = client.getBulkReply(); String relpy = client.getBulkReply();
return (relpy != null ? new Double(relpy) : null); return (relpy != null ? new Double(relpy) : null);
} }
public ScanResult<String> scan(int cursor) {
return scan(cursor, new ScanParams());
}
public ScanResult<String> scan(int cursor, final ScanParams params) {
checkIsInMulti();
client.scan(cursor, params);
List<Object> result = client.getObjectMultiBulkReply();
int newcursor = Integer.parseInt(new String((byte[]) result.get(0)));
List<String> results = new ArrayList<String>();
List<byte[]> rawResults = (List<byte[]>) result.get(1);
for (byte[] bs : rawResults) {
results.add(SafeEncoder.encode(bs));
}
return new ScanResult<String>(newcursor, results);
}
public ScanResult<Map.Entry<String, String>> hscan(final String key,
int cursor) {
return hscan(key, cursor, new ScanParams());
}
public ScanResult<Map.Entry<String, String>> hscan(final String key,
int cursor, final ScanParams params) {
checkIsInMulti();
client.hscan(key, cursor, params);
List<Object> result = client.getObjectMultiBulkReply();
int newcursor = Integer.parseInt(new String((byte[]) result.get(0)));
List<Map.Entry<String, String>> results = new ArrayList<Map.Entry<String, String>>();
List<byte[]> rawResults = (List<byte[]>) result.get(1);
Iterator<byte[]> iterator = rawResults.iterator();
while (iterator.hasNext()) {
results.add(new AbstractMap.SimpleEntry<String, String>(SafeEncoder
.encode(iterator.next()), SafeEncoder.encode(iterator
.next())));
}
return new ScanResult<Map.Entry<String, String>>(newcursor, results);
}
public ScanResult<String> sscan(final String key, int cursor) {
return sscan(key, cursor, new ScanParams());
}
public ScanResult<String> sscan(final String key, int cursor,
final ScanParams params) {
checkIsInMulti();
client.sscan(key, cursor, params);
List<Object> result = client.getObjectMultiBulkReply();
int newcursor = Integer.parseInt(new String((byte[]) result.get(0)));
List<String> results = new ArrayList<String>();
List<byte[]> rawResults = (List<byte[]>) result.get(1);
for (byte[] bs : rawResults) {
results.add(SafeEncoder.encode(bs));
}
return new ScanResult<String>(newcursor, results);
}
public ScanResult<Tuple> zscan(final String key, int cursor) {
return zscan(key, cursor, new ScanParams());
}
public ScanResult<Tuple> zscan(final String key, int cursor,
final ScanParams params) {
checkIsInMulti();
client.zscan(key, cursor, params);
List<Object> result = client.getObjectMultiBulkReply();
int newcursor = Integer.parseInt(new String((byte[]) result.get(0)));
List<Tuple> results = new ArrayList<Tuple>();
List<byte[]> rawResults = (List<byte[]>) result.get(1);
Iterator<byte[]> iterator = rawResults.iterator();
while (iterator.hasNext()) {
results.add(new Tuple(SafeEncoder.encode(iterator.next()), Double
.valueOf(SafeEncoder.encode(iterator.next()))));
}
return new ScanResult<Tuple>(newcursor, results);
}
public String clusterNodes() {
checkIsInMulti();
client.clusterNodes();
return client.getBulkReply();
}
public String clusterMeet(final String ip, final int port) {
checkIsInMulti();
client.clusterMeet(ip, port);
return client.getStatusCodeReply();
}
public String clusterAddSlots(final int... slots) {
checkIsInMulti();
client.clusterAddSlots(slots);
return client.getStatusCodeReply();
}
public String clusterDelSlots(final int... slots) {
checkIsInMulti();
client.clusterDelSlots(slots);
return client.getStatusCodeReply();
}
public String clusterInfo() {
checkIsInMulti();
client.clusterInfo();
return client.getStatusCodeReply();
}
public List<String> clusterGetKeysInSlot(final int slot, final int count) {
checkIsInMulti();
client.clusterGetKeysInSlot(slot, count);
return client.getMultiBulkReply();
}
public String clusterSetSlotNode(final int slot, final String nodeId) {
checkIsInMulti();
client.clusterSetSlotNode(slot, nodeId);
return client.getStatusCodeReply();
}
public String clusterSetSlotMigrating(final int slot, final String nodeId) {
checkIsInMulti();
client.clusterSetSlotMigrating(slot, nodeId);
return client.getStatusCodeReply();
}
public String clusterSetSlotImporting(final int slot, final String nodeId) {
checkIsInMulti();
client.clusterSetSlotImporting(slot, nodeId);
return client.getStatusCodeReply();
}
public String asking() {
checkIsInMulti();
client.asking();
return client.getStatusCodeReply();
}
public List<String> pubsubChannels(String pattern) {
checkIsInMulti();
client.pubsubChannels(pattern);
return client.getMultiBulkReply();
}
public Long pubsubNumPat() {
checkIsInMulti();
client.pubsubNumPat();
return client.getIntegerReply();
}
public Map<String, String> pubsubNumSub(String... channels) {
checkIsInMulti();
client.pubsubNumSub(channels);
return BuilderFactory.STRING_MAP
.build(client.getBinaryMultiBulkReply());
}
} }

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,60 @@
package redis.clients.jedis;
import redis.clients.jedis.exceptions.JedisAskDataException;
import redis.clients.jedis.exceptions.JedisClusterException;
import redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException;
import redis.clients.jedis.exceptions.JedisRedirectionException;
import redis.clients.util.JedisClusterCRC16;
public abstract class JedisClusterCommand<T> {
private boolean asking = false;
private JedisClusterConnectionHandler connectionHandler;
private int commandTimeout;
private int redirections;
// private boolean asking = false;
public JedisClusterCommand(JedisClusterConnectionHandler connectionHandler,
int timeout, int maxRedirections) {
this.connectionHandler = connectionHandler;
this.commandTimeout = timeout;
this.redirections = maxRedirections;
}
public abstract T execute();
public T run(String key) {
try {
if (key == null) {
throw new JedisClusterException(
"No way to dispatch this command to Redis Cluster.");
} else if (redirections == 0) {
throw new JedisClusterMaxRedirectionsException(
"Too many Cluster redirections?");
}
connectionHandler.getConnectionFromSlot(JedisClusterCRC16
.getSlot(key));
if (asking) {
// TODO: Pipeline asking with the original command to make it
// faster....
connectionHandler.getConnection().asking();
}
return execute();
} catch (JedisRedirectionException jre) {
return handleRedirection(jre, key);
}
}
private T handleRedirection(JedisRedirectionException jre, String key) {
if (jre instanceof JedisAskDataException) {
asking = true;
}
redirections--;
this.connectionHandler.assignSlotToNode(jre.getSlot(),
jre.getTargetNode());
return run(key);
}
}

View File

@@ -0,0 +1,92 @@
package redis.clients.jedis;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Set;
public abstract class JedisClusterConnectionHandler {
protected Map<String, JedisPool> nodes = new HashMap<String, JedisPool>();
protected Map<Integer, JedisPool> slots = new HashMap<Integer, JedisPool>();
abstract Jedis getConnection();
abstract Jedis getConnectionFromSlot(int slot);
public JedisClusterConnectionHandler(Set<HostAndPort> nodes) {
initializeSlotsCache(nodes);
}
public Map<String, JedisPool> getNodes() {
return nodes;
}
private void initializeSlotsCache(Set<HostAndPort> nodes) {
for (HostAndPort hostAndPort : nodes) {
JedisPool jp = new JedisPool(hostAndPort.getHost(),
hostAndPort.getPort());
this.nodes.put(hostAndPort.getHost() + hostAndPort.getPort(), jp);
Jedis jedis = jp.getResource();
try {
discoverClusterNodesAndSlots(jedis);
} finally {
jp.returnResource(jedis);
}
}
}
private void discoverClusterNodesAndSlots(Jedis jedis) {
String localNodes = jedis.clusterNodes();
for (String nodeInfo : localNodes.split("\n")) {
HostAndPort node = getHostAndPortFromNodeLine(nodeInfo, jedis);
JedisPool nodePool = new JedisPool(node.getHost(), node.getPort());
this.nodes.put(node.getHost() + node.getPort(), nodePool);
populateNodeSlots(nodeInfo, nodePool);
}
}
private void populateNodeSlots(String nodeInfo, JedisPool nodePool) {
String[] nodeInfoArray = nodeInfo.split(" ");
if (nodeInfoArray.length > 7) {
for (int i = 8; i < nodeInfoArray.length; i++) {
processSlot(nodeInfoArray[i], nodePool);
}
}
}
private void processSlot(String slot, JedisPool nodePool) {
if (slot.contains("-")) {
String[] slotRange = slot.split("-");
for (int i = Integer.valueOf(slotRange[0]); i <= Integer
.valueOf(slotRange[1]); i++) {
slots.put(i, nodePool);
}
} else {
slots.put(Integer.valueOf(slot), nodePool);
}
}
private HostAndPort getHostAndPortFromNodeLine(String nodeInfo, Jedis currentConnection) {
String stringHostAndPort = nodeInfo.split(" ", 3)[1];
if (":0".equals(stringHostAndPort)) {
return new HostAndPort(currentConnection.getClient().getHost(),
currentConnection.getClient().getPort());
}
String[] arrayHostAndPort = stringHostAndPort.split(":");
return new HostAndPort(arrayHostAndPort[0],
Integer.valueOf(arrayHostAndPort[1]));
}
public void assignSlotToNode(int slot, HostAndPort targetNode) {
JedisPool targetPool = nodes.get(targetNode.getHost()
+ targetNode.getPort());
slots.put(slot, targetPool);
}
protected JedisPool getRandomConnection() {
Object[] nodeArray = nodes.values().toArray();
return (JedisPool) (nodeArray[new Random().nextInt(nodeArray.length)]);
}
}

View File

@@ -7,8 +7,7 @@ import java.util.Set;
/** /**
* Common interface for sharded and non-sharded Jedis * Common interface for sharded and non-sharded Jedis
*/ */
public interface public interface JedisCommands {
JedisCommands {
String set(String key, String value); String set(String key, String value);
String get(String key); String get(String key);
@@ -115,7 +114,7 @@ public interface
Long zadd(String key, double score, String member); Long zadd(String key, double score, String member);
Long zadd(String key, Map<Double, String> scoreMembers); Long zadd(String key, Map<String, Double> scoreMembers);
Set<String> zrange(String key, long start, long end); Set<String> zrange(String key, long start, long end);
@@ -211,4 +210,10 @@ public interface
Long bitcount(final String key); Long bitcount(final String key);
Long bitcount(final String key, long start, long end); Long bitcount(final String key, long start, long end);
ScanResult<Map.Entry<String, String>> hscan(final String key, int cursor);
ScanResult<String> sscan(final String key, int cursor);
ScanResult<Tuple> zscan(final String key, int cursor);
} }

View File

@@ -1,11 +1,13 @@
package redis.clients.jedis; package redis.clients.jedis;
import org.apache.commons.pool.BasePoolableObjectFactory; import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
/** /**
* PoolableObjectFactory custom impl. * PoolableObjectFactory custom impl.
*/ */
class JedisFactory extends BasePoolableObjectFactory { class JedisFactory implements PooledObjectFactory<Jedis> {
private final String host; private final String host;
private final int port; private final int port;
private final int timeout; private final int timeout;
@@ -13,12 +15,13 @@ class JedisFactory extends BasePoolableObjectFactory {
private final int database; private final int database;
private final String clientName; private final String clientName;
public JedisFactory(final String host, final int port, public JedisFactory(final String host, final int port, final int timeout,
final int timeout, final String password, final int database) { final String password, final int database) {
this(host, port, timeout, password, database, null); this(host, port, timeout, password, database, null);
} }
public JedisFactory(final String host, final int port,
final int timeout, final String password, final int database, final String clientName) { public JedisFactory(final String host, final int port, final int timeout,
final String password, final int database, final String clientName) {
super(); super();
this.host = host; this.host = host;
this.port = port; this.port = port;
@@ -28,7 +31,35 @@ class JedisFactory extends BasePoolableObjectFactory {
this.clientName = clientName; this.clientName = clientName;
} }
public Object makeObject() throws Exception { @Override
public void activateObject(PooledObject<Jedis> pooledJedis)
throws Exception {
final BinaryJedis jedis = pooledJedis.getObject();
if (jedis.getDB() != database) {
jedis.select(database);
}
}
@Override
public void destroyObject(PooledObject<Jedis> pooledJedis) throws Exception {
final BinaryJedis jedis = pooledJedis.getObject();
if (jedis.isConnected()) {
try {
try {
jedis.quit();
} catch (Exception e) {
}
jedis.disconnect();
} catch (Exception e) {
}
}
}
@Override
public PooledObject<Jedis> makeObject() throws Exception {
final Jedis jedis = new Jedis(this.host, this.port, this.timeout); final Jedis jedis = new Jedis(this.host, this.port, this.timeout);
jedis.connect(); jedis.connect();
@@ -42,46 +73,22 @@ class JedisFactory extends BasePoolableObjectFactory {
jedis.clientSetname(clientName); jedis.clientSetname(clientName);
} }
return jedis; return new DefaultPooledObject<Jedis>(jedis);
} }
@Override @Override
public void activateObject(Object obj) throws Exception { public void passivateObject(PooledObject<Jedis> pooledJedis)
if (obj instanceof Jedis) { throws Exception {
final Jedis jedis = (Jedis)obj; // TODO maybe should select db 0? Not sure right now.
if (jedis.getDB() != database) {
jedis.select(database);
}
}
} }
public void destroyObject(final Object obj) throws Exception { @Override
if (obj instanceof Jedis) { public boolean validateObject(PooledObject<Jedis> pooledJedis) {
final Jedis jedis = (Jedis) obj; final BinaryJedis jedis = pooledJedis.getObject();
if (jedis.isConnected()) {
try {
try {
jedis.quit();
} catch (Exception e) {
}
jedis.disconnect();
} catch (Exception e) {
}
}
}
}
public boolean validateObject(final Object obj) {
if (obj instanceof Jedis) {
final Jedis jedis = (Jedis) obj;
try { try {
return jedis.isConnected() && jedis.ping().equals("PONG"); return jedis.isConnected() && jedis.ping().equals("PONG");
} catch (final Exception e) { } catch (final Exception e) {
return false; return false;
} }
} else {
return false;
}
} }
} }

View File

@@ -2,19 +2,21 @@ package redis.clients.jedis;
import java.net.URI; import java.net.URI;
import org.apache.commons.pool.impl.GenericObjectPool; import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool.Config; import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.util.Pool; import redis.clients.util.Pool;
public class JedisPool extends Pool<Jedis> { public class JedisPool extends Pool<Jedis> {
public JedisPool(final Config poolConfig, final String host) { public JedisPool(final GenericObjectPoolConfig poolConfig, final String host) {
this(poolConfig, host, Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE, null); this(poolConfig, host, Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT,
null, Protocol.DEFAULT_DATABASE, null);
} }
public JedisPool(String host, int port) { public JedisPool(String host, int port) {
this(new Config(), host, port, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE, null); this(new GenericObjectPoolConfig(), host, port,
Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE, null);
} }
public JedisPool(final String host) { public JedisPool(final String host) {
@@ -24,12 +26,15 @@ public class JedisPool extends Pool<Jedis> {
int port = uri.getPort(); int port = uri.getPort();
String password = uri.getUserInfo().split(":", 2)[1]; String password = uri.getUserInfo().split(":", 2)[1];
int database = Integer.parseInt(uri.getPath().split("/", 2)[1]); int database = Integer.parseInt(uri.getPath().split("/", 2)[1]);
this.internalPool = new GenericObjectPool(new JedisFactory(h, port, this.internalPool = new GenericObjectPool<Jedis>(
Protocol.DEFAULT_TIMEOUT, password, database, null), new Config()); new JedisFactory(h, port, Protocol.DEFAULT_TIMEOUT,
password, database, null),
new GenericObjectPoolConfig());
} else { } else {
this.internalPool = new GenericObjectPool(new JedisFactory(host, this.internalPool = new GenericObjectPool<Jedis>(new JedisFactory(
Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT, null, host, Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT,
Protocol.DEFAULT_DATABASE, null), new Config()); null, Protocol.DEFAULT_DATABASE, null),
new GenericObjectPoolConfig());
} }
} }
@@ -38,39 +43,48 @@ public class JedisPool extends Pool<Jedis> {
int port = uri.getPort(); int port = uri.getPort();
String password = uri.getUserInfo().split(":", 2)[1]; String password = uri.getUserInfo().split(":", 2)[1];
int database = Integer.parseInt(uri.getPath().split("/", 2)[1]); int database = Integer.parseInt(uri.getPath().split("/", 2)[1]);
this.internalPool = new GenericObjectPool(new JedisFactory(h, port, this.internalPool = new GenericObjectPool<Jedis>(new JedisFactory(h,
Protocol.DEFAULT_TIMEOUT, password, database, null), new Config()); port, Protocol.DEFAULT_TIMEOUT, password, database, null),
new GenericObjectPoolConfig());
} }
public JedisPool(final Config poolConfig, final String host, int port, public JedisPool(final GenericObjectPoolConfig poolConfig,
int timeout, final String password) { final String host, int port, int timeout, final String password) {
this(poolConfig, host, port, timeout, password, Protocol.DEFAULT_DATABASE, null); this(poolConfig, host, port, timeout, password,
Protocol.DEFAULT_DATABASE, null);
} }
public JedisPool(final Config poolConfig, final String host, final int port) { public JedisPool(final GenericObjectPoolConfig poolConfig,
this(poolConfig, host, port, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE, null); final String host, final int port) {
this(poolConfig, host, port, Protocol.DEFAULT_TIMEOUT, null,
Protocol.DEFAULT_DATABASE, null);
} }
public JedisPool(final Config poolConfig, final String host, final int port, final int timeout) { public JedisPool(final GenericObjectPoolConfig poolConfig,
this(poolConfig, host, port, timeout, null, Protocol.DEFAULT_DATABASE, null); final String host, final int port, final int timeout) {
this(poolConfig, host, port, timeout, null, Protocol.DEFAULT_DATABASE,
null);
} }
public JedisPool(final Config poolConfig, final String host, int port, int timeout, final String password, public JedisPool(final GenericObjectPoolConfig poolConfig,
final String host, int port, int timeout, final String password,
final int database) { final int database) {
this(poolConfig, host, port, timeout, password, database, null); this(poolConfig, host, port, timeout, password, database, null);
} }
public JedisPool(final Config poolConfig, final String host, int port, int timeout, final String password, public JedisPool(final GenericObjectPoolConfig poolConfig,
final String host, int port, int timeout, final String password,
final int database, final String clientName) { final int database, final String clientName) {
super(poolConfig, new JedisFactory(host, port, timeout, password, database, clientName)); super(poolConfig, new JedisFactory(host, port, timeout, password,
database, clientName));
} }
public void returnBrokenResource(final Jedis resource) {
public void returnBrokenResource(final BinaryJedis resource) {
returnBrokenResourceObject(resource); returnBrokenResourceObject(resource);
} }
public void returnResource(final BinaryJedis resource) { public void returnResource(final Jedis resource) {
resource.resetState();
returnResourceObject(resource); returnResourceObject(resource);
} }
} }

View File

@@ -1,28 +1,8 @@
package redis.clients.jedis; package redis.clients.jedis;
import org.apache.commons.pool.impl.GenericObjectPool.Config; import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
/** public class JedisPoolConfig extends GenericObjectPoolConfig {
* Subclass of org.apache.commons.pool.impl.GenericObjectPool.Config that
* includes getters/setters so it can be more easily configured by Spring and
* other IoC frameworks.
*
* Spring example:
*
* <bean id="jedisConfig" class="redis.clients.jedis.JedisPoolConfig"> <property
* name="testWhileIdle" value="true"/> </bean>
*
* <bean id="jedisPool" class="redis.clients.jedis.JedisPool"
* destroy-method="destroy"> <constructor-arg ref="jedisConfig" />
* <constructor-arg value="localhost" /> <constructor-arg type="int"
* value="6379" /> </bean>
*
* For information on parameters refer to:
*
* http://commons.apache.org/pool/apidocs/org/apache/commons/pool/impl/
* GenericObjectPool.html
*/
public class JedisPoolConfig extends Config {
public JedisPoolConfig() { public JedisPoolConfig() {
// defaults to make your life with connection pool easier :) // defaults to make your life with connection pool easier :)
setTestWhileIdle(true); setTestWhileIdle(true);
@@ -30,103 +10,4 @@ public class JedisPoolConfig extends Config {
setTimeBetweenEvictionRunsMillis(30000); setTimeBetweenEvictionRunsMillis(30000);
setNumTestsPerEvictionRun(-1); setNumTestsPerEvictionRun(-1);
} }
public int getMaxIdle() {
return maxIdle;
}
public void setMaxIdle(int maxIdle) {
this.maxIdle = maxIdle;
}
public int getMinIdle() {
return minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public int getMaxActive() {
return maxActive;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
public long getMaxWait() {
return maxWait;
}
public void setMaxWait(long maxWait) {
this.maxWait = maxWait;
}
public byte getWhenExhaustedAction() {
return whenExhaustedAction;
}
public void setWhenExhaustedAction(byte whenExhaustedAction) {
this.whenExhaustedAction = whenExhaustedAction;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public boolean isTestOnReturn() {
return testOnReturn;
}
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
public boolean isTestWhileIdle() {
return testWhileIdle;
}
public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
public long getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
}
public void setTimeBetweenEvictionRunsMillis(
long timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
public int getNumTestsPerEvictionRun() {
return numTestsPerEvictionRun;
}
public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
this.numTestsPerEvictionRun = numTestsPerEvictionRun;
}
public long getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
}
public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
public long getSoftMinEvictableIdleTimeMillis() {
return softMinEvictableIdleTimeMillis;
}
public void setSoftMinEvictableIdleTimeMillis(
long softMinEvictableIdleTimeMillis) {
this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
}
} }

View File

@@ -16,7 +16,7 @@ import redis.clients.util.SafeEncoder;
public abstract class JedisPubSub { public abstract class JedisPubSub {
private int subscribedChannels = 0; private int subscribedChannels = 0;
private Client client; private volatile Client client;
public abstract void onMessage(String channel, String message); public abstract void onMessage(String channel, String message);
@@ -41,26 +41,46 @@ public abstract class JedisPubSub {
} }
public void unsubscribe(String... channels) { public void unsubscribe(String... channels) {
if (client == null) {
throw new JedisConnectionException(
"JedisPubSub is not subscribed to a Jedis instance.");
}
client.unsubscribe(channels); client.unsubscribe(channels);
client.flush(); client.flush();
} }
public void subscribe(String... channels) { public void subscribe(String... channels) {
if (client == null) {
throw new JedisConnectionException(
"JedisPubSub is not subscribed to a Jedis instance.");
}
client.subscribe(channels); client.subscribe(channels);
client.flush(); client.flush();
} }
public void psubscribe(String... patterns) { public void psubscribe(String... patterns) {
if (client == null) {
throw new JedisConnectionException(
"JedisPubSub is not subscribed to a Jedis instance.");
}
client.psubscribe(patterns); client.psubscribe(patterns);
client.flush(); client.flush();
} }
public void punsubscribe() { public void punsubscribe() {
if (client == null) {
throw new JedisConnectionException(
"JedisPubSub is not subscribed to a Jedis instance.");
}
client.punsubscribe(); client.punsubscribe();
client.flush(); client.flush();
} }
public void punsubscribe(String... patterns) { public void punsubscribe(String... patterns) {
if (client == null) {
throw new JedisConnectionException(
"JedisPubSub is not subscribed to a Jedis instance.");
}
client.punsubscribe(patterns); client.punsubscribe(patterns);
client.flush(); client.flush();
} }
@@ -84,8 +104,9 @@ public abstract class JedisPubSub {
} }
private void process(Client client) { private void process(Client client) {
do { do {
List<Object> reply = client.getObjectMultiBulkReply(); List<Object> reply = client.getRawObjectMultiBulkReply();
final Object firstObj = reply.get(0); final Object firstObj = reply.get(0);
if (!(firstObj instanceof byte[])) { if (!(firstObj instanceof byte[])) {
throw new JedisException("Unknown message type: " + firstObj); throw new JedisException("Unknown message type: " + firstObj);
@@ -138,6 +159,15 @@ public abstract class JedisPubSub {
throw new JedisException("Unknown message type: " + firstObj); throw new JedisException("Unknown message type: " + firstObj);
} }
} while (isSubscribed()); } while (isSubscribed());
/* Invalidate instance since this thread is no longer listening */
this.client = null;
/*
* Reset pipeline count because subscribe() calls would have increased
* it but nothing decremented it.
*/
client.resetPipelinedCount();
} }
public int getSubscribedChannels() { public int getSubscribedChannels() {

View File

@@ -0,0 +1,19 @@
package redis.clients.jedis;
import java.util.Set;
public class JedisRandomConnectionHandler extends JedisClusterConnectionHandler {
public JedisRandomConnectionHandler(Set<HostAndPort> nodes) {
super(nodes);
}
public Jedis getConnection() {
return getRandomConnection().getResource();
}
@Override
Jedis getConnectionFromSlot(int slot) {
return getRandomConnection().getResource();
}
}

View File

@@ -7,14 +7,14 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.apache.commons.pool.impl.GenericObjectPool.Config; import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.util.Pool; import redis.clients.util.Pool;
public class JedisSentinelPool extends Pool<Jedis> { public class JedisSentinelPool extends Pool<Jedis> {
protected Config poolConfig; protected GenericObjectPoolConfig poolConfig;
protected int timeout = Protocol.DEFAULT_TIMEOUT; protected int timeout = Protocol.DEFAULT_TIMEOUT;
@@ -27,43 +27,44 @@ public class JedisSentinelPool extends Pool<Jedis> {
protected Logger log = Logger.getLogger(getClass().getName()); protected Logger log = Logger.getLogger(getClass().getName());
public JedisSentinelPool(String masterName, Set<String> sentinels, public JedisSentinelPool(String masterName, Set<String> sentinels,
final Config poolConfig) { final GenericObjectPoolConfig poolConfig) {
this(masterName, sentinels, poolConfig, Protocol.DEFAULT_TIMEOUT, null, this(masterName, sentinels, poolConfig, Protocol.DEFAULT_TIMEOUT, null,
Protocol.DEFAULT_DATABASE); Protocol.DEFAULT_DATABASE);
} }
public JedisSentinelPool(String masterName, Set<String> sentinels) { public JedisSentinelPool(String masterName, Set<String> sentinels) {
this(masterName, sentinels, new Config(), Protocol.DEFAULT_TIMEOUT, this(masterName, sentinels, new GenericObjectPoolConfig(),
null, Protocol.DEFAULT_DATABASE); Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
} }
public JedisSentinelPool(String masterName, Set<String> sentinels, public JedisSentinelPool(String masterName, Set<String> sentinels,
String password) { String password) {
this(masterName, sentinels, new Config(), Protocol.DEFAULT_TIMEOUT, this(masterName, sentinels, new GenericObjectPoolConfig(),
password); Protocol.DEFAULT_TIMEOUT, password);
} }
public JedisSentinelPool(String masterName, Set<String> sentinels, public JedisSentinelPool(String masterName, Set<String> sentinels,
final Config poolConfig, int timeout, final String password) { final GenericObjectPoolConfig poolConfig, int timeout,
final String password) {
this(masterName, sentinels, poolConfig, timeout, password, this(masterName, sentinels, poolConfig, timeout, password,
Protocol.DEFAULT_DATABASE); Protocol.DEFAULT_DATABASE);
} }
public JedisSentinelPool(String masterName, Set<String> sentinels, public JedisSentinelPool(String masterName, Set<String> sentinels,
final Config poolConfig, final int timeout) { final GenericObjectPoolConfig poolConfig, final int timeout) {
this(masterName, sentinels, poolConfig, timeout, null, this(masterName, sentinels, poolConfig, timeout, null,
Protocol.DEFAULT_DATABASE); Protocol.DEFAULT_DATABASE);
} }
public JedisSentinelPool(String masterName, Set<String> sentinels, public JedisSentinelPool(String masterName, Set<String> sentinels,
final Config poolConfig, final String password) { final GenericObjectPoolConfig poolConfig, final String password) {
this(masterName, sentinels, poolConfig, Protocol.DEFAULT_TIMEOUT, this(masterName, sentinels, poolConfig, Protocol.DEFAULT_TIMEOUT,
password); password);
} }
public JedisSentinelPool(String masterName, Set<String> sentinels, public JedisSentinelPool(String masterName, Set<String> sentinels,
final Config poolConfig, int timeout, final String password, final GenericObjectPoolConfig poolConfig, int timeout,
final int database) { final String password, final int database) {
this.poolConfig = poolConfig; this.poolConfig = poolConfig;
this.timeout = timeout; this.timeout = timeout;
this.password = password; this.password = password;
@@ -73,33 +74,15 @@ public class JedisSentinelPool extends Pool<Jedis> {
initPool(master); initPool(master);
} }
public void returnBrokenResource(final BinaryJedis resource) { public void returnBrokenResource(final Jedis resource) {
returnBrokenResourceObject(resource); returnBrokenResourceObject(resource);
} }
public void returnResource(final BinaryJedis resource) { public void returnResource(final Jedis resource) {
resource.resetState();
returnResourceObject(resource); returnResourceObject(resource);
} }
private class HostAndPort {
String host;
int port;
@Override
public boolean equals(Object obj) {
if (obj instanceof HostAndPort) {
HostAndPort hp = (HostAndPort) obj;
return port == hp.port && host.equals(hp.host);
}
return false;
}
@Override
public String toString() {
return host + ":" + port;
}
}
private volatile HostAndPort currentHostMaster; private volatile HostAndPort currentHostMaster;
public void destroy() { public void destroy() {
@@ -118,7 +101,8 @@ public class JedisSentinelPool extends Pool<Jedis> {
if (!master.equals(currentHostMaster)) { if (!master.equals(currentHostMaster)) {
currentHostMaster = master; currentHostMaster = master;
log.info("Created JedisPool to master at " + master); log.info("Created JedisPool to master at " + master);
initPool(poolConfig, new JedisFactory(master.host, master.port, initPool(poolConfig,
new JedisFactory(master.getHost(), master.getPort(),
timeout, password, database)); timeout, password, database));
} }
} }
@@ -141,7 +125,7 @@ public class JedisSentinelPool extends Pool<Jedis> {
log.fine("Connecting to Sentinel " + hap); log.fine("Connecting to Sentinel " + hap);
try { try {
Jedis jedis = new Jedis(hap.host, hap.port); Jedis jedis = new Jedis(hap.getHost(), hap.getPort());
if (master == null) { if (master == null) {
master = toHostAndPort(jedis master = toHostAndPort(jedis
@@ -172,7 +156,7 @@ public class JedisSentinelPool extends Pool<Jedis> {
final HostAndPort hap = toHostAndPort(Arrays.asList(sentinel final HostAndPort hap = toHostAndPort(Arrays.asList(sentinel
.split(":"))); .split(":")));
MasterListener masterListener = new MasterListener(masterName, MasterListener masterListener = new MasterListener(masterName,
hap.host, hap.port); hap.getHost(), hap.getPort());
masterListeners.add(masterListener); masterListeners.add(masterListener);
masterListener.start(); masterListener.start();
} }
@@ -181,10 +165,10 @@ public class JedisSentinelPool extends Pool<Jedis> {
} }
private HostAndPort toHostAndPort(List<String> getMasterAddrByNameResult) { private HostAndPort toHostAndPort(List<String> getMasterAddrByNameResult) {
final HostAndPort hap = new HostAndPort(); String host = getMasterAddrByNameResult.get(0);
hap.host = getMasterAddrByNameResult.get(0); int port = Integer.parseInt(getMasterAddrByNameResult.get(1));
hap.port = Integer.parseInt(getMasterAddrByNameResult.get(1));
return hap; return new HostAndPort(host, port);
} }
protected class JedisPubSubAdapter extends JedisPubSub { protected class JedisPubSubAdapter extends JedisPubSub {

View File

@@ -0,0 +1,46 @@
package redis.clients.jedis;
import java.util.Set;
public class JedisSlotBasedConnectionHandler extends
JedisClusterConnectionHandler {
private Jedis currentConnection;
public JedisSlotBasedConnectionHandler(Set<HostAndPort> nodes) {
super(nodes);
}
public Jedis getConnection() {
return currentConnection != null ? currentConnection
: getRandomConnection().getResource();
}
private void returnCurrentConnection() {
if (currentConnection != null) {
nodes.get(
currentConnection.getClient().getHost()
+ currentConnection.getClient().getPort())
.returnResource(currentConnection);
}
}
@Override
public void assignSlotToNode(int slot, HostAndPort targetNode) {
super.assignSlotToNode(slot, targetNode);
getConnectionFromSlot(slot);
}
@Override
public Jedis getConnectionFromSlot(int slot) {
returnCurrentConnection();
JedisPool connectionPool = slots.get(slot);
if (connectionPool == null) {
connectionPool = getRandomConnection();
}
currentConnection = connectionPool.getResource();
return connectionPool.getResource();
}
}

View File

@@ -1,6 +1,5 @@
package redis.clients.jedis; package redis.clients.jedis;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;

View File

@@ -1,11 +1,11 @@
package redis.clients.jedis; package redis.clients.jedis;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
* Multikey related commands (these are split out because they are non-shardable) * Multikey related commands (these are split out because they are
* non-shardable)
*/ */
public interface MultiKeyBinaryRedisPipeline { public interface MultiKeyBinaryRedisPipeline {
@@ -39,7 +39,8 @@ public interface MultiKeyBinaryRedisPipeline {
Response<Long> smove(byte[] srckey, byte[] dstkey, byte[] member); Response<Long> smove(byte[] srckey, byte[] dstkey, byte[] member);
Response<Long> sort(byte[] key, SortingParams sortingParameters, byte[] dstkey); Response<Long> sort(byte[] key, SortingParams sortingParameters,
byte[] dstkey);
Response<Long> sort(byte[] key, byte[] dstkey); Response<Long> sort(byte[] key, byte[] dstkey);

View File

@@ -1,6 +1,5 @@
package redis.clients.jedis; package redis.clients.jedis;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@@ -70,4 +69,6 @@ public interface MultiKeyCommands {
String randomKey(); String randomKey();
Long bitop(BitOP op, final String destKey, String... srcKeys); Long bitop(BitOP op, final String destKey, String... srcKeys);
ScanResult<String> scan(int cursor);
} }

View File

@@ -1,12 +1,11 @@
package redis.clients.jedis; package redis.clients.jedis;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
* Multikey related commands (these are split out because they are non-shardable) * Multikey related commands (these are split out because they are
* non-shardable)
*/ */
public interface MultiKeyCommandsPipeline { public interface MultiKeyCommandsPipeline {
Response<Long> del(String... keys); Response<Long> del(String... keys);
@@ -39,7 +38,8 @@ public interface MultiKeyCommandsPipeline {
Response<Long> smove(String srckey, String dstkey, String member); Response<Long> smove(String srckey, String dstkey, String member);
Response<Long> sort(String key, SortingParams sortingParameters, String dstkey); Response<Long> sort(String key, SortingParams sortingParameters,
String dstkey);
Response<Long> sort(String key, String dstkey); Response<Long> sort(String key, String dstkey);

View File

@@ -5,9 +5,8 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
abstract class MultiKeyPipelineBase extends PipelineBase implements abstract class MultiKeyPipelineBase extends PipelineBase implements
BasicRedisPipeline, BasicRedisPipeline, MultiKeyBinaryRedisPipeline,
MultiKeyBinaryRedisPipeline, MultiKeyCommandsPipeline, ClusterPipeline {
MultiKeyCommandsPipeline {
protected Client client = null; protected Client client = null;
@@ -191,14 +190,14 @@ abstract class MultiKeyPipelineBase extends PipelineBase implements
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> sort(String key, public Response<Long> sort(String key, SortingParams sortingParameters,
SortingParams sortingParameters, String dstkey) { String dstkey) {
client.sort(key, sortingParameters, dstkey); client.sort(key, sortingParameters, dstkey);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> sort(byte[] key, public Response<Long> sort(byte[] key, SortingParams sortingParameters,
SortingParams sortingParameters, byte[] dstkey) { byte[] dstkey) {
client.sort(key, sortingParameters, dstkey); client.sort(key, sortingParameters, dstkey);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
@@ -398,4 +397,53 @@ abstract class MultiKeyPipelineBase extends PipelineBase implements
client.bitop(op, destKey, srcKeys); client.bitop(op, destKey, srcKeys);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<String> clusterNodes() {
client.clusterNodes();
return getResponse(BuilderFactory.STRING);
}
public Response<String> clusterMeet(final String ip, final int port) {
client.clusterMeet(ip, port);
return getResponse(BuilderFactory.STRING);
}
public Response<String> clusterAddSlots(final int... slots) {
client.clusterAddSlots(slots);
return getResponse(BuilderFactory.STRING);
}
public Response<String> clusterDelSlots(final int... slots) {
client.clusterDelSlots(slots);
return getResponse(BuilderFactory.STRING);
}
public Response<String> clusterInfo() {
client.clusterInfo();
return getResponse(BuilderFactory.STRING);
}
public Response<List<String>> clusterGetKeysInSlot(final int slot,
final int count) {
client.clusterGetKeysInSlot(slot, count);
return getResponse(BuilderFactory.STRING_LIST);
}
public Response<String> clusterSetSlotNode(final int slot,
final String nodeId) {
client.clusterSetSlotNode(slot, nodeId);
return getResponse(BuilderFactory.STRING);
}
public Response<String> clusterSetSlotMigrating(final int slot,
final String nodeId) {
client.clusterSetSlotMigrating(slot, nodeId);
return getResponse(BuilderFactory.STRING);
}
public Response<String> clusterSetSlotImporting(final int slot,
final String nodeId) {
client.clusterSetSlotImporting(slot, nodeId);
return getResponse(BuilderFactory.STRING);
}
} }

View File

@@ -1,10 +1,10 @@
package redis.clients.jedis; package redis.clients.jedis;
import redis.clients.jedis.exceptions.JedisDataException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import redis.clients.jedis.exceptions.JedisDataException;
public class Pipeline extends MultiKeyPipelineBase { public class Pipeline extends MultiKeyPipelineBase {
private MultiResponseBuilder currentMulti; private MultiResponseBuilder currentMulti;
@@ -19,7 +19,8 @@ public class Pipeline extends MultiKeyPipelineBase {
List<Object> values = new ArrayList<Object>(); List<Object> values = new ArrayList<Object>();
if (list.size() != responses.size()) { if (list.size() != responses.size()) {
throw new JedisDataException("Expected data size " + responses.size() + " but was " + list.size()); throw new JedisDataException("Expected data size "
+ responses.size() + " but was " + list.size());
} }
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
@@ -43,8 +44,7 @@ public class Pipeline extends MultiKeyPipelineBase {
Response<T> lr = new Response<T>(builder); Response<T> lr = new Response<T>(builder);
currentMulti.addResponse(lr); currentMulti.addResponse(lr);
return lr; return lr;
} } else {
else{
return super.getResponse(builder); return super.getResponse(builder);
} }
} }
@@ -112,7 +112,8 @@ public class Pipeline extends MultiKeyPipelineBase {
public Response<String> multi() { public Response<String> multi() {
client.multi(); client.multi();
Response<String> response = getResponse(BuilderFactory.STRING); //Expecting OK Response<String> response = getResponse(BuilderFactory.STRING); // Expecting
// OK
currentMulti = new MultiResponseBuilder(); currentMulti = new MultiResponseBuilder();
return response; return response;
} }

View File

@@ -1,15 +1,14 @@
package redis.clients.jedis; package redis.clients.jedis;
import redis.clients.jedis.BinaryClient.LIST_POSITION; import static redis.clients.jedis.Protocol.toByteArray;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import static redis.clients.jedis.Protocol.toByteArray; import redis.clients.jedis.BinaryClient.LIST_POSITION;
abstract class PipelineBase extends Queable implements abstract class PipelineBase extends Queable implements BinaryRedisPipeline,
BinaryRedisPipeline,
RedisPipeline { RedisPipeline {
protected abstract Client getClient(String key); protected abstract Client getClient(String key);
@@ -654,7 +653,7 @@ abstract class PipelineBase extends Queable implements
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> zadd(String key, Map<Double, String> scoreMembers) { public Response<Long> zadd(String key, Map<String, Double> scoreMembers) {
getClient(key).zadd(key, scoreMembers); getClient(key).zadd(key, scoreMembers);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
@@ -738,14 +737,16 @@ abstract class PipelineBase extends Queable implements
return getResponse(BuilderFactory.STRING_ZSET); return getResponse(BuilderFactory.STRING_ZSET);
} }
public Response<Set<String>> zrangeByScore(String key, String min, String max, int offset, int count) { public Response<Set<String>> zrangeByScore(String key, String min,
String max, int offset, int count) {
getClient(key).zrangeByScore(key, min, max, offset, count); getClient(key).zrangeByScore(key, min, max, offset, count);
return getResponse(BuilderFactory.STRING_ZSET); return getResponse(BuilderFactory.STRING_ZSET);
} }
public Response<Set<byte[]>> zrangeByScore(byte[] key, double min, public Response<Set<byte[]>> zrangeByScore(byte[] key, double min,
double max, int offset, int count) { double max, int offset, int count) {
return zrangeByScore(key, toByteArray(min), toByteArray(max), offset, count); return zrangeByScore(key, toByteArray(min), toByteArray(max), offset,
count);
} }
public Response<Set<byte[]>> zrangeByScore(byte[] key, byte[] min, public Response<Set<byte[]>> zrangeByScore(byte[] key, byte[] min,
@@ -791,7 +792,8 @@ abstract class PipelineBase extends Queable implements
public Response<Set<Tuple>> zrangeByScoreWithScores(byte[] key, double min, public Response<Set<Tuple>> zrangeByScoreWithScores(byte[] key, double min,
double max, int offset, int count) { double max, int offset, int count) {
getClient(key).zrangeByScoreWithScores(key, toByteArray(min), toByteArray(max), offset, count); getClient(key).zrangeByScoreWithScores(key, toByteArray(min),
toByteArray(max), offset, count);
return getResponse(BuilderFactory.TUPLE_ZSET_BINARY); return getResponse(BuilderFactory.TUPLE_ZSET_BINARY);
} }
@@ -809,7 +811,8 @@ abstract class PipelineBase extends Queable implements
public Response<Set<byte[]>> zrevrangeByScore(byte[] key, double max, public Response<Set<byte[]>> zrevrangeByScore(byte[] key, double max,
double min) { double min) {
getClient(key).zrevrangeByScore(key, toByteArray(max), toByteArray(min)); getClient(key)
.zrevrangeByScore(key, toByteArray(max), toByteArray(min));
return getResponse(BuilderFactory.BYTE_ARRAY_ZSET); return getResponse(BuilderFactory.BYTE_ARRAY_ZSET);
} }
@@ -839,7 +842,8 @@ abstract class PipelineBase extends Queable implements
public Response<Set<byte[]>> zrevrangeByScore(byte[] key, double max, public Response<Set<byte[]>> zrevrangeByScore(byte[] key, double max,
double min, int offset, int count) { double min, int offset, int count) {
getClient(key).zrevrangeByScore(key, toByteArray(max), toByteArray(min), offset, count); getClient(key).zrevrangeByScore(key, toByteArray(max),
toByteArray(min), offset, count);
return getResponse(BuilderFactory.BYTE_ARRAY_ZSET); return getResponse(BuilderFactory.BYTE_ARRAY_ZSET);
} }
@@ -863,7 +867,8 @@ abstract class PipelineBase extends Queable implements
public Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key, public Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key,
double max, double min) { double max, double min) {
getClient(key).zrevrangeByScoreWithScores(key, toByteArray(max), toByteArray(min)); getClient(key).zrevrangeByScoreWithScores(key, toByteArray(max),
toByteArray(min));
return getResponse(BuilderFactory.TUPLE_ZSET_BINARY); return getResponse(BuilderFactory.TUPLE_ZSET_BINARY);
} }
@@ -887,7 +892,8 @@ abstract class PipelineBase extends Queable implements
public Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key, public Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key,
double max, double min, int offset, int count) { double max, double min, int offset, int count) {
getClient(key).zrevrangeByScoreWithScores(key, toByteArray(max), toByteArray(min), offset, count); getClient(key).zrevrangeByScoreWithScores(key, toByteArray(max),
toByteArray(min), offset, count);
return getResponse(BuilderFactory.TUPLE_ZSET_BINARY); return getResponse(BuilderFactory.TUPLE_ZSET_BINARY);
} }
@@ -897,12 +903,14 @@ abstract class PipelineBase extends Queable implements
return getResponse(BuilderFactory.TUPLE_ZSET_BINARY); return getResponse(BuilderFactory.TUPLE_ZSET_BINARY);
} }
public Response<Set<Tuple>> zrangeWithScores(String key, long start, long end) { public Response<Set<Tuple>> zrangeWithScores(String key, long start,
long end) {
getClient(key).zrangeWithScores(key, start, end); getClient(key).zrangeWithScores(key, start, end);
return getResponse(BuilderFactory.TUPLE_ZSET); return getResponse(BuilderFactory.TUPLE_ZSET);
} }
public Response<Set<Tuple>> zrangeWithScores(byte[] key, long start, long end) { public Response<Set<Tuple>> zrangeWithScores(byte[] key, long start,
long end) {
getClient(key).zrangeWithScores(key, start, end); getClient(key).zrangeWithScores(key, start, end);
return getResponse(BuilderFactory.TUPLE_ZSET_BINARY); return getResponse(BuilderFactory.TUPLE_ZSET_BINARY);
} }
@@ -948,7 +956,8 @@ abstract class PipelineBase extends Queable implements
} }
public Response<Long> zremrangeByScore(byte[] key, double start, double end) { public Response<Long> zremrangeByScore(byte[] key, double start, double end) {
getClient(key).zremrangeByScore(key, toByteArray(start), toByteArray(end)); getClient(key).zremrangeByScore(key, toByteArray(start),
toByteArray(end));
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
@@ -1029,12 +1038,14 @@ abstract class PipelineBase extends Queable implements
return getResponse(BuilderFactory.BYTE_ARRAY); return getResponse(BuilderFactory.BYTE_ARRAY);
} }
public Response<String> migrate(String host, int port, String key, int destinationDb, int timeout) { public Response<String> migrate(String host, int port, String key,
int destinationDb, int timeout) {
getClient(key).migrate(host, port, key, destinationDb, timeout); getClient(key).migrate(host, port, key, destinationDb, timeout);
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<String> migrate(byte[] host, int port, byte[] key, int destinationDb, int timeout) { public Response<String> migrate(byte[] host, int port, byte[] key,
int destinationDb, int timeout) {
getClient(key).migrate(host, port, key, destinationDb, timeout); getClient(key).migrate(host, port, key, destinationDb, timeout);
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
@@ -1139,22 +1150,26 @@ abstract class PipelineBase extends Queable implements
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<String> set(String key, String value, String nxxx, String expx, int time) { public Response<String> set(String key, String value, String nxxx,
String expx, int time) {
getClient(key).set(key, value, nxxx, expx, time); getClient(key).set(key, value, nxxx, expx, time);
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<String> set(byte[] key, byte[] value, byte[] nxxx, byte[] expx, int time) { public Response<String> set(byte[] key, byte[] value, byte[] nxxx,
byte[] expx, int time) {
getClient(key).set(key, value, nxxx, expx, time); getClient(key).set(key, value, nxxx, expx, time);
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<Double> hincrByFloat(String key, String field, double increment) { public Response<Double> hincrByFloat(String key, String field,
double increment) {
getClient(key).hincrByFloat(key, field, increment); getClient(key).hincrByFloat(key, field, increment);
return getResponse(BuilderFactory.DOUBLE); return getResponse(BuilderFactory.DOUBLE);
} }
public Response<Double> hincrByFloat(byte[] key, byte[] field, double increment) { public Response<Double> hincrByFloat(byte[] key, byte[] field,
double increment) {
getClient(key).hincrByFloat(key, field, increment); getClient(key).hincrByFloat(key, field, increment);
return getResponse(BuilderFactory.DOUBLE); return getResponse(BuilderFactory.DOUBLE);
} }
@@ -1163,7 +1178,8 @@ abstract class PipelineBase extends Queable implements
return this.eval(script, 0, new String[0]); return this.eval(script, 0, new String[0]);
} }
public Response<String> eval(String script, List<String> keys, List<String> args) { public Response<String> eval(String script, List<String> keys,
List<String> args) {
String[] argv = Jedis.getParams(keys, args); String[] argv = Jedis.getParams(keys, args);
return this.eval(script, keys.size(), argv); return this.eval(script, keys.size(), argv);
} }
@@ -1177,7 +1193,8 @@ abstract class PipelineBase extends Queable implements
return this.evalsha(script, 0, new String[0]); return this.evalsha(script, 0, new String[0]);
} }
public Response<String> evalsha(String sha1, List<String> keys, List<String> args) { public Response<String> evalsha(String sha1, List<String> keys,
List<String> args) {
String[] argv = Jedis.getParams(keys, args); String[] argv = Jedis.getParams(keys, args);
return this.evalsha(sha1, keys.size(), argv); return this.evalsha(sha1, keys.size(), argv);
} }
@@ -1187,5 +1204,4 @@ abstract class PipelineBase extends Queable implements
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
} }

View File

@@ -1,6 +1,5 @@
package redis.clients.jedis; package redis.clients.jedis;
public abstract class PipelineBlock extends Pipeline { public abstract class PipelineBlock extends Pipeline {
public abstract void execute(); public abstract void execute();
} }

View File

@@ -4,14 +4,18 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import redis.clients.jedis.exceptions.JedisAskDataException;
import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.exceptions.JedisMovedDataException;
import redis.clients.util.RedisInputStream; import redis.clients.util.RedisInputStream;
import redis.clients.util.RedisOutputStream; import redis.clients.util.RedisOutputStream;
import redis.clients.util.SafeEncoder; import redis.clients.util.SafeEncoder;
public final class Protocol { public final class Protocol {
private static final String ASK_RESPONSE = "ASK";
private static final String MOVED_RESPONSE = "MOVED";
public static final int DEFAULT_PORT = 6379; public static final int DEFAULT_PORT = 6379;
public static final int DEFAULT_SENTINEL_PORT = 26379; public static final int DEFAULT_SENTINEL_PORT = 26379;
public static final int DEFAULT_TIMEOUT = 2000; public static final int DEFAULT_TIMEOUT = 2000;
@@ -29,7 +33,20 @@ public final class Protocol {
public static final String SENTINEL_GET_MASTER_ADDR_BY_NAME = "get-master-addr-by-name"; public static final String SENTINEL_GET_MASTER_ADDR_BY_NAME = "get-master-addr-by-name";
public static final String SENTINEL_RESET = "reset"; public static final String SENTINEL_RESET = "reset";
public static final String SENTINEL_SLAVES = "slaves"; public static final String SENTINEL_SLAVES = "slaves";
public static final String SENTINEL_IS_MASTER_DOWN_BY_ADDR = "is-master-down-by-addr";
public static final String CLUSTER_NODES = "nodes";
public static final String CLUSTER_MEET = "meet";
public static final String CLUSTER_ADDSLOTS = "addslots";
public static final String CLUSTER_DELSLOTS = "delslots";
public static final String CLUSTER_INFO = "info";
public static final String CLUSTER_GETKEYSINSLOT = "getkeysinslot";
public static final String CLUSTER_SETSLOT = "setslot";
public static final String CLUSTER_SETSLOT_NODE = "node";
public static final String CLUSTER_SETSLOT_MIGRATING = "migrating";
public static final String CLUSTER_SETSLOT_IMPORTING = "importing";
public static final String PUBSUB_CHANNELS= "channels";
public static final String PUBSUB_NUMSUB = "numsub";
public static final String PUBSUB_NUM_PAT = "numpat";
private Protocol() { private Protocol() {
// this prevent the class from instantiation // this prevent the class from instantiation
@@ -63,9 +80,33 @@ public final class Protocol {
private static void processError(final RedisInputStream is) { private static void processError(final RedisInputStream is) {
String message = is.readLine(); String message = is.readLine();
// TODO: I'm not sure if this is the best way to do this.
// Maybe Read only first 5 bytes instead?
if (message.startsWith(MOVED_RESPONSE)) {
String[] movedInfo = parseTargetHostAndSlot(message);
throw new JedisMovedDataException(message, new HostAndPort(
movedInfo[1], Integer.valueOf(movedInfo[2])),
Integer.valueOf(movedInfo[0]));
} else if (message.startsWith(ASK_RESPONSE)) {
String[] askInfo = parseTargetHostAndSlot(message);
throw new JedisAskDataException(message, new HostAndPort(
askInfo[1], Integer.valueOf(askInfo[2])),
Integer.valueOf(askInfo[0]));
}
throw new JedisDataException(message); throw new JedisDataException(message);
} }
private static String[] parseTargetHostAndSlot(
String clusterRedirectResponse) {
String[] response = new String[3];
String[] messageInfo = clusterRedirectResponse.split(" ");
String[] targetHostAndPort = messageInfo[2].split(":");
response[0] = messageInfo[1];
response[1] = targetHostAndPort[0];
response[2] = targetHostAndPort[1];
return response;
}
private static Object process(final RedisInputStream is) { private static Object process(final RedisInputStream is) {
try { try {
byte b = is.readByte(); byte b = is.readByte();
@@ -101,7 +142,11 @@ public final class Protocol {
int offset = 0; int offset = 0;
try { try {
while (offset < len) { while (offset < len) {
offset += is.read(read, offset, (len - offset)); int size = is.read(read, offset, (len - offset));
if (size == -1)
throw new JedisConnectionException(
"It seems like server has closed the connection.");
offset += size;
} }
// read 2 more bytes for the command delimiter // read 2 more bytes for the command delimiter
is.readByte(); is.readByte();
@@ -155,8 +200,7 @@ public final class Protocol {
} }
public static enum Command { public static enum Command {
PING, SET, GET, QUIT, EXISTS, DEL, TYPE, FLUSHDB, KEYS, RANDOMKEY, RENAME, RENAMENX, RENAMEX, DBSIZE, EXPIRE, EXPIREAT, TTL, SELECT, MOVE, FLUSHALL, GETSET, MGET, SETNX, SETEX, MSET, MSETNX, DECRBY, DECR, INCRBY, INCR, APPEND, SUBSTR, HSET, HGET, HSETNX, HMSET, HMGET, HINCRBY, HEXISTS, HDEL, HLEN, HKEYS, HVALS, HGETALL, RPUSH, LPUSH, LLEN, LRANGE, LTRIM, LINDEX, LSET, LREM, LPOP, RPOP, RPOPLPUSH, SADD, SMEMBERS, SREM, SPOP, SMOVE, SCARD, SISMEMBER, SINTER, SINTERSTORE, SUNION, SUNIONSTORE, SDIFF, SDIFFSTORE, SRANDMEMBER, ZADD, ZRANGE, ZREM, ZINCRBY, ZRANK, ZREVRANK, ZREVRANGE, ZCARD, ZSCORE, MULTI, DISCARD, EXEC, WATCH, UNWATCH, SORT, BLPOP, BRPOP, AUTH, SUBSCRIBE, PUBLISH, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, ZCOUNT, ZRANGEBYSCORE, ZREVRANGEBYSCORE, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZUNIONSTORE, ZINTERSTORE, SAVE, BGSAVE, BGREWRITEAOF, LASTSAVE, SHUTDOWN, INFO, MONITOR, SLAVEOF, CONFIG, STRLEN, SYNC, LPUSHX, PERSIST, RPUSHX, ECHO, LINSERT, DEBUG, BRPOPLPUSH, SETBIT, GETBIT, SETRANGE, GETRANGE, EVAL, EVALSHA, SCRIPT, SLOWLOG, OBJECT, BITCOUNT, BITOP, SENTINEL, PING, SET, GET, QUIT, EXISTS, DEL, TYPE, FLUSHDB, KEYS, RANDOMKEY, RENAME, RENAMENX, RENAMEX, DBSIZE, EXPIRE, EXPIREAT, TTL, SELECT, MOVE, FLUSHALL, GETSET, MGET, SETNX, SETEX, MSET, MSETNX, DECRBY, DECR, INCRBY, INCR, APPEND, SUBSTR, HSET, HGET, HSETNX, HMSET, HMGET, HINCRBY, HEXISTS, HDEL, HLEN, HKEYS, HVALS, HGETALL, RPUSH, LPUSH, LLEN, LRANGE, LTRIM, LINDEX, LSET, LREM, LPOP, RPOP, RPOPLPUSH, SADD, SMEMBERS, SREM, SPOP, SMOVE, SCARD, SISMEMBER, SINTER, SINTERSTORE, SUNION, SUNIONSTORE, SDIFF, SDIFFSTORE, SRANDMEMBER, ZADD, ZRANGE, ZREM, ZINCRBY, ZRANK, ZREVRANK, ZREVRANGE, ZCARD, ZSCORE, MULTI, DISCARD, EXEC, WATCH, UNWATCH, SORT, BLPOP, BRPOP, AUTH, SUBSCRIBE, PUBLISH, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBSUB, ZCOUNT, ZRANGEBYSCORE, ZREVRANGEBYSCORE, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZUNIONSTORE, ZINTERSTORE, SAVE, BGSAVE, BGREWRITEAOF, LASTSAVE, SHUTDOWN, INFO, MONITOR, SLAVEOF, CONFIG, STRLEN, SYNC, LPUSHX, PERSIST, RPUSHX, ECHO, LINSERT, DEBUG, BRPOPLPUSH, SETBIT, GETBIT, SETRANGE, GETRANGE, EVAL, EVALSHA, SCRIPT, SLOWLOG, OBJECT, BITCOUNT, BITOP, SENTINEL, DUMP, RESTORE, PEXPIRE, PEXPIREAT, PTTL, INCRBYFLOAT, PSETEX, CLIENT, TIME, MIGRATE, HINCRBYFLOAT, SCAN, HSCAN, SSCAN, ZSCAN, WAIT, CLUSTER, ASKING;
DUMP, RESTORE, PEXPIRE, PEXPIREAT, PTTL, INCRBYFLOAT, PSETEX, CLIENT, TIME, MIGRATE, HINCRBYFLOAT;
public final byte[] raw; public final byte[] raw;
@@ -166,8 +210,7 @@ public final class Protocol {
} }
public static enum Keyword { public static enum Keyword {
AGGREGATE, ALPHA, ASC, BY, DESC, GET, LIMIT, MESSAGE, NO, NOSORT, PMESSAGE, PSUBSCRIBE, PUNSUBSCRIBE, OK, ONE, QUEUED, SET, STORE, SUBSCRIBE, UNSUBSCRIBE, WEIGHTS, WITHSCORES, RESETSTAT, RESET, FLUSH, EXISTS, LOAD, KILL, LEN, REFCOUNT, ENCODING, IDLETIME, AND, OR, XOR, NOT, AGGREGATE, ALPHA, ASC, BY, DESC, GET, LIMIT, MESSAGE, NO, NOSORT, PMESSAGE, PSUBSCRIBE, PUNSUBSCRIBE, OK, ONE, QUEUED, SET, STORE, SUBSCRIBE, UNSUBSCRIBE, WEIGHTS, WITHSCORES, RESETSTAT, RESET, FLUSH, EXISTS, LOAD, KILL, LEN, REFCOUNT, ENCODING, IDLETIME, AND, OR, XOR, NOT, GETNAME, SETNAME, LIST, MATCH, COUNT;
GETNAME, SETNAME,LIST;
public final byte[] raw; public final byte[] raw;
Keyword() { Keyword() {

View File

@@ -32,10 +32,7 @@ public interface RedisPipeline {
Response<Boolean> getbit(String key, long offset); Response<Boolean> getbit(String key, long offset);
Response<String> getrange(String key, long startOffset, long endOffset);
Response<String> getrange(String key, long startOffset,
long endOffset);
Response<String> getSet(String key, String value); Response<String> getSet(String key, String value);
@@ -118,8 +115,7 @@ public interface RedisPipeline {
Response<List<String>> sort(String key); Response<List<String>> sort(String key);
Response<List<String>> sort(String key, Response<List<String>> sort(String key, SortingParams sortingParameters);
SortingParams sortingParameters);
Response<String> spop(String key); Response<String> spop(String key);
@@ -145,14 +141,12 @@ public interface RedisPipeline {
Response<Set<String>> zrange(String key, long start, long end); Response<Set<String>> zrange(String key, long start, long end);
Response<Set<String>> zrangeByScore(String key, double min, Response<Set<String>> zrangeByScore(String key, double min, double max);
double max);
Response<Set<String>> zrangeByScore(String key, String min, Response<Set<String>> zrangeByScore(String key, String min, String max);
String max);
Response<Set<String>> zrangeByScore(String key, double min, Response<Set<String>> zrangeByScore(String key, double min, double max,
double max, int offset, int count); int offset, int count);
Response<Set<Tuple>> zrangeByScoreWithScores(String key, double min, Response<Set<Tuple>> zrangeByScoreWithScores(String key, double min,
double max); double max);
@@ -160,21 +154,19 @@ public interface RedisPipeline {
Response<Set<Tuple>> zrangeByScoreWithScores(String key, double min, Response<Set<Tuple>> zrangeByScoreWithScores(String key, double min,
double max, int offset, int count); double max, int offset, int count);
Response<Set<String>> zrevrangeByScore(String key, double max, Response<Set<String>> zrevrangeByScore(String key, double max, double min);
Response<Set<String>> zrevrangeByScore(String key, String max, String min);
Response<Set<String>> zrevrangeByScore(String key, double max, double min,
int offset, int count);
Response<Set<Tuple>> zrevrangeByScoreWithScores(String key, double max,
double min); double min);
Response<Set<String>> zrevrangeByScore(String key, String max, Response<Set<Tuple>> zrevrangeByScoreWithScores(String key, double max,
String min);
Response<Set<String>> zrevrangeByScore(String key, double max,
double min, int offset, int count); double min, int offset, int count);
Response<Set<Tuple>> zrevrangeByScoreWithScores(String key,
double max, double min);
Response<Set<Tuple>> zrevrangeByScoreWithScores(String key,
double max, double min, int offset, int count);
Response<Set<Tuple>> zrangeWithScores(String key, long start, long end); Response<Set<Tuple>> zrangeWithScores(String key, long start, long end);
Response<Long> zrank(String key, String member); Response<Long> zrank(String key, String member);
@@ -187,8 +179,7 @@ public interface RedisPipeline {
Response<Set<String>> zrevrange(String key, long start, long end); Response<Set<String>> zrevrange(String key, long start, long end);
Response<Set<Tuple>> zrevrangeWithScores(String key, long start, Response<Set<Tuple>> zrevrangeWithScores(String key, long start, long end);
long end);
Response<Long> zrevrank(String key, String member); Response<Long> zrevrank(String key, String member);

View File

@@ -0,0 +1,29 @@
package redis.clients.jedis;
import static redis.clients.jedis.Protocol.Keyword.COUNT;
import static redis.clients.jedis.Protocol.Keyword.MATCH;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import redis.clients.util.SafeEncoder;
public class ScanParams {
private List<byte[]> params = new ArrayList<byte[]>();
public void match(final String pattern) {
params.add(MATCH.raw);
params.add(SafeEncoder.encode(pattern));
}
public void count(final int count) {
params.add(COUNT.raw);
params.add(Protocol.toByteArray(count));
}
public Collection<byte[]> getParams() {
return Collections.unmodifiableCollection(params);
}
}

View File

@@ -0,0 +1,21 @@
package redis.clients.jedis;
import java.util.List;
public class ScanResult<T> {
private int cursor;
private List<T> results;
public ScanResult(int cursor, List<T> results) {
this.cursor = cursor;
this.results = results;
}
public int getCursor() {
return cursor;
}
public List<T> getResult() {
return results;
}
}

View File

@@ -1,13 +1,14 @@
package redis.clients.jedis; package redis.clients.jedis;
import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.util.Hashing;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.util.Hashing;
public class ShardedJedis extends BinaryShardedJedis implements JedisCommands { public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
public ShardedJedis(List<JedisShardInfo> shards) { public ShardedJedis(List<JedisShardInfo> shards) {
super(shards); super(shards);
@@ -326,7 +327,7 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
return j.zadd(key, score, member); return j.zadd(key, score, member);
} }
public Long zadd(String key, Map<Double, String> scoreMembers) { public Long zadd(String key, Map<String, Double> scoreMembers) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.zadd(key, scoreMembers); return j.zadd(key, scoreMembers);
} }
@@ -522,5 +523,18 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
return j.bitcount(key, start, end); return j.bitcount(key, start, end);
} }
public ScanResult<Entry<String, String>> hscan(String key, int cursor) {
Jedis j = getShard(key);
return j.hscan(key, cursor);
}
public ScanResult<String> sscan(String key, int cursor) {
Jedis j = getShard(key);
return j.sscan(key, cursor);
}
public ScanResult<Tuple> zscan(String key, int cursor) {
Jedis j = getShard(key);
return j.zscan(key, cursor);
}
} }

View File

@@ -48,8 +48,8 @@ public class ShardedJedisPipeline extends PipelineBase {
/** /**
* Syncronize pipeline by reading all responses. This operation closes the * Syncronize pipeline by reading all responses. This operation closes the
* pipeline. Whenever possible try to avoid using this version and use * pipeline. Whenever possible try to avoid using this version and use
* ShardedJedisPipeline.sync() as it won't go through all the responses and generate the * ShardedJedisPipeline.sync() as it won't go through all the responses and
* right response type (usually it is a waste of time). * generate the right response type (usually it is a waste of time).
* *
* @return A list of all the responses in the order you executed them. * @return A list of all the responses in the order you executed them.
*/ */
@@ -62,8 +62,8 @@ public class ShardedJedisPipeline extends PipelineBase {
} }
/** /**
* This method will be removed in Jedis 3.0. Use the methods that return Response's and call * This method will be removed in Jedis 3.0. Use the methods that return
* sync(). * Response's and call sync().
*/ */
@Deprecated @Deprecated
public void execute() { public void execute() {

View File

@@ -3,29 +3,31 @@ package redis.clients.jedis;
import java.util.List; import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.commons.pool.BasePoolableObjectFactory; import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool.impl.GenericObjectPool; import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.util.Hashing; import redis.clients.util.Hashing;
import redis.clients.util.Pool; import redis.clients.util.Pool;
public class ShardedJedisPool extends Pool<ShardedJedis> { public class ShardedJedisPool extends Pool<ShardedJedis> {
public ShardedJedisPool(final GenericObjectPool.Config poolConfig, public ShardedJedisPool(final GenericObjectPoolConfig poolConfig,
List<JedisShardInfo> shards) { List<JedisShardInfo> shards) {
this(poolConfig, shards, Hashing.MURMUR_HASH); this(poolConfig, shards, Hashing.MURMUR_HASH);
} }
public ShardedJedisPool(final GenericObjectPool.Config poolConfig, public ShardedJedisPool(final GenericObjectPoolConfig poolConfig,
List<JedisShardInfo> shards, Hashing algo) { List<JedisShardInfo> shards, Hashing algo) {
this(poolConfig, shards, algo, null); this(poolConfig, shards, algo, null);
} }
public ShardedJedisPool(final GenericObjectPool.Config poolConfig, public ShardedJedisPool(final GenericObjectPoolConfig poolConfig,
List<JedisShardInfo> shards, Pattern keyTagPattern) { List<JedisShardInfo> shards, Pattern keyTagPattern) {
this(poolConfig, shards, Hashing.MURMUR_HASH, keyTagPattern); this(poolConfig, shards, Hashing.MURMUR_HASH, keyTagPattern);
} }
public ShardedJedisPool(final GenericObjectPool.Config poolConfig, public ShardedJedisPool(final GenericObjectPoolConfig poolConfig,
List<JedisShardInfo> shards, Hashing algo, Pattern keyTagPattern) { List<JedisShardInfo> shards, Hashing algo, Pattern keyTagPattern) {
super(poolConfig, new ShardedJedisFactory(shards, algo, keyTagPattern)); super(poolConfig, new ShardedJedisFactory(shards, algo, keyTagPattern));
} }
@@ -33,7 +35,8 @@ public class ShardedJedisPool extends Pool<ShardedJedis> {
/** /**
* PoolableObjectFactory custom impl. * PoolableObjectFactory custom impl.
*/ */
private static class ShardedJedisFactory extends BasePoolableObjectFactory { private static class ShardedJedisFactory implements
PooledObjectFactory<ShardedJedis> {
private List<JedisShardInfo> shards; private List<JedisShardInfo> shards;
private Hashing algo; private Hashing algo;
private Pattern keyTagPattern; private Pattern keyTagPattern;
@@ -45,14 +48,16 @@ public class ShardedJedisPool extends Pool<ShardedJedis> {
this.keyTagPattern = keyTagPattern; this.keyTagPattern = keyTagPattern;
} }
public Object makeObject() throws Exception { @Override
public PooledObject<ShardedJedis> makeObject() throws Exception {
ShardedJedis jedis = new ShardedJedis(shards, algo, keyTagPattern); ShardedJedis jedis = new ShardedJedis(shards, algo, keyTagPattern);
return jedis; return new DefaultPooledObject<ShardedJedis>(jedis);
} }
public void destroyObject(final Object obj) throws Exception { @Override
if ((obj != null) && (obj instanceof ShardedJedis)) { public void destroyObject(PooledObject<ShardedJedis> pooledShardedJedis)
ShardedJedis shardedJedis = (ShardedJedis) obj; throws Exception {
final ShardedJedis shardedJedis = pooledShardedJedis.getObject();
for (Jedis jedis : shardedJedis.getAllShards()) { for (Jedis jedis : shardedJedis.getAllShards()) {
try { try {
try { try {
@@ -66,11 +71,12 @@ public class ShardedJedisPool extends Pool<ShardedJedis> {
} }
} }
} }
}
public boolean validateObject(final Object obj) { @Override
public boolean validateObject(
PooledObject<ShardedJedis> pooledShardedJedis) {
try { try {
ShardedJedis jedis = (ShardedJedis) obj; ShardedJedis jedis = pooledShardedJedis.getObject();
for (Jedis shard : jedis.getAllShards()) { for (Jedis shard : jedis.getAllShards()) {
if (!shard.ping().equals("PONG")) { if (!shard.ping().equals("PONG")) {
return false; return false;
@@ -81,5 +87,17 @@ public class ShardedJedisPool extends Pool<ShardedJedis> {
return false; return false;
} }
} }
@Override
public void activateObject(PooledObject<ShardedJedis> p)
throws Exception {
}
@Override
public void passivateObject(PooledObject<ShardedJedis> p)
throws Exception {
}
} }
} }

View File

@@ -6,7 +6,8 @@ import java.util.List;
import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.exceptions.JedisDataException;
/** /**
* Transaction is nearly identical to Pipeline, only differences are the multi/discard behaviors * Transaction is nearly identical to Pipeline, only differences are the
* multi/discard behaviors
*/ */
public class Transaction extends MultiKeyPipelineBase { public class Transaction extends MultiKeyPipelineBase {

View File

@@ -0,0 +1,23 @@
package redis.clients.jedis.exceptions;
import redis.clients.jedis.HostAndPort;
public class JedisAskDataException extends JedisRedirectionException {
private static final long serialVersionUID = 3878126572474819403L;
public JedisAskDataException(Throwable cause, HostAndPort targetHost,
int slot) {
super(cause, targetHost, slot);
}
public JedisAskDataException(String message, Throwable cause,
HostAndPort targetHost, int slot) {
super(message, cause, targetHost, slot);
}
public JedisAskDataException(String message, HostAndPort targetHost,
int slot) {
super(message, targetHost, slot);
}
}

View File

@@ -0,0 +1,17 @@
package redis.clients.jedis.exceptions;
public class JedisClusterException extends JedisDataException {
private static final long serialVersionUID = 3878126572474819403L;
public JedisClusterException(Throwable cause) {
super(cause);
}
public JedisClusterException(String message, Throwable cause) {
super(message, cause);
}
public JedisClusterException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,17 @@
package redis.clients.jedis.exceptions;
public class JedisClusterMaxRedirectionsException extends JedisDataException {
private static final long serialVersionUID = 3878126572474819403L;
public JedisClusterMaxRedirectionsException(Throwable cause) {
super(cause);
}
public JedisClusterMaxRedirectionsException(String message, Throwable cause) {
super(message, cause);
}
public JedisClusterMaxRedirectionsException(String message) {
super(message);
}
}

View File

@@ -1,6 +1,5 @@
package redis.clients.jedis.exceptions; package redis.clients.jedis.exceptions;
public class JedisException extends RuntimeException { public class JedisException extends RuntimeException {
private static final long serialVersionUID = -2946266495682282677L; private static final long serialVersionUID = -2946266495682282677L;

View File

@@ -0,0 +1,22 @@
package redis.clients.jedis.exceptions;
import redis.clients.jedis.HostAndPort;
public class JedisMovedDataException extends JedisRedirectionException {
private static final long serialVersionUID = 3878126572474819403L;
public JedisMovedDataException(String message, HostAndPort targetNode,
int slot) {
super(message, targetNode, slot);
}
public JedisMovedDataException(Throwable cause, HostAndPort targetNode,
int slot) {
super(cause, targetNode, slot);
}
public JedisMovedDataException(String message, Throwable cause,
HostAndPort targetNode, int slot) {
super(message, cause, targetNode, slot);
}
}

View File

@@ -0,0 +1,39 @@
package redis.clients.jedis.exceptions;
import redis.clients.jedis.HostAndPort;
public class JedisRedirectionException extends JedisDataException {
private static final long serialVersionUID = 3878126572474819403L;
private HostAndPort targetNode;
private int slot;
public JedisRedirectionException(String message, HostAndPort targetNode,
int slot) {
super(message);
this.targetNode = targetNode;
this.slot = slot;
}
public JedisRedirectionException(Throwable cause, HostAndPort targetNode,
int slot) {
super(cause);
this.targetNode = targetNode;
this.slot = slot;
}
public JedisRedirectionException(String message, Throwable cause,
HostAndPort targetNode, int slot) {
super(message, cause);
this.targetNode = targetNode;
this.slot = slot;
}
public HostAndPort getTargetNode() {
return targetNode;
}
public int getSlot() {
return slot;
}
}

View File

@@ -69,8 +69,8 @@ public class JedisByteHashMap implements Map<byte[], byte[]>, Cloneable,
while (iterator.hasNext()) { while (iterator.hasNext()) {
Entry<? extends byte[], ? extends byte[]> next = (Entry<? extends byte[], ? extends byte[]>) iterator Entry<? extends byte[], ? extends byte[]> next = (Entry<? extends byte[], ? extends byte[]>) iterator
.next(); .next();
internalMap.put(new ByteArrayWrapper(next.getKey()), next internalMap.put(new ByteArrayWrapper(next.getKey()),
.getValue()); next.getValue());
} }
} }

View File

@@ -0,0 +1,23 @@
package redis.clients.util;
public class JedisClusterCRC16 {
public final static int polynomial = 0x1021; // Represents x^16+x^12+x^5+1
static int crc;
public static int getSlot(String key) {
crc = 0x0000;
for (byte b : key.getBytes()) {
for (int i = 0; i < 8; i++) {
boolean bit = ((b >> (7 - i) & 1) == 1);
boolean c15 = ((crc >> 15 & 1) == 1);
crc <<= 1;
// If coefficient of bit and remainder polynomial = 1 xor crc
// with polynomial
if (c15 ^ bit)
crc ^= polynomial;
}
}
return crc &= 0xffff % 16384;
}
}

View File

@@ -1,26 +1,29 @@
package redis.clients.util; package redis.clients.util;
import org.apache.commons.pool.PoolableObjectFactory; import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool; import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisException; import redis.clients.jedis.exceptions.JedisException;
public abstract class Pool<T> { public abstract class Pool<T> {
protected GenericObjectPool internalPool; protected GenericObjectPool<T> internalPool;
/** /**
* Using this constructor means you have to set * Using this constructor means you have to set and initialize the
* and initialize the internalPool yourself. * internalPool yourself.
*/ */
public Pool() {} public Pool() {
}
public Pool(final GenericObjectPool.Config poolConfig, public Pool(final GenericObjectPoolConfig poolConfig,
PoolableObjectFactory factory) { PooledObjectFactory<T> factory) {
initPool(poolConfig, factory); initPool(poolConfig, factory);
} }
public void initPool(final GenericObjectPool.Config poolConfig, PoolableObjectFactory factory) { public void initPool(final GenericObjectPoolConfig poolConfig,
PooledObjectFactory<T> factory) {
if (this.internalPool != null) { if (this.internalPool != null) {
try { try {
@@ -29,20 +32,19 @@ public abstract class Pool<T> {
} }
} }
this.internalPool = new GenericObjectPool(factory, poolConfig); this.internalPool = new GenericObjectPool<T>(factory, poolConfig);
} }
@SuppressWarnings("unchecked")
public T getResource() { public T getResource() {
try { try {
return (T) internalPool.borrowObject(); return internalPool.borrowObject();
} catch (Exception e) { } catch (Exception e) {
throw new JedisConnectionException( throw new JedisConnectionException(
"Could not get a resource from the pool", e); "Could not get a resource from the pool", e);
} }
} }
public void returnResourceObject(final Object resource) { public void returnResourceObject(final T resource) {
try { try {
internalPool.returnObject(resource); internalPool.returnObject(resource);
} catch (Exception e) { } catch (Exception e) {
@@ -63,7 +65,7 @@ public abstract class Pool<T> {
closeInternalPool(); closeInternalPool();
} }
protected void returnBrokenResourceObject(final Object resource) { protected void returnBrokenResourceObject(final T resource) {
try { try {
internalPool.invalidateObject(resource); internalPool.invalidateObject(resource);
} catch (Exception e) { } catch (Exception e) {

View File

@@ -1,11 +1,13 @@
package redis.clients.util; package redis.clients.util;
import java.io.*; import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/** /**
* The class implements a buffered output stream without synchronization * The class implements a buffered output stream without synchronization There
* There are also special operations like in-place string encoding. * are also special operations like in-place string encoding. This stream fully
* This stream fully ignore mark/reset and should not be used outside Jedis * ignore mark/reset and should not be used outside Jedis
*/ */
public final class RedisOutputStream extends FilterOutputStream { public final class RedisOutputStream extends FilterOutputStream {
protected final byte buf[]; protected final byte buf[];
@@ -42,7 +44,8 @@ public final class RedisOutputStream extends FilterOutputStream {
write(b, 0, b.length); write(b, 0, b.length);
} }
public void write(final byte b[], final int off, final int len) throws IOException { public void write(final byte b[], final int off, final int len)
throws IOException {
if (len >= buf.length) { if (len >= buf.length) {
flushBuffer(); flushBuffer();
out.write(b, off, len); out.write(b, off, len);
@@ -106,7 +109,8 @@ public final class RedisOutputStream extends FilterOutputStream {
int i; int i;
for (i = 0; i < strLen; i++) { for (i = 0; i < strLen; i++) {
char c = str.charAt(i); char c = str.charAt(i);
if (!(c < 0x80)) break; if (!(c < 0x80))
break;
buf[count++] = (byte) c; buf[count++] = (byte) c;
if (count == buf.length) { if (count == buf.length) {
flushBuffer(); flushBuffer();
@@ -148,46 +152,37 @@ public final class RedisOutputStream extends FilterOutputStream {
writeCrLf(); writeCrLf();
} }
private final static int[] sizeTable = {9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE}; private final static int[] sizeTable = { 9, 99, 999, 9999, 99999, 999999,
9999999, 99999999, 999999999, Integer.MAX_VALUE };
private final static byte[] DigitTens = { private final static byte[] DigitTens = { '0', '0', '0', '0', '0', '0',
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1',
'1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', '3',
'2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', '3', '3', '3', '3', '3', '3', '3', '4', '4', '4', '4', '4',
'3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '5', '5', '5',
'4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '5', '5', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '7',
'5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '7', '7', '7', '7', '7', '7', '7', '7', '7', '8', '8', '8', '8',
'6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '8', '8', '8', '8', '8', '8', '9', '9', '9', '9', '9', '9', '9',
'7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '9', '9', '9', };
'8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
'9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
};
private final static byte[] DigitOnes = { private final static byte[] DigitOnes = { '0', '1', '2', '3', '4', '5',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '7', '8', '9', };
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
};
private final static byte[] digits = { private final static byte[] digits = { '0', '1', '2', '3', '4', '5', '6',
'0', '1', '2', '3', '4', '5', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'6', '7', '8', '9', 'a', 'b', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'c', 'd', 'e', 'f', 'g', 'h', 'x', 'y', 'z' };
'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z'
};
public void writeIntCrLf(int value) throws IOException { public void writeIntCrLf(int value) throws IOException {
if (value < 0) { if (value < 0) {
write('-'); write((byte) '-');
value = -value; value = -value;
} }
@@ -216,7 +211,8 @@ public final class RedisOutputStream extends FilterOutputStream {
r = value - ((q << 3) + (q << 1)); r = value - ((q << 3) + (q << 1));
buf[--charPos] = digits[r]; buf[--charPos] = digits[r];
value = q; value = q;
if (value == 0) break; if (value == 0)
break;
} }
count += size; count += size;

View File

@@ -57,11 +57,14 @@ public class Sharded<R, S extends ShardInfo<R>> {
final S shardInfo = shards.get(i); final S shardInfo = shards.get(i);
if (shardInfo.getName() == null) if (shardInfo.getName() == null)
for (int n = 0; n < 160 * shardInfo.getWeight(); n++) { for (int n = 0; n < 160 * shardInfo.getWeight(); n++) {
nodes.put(this.algo.hash("SHARD-" + i + "-NODE-" + n), shardInfo); nodes.put(this.algo.hash("SHARD-" + i + "-NODE-" + n),
shardInfo);
} }
else else
for (int n = 0; n < 160 * shardInfo.getWeight(); n++) { for (int n = 0; n < 160 * shardInfo.getWeight(); n++) {
nodes.put(this.algo.hash(shardInfo.getName() + "*" + shardInfo.getWeight() + n), shardInfo); nodes.put(
this.algo.hash(shardInfo.getName() + "*"
+ shardInfo.getWeight() + n), shardInfo);
} }
resources.put(shardInfo, shardInfo.createResource()); resources.put(shardInfo, shardInfo.createResource());
} }
@@ -113,4 +116,3 @@ public class Sharded<R, S extends ShardInfo<R>> {
return Collections.unmodifiableCollection(resources.values()); return Collections.unmodifiableCollection(resources.values());
} }
} }

View File

@@ -3,62 +3,69 @@ package redis.clients.jedis.tests;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Protocol; import redis.clients.jedis.Protocol;
public class HostAndPortUtil { public class HostAndPortUtil {
private static List<HostAndPort> redisHostAndPortList = new ArrayList<HostAndPortUtil.HostAndPort>(); private static List<HostAndPort> redisHostAndPortList = new ArrayList<HostAndPort>();
private static List<HostAndPort> sentinelHostAndPortList = new ArrayList<HostAndPortUtil.HostAndPort>(); private static List<HostAndPort> sentinelHostAndPortList = new ArrayList<HostAndPort>();
private static List<HostAndPort> clusterHostAndPortList = new ArrayList<HostAndPort>();
static { static {
HostAndPort defaulthnp1 = new HostAndPort(); HostAndPort defaulthnp1 = new HostAndPort("localhost",
defaulthnp1.host = "localhost"; Protocol.DEFAULT_PORT);
defaulthnp1.port = Protocol.DEFAULT_PORT;
redisHostAndPortList.add(defaulthnp1); redisHostAndPortList.add(defaulthnp1);
HostAndPort defaulthnp2 = new HostAndPort(); HostAndPort defaulthnp2 = new HostAndPort("localhost",
defaulthnp2.host = "localhost"; Protocol.DEFAULT_PORT + 1);
defaulthnp2.port = Protocol.DEFAULT_PORT + 1;
redisHostAndPortList.add(defaulthnp2); redisHostAndPortList.add(defaulthnp2);
HostAndPort defaulthnp3 = new HostAndPort(); HostAndPort defaulthnp3 = new HostAndPort("localhost",
defaulthnp3.host = "localhost"; Protocol.DEFAULT_PORT + 2);
defaulthnp3.port = Protocol.DEFAULT_PORT + 2;
redisHostAndPortList.add(defaulthnp3); redisHostAndPortList.add(defaulthnp3);
HostAndPort defaulthnp4 = new HostAndPort(); HostAndPort defaulthnp4 = new HostAndPort("localhost",
defaulthnp4.host = "localhost"; Protocol.DEFAULT_PORT + 3);
defaulthnp4.port = Protocol.DEFAULT_PORT + 3;
redisHostAndPortList.add(defaulthnp4); redisHostAndPortList.add(defaulthnp4);
HostAndPort defaulthnp5 = new HostAndPort(); HostAndPort defaulthnp5 = new HostAndPort("localhost",
defaulthnp5.host = "localhost"; Protocol.DEFAULT_PORT + 4);
defaulthnp5.port = Protocol.DEFAULT_PORT + 4;
redisHostAndPortList.add(defaulthnp5); redisHostAndPortList.add(defaulthnp5);
HostAndPort defaulthnp6 = new HostAndPort(); HostAndPort defaulthnp6 = new HostAndPort("localhost",
defaulthnp6.host = "localhost"; Protocol.DEFAULT_PORT + 5);
defaulthnp6.port = Protocol.DEFAULT_SENTINEL_PORT; redisHostAndPortList.add(defaulthnp6);
sentinelHostAndPortList.add(defaulthnp6);
HostAndPort defaulthnp7 = new HostAndPort(); HostAndPort defaulthnp7 = new HostAndPort("localhost",
defaulthnp7.host = "localhost"; Protocol.DEFAULT_SENTINEL_PORT);
defaulthnp7.port = Protocol.DEFAULT_SENTINEL_PORT + 1;
sentinelHostAndPortList.add(defaulthnp7); sentinelHostAndPortList.add(defaulthnp7);
HostAndPort defaulthnp8 = new HostAndPort(); HostAndPort defaulthnp8 = new HostAndPort("localhost",
defaulthnp8.host = "localhost"; Protocol.DEFAULT_SENTINEL_PORT + 1);
defaulthnp8.port = Protocol.DEFAULT_SENTINEL_PORT + 2;
sentinelHostAndPortList.add(defaulthnp8); sentinelHostAndPortList.add(defaulthnp8);
HostAndPort defaulthnp9 = new HostAndPort("localhost",
Protocol.DEFAULT_SENTINEL_PORT + 2);
sentinelHostAndPortList.add(defaulthnp9);
clusterHostAndPortList.add(new HostAndPort("localhost", 7379));
clusterHostAndPortList.add(new HostAndPort("localhost", 7380));
clusterHostAndPortList.add(new HostAndPort("localhost", 7381));
String envRedisHosts = System.getProperty("redis-hosts"); String envRedisHosts = System.getProperty("redis-hosts");
String envSentinelHosts = System.getProperty("sentinel-hosts"); String envSentinelHosts = System.getProperty("sentinel-hosts");
String envClusterHosts = System.getProperty("cluster-hosts");
redisHostAndPortList = parseHosts(envRedisHosts, redisHostAndPortList); redisHostAndPortList = parseHosts(envRedisHosts, redisHostAndPortList);
sentinelHostAndPortList = parseHosts(envSentinelHosts, sentinelHostAndPortList); sentinelHostAndPortList = parseHosts(envSentinelHosts,
sentinelHostAndPortList);
clusterHostAndPortList = parseHosts(envClusterHosts,
clusterHostAndPortList);
} }
public static List<HostAndPort> parseHosts(String envHosts, List<HostAndPort> existingHostsAndPorts) { public static List<HostAndPort> parseHosts(String envHosts,
List<HostAndPort> existingHostsAndPorts) {
if (null != envHosts && 0 < envHosts.length()) { if (null != envHosts && 0 < envHosts.length()) {
@@ -66,24 +73,23 @@ public class HostAndPortUtil {
if (null != hostDefs && 2 <= hostDefs.length) { if (null != hostDefs && 2 <= hostDefs.length) {
List<HostAndPort> envHostsAndPorts = new ArrayList<HostAndPortUtil.HostAndPort>(hostDefs.length); List<HostAndPort> envHostsAndPorts = new ArrayList<HostAndPort>(
hostDefs.length);
for (String hostDef : hostDefs) { for (String hostDef : hostDefs) {
String[] hostAndPort = hostDef.split(":"); String[] hostAndPort = hostDef.split(":");
if (null != hostAndPort && 2 == hostAndPort.length) { if (null != hostAndPort && 2 == hostAndPort.length) {
String host = hostAndPort[0];
HostAndPort hnp = new HostAndPort(); int port = Protocol.DEFAULT_PORT;
hnp.host = hostAndPort[0];
try { try {
hnp.port = Integer.parseInt(hostAndPort[1]); port = Integer.parseInt(hostAndPort[1]);
} catch (final NumberFormatException nfe) { } catch (final NumberFormatException nfe) {
hnp.port = Protocol.DEFAULT_PORT;
} }
envHostsAndPorts.add(hnp); envHostsAndPorts.add(new HostAndPort(host, port));
} }
} }
@@ -102,13 +108,7 @@ public class HostAndPortUtil {
return sentinelHostAndPortList; return sentinelHostAndPortList;
} }
public static class HostAndPort { public static List<HostAndPort> getClusterServers() {
public String host; return clusterHostAndPortList;
public int port;
@Override
public String toString() {
return host + ":" + port;
}
} }
} }

View File

@@ -0,0 +1,195 @@
package redis.clients.jedis.tests;
import java.util.HashSet;
import java.util.Set;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.exceptions.JedisAskDataException;
import redis.clients.jedis.exceptions.JedisClusterException;
import redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException;
import redis.clients.jedis.exceptions.JedisMovedDataException;
import redis.clients.util.JedisClusterCRC16;
public class JedisClusterTest extends Assert {
private Jedis node1;
private Jedis node2;
private Jedis node3;
private HostAndPort nodeInfo1 = HostAndPortUtil.getClusterServers().get(0);
private HostAndPort nodeInfo2 = HostAndPortUtil.getClusterServers().get(1);
private HostAndPort nodeInfo3 = HostAndPortUtil.getClusterServers().get(2);
@Before
public void setUp() throws InterruptedException {
node1 = new Jedis(nodeInfo1.getHost(), nodeInfo1.getPort());
node1.connect();
node1.flushAll();
node2 = new Jedis(nodeInfo2.getHost(), nodeInfo2.getPort());
node2.connect();
node2.flushAll();
node3 = new Jedis(nodeInfo3.getHost(), nodeInfo3.getPort());
node3.connect();
node3.flushAll();
// ---- configure cluster
// add nodes to cluster
node1.clusterMeet("127.0.0.1", nodeInfo2.getPort());
node1.clusterMeet("127.0.0.1", nodeInfo3.getPort());
// split available slots across the three nodes
int slotsPerNode = JedisCluster.HASHSLOTS / 3;
Pipeline pipeline1 = node1.pipelined();
Pipeline pipeline2 = node2.pipelined();
Pipeline pipeline3 = node3.pipelined();
for (int i = 0; i < JedisCluster.HASHSLOTS; i++) {
if (i < slotsPerNode) {
pipeline1.clusterAddSlots(i);
} else if (i > slotsPerNode * 2) {
pipeline3.clusterAddSlots(i);
} else {
pipeline2.clusterAddSlots(i);
}
}
pipeline1.sync();
pipeline2.sync();
pipeline3.sync();
waitForClusterReady();
}
@After
public void tearDown() {
// clear all slots
int[] slotsToDelete = new int[JedisCluster.HASHSLOTS];
for (int i = 0; i < JedisCluster.HASHSLOTS; i++) {
slotsToDelete[i] = i;
}
node1.clusterDelSlots(slotsToDelete);
node2.clusterDelSlots(slotsToDelete);
node3.clusterDelSlots(slotsToDelete);
}
@Test(expected = JedisMovedDataException.class)
public void testThrowMovedException() {
node1.set("foo", "bar");
}
@Test
public void testMovedExceptionParameters() {
try {
node1.set("foo", "bar");
} catch (JedisMovedDataException jme) {
assertEquals(12182, jme.getSlot());
assertEquals(new HostAndPort("127.0.0.1", 7381),
jme.getTargetNode());
return;
}
fail();
}
@Test(expected = JedisAskDataException.class)
public void testThrowAskException() {
int keySlot = JedisClusterCRC16.getSlot("test");
String node3Id = getNodeId(node3.clusterNodes());
node2.clusterSetSlotMigrating(keySlot, node3Id);
node2.get("test");
}
@Test
public void testDiscoverNodesAutomatically() {
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
JedisCluster jc = new JedisCluster(jedisClusterNode);
assertEquals(jc.getClusterNodes().size(), 3);
}
@Test
public void testCalculateConnectionPerSlot() {
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
JedisCluster jc = new JedisCluster(jedisClusterNode);
jc.set("foo", "bar");
jc.set("test", "test");
assertEquals("bar", node3.get("foo"));
assertEquals("test", node2.get("test"));
}
@Test
public void testRecalculateSlotsWhenMoved() throws InterruptedException {
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
JedisCluster jc = new JedisCluster(jedisClusterNode);
int slot51 = JedisClusterCRC16.getSlot("51");
node2.clusterDelSlots(slot51);
node3.clusterDelSlots(slot51);
node3.clusterAddSlots(slot51);
waitForClusterReady();
jc.set("51", "foo");
assertEquals("foo", jc.get("51"));
}
@Test
public void testAskResponse() throws InterruptedException {
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
JedisCluster jc = new JedisCluster(jedisClusterNode);
int slot51 = JedisClusterCRC16.getSlot("51");
node3.clusterSetSlotImporting(slot51, getNodeId(node2.clusterNodes()));
node2.clusterSetSlotMigrating(slot51, getNodeId(node3.clusterNodes()));
jc.set("51", "foo");
assertEquals("foo", jc.get("51"));
}
@Test(expected = JedisClusterException.class)
public void testThrowExceptionWithoutKey() {
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
JedisCluster jc = new JedisCluster(jedisClusterNode);
jc.ping();
}
@Test(expected = JedisClusterMaxRedirectionsException.class)
public void testRedisClusterMaxRedirections() {
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
JedisCluster jc = new JedisCluster(jedisClusterNode);
int slot51 = JedisClusterCRC16.getSlot("51");
// This will cause an infinite redirection loop
node2.clusterSetSlotMigrating(slot51, getNodeId(node3.clusterNodes()));
jc.set("51", "foo");
}
private String getNodeId(String infoOutput) {
for (String infoLine : infoOutput.split("\n")) {
if (infoLine.contains("myself")) {
return infoLine.split(" ")[0];
}
}
return "";
}
private void waitForClusterReady() throws InterruptedException {
boolean clusterOk = false;
while (!clusterOk) {
if (node1.clusterInfo().split("\n")[0].contains("ok")
&& node2.clusterInfo().split("\n")[0].contains("ok")
&& node3.clusterInfo().split("\n")[0].contains("ok")) {
clusterOk = true;
}
Thread.sleep(50);
}
}
}

View File

@@ -3,25 +3,24 @@ package redis.clients.jedis.tests;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import org.apache.commons.pool.impl.GenericObjectPool; import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.apache.commons.pool.impl.GenericObjectPool.Config;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import redis.clients.jedis.BinaryJedis; import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
public class JedisPoolTest extends Assert { public class JedisPoolTest extends Assert {
private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0); private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0);
@Test @Test
public void checkConnections() { public void checkConnections() {
JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.host, JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
hnp.port, 2000); hnp.getPort(), 2000);
Jedis jedis = pool.getResource(); Jedis jedis = pool.getResource();
jedis.auth("foobared"); jedis.auth("foobared");
jedis.set("foo", "bar"); jedis.set("foo", "bar");
@@ -32,8 +31,8 @@ public class JedisPoolTest extends Assert {
@Test @Test
public void checkConnectionWithDefaultPort() { public void checkConnectionWithDefaultPort() {
JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.host, JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
hnp.port); hnp.getPort());
Jedis jedis = pool.getResource(); Jedis jedis = pool.getResource();
jedis.auth("foobared"); jedis.auth("foobared");
jedis.set("foo", "bar"); jedis.set("foo", "bar");
@@ -44,8 +43,9 @@ public class JedisPoolTest extends Assert {
@Test @Test
public void checkJedisIsReusedWhenReturned() { public void checkJedisIsReusedWhenReturned() {
JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.host,
hnp.port); JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
hnp.getPort());
Jedis jedis = pool.getResource(); Jedis jedis = pool.getResource();
jedis.auth("foobared"); jedis.auth("foobared");
jedis.set("foo", "0"); jedis.set("foo", "0");
@@ -60,8 +60,8 @@ public class JedisPoolTest extends Assert {
@Test @Test
public void checkPoolRepairedWhenJedisIsBroken() { public void checkPoolRepairedWhenJedisIsBroken() {
JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.host, JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
hnp.port); hnp.getPort());
Jedis jedis = pool.getResource(); Jedis jedis = pool.getResource();
jedis.auth("foobared"); jedis.auth("foobared");
jedis.quit(); jedis.quit();
@@ -76,10 +76,10 @@ public class JedisPoolTest extends Assert {
@Test(expected = JedisConnectionException.class) @Test(expected = JedisConnectionException.class)
public void checkPoolOverflow() { public void checkPoolOverflow() {
Config config = new Config(); GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.maxActive = 1; config.setMaxTotal(1);
config.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_FAIL; config.setBlockWhenExhausted(false);
JedisPool pool = new JedisPool(config, hnp.host, hnp.port); JedisPool pool = new JedisPool(config, hnp.getHost(), hnp.getPort());
Jedis jedis = pool.getResource(); Jedis jedis = pool.getResource();
jedis.auth("foobared"); jedis.auth("foobared");
jedis.set("foo", "0"); jedis.set("foo", "0");
@@ -93,7 +93,8 @@ public class JedisPoolTest extends Assert {
public void securePool() { public void securePool() {
JedisPoolConfig config = new JedisPoolConfig(); JedisPoolConfig config = new JedisPoolConfig();
config.setTestOnBorrow(true); config.setTestOnBorrow(true);
JedisPool pool = new JedisPool(config, hnp.host, hnp.port, 2000, "foobared"); JedisPool pool = new JedisPool(config, hnp.getHost(), hnp.getPort(),
2000, "foobared");
Jedis jedis = pool.getResource(); Jedis jedis = pool.getResource();
jedis.set("foo", "bar"); jedis.set("foo", "bar");
pool.returnResource(jedis); pool.returnResource(jedis);
@@ -102,31 +103,22 @@ public class JedisPoolTest extends Assert {
@Test @Test
public void nonDefaultDatabase() { public void nonDefaultDatabase() {
JedisPool pool0 = new JedisPool(new JedisPoolConfig(), hnp.host, JedisPool pool0 = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
hnp.port, 2000, "foobared"); hnp.getPort(), 2000, "foobared");
Jedis jedis0 = pool0.getResource(); Jedis jedis0 = pool0.getResource();
jedis0.set("foo", "bar"); jedis0.set("foo", "bar");
assertEquals("bar", jedis0.get("foo")); assertEquals("bar", jedis0.get("foo"));
pool0.returnResource(jedis0); pool0.returnResource(jedis0);
pool0.destroy(); pool0.destroy();
JedisPool pool1 = new JedisPool(new JedisPoolConfig(), hnp.host, JedisPool pool1 = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
hnp.port, 2000, "foobared", 1); hnp.getPort(), 2000, "foobared", 1);
Jedis jedis1 = pool1.getResource(); Jedis jedis1 = pool1.getResource();
assertNull(jedis1.get("foo")); assertNull(jedis1.get("foo"));
pool1.returnResource(jedis0); pool1.returnResource(jedis1);
pool1.destroy(); pool1.destroy();
} }
@Test
public void returnBinary() {
JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.host,
hnp.port, 2000);
BinaryJedis jedis = pool.getResource();
pool.returnResource(jedis);
pool.destroy();
}
@Test @Test
public void startWithUrlString() { public void startWithUrlString() {
Jedis j = new Jedis("localhost", 6380); Jedis j = new Jedis("localhost", 6380);
@@ -145,7 +137,8 @@ public class JedisPoolTest extends Assert {
j.auth("foobared"); j.auth("foobared");
j.select(2); j.select(2);
j.set("foo", "bar"); j.set("foo", "bar");
JedisPool pool = new JedisPool(new URI("redis://:foobared@localhost:6380/2")); JedisPool pool = new JedisPool(new URI(
"redis://:foobared@localhost:6380/2"));
Jedis jedis = pool.getResource(); Jedis jedis = pool.getResource();
assertEquals("PONG", jedis.ping()); assertEquals("PONG", jedis.ping());
assertEquals("bar", jedis.get("foo")); assertEquals("bar", jedis.get("foo"));
@@ -153,7 +146,8 @@ public class JedisPoolTest extends Assert {
@Test @Test
public void selectDatabaseOnActivation() { public void selectDatabaseOnActivation() {
JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.host, hnp.port, 2000, "foobared"); JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
hnp.getPort(), 2000, "foobared");
Jedis jedis0 = pool.getResource(); Jedis jedis0 = pool.getResource();
assertEquals(0L, jedis0.getDB().longValue()); assertEquals(0L, jedis0.getDB().longValue());
@@ -173,8 +167,8 @@ public class JedisPoolTest extends Assert {
@Test @Test
public void customClientName() { public void customClientName() {
JedisPool pool0 = new JedisPool(new JedisPoolConfig(), hnp.host, JedisPool pool0 = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
hnp.port, 2000, "foobared", 0, "my_shiny_client_name"); hnp.getPort(), 2000, "foobared", 0, "my_shiny_client_name");
Jedis jedis = pool0.getResource(); Jedis jedis = pool0.getResource();
@@ -183,5 +177,25 @@ public class JedisPoolTest extends Assert {
pool0.returnResource(jedis); pool0.returnResource(jedis);
pool0.destroy(); pool0.destroy();
} }
}
@Test
public void returnResourceShouldResetState() {
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMaxTotal(1);
config.setBlockWhenExhausted(false);
JedisPool pool = new JedisPool(config, hnp.getHost(), hnp.getPort(),
2000, "foobared");
Jedis jedis = pool.getResource();
jedis.set("hello", "jedis");
Transaction t = jedis.multi();
t.set("hello", "world");
pool.returnResource(jedis);
Jedis jedis2 = pool.getResource();
assertTrue(jedis == jedis2);
assertEquals("jedis", jedis2.get("hello"));
pool.returnResource(jedis2);
pool.destroy();
}
}

View File

@@ -2,17 +2,21 @@ package redis.clients.jedis.tests;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.pool.impl.GenericObjectPool.Config; import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import redis.clients.jedis.DebugParams; import redis.clients.jedis.DebugParams;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;
import redis.clients.jedis.JedisSentinelPool; import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort; import redis.clients.jedis.Transaction;
public class JedisSentinelPoolTest extends JedisTestBase { public class JedisSentinelPoolTest extends JedisTestBase {
private static final String MASTER_NAME = "mymaster";
protected static HostAndPort master = HostAndPortUtil.getRedisServers() protected static HostAndPort master = HostAndPortUtil.getRedisServers()
.get(2); .get(2);
@@ -25,45 +29,22 @@ public class JedisSentinelPoolTest extends JedisTestBase {
protected static HostAndPort sentinel2 = HostAndPortUtil protected static HostAndPort sentinel2 = HostAndPortUtil
.getSentinelServers().get(2); .getSentinelServers().get(2);
protected static Jedis masterJedis; protected static Jedis sentinelJedis1;
protected static Jedis slaveJedis1;
protected static Jedis slaveJedis2;
protected static int slaveCount = 0;
protected Set<String> sentinels = new HashSet<String>(); protected Set<String> sentinels = new HashSet<String>();
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
// set up master and slaves
masterJedis = new Jedis(master.host, master.port);
masterJedis.auth("foobared");
masterJedis.slaveofNoOne();
slaveJedis1 = new Jedis(slave1.host, slave1.port);
slaveJedis1.auth("foobared");
slaveJedis1.slaveof(master.host, master.port);
slaveCount++;
slaveJedis2 = new Jedis(slave2.host, slave2.port);
slaveJedis2.auth("foobared");
slaveJedis2.slaveof(master.host, master.port);
slaveCount++;
sentinels.add(sentinel1.toString()); sentinels.add(sentinel1.toString());
sentinels.add(sentinel2.toString()); sentinels.add(sentinel2.toString());
// FIXME: The following allows the master/slave relationship to sentinelJedis1 = new Jedis(sentinel1.getHost(), sentinel1.getPort());
// be established, and let sentinels know about this relationship.
// We can do this more elegantly.
Thread.sleep(10000);
} }
@Test @Test
public void ensureSafeTwiceFailover() throws InterruptedException { public void ensureSafeTwiceFailover() throws InterruptedException {
JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels, JedisSentinelPool pool = new JedisSentinelPool(MASTER_NAME, sentinels,
new Config(), 1000, "foobared", 2); new GenericObjectPoolConfig(), 1000, "foobared", 2);
// perform failover // perform failover
doSegFaultMaster(pool); doSegFaultMaster(pool);
@@ -75,7 +56,10 @@ public class JedisSentinelPoolTest extends JedisTestBase {
// but you need to prepare additional slave per failover // but you need to prepare additional slave per failover
} }
private void doSegFaultMaster(JedisSentinelPool pool) throws InterruptedException { private void doSegFaultMaster(JedisSentinelPool pool)
throws InterruptedException {
HostAndPort oldMaster = pool.getCurrentHostMaster();
// jedis connection should be master // jedis connection should be master
Jedis jedis = pool.getResource(); Jedis jedis = pool.getResource();
assertEquals("PONG", jedis.ping()); assertEquals("PONG", jedis.ping());
@@ -85,14 +69,106 @@ public class JedisSentinelPoolTest extends JedisTestBase {
} catch (Exception e) { } catch (Exception e) {
} }
// wait for the sentinel to promote a master waitForFailover(pool, oldMaster);
// FIXME: we can query the sentinel and sleep Thread.sleep(100);
// right until the master is promoted
Thread.sleep(35000);
jedis = pool.getResource(); jedis = pool.getResource();
assertEquals("PONG", jedis.ping()); assertEquals("PONG", jedis.ping());
assertEquals("foobared", jedis.configGet("requirepass").get(1)); assertEquals("foobared", jedis.configGet("requirepass").get(1));
assertEquals(2, jedis.getDB().intValue()); assertEquals(2, jedis.getDB().intValue());
} }
private void waitForFailover(JedisSentinelPool pool, HostAndPort oldMaster)
throws InterruptedException {
waitForJedisSentinelPoolRecognizeNewMaster(pool);
}
private void waitForJedisSentinelPoolRecognizeNewMaster(
JedisSentinelPool pool) throws InterruptedException {
final AtomicReference<String> newmaster = new AtomicReference<String>(
"");
sentinelJedis1.psubscribe(new JedisPubSub() {
@Override
public void onMessage(String channel, String message) {
// TODO Auto-generated method stub
}
@Override
public void onPMessage(String pattern, String channel,
String message) {
if (channel.equals("+switch-master")) {
newmaster.set(message);
punsubscribe();
}
// TODO Auto-generated method stub
}
@Override
public void onSubscribe(String channel, int subscribedChannels) {
// TODO Auto-generated method stub
}
@Override
public void onUnsubscribe(String channel, int subscribedChannels) {
// TODO Auto-generated method stub
}
@Override
public void onPUnsubscribe(String pattern, int subscribedChannels) {
// TODO Auto-generated method stub
}
@Override
public void onPSubscribe(String pattern, int subscribedChannels) {
// TODO Auto-generated method stub
}
}, "*");
String[] chunks = newmaster.get().split(" ");
HostAndPort newMaster = new HostAndPort(chunks[3],
Integer.parseInt(chunks[4]));
while (true) {
String host = pool.getCurrentHostMaster().getHost();
int port = pool.getCurrentHostMaster().getPort();
if (host.equals(newMaster.getHost()) && port == newMaster.getPort())
break;
System.out
.println("JedisSentinelPool's master is not yet changed, sleep...");
Thread.sleep(100);
}
}
@Test
public void returnResourceShouldResetState() {
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMaxTotal(1);
config.setBlockWhenExhausted(false);
JedisSentinelPool pool = new JedisSentinelPool(MASTER_NAME, sentinels,
config, 1000, "foobared", 2);
Jedis jedis = pool.getResource();
jedis.set("hello", "jedis");
Transaction t = jedis.multi();
t.set("hello", "world");
pool.returnResource(jedis);
Jedis jedis2 = pool.getResource();
assertTrue(jedis == jedis2);
assertEquals("jedis", jedis2.get("hello"));
pool.returnResource(jedis2);
pool.destroy();
}
} }

View File

@@ -1,9 +1,5 @@
package redis.clients.jedis.tests; package redis.clients.jedis.tests;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -11,33 +7,40 @@ import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
public class JedisSentinelTest { public class JedisSentinelTest extends JedisTestBase {
private static final String MASTER_NAME = "mymaster"; private static final String MASTER_NAME = "mymaster";
protected static HostAndPort master = HostAndPortUtil.getRedisServers()
.get(0);
protected static HostAndPort slave = HostAndPortUtil.getRedisServers().get(
5);
protected static HostAndPort sentinel = HostAndPortUtil
.getSentinelServers().get(0);
protected static Jedis masterJedis;
protected static Jedis slaveJedis;
protected static Jedis sentinelJedis;
@Before @Before
public void setup() throws InterruptedException { public void setup() throws InterruptedException {
Jedis j = new Jedis("localhost", 6380);
j.auth("foobared");
j.configSet("masterauth", "foobared");
j.slaveof("localhost", 6379);
// TODO: The sleep is to give time to the slave to synchronize with the
// master and also let know the sentinels about this new topology. We
// should find a better way to do this.
Thread.sleep(10000);
} }
@After @After
public void clear() { public void clear() throws InterruptedException {
Jedis j = new Jedis("localhost", 6380); // New Sentinel (after 2.8.1)
j.auth("foobared"); // when slave promoted to master (slave of no one), New Sentinel force
j.slaveofNoOne(); // to restore it (demote)
// so, promote(slaveof) slave to master has no effect, not same to old
// Sentinel's behavior
} }
@Test @Test
public void sentinel() { public void sentinel() {
Jedis j = new Jedis("localhost", 26379); Jedis j = new Jedis(sentinel.getHost(), sentinel.getPort());
List<Map<String, String>> masters = j.sentinelMasters(); List<Map<String, String>> masters = j.sentinelMasters();
final String masterName = masters.get(0).get("name"); final String masterName = masters.get(0).get("name");
@@ -45,25 +48,18 @@ public class JedisSentinelTest {
List<String> masterHostAndPort = j List<String> masterHostAndPort = j
.sentinelGetMasterAddrByName(masterName); .sentinelGetMasterAddrByName(masterName);
assertEquals("127.0.0.1", masterHostAndPort.get(0)); HostAndPort masterFromSentinel = new HostAndPort(
assertEquals("6379", masterHostAndPort.get(1)); masterHostAndPort.get(0), Integer.parseInt(masterHostAndPort
.get(1)));
assertEquals(master, masterFromSentinel);
List<Map<String, String>> slaves = j.sentinelSlaves(masterName); List<Map<String, String>> slaves = j.sentinelSlaves(masterName);
assertTrue(slaves.size() > 0); assertTrue(slaves.size() > 0);
assertEquals("6379", slaves.get(0).get("master-port")); assertEquals(master.getPort(),
Integer.parseInt(slaves.get(0).get("master-port")));
List<? extends Object> isMasterDownByAddr = j
.sentinelIsMasterDownByAddr("127.0.0.1", 6379);
assertEquals(Long.valueOf(0), (Long) isMasterDownByAddr.get(0));
assertFalse("?".equals(isMasterDownByAddr.get(1)));
isMasterDownByAddr = j.sentinelIsMasterDownByAddr("127.0.0.1", 1);
assertEquals(Long.valueOf(0), (Long) isMasterDownByAddr.get(0));
assertTrue("?".equals(isMasterDownByAddr.get(1)));
// DO NOT RE-RUN TEST TOO FAST, RESET TAKES SOME TIME TO... RESET // DO NOT RE-RUN TEST TOO FAST, RESET TAKES SOME TIME TO... RESET
assertEquals(Long.valueOf(1), j.sentinelReset(masterName)); assertEquals(Long.valueOf(1), j.sentinelReset(masterName));
assertEquals(Long.valueOf(0), j.sentinelReset("woof" + masterName)); assertEquals(Long.valueOf(0), j.sentinelReset("woof" + masterName));
} }
} }

View File

@@ -52,9 +52,7 @@ public class JedisTest extends JedisCommandTestBase {
jedis = new Jedis("localhost", 6379, 15000); jedis = new Jedis("localhost", 6379, 15000);
jedis.auth("foobared"); jedis.auth("foobared");
jedis.configSet("timeout", "1"); jedis.configSet("timeout", "1");
// we need to sleep a long time since redis check for idle connections Thread.sleep(2000);
// every 10 seconds or so
Thread.sleep(20000);
jedis.hmget("foobar", "foo"); jedis.hmget("foobar", "foo");
} }

View File

@@ -1,14 +1,24 @@
package redis.clients.jedis.tests; package redis.clients.jedis.tests;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import redis.clients.jedis.*;
import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
import java.io.UnsupportedEncodingException; import redis.clients.jedis.HostAndPort;
import java.util.*; import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.PipelineBlock;
import redis.clients.jedis.Response;
import redis.clients.jedis.Tuple;
import redis.clients.jedis.exceptions.JedisDataException;
public class PipeliningTest extends Assert { public class PipeliningTest extends Assert {
private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0); private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0);
@@ -17,7 +27,7 @@ public class PipeliningTest extends Assert {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
jedis = new Jedis(hnp.host, hnp.port, 500); jedis = new Jedis(hnp.getHost(), hnp.getPort(), 500);
jedis.connect(); jedis.connect();
jedis.auth("foobared"); jedis.auth("foobared");
jedis.flushAll(); jedis.flushAll();
@@ -106,14 +116,18 @@ public class PipeliningTest extends Assert {
Pipeline p = jedis.pipelined(); Pipeline p = jedis.pipelined();
Response<Map<byte[], byte[]>> fmap = p.hgetAll("key".getBytes()); Response<Map<byte[], byte[]>> fmap = p.hgetAll("key".getBytes());
Response<Set<byte[]>> fkeys = p.hkeys("key".getBytes()); Response<Set<byte[]>> fkeys = p.hkeys("key".getBytes());
Response<List<byte[]>> fordered = p.hmget("key".getBytes(), "f22".getBytes(), "f1".getBytes()); Response<List<byte[]>> fordered = p.hmget("key".getBytes(),
"f22".getBytes(), "f1".getBytes());
Response<List<byte[]>> fvals = p.hvals("key".getBytes()); Response<List<byte[]>> fvals = p.hvals("key".getBytes());
p.sync(); p.sync();
assertNotNull(fmap.get()); assertNotNull(fmap.get());
// we have to do these strange contortions because byte[] is not a very good key // we have to do these strange contortions because byte[] is not a very
// for a java Map. It only works with equality (you need the exact key object to retrieve // good key
// the value) I recommend we switch to using ByteBuffer or something similar: // for a java Map. It only works with equality (you need the exact key
// object to retrieve
// the value) I recommend we switch to using ByteBuffer or something
// similar:
// http://stackoverflow.com/questions/1058149/using-a-byte-array-as-hashmap-key-java // http://stackoverflow.com/questions/1058149/using-a-byte-array-as-hashmap-key-java
Map<byte[], byte[]> map = fmap.get(); Map<byte[], byte[]> map = fmap.get();
Set<byte[]> mapKeys = map.keySet(); Set<byte[]> mapKeys = map.keySet();
@@ -121,17 +135,20 @@ public class PipeliningTest extends Assert {
byte[] firstMapKey = iterMap.next(); byte[] firstMapKey = iterMap.next();
byte[] secondMapKey = iterMap.next(); byte[] secondMapKey = iterMap.next();
assertFalse(iterMap.hasNext()); assertFalse(iterMap.hasNext());
verifyHasBothValues(firstMapKey, secondMapKey, "f1".getBytes(), "f22".getBytes()); verifyHasBothValues(firstMapKey, secondMapKey, "f1".getBytes(),
"f22".getBytes());
byte[] firstMapValue = map.get(firstMapKey); byte[] firstMapValue = map.get(firstMapKey);
byte[] secondMapValue = map.get(secondMapKey); byte[] secondMapValue = map.get(secondMapKey);
verifyHasBothValues(firstMapValue, secondMapValue, "v111".getBytes(), "v2222".getBytes()); verifyHasBothValues(firstMapValue, secondMapValue, "v111".getBytes(),
"v2222".getBytes());
assertNotNull(fkeys.get()); assertNotNull(fkeys.get());
Iterator<byte[]> iter = fkeys.get().iterator(); Iterator<byte[]> iter = fkeys.get().iterator();
byte[] firstKey = iter.next(); byte[] firstKey = iter.next();
byte[] secondKey = iter.next(); byte[] secondKey = iter.next();
assertFalse(iter.hasNext()); assertFalse(iter.hasNext());
verifyHasBothValues(firstKey, secondKey, "f1".getBytes(), "f22".getBytes()); verifyHasBothValues(firstKey, secondKey, "f1".getBytes(),
"f22".getBytes());
assertNotNull(fordered.get()); assertNotNull(fordered.get());
assertArrayEquals("v2222".getBytes(), fordered.get().get(0)); assertArrayEquals("v2222".getBytes(), fordered.get().get(0));
@@ -141,13 +158,17 @@ public class PipeliningTest extends Assert {
assertEquals(2, fvals.get().size()); assertEquals(2, fvals.get().size());
byte[] firstValue = fvals.get().get(0); byte[] firstValue = fvals.get().get(0);
byte[] secondValue = fvals.get().get(1); byte[] secondValue = fvals.get().get(1);
verifyHasBothValues(firstValue, secondValue, "v111".getBytes(), "v2222".getBytes()); verifyHasBothValues(firstValue, secondValue, "v111".getBytes(),
"v2222".getBytes());
} }
private void verifyHasBothValues(byte[] firstKey, byte[] secondKey, byte[] value1, byte[] value2) { private void verifyHasBothValues(byte[] firstKey, byte[] secondKey,
byte[] value1, byte[] value2) {
assertFalse(Arrays.equals(firstKey, secondKey)); assertFalse(Arrays.equals(firstKey, secondKey));
assertTrue(Arrays.equals(firstKey, value1) || Arrays.equals(firstKey, value2)); assertTrue(Arrays.equals(firstKey, value1)
assertTrue(Arrays.equals(secondKey, value1) || Arrays.equals(secondKey, value2)); || Arrays.equals(firstKey, value2));
assertTrue(Arrays.equals(secondKey, value1)
|| Arrays.equals(secondKey, value2));
} }
@Test @Test
@@ -168,7 +189,6 @@ public class PipeliningTest extends Assert {
assertNull(score.get()); assertNull(score.get());
} }
@Test(expected = JedisDataException.class) @Test(expected = JedisDataException.class)
public void pipelineResponseWithinPipeline() { public void pipelineResponseWithinPipeline() {
jedis.set("string", "foo"); jedis.set("string", "foo");
@@ -183,8 +203,8 @@ public class PipeliningTest extends Assert {
public void pipelineWithPubSub() { public void pipelineWithPubSub() {
Pipeline pipelined = jedis.pipelined(); Pipeline pipelined = jedis.pipelined();
Response<Long> p1 = pipelined.publish("foo", "bar"); Response<Long> p1 = pipelined.publish("foo", "bar");
Response<Long> p2 = pipelined.publish("foo".getBytes(), "bar" Response<Long> p2 = pipelined.publish("foo".getBytes(),
.getBytes()); "bar".getBytes());
pipelined.sync(); pipelined.sync();
assertEquals(0, p1.get().longValue()); assertEquals(0, p1.get().longValue());
assertEquals(0, p2.get().longValue()); assertEquals(0, p2.get().longValue());
@@ -274,9 +294,11 @@ public class PipeliningTest extends Assert {
Pipeline p = jedis.pipelined(); Pipeline p = jedis.pipelined();
p.set(key, "0"); p.set(key, "0");
Response<String> result0 = p.eval(script, Arrays.asList(key), Arrays.asList(arg)); Response<String> result0 = p.eval(script, Arrays.asList(key),
Arrays.asList(arg));
p.incr(key); p.incr(key);
Response<String> result1 = p.eval(script, Arrays.asList(key), Arrays.asList(arg)); Response<String> result1 = p.eval(script, Arrays.asList(key),
Arrays.asList(arg));
Response<String> result2 = p.get(key); Response<String> result2 = p.get(key);
p.sync(); p.sync();
@@ -310,9 +332,11 @@ public class PipeliningTest extends Assert {
Pipeline p = jedis.pipelined(); Pipeline p = jedis.pipelined();
p.set(key, "0"); p.set(key, "0");
Response<String> result0 = p.evalsha(sha1, Arrays.asList(key), Arrays.asList(arg)); Response<String> result0 = p.evalsha(sha1, Arrays.asList(key),
Arrays.asList(arg));
p.incr(key); p.incr(key);
Response<String> result1 = p.evalsha(sha1, Arrays.asList(key), Arrays.asList(arg)); Response<String> result1 = p.evalsha(sha1, Arrays.asList(key),
Arrays.asList(arg));
Response<String> result2 = p.get(key); Response<String> result2 = p.get(key);
p.sync(); p.sync();

View File

@@ -1,9 +1,9 @@
package redis.clients.jedis.tests; package redis.clients.jedis.tests;
import static junit.framework.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.ArrayList; import java.util.ArrayList;
@@ -15,6 +15,7 @@ import java.util.UUID;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisShardInfo; import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.Response; import redis.clients.jedis.Response;
@@ -24,32 +25,36 @@ import redis.clients.jedis.Tuple;
import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.exceptions.JedisDataException;
public class ShardedJedisPipelineTest { public class ShardedJedisPipelineTest {
private static HostAndPortUtil.HostAndPort redis1 = HostAndPortUtil
.getRedisServers().get(0); private static HostAndPort redis1 = HostAndPortUtil.getRedisServers()
private static HostAndPortUtil.HostAndPort redis2 = HostAndPortUtil .get(0);
.getRedisServers().get(1); private static HostAndPort redis2 = HostAndPortUtil.getRedisServers()
.get(1);
private ShardedJedis jedis; private ShardedJedis jedis;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
Jedis jedis = new Jedis(redis1.host, redis1.port); Jedis jedis = new Jedis(redis1.getHost(), redis1.getPort());
jedis.auth("foobared"); jedis.auth("foobared");
jedis.flushAll(); jedis.flushAll();
jedis.disconnect(); jedis.disconnect();
jedis = new Jedis(redis2.host, redis2.port); jedis = new Jedis(redis2.getHost(), redis2.getPort());
jedis.auth("foobared"); jedis.auth("foobared");
jedis.flushAll(); jedis.flushAll();
jedis.disconnect(); jedis.disconnect();
JedisShardInfo shardInfo1 = new JedisShardInfo(redis1.host, redis1.port); JedisShardInfo shardInfo1 = new JedisShardInfo(redis1.getHost(),
JedisShardInfo shardInfo2 = new JedisShardInfo(redis2.host, redis2.port); redis1.getPort());
JedisShardInfo shardInfo2 = new JedisShardInfo(redis2.getHost(),
redis2.getPort());
shardInfo1.setPassword("foobared"); shardInfo1.setPassword("foobared");
shardInfo2.setPassword("foobared"); shardInfo2.setPassword("foobared");
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
shards.add(shardInfo1); shards.add(shardInfo1);
shards.add(shardInfo2); shards.add(shardInfo2);
this.jedis = new ShardedJedis(shards); this.jedis = new ShardedJedis(shards);
} }
@Test @Test

View File

@@ -5,18 +5,17 @@ import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.commons.pool.impl.GenericObjectPool; import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.apache.commons.pool.impl.GenericObjectPool.Config;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisShardInfo; import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis; import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool; import redis.clients.jedis.ShardedJedisPool;
import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
public class ShardedJedisPoolTest extends Assert { public class ShardedJedisPoolTest extends Assert {
private static HostAndPort redis1 = HostAndPortUtil.getRedisServers() private static HostAndPort redis1 = HostAndPortUtil.getRedisServers()
@@ -29,8 +28,8 @@ public class ShardedJedisPoolTest extends Assert {
@Before @Before
public void startUp() { public void startUp() {
shards = new ArrayList<JedisShardInfo>(); shards = new ArrayList<JedisShardInfo>();
shards.add(new JedisShardInfo(redis1.host, redis1.port)); shards.add(new JedisShardInfo(redis1.getHost(), redis1.getPort()));
shards.add(new JedisShardInfo(redis2.host, redis2.port)); shards.add(new JedisShardInfo(redis2.getHost(), redis2.getPort()));
shards.get(0).setPassword("foobared"); shards.get(0).setPassword("foobared");
shards.get(1).setPassword("foobared"); shards.get(1).setPassword("foobared");
Jedis j = new Jedis(shards.get(0)); Jedis j = new Jedis(shards.get(0));
@@ -41,11 +40,13 @@ public class ShardedJedisPoolTest extends Assert {
j.connect(); j.connect();
j.flushAll(); j.flushAll();
j.disconnect(); j.disconnect();
} }
@Test @Test
public void checkConnections() { public void checkConnections() {
ShardedJedisPool pool = new ShardedJedisPool(new Config(), shards); ShardedJedisPool pool = new ShardedJedisPool(
new GenericObjectPoolConfig(), shards);
ShardedJedis jedis = pool.getResource(); ShardedJedis jedis = pool.getResource();
jedis.set("foo", "bar"); jedis.set("foo", "bar");
assertEquals("bar", jedis.get("foo")); assertEquals("bar", jedis.get("foo"));
@@ -55,7 +56,8 @@ public class ShardedJedisPoolTest extends Assert {
@Test @Test
public void checkConnectionWithDefaultPort() { public void checkConnectionWithDefaultPort() {
ShardedJedisPool pool = new ShardedJedisPool(new Config(), shards); ShardedJedisPool pool = new ShardedJedisPool(
new GenericObjectPoolConfig(), shards);
ShardedJedis jedis = pool.getResource(); ShardedJedis jedis = pool.getResource();
jedis.set("foo", "bar"); jedis.set("foo", "bar");
assertEquals("bar", jedis.get("foo")); assertEquals("bar", jedis.get("foo"));
@@ -65,7 +67,8 @@ public class ShardedJedisPoolTest extends Assert {
@Test @Test
public void checkJedisIsReusedWhenReturned() { public void checkJedisIsReusedWhenReturned() {
ShardedJedisPool pool = new ShardedJedisPool(new Config(), shards); ShardedJedisPool pool = new ShardedJedisPool(
new GenericObjectPoolConfig(), shards);
ShardedJedis jedis = pool.getResource(); ShardedJedis jedis = pool.getResource();
jedis.set("foo", "0"); jedis.set("foo", "0");
pool.returnResource(jedis); pool.returnResource(jedis);
@@ -78,7 +81,8 @@ public class ShardedJedisPoolTest extends Assert {
@Test @Test
public void checkPoolRepairedWhenJedisIsBroken() { public void checkPoolRepairedWhenJedisIsBroken() {
ShardedJedisPool pool = new ShardedJedisPool(new Config(), shards); ShardedJedisPool pool = new ShardedJedisPool(
new GenericObjectPoolConfig(), shards);
ShardedJedis jedis = pool.getResource(); ShardedJedis jedis = pool.getResource();
jedis.disconnect(); jedis.disconnect();
pool.returnBrokenResource(jedis); pool.returnBrokenResource(jedis);
@@ -91,9 +95,9 @@ public class ShardedJedisPoolTest extends Assert {
@Test(expected = JedisConnectionException.class) @Test(expected = JedisConnectionException.class)
public void checkPoolOverflow() { public void checkPoolOverflow() {
Config config = new Config(); GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.maxActive = 1; config.setMaxTotal(1);
config.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_FAIL; config.setBlockWhenExhausted(false);
ShardedJedisPool pool = new ShardedJedisPool(config, shards); ShardedJedisPool pool = new ShardedJedisPool(config, shards);
@@ -106,9 +110,8 @@ public class ShardedJedisPoolTest extends Assert {
@Test @Test
public void shouldNotShareInstances() { public void shouldNotShareInstances() {
Config config = new Config(); GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.maxActive = 2; config.setMaxTotal(2);
config.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_FAIL;
ShardedJedisPool pool = new ShardedJedisPool(config, shards); ShardedJedisPool pool = new ShardedJedisPool(config, shards);
@@ -120,7 +123,8 @@ public class ShardedJedisPoolTest extends Assert {
@Test @Test
public void checkFailedJedisServer() { public void checkFailedJedisServer() {
ShardedJedisPool pool = new ShardedJedisPool(new Config(), shards); ShardedJedisPool pool = new ShardedJedisPool(
new GenericObjectPoolConfig(), shards);
ShardedJedis jedis = pool.getResource(); ShardedJedis jedis = pool.getResource();
jedis.incr("foo"); jedis.incr("foo");
pool.returnResource(jedis); pool.returnResource(jedis);
@@ -129,8 +133,8 @@ public class ShardedJedisPoolTest extends Assert {
@Test @Test
public void shouldReturnActiveShardsWhenOneGoesOffline() { public void shouldReturnActiveShardsWhenOneGoesOffline() {
Config redisConfig = new Config(); GenericObjectPoolConfig redisConfig = new GenericObjectPoolConfig();
redisConfig.testOnBorrow = false; redisConfig.setTestOnBorrow(false);
ShardedJedisPool pool = new ShardedJedisPool(redisConfig, shards); ShardedJedisPool pool = new ShardedJedisPool(redisConfig, shards);
ShardedJedis jedis = pool.getResource(); ShardedJedis jedis = pool.getResource();
// fill the shards // fill the shards
@@ -184,10 +188,11 @@ public class ShardedJedisPoolTest extends Assert {
shards.add(new JedisShardInfo("redis://:foobared@localhost:6380")); shards.add(new JedisShardInfo("redis://:foobared@localhost:6380"));
shards.add(new JedisShardInfo("redis://:foobared@localhost:6379")); shards.add(new JedisShardInfo("redis://:foobared@localhost:6379"));
Config redisConfig = new Config(); GenericObjectPoolConfig redisConfig = new GenericObjectPoolConfig();
ShardedJedisPool pool = new ShardedJedisPool(redisConfig, shards); ShardedJedisPool pool = new ShardedJedisPool(redisConfig, shards);
Jedis[] jedises = pool.getResource().getAllShards().toArray(new Jedis[2]); Jedis[] jedises = pool.getResource().getAllShards()
.toArray(new Jedis[2]);
Jedis jedis = jedises[0]; Jedis jedis = jedises[0];
assertEquals("PONG", jedis.ping()); assertEquals("PONG", jedis.ping());
@@ -209,13 +214,16 @@ public class ShardedJedisPoolTest extends Assert {
j.set("foo", "bar"); j.set("foo", "bar");
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
shards.add(new JedisShardInfo(new URI("redis://:foobared@localhost:6380"))); shards.add(new JedisShardInfo(new URI(
shards.add(new JedisShardInfo(new URI("redis://:foobared@localhost:6379"))); "redis://:foobared@localhost:6380")));
shards.add(new JedisShardInfo(new URI(
"redis://:foobared@localhost:6379")));
Config redisConfig = new Config(); GenericObjectPoolConfig redisConfig = new GenericObjectPoolConfig();
ShardedJedisPool pool = new ShardedJedisPool(redisConfig, shards); ShardedJedisPool pool = new ShardedJedisPool(redisConfig, shards);
Jedis[] jedises = pool.getResource().getAllShards().toArray(new Jedis[2]); Jedis[] jedises = pool.getResource().getAllShards()
.toArray(new Jedis[2]);
Jedis jedis = jedises[0]; Jedis jedis = jedises[0];
assertEquals("PONG", jedis.ping()); assertEquals("PONG", jedis.ping());

View File

@@ -6,12 +6,12 @@ import java.util.List;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisShardInfo; import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.Protocol; import redis.clients.jedis.Protocol;
import redis.clients.jedis.ShardedJedis; import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPipeline; import redis.clients.jedis.ShardedJedisPipeline;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
import redis.clients.util.Hashing; import redis.clients.util.Hashing;
import redis.clients.util.SafeEncoder; import redis.clients.util.SafeEncoder;
import redis.clients.util.Sharded; import redis.clients.util.Sharded;
@@ -41,8 +41,8 @@ public class ShardedJedisTest extends Assert {
@Test @Test
public void checkSharding() { public void checkSharding() {
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
shards.add(new JedisShardInfo(redis1.host, redis1.port)); shards.add(new JedisShardInfo(redis1.getHost(), redis1.getPort()));
shards.add(new JedisShardInfo(redis2.host, redis2.port)); shards.add(new JedisShardInfo(redis2.getHost(), redis2.getPort()));
ShardedJedis jedis = new ShardedJedis(shards); ShardedJedis jedis = new ShardedJedis(shards);
List<String> keys = getKeysDifferentShard(jedis); List<String> keys = getKeysDifferentShard(jedis);
JedisShardInfo s1 = jedis.getShardInfo(keys.get(0)); JedisShardInfo s1 = jedis.getShardInfo(keys.get(0));
@@ -53,10 +53,11 @@ public class ShardedJedisTest extends Assert {
@Test @Test
public void trySharding() { public void trySharding() {
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
JedisShardInfo si = new JedisShardInfo(redis1.host, redis1.port); JedisShardInfo si = new JedisShardInfo(redis1.getHost(),
redis1.getPort());
si.setPassword("foobared"); si.setPassword("foobared");
shards.add(si); shards.add(si);
si = new JedisShardInfo(redis2.host, redis2.port); si = new JedisShardInfo(redis2.getHost(), redis2.getPort());
si.setPassword("foobared"); si.setPassword("foobared");
shards.add(si); shards.add(si);
ShardedJedis jedis = new ShardedJedis(shards); ShardedJedis jedis = new ShardedJedis(shards);
@@ -80,10 +81,11 @@ public class ShardedJedisTest extends Assert {
@Test @Test
public void tryShardingWithMurmure() { public void tryShardingWithMurmure() {
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
JedisShardInfo si = new JedisShardInfo(redis1.host, redis1.port); JedisShardInfo si = new JedisShardInfo(redis1.getHost(),
redis1.getPort());
si.setPassword("foobared"); si.setPassword("foobared");
shards.add(si); shards.add(si);
si = new JedisShardInfo(redis2.host, redis2.port); si = new JedisShardInfo(redis2.getHost(), redis2.getPort());
si.setPassword("foobared"); si.setPassword("foobared");
shards.add(si); shards.add(si);
ShardedJedis jedis = new ShardedJedis(shards, Hashing.MURMUR_HASH); ShardedJedis jedis = new ShardedJedis(shards, Hashing.MURMUR_HASH);
@@ -107,8 +109,8 @@ public class ShardedJedisTest extends Assert {
@Test @Test
public void checkKeyTags() { public void checkKeyTags() {
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
shards.add(new JedisShardInfo(redis1.host, redis1.port)); shards.add(new JedisShardInfo(redis1.getHost(), redis1.getPort()));
shards.add(new JedisShardInfo(redis2.host, redis2.port)); shards.add(new JedisShardInfo(redis2.getHost(), redis2.getPort()));
ShardedJedis jedis = new ShardedJedis(shards, ShardedJedis jedis = new ShardedJedis(shards,
ShardedJedis.DEFAULT_KEY_TAG_PATTERN); ShardedJedis.DEFAULT_KEY_TAG_PATTERN);
@@ -143,8 +145,8 @@ public class ShardedJedisTest extends Assert {
@Test @Test
public void shardedPipeline() { public void shardedPipeline() {
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
shards.add(new JedisShardInfo(redis1.host, redis1.port)); shards.add(new JedisShardInfo(redis1.getHost(), redis1.getPort()));
shards.add(new JedisShardInfo(redis2.host, redis2.port)); shards.add(new JedisShardInfo(redis2.getHost(), redis2.getPort()));
shards.get(0).setPassword("foobared"); shards.get(0).setPassword("foobared");
shards.get(1).setPassword("foobared"); shards.get(1).setPassword("foobared");
ShardedJedis jedis = new ShardedJedis(shards); ShardedJedis jedis = new ShardedJedis(shards);
@@ -264,8 +266,8 @@ public class ShardedJedisTest extends Assert {
.toString(i)); .toString(i));
JedisShardInfo jedisShardInfo2 = sharded2.getShardInfo(Integer JedisShardInfo jedisShardInfo2 = sharded2.getShardInfo(Integer
.toString(i)); .toString(i));
assertEquals(shards.indexOf(jedisShardInfo), otherShards assertEquals(shards.indexOf(jedisShardInfo),
.indexOf(jedisShardInfo2)); otherShards.indexOf(jedisShardInfo2));
} }
} }

View File

@@ -4,9 +4,9 @@ import java.io.IOException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Calendar; import java.util.Calendar;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.tests.HostAndPortUtil; import redis.clients.jedis.tests.HostAndPortUtil;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
public class GetSetBenchmark { public class GetSetBenchmark {
private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0); private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0);
@@ -14,7 +14,7 @@ public class GetSetBenchmark {
public static void main(String[] args) throws UnknownHostException, public static void main(String[] args) throws UnknownHostException,
IOException { IOException {
Jedis jedis = new Jedis(hnp.host, hnp.port); Jedis jedis = new Jedis(hnp.getHost(), hnp.getPort());
jedis.connect(); jedis.connect();
jedis.auth("foobared"); jedis.auth("foobared");
jedis.flushAll(); jedis.flushAll();

View File

@@ -7,11 +7,11 @@ import java.util.Calendar;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisShardInfo; import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis; import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.tests.HostAndPortUtil; import redis.clients.jedis.tests.HostAndPortUtil;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
public class HashingBenchmark { public class HashingBenchmark {
private static HostAndPort hnp1 = HostAndPortUtil.getRedisServers().get(0); private static HostAndPort hnp1 = HostAndPortUtil.getRedisServers().get(0);
@@ -21,10 +21,11 @@ public class HashingBenchmark {
public static void main(String[] args) throws UnknownHostException, public static void main(String[] args) throws UnknownHostException,
IOException { IOException {
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
JedisShardInfo shard = new JedisShardInfo(hnp1.host, hnp1.port); JedisShardInfo shard = new JedisShardInfo(hnp1.getHost(),
hnp1.getPort());
shard.setPassword("foobared"); shard.setPassword("foobared");
shards.add(shard); shards.add(shard);
shard = new JedisShardInfo(hnp2.host, hnp2.port); shard = new JedisShardInfo(hnp2.getHost(), hnp2.getPort());
shard.setPassword("foobared"); shard.setPassword("foobared");
shards.add(shard); shards.add(shard);
ShardedJedis jedis = new ShardedJedis(shards); ShardedJedis jedis = new ShardedJedis(shards);

View File

@@ -4,10 +4,10 @@ import java.io.IOException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Calendar; import java.util.Calendar;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline; import redis.clients.jedis.Pipeline;
import redis.clients.jedis.tests.HostAndPortUtil; import redis.clients.jedis.tests.HostAndPortUtil;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
public class PipelinedGetSetBenchmark { public class PipelinedGetSetBenchmark {
private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0); private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0);
@@ -15,7 +15,7 @@ public class PipelinedGetSetBenchmark {
public static void main(String[] args) throws UnknownHostException, public static void main(String[] args) throws UnknownHostException,
IOException { IOException {
Jedis jedis = new Jedis(hnp.host, hnp.port); Jedis jedis = new Jedis(hnp.getHost(), hnp.getPort());
jedis.connect(); jedis.connect();
jedis.auth("foobared"); jedis.auth("foobared");
jedis.flushAll(); jedis.flushAll();

View File

@@ -4,19 +4,19 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.pool.impl.GenericObjectPool.Config; import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPool;
import redis.clients.jedis.tests.HostAndPortUtil; import redis.clients.jedis.tests.HostAndPortUtil;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
public class PoolBenchmark { public class PoolBenchmark {
private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0); private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0);
private static final int TOTAL_OPERATIONS = 100000; private static final int TOTAL_OPERATIONS = 100000;
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Jedis j = new Jedis(hnp.host, hnp.port); Jedis j = new Jedis(hnp.getHost(), hnp.getPort());
j.connect(); j.connect();
j.auth("foobared"); j.auth("foobared");
j.flushAll(); j.flushAll();
@@ -30,8 +30,8 @@ public class PoolBenchmark {
} }
private static void withPool() throws Exception { private static void withPool() throws Exception {
final JedisPool pool = new JedisPool(new Config(), hnp.host, hnp.port, final JedisPool pool = new JedisPool(new GenericObjectPoolConfig(),
2000, "foobared"); hnp.getHost(), hnp.getPort(), 2000, "foobared");
List<Thread> tds = new ArrayList<Thread>(); List<Thread> tds = new ArrayList<Thread>();
final AtomicInteger ind = new AtomicInteger(); final AtomicInteger ind = new AtomicInteger();
@@ -59,5 +59,6 @@ public class PoolBenchmark {
t.join(); t.join();
pool.destroy(); pool.destroy();
} }
} }

View File

@@ -6,6 +6,8 @@ import java.util.Set;
import org.junit.Test; import org.junit.Test;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.util.SafeEncoder; import redis.clients.util.SafeEncoder;
@@ -299,11 +301,8 @@ public class AllKindOfValuesCommandsTest extends JedisCommandTestBase {
@Test @Test
public void ttl() { public void ttl() {
// This is supposed to return -2 according to
// http://redis.io/commands/ttl
// and needs to be fixed in Redis.
long ttl = jedis.ttl("foo"); long ttl = jedis.ttl("foo");
assertEquals(-1, ttl); assertEquals(-2, ttl);
jedis.set("foo", "bar"); jedis.set("foo", "bar");
ttl = jedis.ttl("foo"); ttl = jedis.ttl("foo");
@@ -313,13 +312,9 @@ public class AllKindOfValuesCommandsTest extends JedisCommandTestBase {
ttl = jedis.ttl("foo"); ttl = jedis.ttl("foo");
assertTrue(ttl >= 0 && ttl <= 20); assertTrue(ttl >= 0 && ttl <= 20);
// This is supposed to return -2 according to
// http://redis.io/commands/ttl
// and needs to be fixed in Redis.
// Binary // Binary
long bttl = jedis.ttl(bfoo); long bttl = jedis.ttl(bfoo);
assertEquals(-1, bttl); assertEquals(-2, bttl);
jedis.set(bfoo, bbar); jedis.set(bfoo, bbar);
bttl = jedis.ttl(bfoo); bttl = jedis.ttl(bfoo);
@@ -499,7 +494,7 @@ public class AllKindOfValuesCommandsTest extends JedisCommandTestBase {
@Test @Test
public void pttl() { public void pttl() {
long pttl = jedis.pttl("foo"); long pttl = jedis.pttl("foo");
assertEquals(-1, pttl); assertEquals(-2, pttl);
jedis.set("foo", "bar"); jedis.set("foo", "bar");
pttl = jedis.pttl("foo"); pttl = jedis.pttl("foo");
@@ -510,4 +505,42 @@ public class AllKindOfValuesCommandsTest extends JedisCommandTestBase {
assertTrue(pttl >= 0 && pttl <= 20000); assertTrue(pttl >= 0 && pttl <= 20000);
} }
@Test
public void scan() {
jedis.set("b", "b");
jedis.set("a", "a");
ScanResult<String> result = jedis.scan(0);
assertEquals(0, result.getCursor());
assertFalse(result.getResult().isEmpty());
}
@Test
public void scanMatch() {
ScanParams params = new ScanParams();
params.match("a*");
jedis.set("b", "b");
jedis.set("a", "a");
jedis.set("aa", "aa");
ScanResult<String> result = jedis.scan(0, params);
assertEquals(0, result.getCursor());
assertFalse(result.getResult().isEmpty());
}
@Test
public void scanCount() {
ScanParams params = new ScanParams();
params.count(2);
for (int i = 0; i < 10; i++) {
jedis.set("a" + i, "a" + i);
}
ScanResult<String> result = jedis.scan(0, params);
assertFalse(result.getResult().isEmpty());
}
} }

View File

@@ -1,14 +1,15 @@
package redis.clients.jedis.tests.commands; package redis.clients.jedis.tests.commands;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Protocol.Keyword;
import redis.clients.jedis.exceptions.JedisDataException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Protocol.Keyword;
import redis.clients.jedis.exceptions.JedisDataException;
public class BinaryValuesCommandsTest extends JedisCommandTestBase { public class BinaryValuesCommandsTest extends JedisCommandTestBase {
byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 }; byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
byte[] bbar = { 0x05, 0x06, 0x07, 0x08 }; byte[] bbar = { 0x05, 0x06, 0x07, 0x08 };
@@ -57,7 +58,8 @@ public class BinaryValuesCommandsTest extends JedisCommandTestBase {
String status = jedis.set(bfoo, binaryValue); String status = jedis.set(bfoo, binaryValue);
assertTrue(Keyword.OK.name().equalsIgnoreCase(status)); assertTrue(Keyword.OK.name().equalsIgnoreCase(status));
// nx should fail if value exists // nx should fail if value exists
String statusFail = jedis.set(bfoo, binaryValue, bnx, bex, expireSeconds); String statusFail = jedis.set(bfoo, binaryValue, bnx, bex,
expireSeconds);
assertNull(statusFail); assertNull(statusFail);
byte[] value = jedis.get(bfoo); byte[] value = jedis.get(bfoo);
@@ -71,7 +73,8 @@ public class BinaryValuesCommandsTest extends JedisCommandTestBase {
String status = jedis.set(bfoo, binaryValue); String status = jedis.set(bfoo, binaryValue);
assertTrue(Keyword.OK.name().equalsIgnoreCase(status)); assertTrue(Keyword.OK.name().equalsIgnoreCase(status));
// nx should fail if value exists // nx should fail if value exists
String statusSuccess = jedis.set(bfoo, binaryValue, bxx, bex, expireSeconds); String statusSuccess = jedis.set(bfoo, binaryValue, bxx, bex,
expireSeconds);
assertTrue(Keyword.OK.name().equalsIgnoreCase(statusSuccess)); assertTrue(Keyword.OK.name().equalsIgnoreCase(statusSuccess));
byte[] value = jedis.get(bfoo); byte[] value = jedis.get(bfoo);
@@ -83,7 +86,8 @@ public class BinaryValuesCommandsTest extends JedisCommandTestBase {
@Test @Test
public void setFailIfNotExistAndGet() { public void setFailIfNotExistAndGet() {
// xx should fail if value does NOT exists // xx should fail if value does NOT exists
String statusFail = jedis.set(bfoo, binaryValue, bxx, bex, expireSeconds); String statusFail = jedis.set(bfoo, binaryValue, bxx, bex,
expireSeconds);
assertNull(statusFail); assertNull(statusFail);
} }
@@ -95,7 +99,6 @@ public class BinaryValuesCommandsTest extends JedisCommandTestBase {
assertTrue(ttl > 0 && ttl <= expireSeconds); assertTrue(ttl > 0 && ttl <= expireSeconds);
} }
@Test @Test
public void setAndExpire() { public void setAndExpire() {
String status = jedis.set(bfoo, binaryValue, bnx, bex, expireSeconds); String status = jedis.set(bfoo, binaryValue, bnx, bex, expireSeconds);
@@ -104,7 +107,6 @@ public class BinaryValuesCommandsTest extends JedisCommandTestBase {
assertTrue(ttl > 0 && ttl <= expireSeconds); assertTrue(ttl > 0 && ttl <= expireSeconds);
} }
@Test @Test
public void getSet() { public void getSet() {
byte[] value = jedis.getSet(bfoo, binaryValue); byte[] value = jedis.getSet(bfoo, binaryValue);
@@ -263,15 +265,13 @@ public class BinaryValuesCommandsTest extends JedisCommandTestBase {
assertTrue(Arrays.equals(first512, rfirst512)); assertTrue(Arrays.equals(first512, rfirst512));
byte[] last512 = new byte[512]; byte[] last512 = new byte[512];
System System.arraycopy(binaryValue, binaryValue.length - 512, last512, 0, 512);
.arraycopy(binaryValue, binaryValue.length - 512, last512, 0,
512);
assertTrue(Arrays.equals(last512, jedis.substr(bfoo, -512, -1))); assertTrue(Arrays.equals(last512, jedis.substr(bfoo, -512, -1)));
assertTrue(Arrays.equals(binaryValue, jedis.substr(bfoo, 0, -1))); assertTrue(Arrays.equals(binaryValue, jedis.substr(bfoo, 0, -1)));
assertTrue(Arrays.equals(last512, jedis.substr(bfoo, assertTrue(Arrays.equals(last512,
binaryValue.length - 512, 100000))); jedis.substr(bfoo, binaryValue.length - 512, 100000)));
} }
@Test @Test

View File

@@ -51,8 +51,7 @@ public class BitCommandsTest extends JedisCommandTestBase {
} }
@Test @Test
public void bitOp() public void bitOp() {
{
jedis.set("key1", "\u0060"); jedis.set("key1", "\u0060");
jedis.set("key2", "\u0044"); jedis.set("key2", "\u0044");
@@ -76,8 +75,7 @@ public class BitCommandsTest extends JedisCommandTestBase {
} }
@Test @Test
public void bitOpNot() public void bitOpNot() {
{
jedis.del("key"); jedis.del("key");
jedis.setbit("key", 0, true); jedis.setbit("key", 0, true);
jedis.setbit("key", 4, true); jedis.setbit("key", 4, true);

View File

@@ -0,0 +1,141 @@
package redis.clients.jedis.tests.commands;
import java.util.List;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.tests.HostAndPortUtil;
import redis.clients.jedis.tests.JedisTestBase;
public class ClusterCommandsTest extends JedisTestBase {
private static Jedis node1;
private static Jedis node2;
private HostAndPort nodeInfo1 = HostAndPortUtil.getClusterServers().get(0);
private HostAndPort nodeInfo2 = HostAndPortUtil.getClusterServers().get(1);
@Before
public void setUp() throws Exception {
node1 = new Jedis(nodeInfo1.getHost(), nodeInfo1.getPort());
node1.connect();
node1.flushAll();
node2 = new Jedis(nodeInfo2.getHost(), nodeInfo2.getPort());
node2.connect();
node2.flushAll();
}
@After
public void tearDown() {
node1.disconnect();
node2.disconnect();
}
@AfterClass
public static void removeSlots() throws InterruptedException {
// This is to wait for gossip to replicate data.
waitForEqualClusterSize();
String[] nodes = node1.clusterNodes().split("\n");
String node1Id = nodes[0].split(" ")[0];
node1.clusterDelSlots(1, 2, 3, 4, 5, 500);
node1.clusterSetSlotNode(5000, node1Id);
node1.clusterDelSlots(5000, 10000);
node1.clusterDelSlots(6000);
node2.clusterDelSlots(6000, 1, 2, 3, 4, 5, 500, 5000);
try {
node2.clusterDelSlots(10000);
} catch (JedisDataException jde) {
// Do nothing, slot may or may not be assigned depending on gossip
}
}
private static void waitForEqualClusterSize() throws InterruptedException {
boolean notEqualSize = true;
while (notEqualSize) {
notEqualSize = getClusterAttribute(node1.clusterInfo(),
"cluster_known_nodes") == getClusterAttribute(
node2.clusterInfo(), "cluster_size") ? false : true;
}
}
private static int getClusterAttribute(String clusterInfo,
String attributeName) {
for (String infoElement : clusterInfo.split("\n")) {
if (infoElement.contains(attributeName)) {
return Integer.valueOf(infoElement.split(":")[1].trim());
}
}
return 0;
}
@Test
public void clusterNodes() {
String nodes = node1.clusterNodes();
assertTrue(nodes.split("\n").length > 0);
}
@Test
public void clusterMeet() {
String status = node1.clusterMeet("127.0.0.1", nodeInfo2.getPort());
assertEquals("OK", status);
}
@Test
public void clusterAddSlots() {
String status = node1.clusterAddSlots(1, 2, 3, 4, 5);
assertEquals("OK", status);
}
@Test
public void clusterDelSlots() {
node1.clusterAddSlots(900);
String status = node1.clusterDelSlots(900);
assertEquals("OK", status);
}
@Test
public void clusterInfo() {
String info = node1.clusterInfo();
assertNotNull(info);
}
@Test
public void clusterGetKeysInSlot() {
node1.clusterAddSlots(500);
List<String> keys = node1.clusterGetKeysInSlot(500, 1);
assertEquals(0, keys.size());
}
@Test
public void clusterSetSlotNode() {
String[] nodes = node1.clusterNodes().split("\n");
String nodeId = nodes[0].split(" ")[0];
String status = node1.clusterSetSlotNode(10000, nodeId);
assertEquals("OK", status);
}
@Test
public void clusterSetSlotMigrating() {
node1.clusterAddSlots(5000);
String[] nodes = node1.clusterNodes().split("\n");
String nodeId = nodes[0].split(" ")[0];
String status = node1.clusterSetSlotMigrating(5000, nodeId);
assertEquals("OK", status);
}
@Test
public void clusterSetSlotImporting() {
node2.clusterAddSlots(6000);
String[] nodes = node1.clusterNodes().split("\n");
String nodeId = nodes[0].split(" ")[0];
String status = node1.clusterSetSlotImporting(6000, nodeId);
assertEquals("OK", status);
}
}

View File

@@ -3,8 +3,8 @@ package redis.clients.jedis.tests.commands;
import org.junit.Test; import org.junit.Test;
import redis.clients.jedis.BinaryJedis; import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.tests.HostAndPortUtil; import redis.clients.jedis.tests.HostAndPortUtil;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
public class ConnectionHandlingCommandsTest extends JedisCommandTestBase { public class ConnectionHandlingCommandsTest extends JedisCommandTestBase {
protected static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0); protected static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0);
@@ -16,7 +16,7 @@ public class ConnectionHandlingCommandsTest extends JedisCommandTestBase {
@Test @Test
public void binary_quit() { public void binary_quit() {
BinaryJedis bj = new BinaryJedis(hnp.host); BinaryJedis bj = new BinaryJedis(hnp.getHost());
assertEquals("OK", bj.quit()); assertEquals("OK", bj.quit());
} }
} }

View File

@@ -45,18 +45,8 @@ public class ControlCommandsTest extends JedisCommandTestBase {
@Test @Test
public void lastsave() throws InterruptedException { public void lastsave() throws InterruptedException {
long before = jedis.lastsave(); long saved = jedis.lastsave();
String st = ""; assertTrue(saved > 0);
while (!st.equals("OK")) {
try {
Thread.sleep(1000);
st = jedis.save();
} catch (JedisDataException e) {
}
}
long after = jedis.lastsave();
assertTrue((after - before) > 0);
} }
@Test @Test
@@ -71,16 +61,16 @@ public class ControlCommandsTest extends JedisCommandTestBase {
public void monitor() { public void monitor() {
new Thread(new Runnable() { new Thread(new Runnable() {
public void run() { public void run() {
Jedis j = new Jedis("localhost");
j.auth("foobared");
for (int i = 0; i < 4; i++) {
j.incr("foobared");
}
try { try {
Thread.sleep(2500); // sleep 100ms to make sure that monitor thread runs first
Thread.sleep(100);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
Jedis j = new Jedis("localhost");
j.auth("foobared");
for (int i = 0; i < 5; i++) {
j.incr("foobared"); j.incr("foobared");
}
j.disconnect(); j.disconnect();
} }
}).start(); }).start();
@@ -127,4 +117,10 @@ public class ControlCommandsTest extends JedisCommandTestBase {
resp = jedis.debug(DebugParams.RELOAD()); resp = jedis.debug(DebugParams.RELOAD());
assertNotNull(resp); assertNotNull(resp);
} }
@Test
public void waitReplicas() {
Long replicas = jedis.waitReplicas(1, 100);
assertEquals(1, replicas.longValue());
}
} }

View File

@@ -10,6 +10,9 @@ import java.util.Set;
import org.junit.Test; import org.junit.Test;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
public class HashesCommandsTest extends JedisCommandTestBase { public class HashesCommandsTest extends JedisCommandTestBase {
final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 }; final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
final byte[] bbar = { 0x05, 0x06, 0x07, 0x08 }; final byte[] bbar = { 0x05, 0x06, 0x07, 0x08 };
@@ -286,4 +289,45 @@ public class HashesCommandsTest extends JedisCommandTestBase {
assertArrayEquals(bcar, bhash.get(bbar)); assertArrayEquals(bcar, bhash.get(bbar));
assertArrayEquals(bbar, bhash.get(bcar)); assertArrayEquals(bbar, bhash.get(bcar));
} }
@Test
public void hscan() {
jedis.hset("foo", "b", "b");
jedis.hset("foo", "a", "a");
ScanResult<Map.Entry<String, String>> result = jedis.hscan("foo", 0);
assertEquals(0, result.getCursor());
assertFalse(result.getResult().isEmpty());
}
@Test
public void hscanMatch() {
ScanParams params = new ScanParams();
params.match("a*");
jedis.hset("foo", "b", "b");
jedis.hset("foo", "a", "a");
jedis.hset("foo", "aa", "aa");
ScanResult<Map.Entry<String, String>> result = jedis.hscan("foo", 0,
params);
assertEquals(0, result.getCursor());
assertFalse(result.getResult().isEmpty());
}
@Test
public void hscanCount() {
ScanParams params = new ScanParams();
params.count(2);
for (int i = 0; i < 10; i++) {
jedis.hset("foo", "a" + i, "a" + i);
}
ScanResult<Map.Entry<String, String>> result = jedis.hscan("foo", 0,
params);
assertFalse(result.getResult().isEmpty());
}
} }

View File

@@ -1,18 +1,19 @@
package redis.clients.jedis.tests.commands; package redis.clients.jedis.tests.commands;
import org.junit.After;
import org.junit.Before;
import org.junit.ComparisonFailure;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.tests.HostAndPortUtil;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
import redis.clients.jedis.tests.JedisTestBase;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.junit.After;
import org.junit.Before;
import org.junit.ComparisonFailure;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.tests.HostAndPortUtil;
import redis.clients.jedis.tests.JedisTestBase;
public abstract class JedisCommandTestBase extends JedisTestBase { public abstract class JedisCommandTestBase extends JedisTestBase {
protected static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0); protected static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0);
@@ -24,7 +25,7 @@ public abstract class JedisCommandTestBase extends JedisTestBase {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
jedis = new Jedis(hnp.host, hnp.port, 500); jedis = new Jedis(hnp.getHost(), hnp.getPort(), 500);
jedis.connect(); jedis.connect();
jedis.auth("foobared"); jedis.auth("foobared");
jedis.configSet("timeout", "300"); jedis.configSet("timeout", "300");
@@ -37,7 +38,7 @@ public abstract class JedisCommandTestBase extends JedisTestBase {
} }
protected Jedis createJedis() { protected Jedis createJedis() {
Jedis j = new Jedis(hnp.host, hnp.port); Jedis j = new Jedis(hnp.getHost(), hnp.getPort());
j.connect(); j.connect();
j.auth("foobared"); j.auth("foobared");
j.flushAll(); j.flushAll();

View File

@@ -33,7 +33,6 @@ public class ListCommandsTest extends JedisCommandTestBase {
size = jedis.rpush("foo", "bar", "foo"); size = jedis.rpush("foo", "bar", "foo");
assertEquals(4, size); assertEquals(4, size);
// Binary // Binary
long bsize = jedis.rpush(bfoo, bbar); long bsize = jedis.rpush(bfoo, bbar);
assertEquals(1, bsize); assertEquals(1, bsize);
@@ -421,41 +420,18 @@ public class ListCommandsTest extends JedisCommandTestBase {
List<String> result = jedis.blpop(1, "foo"); List<String> result = jedis.blpop(1, "foo");
assertNull(result); assertNull(result);
new Thread(new Runnable() { jedis.lpush("foo", "bar");
public void run() {
try {
Jedis j = createJedis();
j.lpush("foo", "bar");
j.disconnect();
} catch (Exception ex) {
fail(ex.getMessage());
}
}
}).start();
result = jedis.blpop(1, "foo"); result = jedis.blpop(1, "foo");
assertNotNull(result); assertNotNull(result);
assertEquals(2, result.size()); assertEquals(2, result.size());
assertEquals("foo", result.get(0)); assertEquals("foo", result.get(0));
assertEquals("bar", result.get(1)); assertEquals("bar", result.get(1));
// Binary // Binary
jedis.lpush(bfoo, bbar);
List<byte[]> bresult = jedis.blpop(1, bfoo); List<byte[]> bresult = jedis.blpop(1, bfoo);
assertNull(bresult);
new Thread(new Runnable() {
public void run() {
try {
Jedis j = createJedis();
j.lpush(bfoo, bbar);
j.disconnect();
} catch (Exception ex) {
fail(ex.getMessage());
}
}
}).start();
bresult = jedis.blpop(1, bfoo);
assertNotNull(bresult); assertNotNull(bresult);
assertEquals(2, bresult.size()); assertEquals(2, bresult.size());
assertArrayEquals(bfoo, bresult.get(0)); assertArrayEquals(bfoo, bresult.get(0));
@@ -468,18 +444,7 @@ public class ListCommandsTest extends JedisCommandTestBase {
List<String> result = jedis.brpop(1, "foo"); List<String> result = jedis.brpop(1, "foo");
assertNull(result); assertNull(result);
new Thread(new Runnable() { jedis.lpush("foo", "bar");
public void run() {
try {
Jedis j = createJedis();
j.lpush("foo", "bar");
j.disconnect();
} catch (Exception ex) {
fail(ex.getMessage());
}
}
}).start();
result = jedis.brpop(1, "foo"); result = jedis.brpop(1, "foo");
assertNotNull(result); assertNotNull(result);
assertEquals(2, result.size()); assertEquals(2, result.size());
@@ -487,22 +452,9 @@ public class ListCommandsTest extends JedisCommandTestBase {
assertEquals("bar", result.get(1)); assertEquals("bar", result.get(1));
// Binary // Binary
jedis.lpush(bfoo, bbar);
List<byte[]> bresult = jedis.brpop(1, bfoo); List<byte[]> bresult = jedis.brpop(1, bfoo);
assertNull(bresult);
new Thread(new Runnable() {
public void run() {
try {
Jedis j = createJedis();
j.lpush(bfoo, bbar);
j.disconnect();
} catch (Exception ex) {
fail(ex.getMessage());
}
}
}).start();
bresult = jedis.brpop(1, bfoo);
assertNotNull(bresult); assertNotNull(bresult);
assertEquals(2, bresult.size()); assertEquals(2, bresult.size());
assertArrayEquals(bfoo, bresult.get(0)); assertArrayEquals(bfoo, bresult.get(0));
@@ -594,7 +546,7 @@ public class ListCommandsTest extends JedisCommandTestBase {
(new Thread(new Runnable() { (new Thread(new Runnable() {
public void run() { public void run() {
try { try {
Thread.sleep(2000); Thread.sleep(100);
Jedis j = createJedis(); Jedis j = createJedis();
j.lpush("foo", "a"); j.lpush("foo", "a");
} catch (InterruptedException e) { } catch (InterruptedException e) {

View File

@@ -36,14 +36,11 @@ public class ObjectCommandsTest extends JedisCommandTestBase {
public void objectIdletime() throws InterruptedException { public void objectIdletime() throws InterruptedException {
jedis.lpush(key, "hello world"); jedis.lpush(key, "hello world");
// Wait a little bit more than 10 seconds so the idle time is 10
// seconds.
Thread.sleep(10001);
Long time = jedis.objectIdletime(key); Long time = jedis.objectIdletime(key);
assertEquals(new Long(10), time); assertEquals(new Long(0), time);
// Binary // Binary
time = jedis.objectIdletime(binaryKey); time = jedis.objectIdletime(binaryKey);
assertEquals(new Long(10), time); assertEquals(new Long(0), time);
} }
} }

View File

@@ -3,33 +3,36 @@ package redis.clients.jedis.tests.commands;
import java.io.IOException; import java.io.IOException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import redis.clients.jedis.BinaryJedisPubSub; import redis.clients.jedis.BinaryJedisPubSub;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub; import redis.clients.jedis.JedisPubSub;
import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.util.SafeEncoder; import redis.clients.util.SafeEncoder;
public class PublishSubscribeCommandsTest extends JedisCommandTestBase { public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
@Test private void publishOne(final String channel, final String message) {
public void subscribe() throws InterruptedException {
Thread t = new Thread(new Runnable() { Thread t = new Thread(new Runnable() {
public void run() { public void run() {
try { try {
Jedis j = createJedis(); Jedis j = createJedis();
Thread.sleep(1000); j.publish(channel, message);
j.publish("foo", "exit");
j.disconnect(); j.disconnect();
} catch (Exception ex) { } catch (Exception ex) {
fail(ex.getMessage());
} }
} }
}); });
t.start(); t.start();
}
@Test
public void subscribe() throws InterruptedException {
jedis.subscribe(new JedisPubSub() { jedis.subscribe(new JedisPubSub() {
public void onMessage(String channel, String message) { public void onMessage(String channel, String message) {
assertEquals("foo", channel); assertEquals("foo", channel);
@@ -40,6 +43,9 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
public void onSubscribe(String channel, int subscribedChannels) { public void onSubscribe(String channel, int subscribedChannels) {
assertEquals("foo", channel); assertEquals("foo", channel);
assertEquals(1, subscribedChannels); assertEquals(1, subscribedChannels);
// now that I'm subscribed... publish
publishOne("foo", "exit");
} }
public void onUnsubscribe(String channel, int subscribedChannels) { public void onUnsubscribe(String channel, int subscribedChannels) {
@@ -57,33 +63,136 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
String message) { String message) {
} }
}, "foo"); }, "foo");
t.join(); }
@Test
public void pubSubChannels(){
final List<String> expectedActiveChannels = Arrays.asList("testchan1", "testchan2", "testchan3");
jedis.subscribe(new JedisPubSub() {
private int count = 0;
@Override
public void onUnsubscribe(String channel, int subscribedChannels) {
}
@Override
public void onSubscribe(String channel, int subscribedChannels) {
count++;
//All channels are subscribed
if (count == 3) {
Jedis otherJedis = createJedis();
List<String> activeChannels = otherJedis.pubsubChannels("test*");
assertTrue(expectedActiveChannels.containsAll(activeChannels));
unsubscribe();
}
}
@Override
public void onPUnsubscribe(String pattern, int subscribedChannels) {
}
@Override
public void onPSubscribe(String pattern, int subscribedChannels) {
}
@Override
public void onPMessage(String pattern, String channel, String message) {
}
@Override
public void onMessage(String channel, String message) {
}
}, "testchan1", "testchan2", "testchan3");
}
@Test
public void pubSubNumPat(){
jedis.psubscribe(new JedisPubSub() {
private int count=0;
@Override
public void onUnsubscribe(String channel, int subscribedChannels) {
}
@Override
public void onSubscribe(String channel, int subscribedChannels) {
}
@Override
public void onPUnsubscribe(String pattern, int subscribedChannels) {
}
@Override
public void onPSubscribe(String pattern, int subscribedChannels) {
count++;
if (count == 3) {
Jedis otherJedis = createJedis();
Long numPatterns = otherJedis.pubsubNumPat();
assertEquals(new Long(2l), numPatterns);
punsubscribe();
}
}
@Override
public void onPMessage(String pattern, String channel, String message) {
}
@Override
public void onMessage(String channel, String message) {
}
}, "test*", "test*", "chan*");
}
@Test
public void pubSubNumSub(){
final Map<String, String> expectedNumSub = new HashMap<String, String>();
expectedNumSub.put("testchannel2", "1");
expectedNumSub.put("testchannel1", "1");
jedis.subscribe(new JedisPubSub() {
private int count=0;
@Override
public void onUnsubscribe(String channel, int subscribedChannels) {
}
@Override
public void onSubscribe(String channel, int subscribedChannels) {
count++;
if (count == 2) {
Jedis otherJedis = createJedis();
Map<String, String> numSub = otherJedis.pubsubNumSub("testchannel1", "testchannel2");
assertEquals(expectedNumSub, numSub);
unsubscribe();
}
}
@Override
public void onPUnsubscribe(String pattern, int subscribedChannels) {
}
@Override
public void onPSubscribe(String pattern, int subscribedChannels) {
}
@Override
public void onPMessage(String pattern, String channel, String message) {
}
@Override
public void onMessage(String channel, String message) {
}
}, "testchannel1", "testchannel2");
} }
@Test @Test
public void subscribeMany() throws UnknownHostException, IOException, public void subscribeMany() throws UnknownHostException, IOException,
InterruptedException { InterruptedException {
Thread t = new Thread(new Runnable() {
public void run() {
try {
Jedis j = createJedis();
Thread.sleep(1000);
j.publish("foo", "exit");
Thread.sleep(1000);
j.publish("bar", "exit");
j.disconnect();
} catch (Exception ex) {
fail(ex.getMessage());
}
}
});
t.start();
jedis.subscribe(new JedisPubSub() { jedis.subscribe(new JedisPubSub() {
public void onMessage(String channel, String message) { public void onMessage(String channel, String message) {
unsubscribe(channel); unsubscribe(channel);
} }
public void onSubscribe(String channel, int subscribedChannels) { public void onSubscribe(String channel, int subscribedChannels) {
publishOne(channel, "exit");
} }
public void onUnsubscribe(String channel, int subscribedChannels) { public void onUnsubscribe(String channel, int subscribedChannels) {
@@ -99,25 +208,11 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
String message) { String message) {
} }
}, "foo", "bar"); }, "foo", "bar");
t.join();
} }
@Test @Test
public void psubscribe() throws UnknownHostException, IOException, public void psubscribe() throws UnknownHostException, IOException,
InterruptedException { InterruptedException {
Thread t = new Thread(new Runnable() {
public void run() {
try {
Jedis j = createJedis();
Thread.sleep(1000);
j.publish("foo.bar", "exit");
j.disconnect();
} catch (Exception ex) {
fail(ex.getMessage());
}
}
});
t.start();
jedis.psubscribe(new JedisPubSub() { jedis.psubscribe(new JedisPubSub() {
public void onMessage(String channel, String message) { public void onMessage(String channel, String message) {
} }
@@ -131,6 +226,8 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
public void onPSubscribe(String pattern, int subscribedChannels) { public void onPSubscribe(String pattern, int subscribedChannels) {
assertEquals("foo.*", pattern); assertEquals("foo.*", pattern);
assertEquals(1, subscribedChannels); assertEquals(1, subscribedChannels);
publishOne("foo.bar", "exit");
} }
public void onPUnsubscribe(String pattern, int subscribedChannels) { public void onPUnsubscribe(String pattern, int subscribedChannels) {
@@ -146,27 +243,11 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
punsubscribe(); punsubscribe();
} }
}, "foo.*"); }, "foo.*");
t.join();
} }
@Test @Test
public void psubscribeMany() throws UnknownHostException, IOException, public void psubscribeMany() throws UnknownHostException, IOException,
InterruptedException { InterruptedException {
Thread t = new Thread(new Runnable() {
public void run() {
try {
Jedis j = createJedis();
Thread.sleep(1000);
j.publish("foo.123", "exit");
Thread.sleep(1000);
j.publish("bar.123", "exit");
j.disconnect();
} catch (Exception ex) {
fail(ex.getMessage());
}
}
});
t.start();
jedis.psubscribe(new JedisPubSub() { jedis.psubscribe(new JedisPubSub() {
public void onMessage(String channel, String message) { public void onMessage(String channel, String message) {
} }
@@ -178,6 +259,7 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
} }
public void onPSubscribe(String pattern, int subscribedChannels) { public void onPSubscribe(String pattern, int subscribedChannels) {
publishOne(pattern.replace("*", "123"), "exit");
} }
public void onPUnsubscribe(String pattern, int subscribedChannels) { public void onPUnsubscribe(String pattern, int subscribedChannels) {
@@ -188,7 +270,6 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
punsubscribe(pattern); punsubscribe(pattern);
} }
}, "foo.*", "bar.*"); }, "foo.*", "bar.*");
t.join();
} }
@Test @Test
@@ -200,12 +281,18 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
} }
public void onSubscribe(String channel, int subscribedChannels) { public void onSubscribe(String channel, int subscribedChannels) {
publishOne(channel, "exit");
if (!channel.equals("bar")) {
this.subscribe("bar");
this.psubscribe("bar.*");
}
} }
public void onUnsubscribe(String channel, int subscribedChannels) { public void onUnsubscribe(String channel, int subscribedChannels) {
} }
public void onPSubscribe(String pattern, int subscribedChannels) { public void onPSubscribe(String pattern, int subscribedChannels) {
publishOne(pattern.replace("*", "123"), "exit");
} }
public void onPUnsubscribe(String pattern, int subscribedChannels) { public void onPUnsubscribe(String pattern, int subscribedChannels) {
@@ -217,44 +304,12 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
} }
}; };
Thread t = new Thread(new Runnable() {
public void run() {
try {
Jedis j = createJedis();
Thread.sleep(1000);
pubsub.subscribe("bar");
pubsub.psubscribe("bar.*");
j.publish("foo", "exit");
j.publish("bar", "exit");
j.publish("bar.123", "exit");
j.disconnect();
} catch (Exception ex) {
fail(ex.getMessage());
}
}
});
t.start();
jedis.subscribe(pubsub, "foo"); jedis.subscribe(pubsub, "foo");
t.join();
} }
@Test @Test
public void binarySubscribe() throws UnknownHostException, IOException, public void binarySubscribe() throws UnknownHostException, IOException,
InterruptedException { InterruptedException {
Thread t = new Thread(new Runnable() {
public void run() {
try {
Jedis j = createJedis();
Thread.sleep(1000);
j.publish(SafeEncoder.encode("foo"), SafeEncoder
.encode("exit"));
j.disconnect();
} catch (Exception ex) {
fail(ex.getMessage());
}
}
});
t.start();
jedis.subscribe(new BinaryJedisPubSub() { jedis.subscribe(new BinaryJedisPubSub() {
public void onMessage(byte[] channel, byte[] message) { public void onMessage(byte[] channel, byte[] message) {
assertTrue(Arrays.equals(SafeEncoder.encode("foo"), channel)); assertTrue(Arrays.equals(SafeEncoder.encode("foo"), channel));
@@ -265,6 +320,7 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
public void onSubscribe(byte[] channel, int subscribedChannels) { public void onSubscribe(byte[] channel, int subscribedChannels) {
assertTrue(Arrays.equals(SafeEncoder.encode("foo"), channel)); assertTrue(Arrays.equals(SafeEncoder.encode("foo"), channel));
assertEquals(1, subscribedChannels); assertEquals(1, subscribedChannels);
publishOne(SafeEncoder.encode(channel), "exit");
} }
public void onUnsubscribe(byte[] channel, int subscribedChannels) { public void onUnsubscribe(byte[] channel, int subscribedChannels) {
@@ -282,35 +338,18 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
byte[] message) { byte[] message) {
} }
}, SafeEncoder.encode("foo")); }, SafeEncoder.encode("foo"));
t.join();
} }
@Test @Test
public void binarySubscribeMany() throws UnknownHostException, IOException, public void binarySubscribeMany() throws UnknownHostException, IOException,
InterruptedException { InterruptedException {
Thread t = new Thread(new Runnable() {
public void run() {
try {
Jedis j = createJedis();
Thread.sleep(1000);
j.publish(SafeEncoder.encode("foo"), SafeEncoder
.encode("exit"));
Thread.sleep(1000);
j.publish(SafeEncoder.encode("bar"), SafeEncoder
.encode("exit"));
j.disconnect();
} catch (Exception ex) {
fail(ex.getMessage());
}
}
});
t.start();
jedis.subscribe(new BinaryJedisPubSub() { jedis.subscribe(new BinaryJedisPubSub() {
public void onMessage(byte[] channel, byte[] message) { public void onMessage(byte[] channel, byte[] message) {
unsubscribe(channel); unsubscribe(channel);
} }
public void onSubscribe(byte[] channel, int subscribedChannels) { public void onSubscribe(byte[] channel, int subscribedChannels) {
publishOne(SafeEncoder.encode(channel), "exit");
} }
public void onUnsubscribe(byte[] channel, int subscribedChannels) { public void onUnsubscribe(byte[] channel, int subscribedChannels) {
@@ -326,26 +365,11 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
byte[] message) { byte[] message) {
} }
}, SafeEncoder.encode("foo"), SafeEncoder.encode("bar")); }, SafeEncoder.encode("foo"), SafeEncoder.encode("bar"));
t.join();
} }
@Test @Test
public void binaryPsubscribe() throws UnknownHostException, IOException, public void binaryPsubscribe() throws UnknownHostException, IOException,
InterruptedException { InterruptedException {
Thread t = new Thread(new Runnable() {
public void run() {
try {
Jedis j = createJedis();
Thread.sleep(1000);
j.publish(SafeEncoder.encode("foo.bar"), SafeEncoder
.encode("exit"));
j.disconnect();
} catch (Exception ex) {
fail(ex.getMessage());
}
}
});
t.start();
jedis.psubscribe(new BinaryJedisPubSub() { jedis.psubscribe(new BinaryJedisPubSub() {
public void onMessage(byte[] channel, byte[] message) { public void onMessage(byte[] channel, byte[] message) {
} }
@@ -359,6 +383,8 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
public void onPSubscribe(byte[] pattern, int subscribedChannels) { public void onPSubscribe(byte[] pattern, int subscribedChannels) {
assertTrue(Arrays.equals(SafeEncoder.encode("foo.*"), pattern)); assertTrue(Arrays.equals(SafeEncoder.encode("foo.*"), pattern));
assertEquals(1, subscribedChannels); assertEquals(1, subscribedChannels);
publishOne(SafeEncoder.encode(pattern).replace("*", "bar"),
"exit");
} }
public void onPUnsubscribe(byte[] pattern, int subscribedChannels) { public void onPUnsubscribe(byte[] pattern, int subscribedChannels) {
@@ -375,29 +401,11 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
punsubscribe(); punsubscribe();
} }
}, SafeEncoder.encode("foo.*")); }, SafeEncoder.encode("foo.*"));
t.join();
} }
@Test @Test
public void binaryPsubscribeMany() throws UnknownHostException, public void binaryPsubscribeMany() throws UnknownHostException,
IOException, InterruptedException { IOException, InterruptedException {
Thread t = new Thread(new Runnable() {
public void run() {
try {
Jedis j = createJedis();
Thread.sleep(1000);
j.publish(SafeEncoder.encode("foo.123"), SafeEncoder
.encode("exit"));
Thread.sleep(1000);
j.publish(SafeEncoder.encode("bar.123"), SafeEncoder
.encode("exit"));
j.disconnect();
} catch (Exception ex) {
fail(ex.getMessage());
}
}
});
t.start();
jedis.psubscribe(new BinaryJedisPubSub() { jedis.psubscribe(new BinaryJedisPubSub() {
public void onMessage(byte[] channel, byte[] message) { public void onMessage(byte[] channel, byte[] message) {
} }
@@ -409,6 +417,8 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
} }
public void onPSubscribe(byte[] pattern, int subscribedChannels) { public void onPSubscribe(byte[] pattern, int subscribedChannels) {
publishOne(SafeEncoder.encode(pattern).replace("*", "123"),
"exit");
} }
public void onPUnsubscribe(byte[] pattern, int subscribedChannels) { public void onPUnsubscribe(byte[] pattern, int subscribedChannels) {
@@ -419,7 +429,6 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
punsubscribe(pattern); punsubscribe(pattern);
} }
}, SafeEncoder.encode("foo.*"), SafeEncoder.encode("bar.*")); }, SafeEncoder.encode("foo.*"), SafeEncoder.encode("bar.*"));
t.join();
} }
@Test @Test
@@ -431,12 +440,20 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
} }
public void onSubscribe(byte[] channel, int subscribedChannels) { public void onSubscribe(byte[] channel, int subscribedChannels) {
publishOne(SafeEncoder.encode(channel), "exit");
if (!SafeEncoder.encode(channel).equals("bar")) {
this.subscribe(SafeEncoder.encode("bar"));
this.psubscribe(SafeEncoder.encode("bar.*"));
}
} }
public void onUnsubscribe(byte[] channel, int subscribedChannels) { public void onUnsubscribe(byte[] channel, int subscribedChannels) {
} }
public void onPSubscribe(byte[] pattern, int subscribedChannels) { public void onPSubscribe(byte[] pattern, int subscribedChannels) {
publishOne(SafeEncoder.encode(pattern).replace("*", "123"),
"exit");
} }
public void onPUnsubscribe(byte[] pattern, int subscribedChannels) { public void onPUnsubscribe(byte[] pattern, int subscribedChannels) {
@@ -448,60 +465,7 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
} }
}; };
Thread t = new Thread(new Runnable() {
public void run() {
try {
Jedis j = createJedis();
Thread.sleep(1000);
pubsub.subscribe(SafeEncoder.encode("bar"));
pubsub.psubscribe(SafeEncoder.encode("bar.*"));
j.publish(SafeEncoder.encode("foo"), SafeEncoder
.encode("exit"));
j.publish(SafeEncoder.encode("bar"), SafeEncoder
.encode("exit"));
j.publish(SafeEncoder.encode("bar.123"), SafeEncoder
.encode("exit"));
j.disconnect();
} catch (Exception ex) {
fail(ex.getMessage());
}
}
});
t.start();
jedis.subscribe(pubsub, SafeEncoder.encode("foo")); jedis.subscribe(pubsub, SafeEncoder.encode("foo"));
t.join();
}
@Test @Ignore
public void subscribeWithoutConnecting() {
try {
Jedis jedis = new Jedis(hnp.host, hnp.port);
jedis.subscribe(new JedisPubSub() {
public void onMessage(String channel, String message) {
}
public void onPMessage(String pattern, String channel,
String message) {
}
public void onSubscribe(String channel, int subscribedChannels) {
}
public void onUnsubscribe(String channel, int subscribedChannels) {
}
public void onPUnsubscribe(String pattern,
int subscribedChannels) {
}
public void onPSubscribe(String pattern, int subscribedChannels) {
}
}, "foo");
} catch (NullPointerException ex) {
fail();
} catch (JedisDataException ex) {
// this is OK because we are not sending AUTH command
}
} }
@Test(expected = JedisConnectionException.class) @Test(expected = JedisConnectionException.class)
@@ -528,4 +492,89 @@ public class PublishSubscribeCommandsTest extends JedisCommandTestBase {
}; };
pubsub.unsubscribe(); pubsub.unsubscribe();
} }
@Test(expected = JedisConnectionException.class)
public void handleClientOutputBufferLimitForSubscribeTooSlow()
throws InterruptedException {
final Jedis j = createJedis();
final AtomicBoolean exit = new AtomicBoolean(false);
final Thread t = new Thread(new Runnable() {
public void run() {
try {
// we already set jedis1 config to
// client-output-buffer-limit pubsub 256k 128k 5
// it means if subscriber delayed to receive over 256k or
// 128k continuously 5 sec,
// redis disconnects subscriber
// we publish over 100M data for making situation for exceed
// client-output-buffer-limit
String veryLargeString = makeLargeString(10485760);
// 10M * 10 = 100M
for (int i = 0; i < 10 && !exit.get(); i++) {
j.publish("foo", veryLargeString);
}
j.disconnect();
} catch (Exception ex) {
}
}
});
t.start();
try {
jedis.subscribe(new JedisPubSub() {
public void onMessage(String channel, String message) {
try {
// wait 0.5 secs to slow down subscribe and
// client-output-buffer exceed
// System.out.println("channel - " + channel +
// " / message - " + message);
Thread.sleep(100);
} catch (Exception e) {
try {
t.join();
} catch (InterruptedException e1) {
}
fail(e.getMessage());
}
}
public void onSubscribe(String channel, int subscribedChannels) {
}
public void onUnsubscribe(String channel, int subscribedChannels) {
}
public void onPSubscribe(String pattern, int subscribedChannels) {
}
public void onPUnsubscribe(String pattern,
int subscribedChannels) {
}
public void onPMessage(String pattern, String channel,
String message) {
}
}, "foo");
} finally {
// exit the publisher thread. if exception is thrown, thread might
// still keep publishing things.
exit.set(true);
if (t.isAlive()) {
t.join();
}
}
}
private String makeLargeString(int size) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < size; i++)
sb.append((char) ('a' + i % 26));
return sb.toString();
}
} }

View File

@@ -3,6 +3,8 @@ package redis.clients.jedis.tests.commands;
import org.hamcrest.CoreMatchers; import org.hamcrest.CoreMatchers;
import org.hamcrest.core.CombinableMatcher; import org.hamcrest.core.CombinableMatcher;
import org.junit.Test; import org.junit.Test;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.util.SafeEncoder; import redis.clients.util.SafeEncoder;
@@ -18,7 +20,7 @@ public class ScriptingCommandsTest extends JedisCommandTestBase {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Test @Test
public void evalMultiBulk() { public void evalMultiBulk() {
String script = "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}"; String script = "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2],ARGV[3]}";
List<String> keys = new ArrayList<String>(); List<String> keys = new ArrayList<String>();
keys.add("key1"); keys.add("key1");
keys.add("key2"); keys.add("key2");
@@ -26,14 +28,44 @@ public class ScriptingCommandsTest extends JedisCommandTestBase {
List<String> args = new ArrayList<String>(); List<String> args = new ArrayList<String>();
args.add("first"); args.add("first");
args.add("second"); args.add("second");
args.add("third");
List<String> response = (List<String>) jedis.eval(script, keys, args); List<String> response = (List<String>) jedis.eval(script, keys, args);
assertEquals(4, response.size()); assertEquals(5, response.size());
assertEquals("key1", response.get(0)); assertEquals("key1", response.get(0));
assertEquals("key2", response.get(1)); assertEquals("key2", response.get(1));
assertEquals("first", response.get(2)); assertEquals("first", response.get(2));
assertEquals("second", response.get(3)); assertEquals("second", response.get(3));
assertEquals("third", response.get(4));
}
@SuppressWarnings("unchecked")
@Test
public void evalMultiBulkWithBinaryJedis() {
String script = "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2],ARGV[3]}";
List<byte[]> keys = new ArrayList<byte[]>();
keys.add("key1".getBytes());
keys.add("key2".getBytes());
List<byte[]> args = new ArrayList<byte[]>();
args.add("first".getBytes());
args.add("second".getBytes());
args.add("third".getBytes());
BinaryJedis binaryJedis = new BinaryJedis(hnp.getHost(), hnp.getPort(),
500);
binaryJedis.connect();
binaryJedis.auth("foobared");
List<byte[]> responses = (List<byte[]>) binaryJedis.eval(
script.getBytes(), keys, args);
assertEquals(5, responses.size());
assertEquals("key1", new String(responses.get(0)));
assertEquals("key2", new String(responses.get(1)));
assertEquals("first", new String(responses.get(2)));
assertEquals("second", new String(responses.get(3)));
assertEquals("third", new String(responses.get(4)));
} }
@Test @Test
@@ -176,4 +208,3 @@ public class ScriptingCommandsTest extends JedisCommandTestBase {
return both(CoreMatchers.<List<T>>instanceOf(List.class)).and(hasItem(equalTo(expected))); return both(CoreMatchers.<List<T>>instanceOf(List.class)).and(hasItem(equalTo(expected)));
} }
} }

View File

@@ -6,6 +6,9 @@ import java.util.Set;
import org.junit.Test; import org.junit.Test;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
public class SetCommandsTest extends JedisCommandTestBase { public class SetCommandsTest extends JedisCommandTestBase {
final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 }; final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
final byte[] bbar = { 0x05, 0x06, 0x07, 0x08 }; final byte[] bbar = { 0x05, 0x06, 0x07, 0x08 };
@@ -448,7 +451,39 @@ public class SetCommandsTest extends JedisCommandTestBase {
bmember = jedis.srandmember(bbar); bmember = jedis.srandmember(bbar);
assertNull(bmember); assertNull(bmember);
} }
@Test
public void sscan() {
jedis.sadd("foo", "a", "b");
ScanResult<String> result = jedis.sscan("foo", 0);
assertEquals(0, result.getCursor());
assertFalse(result.getResult().isEmpty());
}
@Test
public void sscanMatch() {
ScanParams params = new ScanParams();
params.match("a*");
jedis.sadd("foo", "b", "a", "aa");
ScanResult<String> result = jedis.sscan("foo", 0, params);
assertEquals(0, result.getCursor());
assertFalse(result.getResult().isEmpty());
}
@Test
public void sscanCount() {
ScanParams params = new ScanParams();
params.count(2);
jedis.sadd("foo", "a1", "a2", "a3", "a4", "a5");
ScanResult<String> result = jedis.sscan("foo", 0, params);
assertFalse(result.getResult().isEmpty());
}
} }

View File

@@ -5,6 +5,8 @@ import java.util.Set;
import org.junit.Test; import org.junit.Test;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import redis.clients.jedis.Tuple; import redis.clients.jedis.Tuple;
import redis.clients.jedis.ZParams; import redis.clients.jedis.ZParams;
import redis.clients.util.SafeEncoder; import redis.clients.util.SafeEncoder;
@@ -387,7 +389,8 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
assertEquals(2, bresult); assertEquals(2, bresult);
bresult = jedis.zcount(bfoo, SafeEncoder.encode("(0.01"), SafeEncoder.encode("+inf")); bresult = jedis.zcount(bfoo, SafeEncoder.encode("(0.01"),
SafeEncoder.encode("+inf"));
assertEquals(3, bresult); assertEquals(3, bresult);
} }
@@ -445,8 +448,8 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
assertEquals(bexpected, brange); assertEquals(bexpected, brange);
brange = jedis.zrangeByScore(bfoo, 0d, 2d, 1, 1); brange = jedis.zrangeByScore(bfoo, 0d, 2d, 1, 1);
Set<byte[]> brange2 = jedis.zrangeByScore(bfoo, SafeEncoder Set<byte[]> brange2 = jedis.zrangeByScore(bfoo,
.encode("-inf"), SafeEncoder.encode("(2")); SafeEncoder.encode("-inf"), SafeEncoder.encode("(2"));
assertEquals(bexpected, brange2); assertEquals(bexpected, brange2);
bexpected = new LinkedHashSet<byte[]>(); bexpected = new LinkedHashSet<byte[]>();
@@ -521,8 +524,8 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
assertEquals(bexpected, brange); assertEquals(bexpected, brange);
Set<byte[]> brange2 = jedis.zrevrangeByScore(bfoo, SafeEncoder Set<byte[]> brange2 = jedis.zrevrangeByScore(bfoo,
.encode("+inf"), SafeEncoder.encode("(2")); SafeEncoder.encode("+inf"), SafeEncoder.encode("(2"));
bexpected = new LinkedHashSet<byte[]>(); bexpected = new LinkedHashSet<byte[]>();
bexpected.add(bb); bexpected.add(bb);
@@ -761,8 +764,8 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
bexpected.add(new Tuple(bb, new Double(4))); bexpected.add(new Tuple(bb, new Double(4)));
bexpected.add(new Tuple(ba, new Double(3))); bexpected.add(new Tuple(ba, new Double(3)));
assertEquals(bexpected, jedis.zrangeWithScores(SafeEncoder assertEquals(bexpected,
.encode("dst"), 0, 100)); jedis.zrangeWithScores(SafeEncoder.encode("dst"), 0, 100));
} }
@Test @Test
@@ -803,8 +806,8 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
bexpected.add(new Tuple(bb, new Double(8))); bexpected.add(new Tuple(bb, new Double(8)));
bexpected.add(new Tuple(ba, new Double(6))); bexpected.add(new Tuple(ba, new Double(6)));
assertEquals(bexpected, jedis.zrangeWithScores(SafeEncoder assertEquals(bexpected,
.encode("dst"), 0, 100)); jedis.zrangeWithScores(SafeEncoder.encode("dst"), 0, 100));
} }
@Test @Test
@@ -834,8 +837,8 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
Set<Tuple> bexpected = new LinkedHashSet<Tuple>(); Set<Tuple> bexpected = new LinkedHashSet<Tuple>();
bexpected.add(new Tuple(ba, new Double(3))); bexpected.add(new Tuple(ba, new Double(3)));
assertEquals(bexpected, jedis.zrangeWithScores(SafeEncoder assertEquals(bexpected,
.encode("dst"), 0, 100)); jedis.zrangeWithScores(SafeEncoder.encode("dst"), 0, 100));
} }
@Test @Test
@@ -872,8 +875,8 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
Set<Tuple> bexpected = new LinkedHashSet<Tuple>(); Set<Tuple> bexpected = new LinkedHashSet<Tuple>();
bexpected.add(new Tuple(ba, new Double(6))); bexpected.add(new Tuple(ba, new Double(6)));
assertEquals(bexpected, jedis.zrangeWithScores(SafeEncoder assertEquals(bexpected,
.encode("dst"), 0, 100)); jedis.zrangeWithScores(SafeEncoder.encode("dst"), 0, 100));
} }
@Test @Test
@@ -885,4 +888,45 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
assertEquals(1, t2.compareTo(t1)); assertEquals(1, t2.compareTo(t1));
assertEquals(0, t2.compareTo(t2)); assertEquals(0, t2.compareTo(t2));
} }
@Test
public void zscan() {
jedis.zadd("foo", 1, "a");
jedis.zadd("foo", 2, "b");
ScanResult<Tuple> result = jedis.zscan("foo", 0);
assertEquals(0, result.getCursor());
assertFalse(result.getResult().isEmpty());
}
@Test
public void zscanMatch() {
ScanParams params = new ScanParams();
params.match("a*");
jedis.zadd("foo", 2, "b");
jedis.zadd("foo", 1, "a");
jedis.zadd("foo", 11, "aa");
ScanResult<Tuple> result = jedis.zscan("foo", 0, params);
assertEquals(0, result.getCursor());
assertFalse(result.getResult().isEmpty());
}
@Test
public void zscanCount() {
ScanParams params = new ScanParams();
params.count(2);
jedis.zadd("foo", 1, "a1");
jedis.zadd("foo", 2, "a2");
jedis.zadd("foo", 3, "a3");
jedis.zadd("foo", 4, "a4");
jedis.zadd("foo", 5, "a5");
ScanResult<Tuple> result = jedis.zscan("foo", 0, params);
assertFalse(result.getResult().isEmpty());
}
} }

View File

@@ -180,8 +180,8 @@ public class StringValuesCommandsTest extends JedisCommandTestBase {
public void incrLargeNumbers() { public void incrLargeNumbers() {
long value = jedis.incr("foo"); long value = jedis.incr("foo");
assertEquals(1, value); assertEquals(1, value);
assertEquals(1L + Integer.MAX_VALUE, (long) jedis.incrBy("foo", assertEquals(1L + Integer.MAX_VALUE,
Integer.MAX_VALUE)); (long) jedis.incrBy("foo", Integer.MAX_VALUE));
} }
@Test(expected = JedisDataException.class) @Test(expected = JedisDataException.class)

View File

@@ -4,6 +4,7 @@ import java.io.IOException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@@ -12,11 +13,12 @@ import org.junit.Test;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline; import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Protocol.Keyword;
import redis.clients.jedis.Response; import redis.clients.jedis.Response;
import redis.clients.jedis.Transaction; import redis.clients.jedis.Transaction;
import redis.clients.jedis.TransactionBlock; import redis.clients.jedis.TransactionBlock;
import redis.clients.jedis.Protocol.Keyword;
import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.exceptions.JedisException;
public class TransactionCommandsTest extends JedisCommandTestBase { public class TransactionCommandsTest extends JedisCommandTestBase {
final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 }; final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
@@ -32,7 +34,7 @@ public class TransactionCommandsTest extends JedisCommandTestBase {
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); super.setUp();
nj = new Jedis(hnp.host, hnp.port, 500); nj = new Jedis(hnp.getHost(), hnp.getPort(), 500);
nj.connect(); nj.connect();
nj.auth("foobared"); nj.auth("foobared");
nj.flushAll(); nj.flushAll();
@@ -106,6 +108,52 @@ public class TransactionCommandsTest extends JedisCommandTestBase {
} }
@Test
public void multiBlockWithErrorRedisDiscardsTransaction() throws Exception {
// Transaction with error - Redis discards transaction automatically
// (Syntax Error, etc.)
TransactionBlock tb = new TransactionBlock() {
@Override
public void execute() throws JedisException {
del("hello");
hmset("hello", new HashMap<String, String>());
}
};
try {
jedis.multi(tb);
} catch (JedisDataException e) {
assertTrue(e.getMessage().contains("EXECABORT"));
} catch (Exception e) {
throw e;
}
}
@Test
public void multiBlockWithErrorRedisForceToExecuteAllCommands()
throws Exception {
// Transaction with error - Redis doesn't roll back (Type Error,
// Deletion of non-exist key, etc.)
jedis.del("hello2");
TransactionBlock tb2 = new TransactionBlock() {
@Override
public void execute() throws JedisException {
del("hello2");
set("hello2", "hello");
sadd("hello2", "hello2");
}
};
List<Object> responses = jedis.multi(tb2);
assertEquals("OK", responses.get(1));
assertEquals(JedisDataException.class, responses.get(2).getClass());
Exception exc = (JedisDataException) responses.get(2);
assertTrue(exc.getMessage().contains("WRONGTYPE"));
}
@Test @Test
public void watch() throws UnknownHostException, IOException { public void watch() throws UnknownHostException, IOException {
jedis.watch("mykey", "somekey"); jedis.watch("mykey", "somekey");
@@ -295,4 +343,48 @@ public class TransactionCommandsTest extends JedisCommandTestBase {
assertNull(results); assertNull(results);
} }
@Test
public void testResetStateWhenInMulti() {
jedis.auth("foobared");
Transaction t = jedis.multi();
t.set("foooo", "barrr");
jedis.resetState();
assertEquals(null, jedis.get("foooo"));
}
@Test
public void testResetStateWhenInMultiWithinPipeline() {
jedis.auth("foobared");
Pipeline p = jedis.pipelined();
p.multi();
p.set("foooo", "barrr");
jedis.resetState();
assertEquals(null, jedis.get("foooo"));
}
@Test
public void testResetStateWhenInWatch() {
jedis.watch("mykey", "somekey");
// state reset : unwatch
jedis.resetState();
Transaction t = jedis.multi();
nj.connect();
nj.auth("foobared");
nj.set("mykey", "bar");
nj.disconnect();
t.set("mykey", "foo");
List<Object> resp = t.exec();
assertNotNull(resp);
assertEquals(1, resp.size());
assertEquals("foo", jedis.get("mykey"));
}
} }

View File

@@ -117,30 +117,30 @@ public class VariadicCommandsTest extends JedisCommandTestBase {
@Test @Test
public void zadd() { public void zadd() {
Map<Double, String> scoreMembers = new HashMap<Double, String>(); Map<String, Double> scoreMembers = new HashMap<String, Double>();
scoreMembers.put(1d, "bar"); scoreMembers.put("bar", 1d);
scoreMembers.put(10d, "foo"); scoreMembers.put("foo", 10d);
long status = jedis.zadd("foo", scoreMembers); long status = jedis.zadd("foo", scoreMembers);
assertEquals(2, status); assertEquals(2, status);
scoreMembers.clear(); scoreMembers.clear();
scoreMembers.put(0.1d, "car"); scoreMembers.put("car", 0.1d);
scoreMembers.put(2d, "bar"); scoreMembers.put("bar", 2d);
status = jedis.zadd("foo", scoreMembers); status = jedis.zadd("foo", scoreMembers);
assertEquals(1, status); assertEquals(1, status);
Map<Double, byte[]> bscoreMembers = new HashMap<Double, byte[]>(); Map<byte[], Double> bscoreMembers = new HashMap<byte[], Double>();
bscoreMembers.put(1d, bbar); bscoreMembers.put(bbar, 1d);
bscoreMembers.put(10d, bfoo); bscoreMembers.put(bfoo, 10d);
status = jedis.zadd(bfoo, bscoreMembers); status = jedis.zadd(bfoo, bscoreMembers);
assertEquals(2, status); assertEquals(2, status);
bscoreMembers.clear(); bscoreMembers.clear();
bscoreMembers.put(0.1d, bcar); bscoreMembers.put(bcar, 0.1d);
bscoreMembers.put(2d, bbar); bscoreMembers.put(bbar, 2d);
status = jedis.zadd(bfoo, bscoreMembers); status = jedis.zadd(bfoo, bscoreMembers);
assertEquals(1, status); assertEquals(1, status);

View File

@@ -0,0 +1,128 @@
package redis.clients.jedis.tests.utils;
import java.util.List;
import java.util.Map;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
public class JedisSentinelTestUtil {
public static void waitForSentinelRecognizeRedisReplication(
HostAndPort sentinel, String masterName, HostAndPort master,
List<HostAndPort> slaves) throws InterruptedException {
Jedis sentinelJedis = new Jedis(sentinel.getHost(), sentinel.getPort());
while (true) {
Thread.sleep(1000);
if (!isMasterRecognized(sentinelJedis, masterName, master)) {
System.out.println("Master not recognized by Sentinel "
+ sentinel.getHost() + ":" + sentinel.getPort()
+ ", sleep...");
continue;
}
if (!isSlavesRecognized(sentinelJedis, masterName, slaves)) {
System.out.println("Slaves not recognized by Sentinel "
+ sentinel.getHost() + ":" + sentinel.getPort()
+ ", sleep...");
continue;
}
// all recognized
break;
}
}
public static HostAndPort waitForNewPromotedMaster(HostAndPort sentinel,
String masterName, HostAndPort oldMaster)
throws InterruptedException {
Jedis sentinelJedis = new Jedis(sentinel.getHost(), sentinel.getPort());
HostAndPort newMaster = null;
while (true) {
Thread.sleep(1000);
List<String> sentinelMasterInfos = sentinelJedis
.sentinelGetMasterAddrByName(masterName);
if (sentinelMasterInfos == null)
continue;
newMaster = new HostAndPort(sentinelMasterInfos.get(0),
Integer.parseInt(sentinelMasterInfos.get(1)));
if (!newMaster.equals(oldMaster))
break;
System.out
.println("Sentinel's master is not yet changed, sleep...");
}
return newMaster;
}
public static void waitForSentinelsRecognizeEachOthers()
throws InterruptedException {
// During failover, master has been changed
// It means that sentinels need to recognize other sentinels from new
// master's hello channel
// Without recognizing, Sentinels cannot run failover
// Sentinels need to take some time to recognize each other...
// http://redis.io/topics/sentinel
// Sentinel Rule #8: Every Sentinel publishes a message to every
// monitored master
// Pub/Sub channel __sentinel__:hello, every five seconds, blabla...
// FIXME There're no command for sentinel to list recognized sentinels
// so sleep wisely (channel's hello message interval + margin)
Thread.sleep(5000 + 500);
}
private static boolean isMasterRecognized(Jedis sentinelJedis,
String masterName, HostAndPort master) {
List<String> sentinelMasterInfos = sentinelJedis
.sentinelGetMasterAddrByName(masterName);
if (sentinelMasterInfos == null)
return false;
HostAndPort sentinelMaster = new HostAndPort(
sentinelMasterInfos.get(0),
Integer.parseInt(sentinelMasterInfos.get(1)));
return sentinelMaster.equals(master);
}
private static boolean isSlavesRecognized(Jedis sentinelJedis,
String masterName, List<HostAndPort> slaves) {
List<Map<String, String>> slavesMap = sentinelJedis
.sentinelSlaves(masterName);
if (slavesMap.size() != slaves.size())
return false;
int slavesRecognized = 0;
for (HostAndPort slave : slaves) {
if (isSlaveFoundInSlavesMap(slavesMap, slave))
slavesRecognized++;
}
return slavesRecognized == slaves.size();
}
private static boolean isSlaveFoundInSlavesMap(
List<Map<String, String>> slavesMap, HostAndPort slave) {
for (Map<String, String> slaveMap : slavesMap) {
HostAndPort sentinelSlave = new HostAndPort(slaveMap.get("ip"),
Integer.parseInt(slaveMap.get("port")));
if (sentinelSlave.equals(slave))
return true;
}
return false;
}
}