diff --git a/src/main/java/redis/clients/jedis/BinaryJedis.java b/src/main/java/redis/clients/jedis/BinaryJedis.java index 09adf46..4166b11 100644 --- a/src/main/java/redis/clients/jedis/BinaryJedis.java +++ b/src/main/java/redis/clients/jedis/BinaryJedis.java @@ -17,6 +17,7 @@ import redis.clients.jedis.BinaryClient.LIST_POSITION; import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.exceptions.JedisException; import redis.clients.util.JedisByteHashMap; +import redis.clients.util.JedisURIHelper; import redis.clients.util.SafeEncoder; public class BinaryJedis implements BasicCommands, BinaryJedisCommands, @@ -29,11 +30,7 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, public BinaryJedis(final String host) { URI uri = URI.create(host); if (uri.getScheme() != null && uri.getScheme().equals("redis")) { - client = new Client(uri.getHost(), uri.getPort()); - client.auth(uri.getUserInfo().split(":", 2)[1]); - client.getStatusCodeReply(); - client.select(Integer.parseInt(uri.getPath().split("/", 2)[1])); - client.getStatusCodeReply(); + initializeClientFromURI(uri); } else { client = new Client(host); } @@ -55,11 +52,28 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, } public BinaryJedis(URI uri) { + initializeClientFromURI(uri); + } + + public BinaryJedis(final URI uri, final int timeout) { + initializeClientFromURI(uri); + client.setTimeout(timeout); + } + + private void initializeClientFromURI(URI uri) { client = new Client(uri.getHost(), uri.getPort()); - client.auth(uri.getUserInfo().split(":", 2)[1]); - client.getStatusCodeReply(); - client.select(Integer.parseInt(uri.getPath().split("/", 2)[1])); - client.getStatusCodeReply(); + + String password = JedisURIHelper.getPassword(uri); + if (password != null) { + client.auth(password); + client.getStatusCodeReply(); + } + + Integer dbIndex = JedisURIHelper.getDBIndex(uri); + if (dbIndex > 0) { + client.select(dbIndex); + client.getStatusCodeReply(); + } } public String ping() { diff --git a/src/main/java/redis/clients/jedis/Jedis.java b/src/main/java/redis/clients/jedis/Jedis.java index d55f880..c80d938 100644 --- a/src/main/java/redis/clients/jedis/Jedis.java +++ b/src/main/java/redis/clients/jedis/Jedis.java @@ -35,6 +35,10 @@ public class Jedis extends BinaryJedis implements JedisCommands, super(uri); } + public Jedis(final URI uri, final int timeout) { + super(uri, timeout); + } + /** * Set the string value as value of the key. The string can't be longer than * 1073741824 bytes (1 GB). @@ -547,26 +551,27 @@ public class Jedis extends BinaryJedis implements JedisCommands, /** * INCRBYFLOAT *

- * INCRBYFLOAT commands are limited to double precision floating point values. + * INCRBYFLOAT commands are limited to double precision floating point + * values. *

* Note: this is actually a string operation, that is, in Redis there are * not "double" types. Simply the string stored at the key is parsed as a * base double precision floating point value, incremented, and then - * converted back as a string. There is no DECRYBYFLOAT but providing a + * converted back as a string. There is no DECRYBYFLOAT but providing a * negative value will work as expected. *

* Time complexity: O(1) - * + * * @param key * @param value * @return Double reply, this commands will reply with the new value of key * after the increment. */ public Double incrByFloat(final String key, final double value) { - checkIsInMulti(); - client.incrByFloat(key, value); - String dval = client.getBulkReply(); - return (dval != null ? new Double(dval) : null); + checkIsInMulti(); + client.incrByFloat(key, value); + String dval = client.getBulkReply(); + return (dval != null ? new Double(dval) : null); } /** @@ -763,28 +768,29 @@ public class Jedis extends BinaryJedis implements JedisCommands, /** * Increment the number stored at field in the hash at key by a double - * precision floating point value. If key does not exist, - * a new key holding a hash is created. If field does not - * exist or holds a string, the value is set to 0 before applying the - * operation. Since the value argument is signed you can use this command to - * perform both increments and decrements. + * precision floating point value. If key does not exist, a new key holding + * a hash is created. If field does not exist or holds a string, the value + * is set to 0 before applying the operation. Since the value argument is + * signed you can use this command to perform both increments and + * decrements. *

- * The range of values supported by HINCRBYFLOAT is limited to - * double precision floating point values. + * The range of values supported by HINCRBYFLOAT is limited to double + * precision floating point values. *

* Time complexity: O(1) - * + * * @param key * @param field * @param value - * @return Double precision floating point reply The new value at field after the increment - * operation. + * @return Double precision floating point reply The new value at field + * after the increment operation. */ - public Double hincrByFloat(final String key, final String field, final double value) { - checkIsInMulti(); - client.hincrByFloat(key, field, value); - final String dval = client.getBulkReply(); - return (dval != null ? new Double(dval) : null); + public Double hincrByFloat(final String key, final String field, + final double value) { + checkIsInMulti(); + client.hincrByFloat(key, field, value); + final String dval = client.getBulkReply(); + return (dval != null ? new Double(dval) : null); } /** @@ -2736,12 +2742,13 @@ public class Jedis extends BinaryJedis implements JedisCommands, client.getrange(key, startOffset, endOffset); return client.getBulkReply(); } - + public Long bitpos(final String key, final boolean value) { return bitpos(key, value, new BitPosParams()); } - - public Long bitpos(final String key, final boolean value, final BitPosParams params) { + + public Long bitpos(final String key, final boolean value, + final BitPosParams params) { client.bitpos(key, value, params); return client.getIntegerReply(); } @@ -3164,7 +3171,6 @@ public class Jedis extends BinaryJedis implements JedisCommands, return client.getIntegerReply(); } - public String psetex(final String key, final int milliseconds, final String value) { checkIsInMulti(); @@ -3334,55 +3340,55 @@ public class Jedis extends BinaryJedis implements JedisCommands, client.clusterSetSlotImporting(slot, nodeId); return client.getStatusCodeReply(); } - + public String clusterSetSlotStable(final int slot) { checkIsInMulti(); client.clusterSetSlotStable(slot); return client.getStatusCodeReply(); } - + public String clusterForget(final String nodeId) { checkIsInMulti(); client.clusterForget(nodeId); return client.getStatusCodeReply(); } - + public String clusterFlushSlots() { checkIsInMulti(); client.clusterFlushSlots(); return client.getStatusCodeReply(); } - + public Long clusterKeySlot(final String key) { checkIsInMulti(); client.clusterKeySlot(key); return client.getIntegerReply(); } - + public Long clusterCountKeysInSlot(final int slot) { checkIsInMulti(); client.clusterCountKeysInSlot(slot); return client.getIntegerReply(); } - + public String clusterSaveConfig() { checkIsInMulti(); client.clusterSaveConfig(); return client.getStatusCodeReply(); } - + public String clusterReplicate(final String nodeId) { checkIsInMulti(); client.clusterReplicate(nodeId); return client.getStatusCodeReply(); } - + public List clusterSlaves(final String nodeId) { checkIsInMulti(); client.clusterSlaves(nodeId); return client.getMultiBulkReply(); } - + public String clusterFailover() { checkIsInMulti(); client.clusterFailover(); @@ -3435,7 +3441,7 @@ public class Jedis extends BinaryJedis implements JedisCommands, } public void setDataSource(Pool jedisPool) { - this.dataSource = jedisPool; + this.dataSource = jedisPool; } public Long pfadd(final String key, final String... elements) { @@ -3452,7 +3458,7 @@ public class Jedis extends BinaryJedis implements JedisCommands, @Override public long pfcount(String... keys) { - checkIsInMulti(); + checkIsInMulti(); client.pfcount(keys); return client.getIntegerReply(); } diff --git a/src/main/java/redis/clients/jedis/JedisPool.java b/src/main/java/redis/clients/jedis/JedisPool.java index c6d2cb3..c5e98d3 100644 --- a/src/main/java/redis/clients/jedis/JedisPool.java +++ b/src/main/java/redis/clients/jedis/JedisPool.java @@ -5,6 +5,7 @@ import java.net.URI; import org.apache.commons.pool2.impl.GenericObjectPool; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; +import redis.clients.util.JedisURIHelper; import redis.clients.util.Pool; public class JedisPool extends Pool { @@ -24,8 +25,12 @@ public class JedisPool extends Pool { if (uri.getScheme() != null && uri.getScheme().equals("redis")) { String h = uri.getHost(); int port = uri.getPort(); - String password = uri.getUserInfo().split(":", 2)[1]; - int database = Integer.parseInt(uri.getPath().split("/", 2)[1]); + String password = JedisURIHelper.getPassword(uri); + int database = 0; + Integer dbIndex = JedisURIHelper.getDBIndex(uri); + if (dbIndex != null) { + database = dbIndex.intValue(); + } this.internalPool = new GenericObjectPool( new JedisFactory(h, port, Protocol.DEFAULT_TIMEOUT, password, database, null), @@ -39,13 +44,11 @@ public class JedisPool extends Pool { } public JedisPool(final URI uri) { - String h = uri.getHost(); - int port = uri.getPort(); - String password = uri.getUserInfo().split(":", 2)[1]; - int database = Integer.parseInt(uri.getPath().split("/", 2)[1]); - this.internalPool = new GenericObjectPool(new JedisFactory(h, - port, Protocol.DEFAULT_TIMEOUT, password, database, null), - new GenericObjectPoolConfig()); + this(new GenericObjectPoolConfig(), uri, Protocol.DEFAULT_TIMEOUT); + } + + public JedisPool(final URI uri, final int timeout) { + this(new GenericObjectPoolConfig(), uri, timeout); } public JedisPool(final GenericObjectPoolConfig poolConfig, @@ -79,6 +82,18 @@ public class JedisPool extends Pool { database, clientName)); } + public JedisPool(final GenericObjectPoolConfig poolConfig, final URI uri) { + this(poolConfig, uri, Protocol.DEFAULT_TIMEOUT); + } + + public JedisPool(final GenericObjectPoolConfig poolConfig, final URI uri, + final int timeout) { + super(poolConfig, new JedisFactory(uri.getHost(), uri.getPort(), + timeout, JedisURIHelper.getPassword(uri), + JedisURIHelper.getDBIndex(uri) != null ? JedisURIHelper + .getDBIndex(uri) : 0, null)); + } + @Override public Jedis getResource() { Jedis jedis = super.getResource(); diff --git a/src/main/java/redis/clients/util/JedisURIHelper.java b/src/main/java/redis/clients/util/JedisURIHelper.java new file mode 100644 index 0000000..d2039a8 --- /dev/null +++ b/src/main/java/redis/clients/util/JedisURIHelper.java @@ -0,0 +1,26 @@ +package redis.clients.util; + +import java.net.URI; + +public class JedisURIHelper { + public static String getPassword(URI uri) { + String userInfo = uri.getUserInfo(); + if (userInfo != null) { + return userInfo.split(":", 2)[1]; + } + return null; + } + + public static Integer getDBIndex(URI uri) { + String[] pathSplit = uri.getPath().split("/", 2); + if (pathSplit.length > 1) { + String dbIndexStr = pathSplit[1]; + if (dbIndexStr.isEmpty()) { + return 0; + } + return Integer.parseInt(dbIndexStr); + } else { + return 0; + } + } +} diff --git a/src/test/java/redis/clients/jedis/tests/JedisPoolTest.java b/src/test/java/redis/clients/jedis/tests/JedisPoolTest.java index cadb208..f8fb2ef 100644 --- a/src/test/java/redis/clients/jedis/tests/JedisPoolTest.java +++ b/src/test/java/redis/clients/jedis/tests/JedisPoolTest.java @@ -164,6 +164,12 @@ public class JedisPoolTest extends Assert { assertEquals("bar", jedis.get("foo")); } + @Test + public void allowUrlWithNoDBAndNoPassword() throws URISyntaxException { + new JedisPool("redis://localhost:6380"); + new JedisPool(new URI("redis://localhost:6380")); + } + @Test public void selectDatabaseOnActivation() { JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(), diff --git a/src/test/java/redis/clients/jedis/tests/JedisTest.java b/src/test/java/redis/clients/jedis/tests/JedisTest.java index 3f5cdf1..3b7a87f 100644 --- a/src/test/java/redis/clients/jedis/tests/JedisTest.java +++ b/src/test/java/redis/clients/jedis/tests/JedisTest.java @@ -57,6 +57,14 @@ public class JedisTest extends JedisCommandTestBase { jedis.hmget("foobar", "foo"); } + @Test(expected = JedisConnectionException.class) + public void timeoutConnectionWithURI() throws Exception { + jedis = new Jedis(new URI("redis://:foobared@localhost:6380/2"), 15000); + jedis.configSet("timeout", "1"); + Thread.sleep(2000); + jedis.hmget("foobar", "foo"); + } + @Test(expected = JedisDataException.class) public void failWhenSendingNullValues() { jedis.set("foo", null); @@ -92,7 +100,22 @@ public class JedisTest extends JedisCommandTestBase { assertEquals("PONG", jedis.ping()); assertEquals("bar", jedis.get("foo")); } - + + @Test + public void allowUrlWithNoDBAndNoPassword() { + Jedis jedis = new Jedis("redis://localhost:6380"); + jedis.auth("foobared"); + assertEquals(jedis.getClient().getHost(), "localhost"); + assertEquals(jedis.getClient().getPort(), 6380); + assertEquals(jedis.getDB(), (Long) 0L); + + jedis = new Jedis("redis://localhost:6380/"); + jedis.auth("foobared"); + assertEquals(jedis.getClient().getHost(), "localhost"); + assertEquals(jedis.getClient().getPort(), 6380); + assertEquals(jedis.getDB(), (Long) 0L); + } + @Test public void checkCloseable() { jedis.close();