diff --git a/docs/src/reference/docbook/appendix/appendix-command-reference.xml b/docs/src/reference/docbook/appendix/appendix-command-reference.xml index 2242301640..4a1d461118 100644 --- a/docs/src/reference/docbook/appendix/appendix-command-reference.xml +++ b/docs/src/reference/docbook/appendix/appendix-command-reference.xml @@ -1,4 +1,4 @@ - +# Spring Data Redis Supported Commands @@ -23,8 +23,8 @@ BLPOPX BRPOPX BRPOPLPUSHX - CLIENT GETNAME- CLIENT KILLX + CLIENT GETNAMEX CLIENT LIST- CLIENT SETNAMEX CONFIG GETX diff --git a/gradle.properties b/gradle.properties index f09fb8eb53..2c52e5bfce 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ jredisVersion=06052013 jedisVersion=2.4.1 springVersion=3.2.8.RELEASE log4jVersion=1.2.17 -version=1.3.0.BUILD-SNAPSHOT +version=1.3.0.DATAREDIS-270-SNAPSHOT srpVersion=0.7 jacksonVersion=1.8.8 fasterXmlJacksonVersion=2.2.0 diff --git a/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java b/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java index beeac1aa9a..e8ac41eed5 100644 --- a/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java @@ -2191,15 +2191,6 @@ public Long time() { return this.delegate.time(); } - /* - * (non-Javadoc) - * @see org.springframework.data.redis.connection.RedisServerCommands#killClient(byte[]) - */ - @Override - public void killClient(String host, int port) { - this.delegate.killClient(host, port); - } - /** * Specifies if pipelined and tx results should be deserialized to Strings. If false, results of * {@link #closePipeline()} and {@link #exec()} will be of the type returned by the underlying connection @@ -2257,4 +2248,20 @@ public void setClientName(String name) { setClientName(this.serializer.serialize(name)); } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisServerCommands#killClient(byte[]) + */ + @Override + public void killClient(String host, int port) { + this.delegate.killClient(host, port); + } + + /* + * @see org.springframework.data.redis.connection.RedisServerCommands#getClientName() + */ + @Override + public String getClientName() { + return this.delegate.getClientName(); + } } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisServerCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisServerCommands.java index 3219df9f4a..1268d83757 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisServerCommands.java @@ -177,4 +177,13 @@ public enum ShutdownOption { * @since 1.3 */ void setClientName(byte[] name); + + /** + * Returns the name of the current connection. + * + * @see http://redis.io/commands/client-getname + * @return + * @since 1.3 + */ + String getClientName(); } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java index 56a4df4822..406142381d 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java @@ -2841,6 +2841,19 @@ public void setClientName(byte[] name) { jedis.clientSetname(name); } + /* + * @see org.springframework.data.redis.connection.RedisServerCommands#getClientName() + */ + @Override + public String getClientName() { + + if (isPipelined() || isQueueing()) { + throw new UnsupportedOperationException(); + } + + return jedis.clientGetname(); + } + /** * Specifies if pipelined results should be converted to the expected data type. If false, results of * {@link #closePipeline()} and {@link #exec()} will be of the type returned by the Jedis driver diff --git a/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java b/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java index 2e4656c331..24613a97f3 100644 --- a/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java @@ -1195,4 +1195,13 @@ public void killClient(String host, int port) { public void setClientName(byte[] name) { throw new UnsupportedOperationException("'CLIENT SETNAME' is not supported by the JRedis driver."); } + + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisServerCommands#getClientName() + */ + @Override + public String getClientName() { + throw new UnsupportedOperationException("The 'CLIENT GETNAME' command is not supported by the JRedis driver."); + } } diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java index 96836323d5..aa1750e253 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java @@ -2935,6 +2935,30 @@ public void setClientName(byte[] name) { getAsyncConnection().clientSetname(name); } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisServerCommands#getClientName() + */ + @Override + public String getClientName() { + + try { + + if (isPipelined()) { + pipeline(new LettuceResult(getAsyncConnection().clientGetname(), LettuceConverters.bytesToString())); + return null; + } + if (isQueueing()) { + transaction(new LettuceTxResult(getConnection().clientGetname(), LettuceConverters.bytesToString())); + return null; + } + + return LettuceConverters.toString(getConnection().clientGetname()); + } catch (Exception ex) { + throw convertLettuceAccessException(ex); + } + } + /** * Specifies if pipelined and transaction results should be converted to the expected data type. If false, results of * {@link #closePipeline()} and {@link #exec()} will be of the type returned by the Lettuce driver diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java index 46d01c1ab8..11cac3959a 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java @@ -16,6 +16,7 @@ package org.springframework.data.redis.connection.lettuce; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.LinkedHashSet; import java.util.List; @@ -47,6 +48,7 @@ abstract public class LettuceConverters extends Converters { private static final Converter DATE_TO_LONG; private static final Converter, Set> BYTES_LIST_TO_BYTES_SET; + private static final Converter BYTES_TO_STRING; private static final Converter, List> BYTES_SET_TO_BYTES_LIST; private static final Converter, List> KEY_VALUE_TO_BYTES_LIST; private static final Converter>, Set> SCORED_VALUES_TO_TUPLE_SET; @@ -65,6 +67,17 @@ public Set convert(List results) { return results != null ? new LinkedHashSet(results) : null; } + }; + BYTES_TO_STRING = new Converter() { + + @Override + public String convert(byte[] source) { + if (source == null || Arrays.equals(source, new byte[0])) { + return null; + } + return new String(source); + } + }; BYTES_SET_TO_BYTES_LIST = new Converter, List>() { public List convert(Set results) { @@ -110,6 +123,10 @@ public static Converter, Set> bytesListToBytesSet() { return BYTES_LIST_TO_BYTES_SET; } + public static Converter bytesToString() { + return BYTES_TO_STRING; + } + public static Converter, List> keyValueToBytesList() { return KEY_VALUE_TO_BYTES_LIST; } @@ -158,6 +175,10 @@ public static DataAccessException toDataAccessException(Exception ex) { return EXCEPTION_CONVERTER.convert(ex); } + public static String toString(byte[] source) { + return BYTES_TO_STRING.convert(source); + } + public static ScriptOutputType toScriptOutputType(ReturnType returnType) { switch (returnType) { case BOOLEAN: diff --git a/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java b/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java index bda3701ee9..7ebb9a5c43 100644 --- a/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java @@ -2260,6 +2260,26 @@ public void setClientName(byte[] name) { } } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisServerCommands#getClientName() + */ + @Override + public String getClientName() { + + try { + + if (isPipelined()) { + pipeline(new SrpGenericResult(pipeline.client_getname(), SrpConverters.replyToString())); + return null; + } + + return SrpConverters.toString(client.client_getname()); + } catch (Exception ex) { + throw convertSrpAccessException(ex); + } + } + private List closeTransaction() { List results = Collections.emptyList(); if (txTracker != null) { diff --git a/src/main/java/org/springframework/data/redis/connection/srp/SrpConverters.java b/src/main/java/org/springframework/data/redis/connection/srp/SrpConverters.java index ee6b032176..6128393351 100644 --- a/src/main/java/org/springframework/data/redis/connection/srp/SrpConverters.java +++ b/src/main/java/org/springframework/data/redis/connection/srp/SrpConverters.java @@ -35,7 +35,6 @@ import org.springframework.data.redis.connection.RedisZSetCommands.Tuple; import org.springframework.data.redis.connection.convert.Converters; import org.springframework.util.Assert; -import org.springframework.util.NumberUtils; import redis.client.RedisException; import redis.reply.IntegerReply; @@ -61,6 +60,7 @@ abstract public class SrpConverters extends Converters { private static final Converter> REPLIES_TO_BYTES_MAP; private static final Converter> REPLIES_TO_BOOLEAN_LIST; private static final Converter> REPLIES_TO_STRING_LIST; + private static final Converter REPLY_TO_STRING; private static final Converter BYTES_TO_PROPERTIES; private static final Converter BYTES_TO_STRING; private static final Converter BYTES_TO_DOUBLE; @@ -171,6 +171,16 @@ public List convert(Reply[] source) { return results; } }; + REPLY_TO_STRING = new Converter() { + + @Override + public String convert(Reply source) { + if (source == null) { + return null; + } + return SrpConverters.toString((byte[]) source.data()); + } + }; } public static Converter> repliesToBytesList() { @@ -201,6 +211,10 @@ public static Converter bytesToString() { return BYTES_TO_STRING; } + public static Converter replyToString() { + return REPLY_TO_STRING; + } + public static Converter> repliesToBooleanList() { return REPLIES_TO_BOOLEAN_LIST; } @@ -237,6 +251,10 @@ public static Map toBytesMap(Reply[] source) { return REPLIES_TO_BYTES_MAP.convert(source); } + public static String toString(Reply source) { + return REPLY_TO_STRING.convert(source); + } + public static String toString(byte[] source) { return BYTES_TO_STRING.convert(source); } @@ -293,4 +311,5 @@ public static byte[] toBytes(Position source) { public static List toStringList(String source) { return Collections.singletonList(source); } + } diff --git a/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTests.java b/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTests.java index 474de96ee4..162b5f79a3 100644 --- a/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTests.java +++ b/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTests.java @@ -1720,6 +1720,16 @@ public void settingClientNameShouldDelegateToNativeConnection() { verify(nativeConnection, times(1)).setClientName(eq("foo".getBytes())); } + /** + * @see DATAREDIS-270 + */ + @Test + public void testGetClientNameIsDelegatedCorrectlyToNativeConnection() { + + actual.add(connection.getClientName()); + verify(nativeConnection, times(1)).getClientName(); + } + protected List getResults() { return actual; } diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionUnitTestSuite.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionUnitTestSuite.java index 6cca22922d..1effabe571 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionUnitTestSuite.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionUnitTestSuite.java @@ -123,6 +123,17 @@ public void killClientShouldDelegateCallCorrectly() { connection.killClient("127.0.0.1", 1001); verifyNativeConnectionInvocation().clientKill(eq("127.0.0.1:1001")); } + + /** + * @see DATAREDIS-270 + */ + @Test + public void getClientNameShouldSendRequestCorrectly() { + + connection.getClientName(); + verifyNativeConnectionInvocation().clientGetname(); + } + } public static class JedisConnectionPipelineUnitTests extends JedisConnectionUnitTests { @@ -151,10 +162,23 @@ public void shutdownSaveShouldBeSentCorrectlyUsingLuaScript() { super.shutdownSaveShouldBeSentCorrectlyUsingLuaScript(); } + /** + * @see DATAREDIS-267 + */ @Test(expected = UnsupportedOperationException.class) public void killClientShouldDelegateCallCorrectly() { super.killClientShouldDelegateCallCorrectly(); } + + /** + * @see DATAREDIS-270 + */ + @Override + @Test(expected = UnsupportedOperationException.class) + public void getClientNameShouldSendRequestCorrectly() { + super.getClientNameShouldSendRequestCorrectly(); + } + } /** diff --git a/src/test/java/org/springframework/data/redis/connection/jredis/JRedisConnectionUnitTests.java b/src/test/java/org/springframework/data/redis/connection/jredis/JRedisConnectionUnitTests.java index 14b60f0de0..1172c080c5 100644 --- a/src/test/java/org/springframework/data/redis/connection/jredis/JRedisConnectionUnitTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jredis/JRedisConnectionUnitTests.java @@ -56,4 +56,13 @@ public void shutdownNosaveShouldThrowUnsupportedOperationException() { public void shutdownWithNullShouldThrowUnsupportedOperationException() { connection.shutdown(null); } + + /** + * @see DATAREDIS-270 + */ + @Test(expected = UnsupportedOperationException.class) + public void getClientNameShouldSendRequestCorrectly() { + connection.getClientName(); + } + } diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionUnitTestSuite.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionUnitTestSuite.java index 3b2587e619..a22a2b346e 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionUnitTestSuite.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionUnitTestSuite.java @@ -93,6 +93,16 @@ public void killClientShouldDelegateCallCorrectly() { verifyNativeConnectionInvocation().clientKill(eq(ipPort)); } + /** + * @see DATAREDIS-270 + */ + @Test + public void getClientNameShouldSendRequestCorrectly() { + + connection.getClientName(); + verifyNativeConnectionInvocation().clientGetname(); + } + } public static class LettucePipelineConnectionUnitTests extends LettuceConnectionUnitTests { diff --git a/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionUnitTestSuite.java b/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionUnitTestSuite.java index 2409503c37..72542b657e 100644 --- a/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionUnitTestSuite.java +++ b/src/test/java/org/springframework/data/redis/connection/srp/SrpConnectionUnitTestSuite.java @@ -89,6 +89,16 @@ public void killClientShouldDelegateCallCorrectly() { verifyNativeConnectionInvocation().client_kill(eq(ipPort)); } + /** + * @see DATAREDIS-270 + */ + @Test + public void getClientNameShouldSendRequestCorrectly() { + + connection.getClientName(); + verifyNativeConnectionInvocation().client_getname(); + } + } public static class SrpConnectionPiplineUnitTests extends AbstractConnectionUnitTestBase { @@ -135,6 +145,16 @@ public void shutdownWithNosaveIsCalledCorrectly() { verifyNativeConnectionInvocation().shutdown("NOSAVE".getBytes(Charsets.UTF_8), null); } + /** + * @see DATAREDIS-270 + */ + @Test + public void getClientNameShouldSendRequestCorrectly() { + + connection.getClientName(); + verifyNativeConnectionInvocation().client_getname(); + } + } }