DATAREDIS-270 - Add support for 'CLIENT GETNAME'.

Support for getting client connection name has been added for 'jedis', 'jredis' and 'srp' drivers.

Using 'jredis' will throw 'UnsupportedOperationException'.

Original Pull Request: #51
This commit is contained in:
Christoph Strobl
2014-03-17 13:48:33 +01:00
committed by Thomas Darimont
parent e280a23550
commit 4bf438f563
14 changed files with 207 additions and 12 deletions

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
#<?xml version="1.0" encoding="UTF-8"?>
<appendix xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="appendix-command-reference" xmlns:xi="http://www.w3.org/2001/XInclude">
<title>Spring Data Redis Supported Commands</title>
@@ -23,8 +23,8 @@
<row><entry><code>BLPOP</code></entry><entry>X</entry></row>
<row><entry><code>BRPOP</code></entry><entry>X</entry></row>
<row><entry><code>BRPOPLPUSH</code></entry><entry>X</entry></row>
<row><entry><code>CLIENT GETNAME</code></entry><entry>-</entry></row>
<row><entry><code>CLIENT KILL</code></entry><entry>X</entry></row>
<row><entry><code>CLIENT GETNAME</code></entry><entry>X</entry></row>
<row><entry><code>CLIENT LIST</code></entry><entry>-</entry></row>
<row><entry><code>CLIENT SETNAME</code></entry><entry>X</entry></row>
<row><entry><code>CONFIG GET</code></entry><entry>X</entry></row>

View File

@@ -2191,15 +2191,6 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
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 class DefaultStringRedisConnection implements StringRedisConnection {
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();
}
}

View File

@@ -177,4 +177,13 @@ public interface RedisServerCommands {
* @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();
}

View File

@@ -2841,6 +2841,19 @@ public class JedisConnection implements RedisConnection {
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

View File

@@ -1195,4 +1195,13 @@ public class JredisConnection implements RedisConnection {
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.");
}
}

View File

@@ -2935,6 +2935,30 @@ public class LettuceConnection implements RedisConnection {
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

View File

@@ -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, Long> DATE_TO_LONG;
private static final Converter<List<byte[]>, Set<byte[]>> BYTES_LIST_TO_BYTES_SET;
private static final Converter<byte[], String> BYTES_TO_STRING;
private static final Converter<Set<byte[]>, List<byte[]>> BYTES_SET_TO_BYTES_LIST;
private static final Converter<KeyValue<byte[], byte[]>, List<byte[]>> KEY_VALUE_TO_BYTES_LIST;
private static final Converter<List<ScoredValue<byte[]>>, Set<Tuple>> SCORED_VALUES_TO_TUPLE_SET;
@@ -65,6 +67,17 @@ abstract public class LettuceConverters extends Converters {
return results != null ? new LinkedHashSet<byte[]>(results) : null;
}
};
BYTES_TO_STRING = new Converter<byte[], String>() {
@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<Set<byte[]>, List<byte[]>>() {
public List<byte[]> convert(Set<byte[]> results) {
@@ -110,6 +123,10 @@ abstract public class LettuceConverters extends Converters {
return BYTES_LIST_TO_BYTES_SET;
}
public static Converter<byte[], String> bytesToString() {
return BYTES_TO_STRING;
}
public static Converter<KeyValue<byte[], byte[]>, List<byte[]>> keyValueToBytesList() {
return KEY_VALUE_TO_BYTES_LIST;
}
@@ -158,6 +175,10 @@ abstract public class LettuceConverters extends Converters {
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:

View File

@@ -2260,6 +2260,26 @@ public class SrpConnection implements RedisConnection {
}
}
/*
* (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<Object> closeTransaction() {
List<Object> results = Collections.emptyList();
if (txTracker != null) {

View File

@@ -35,7 +35,6 @@ import org.springframework.data.redis.connection.RedisStringCommands.BitOperatio
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<Reply[], Map<byte[], byte[]>> REPLIES_TO_BYTES_MAP;
private static final Converter<Reply[], List<Boolean>> REPLIES_TO_BOOLEAN_LIST;
private static final Converter<Reply[], List<String>> REPLIES_TO_STRING_LIST;
private static final Converter<Reply, String> REPLY_TO_STRING;
private static final Converter<byte[], Properties> BYTES_TO_PROPERTIES;
private static final Converter<byte[], String> BYTES_TO_STRING;
private static final Converter<byte[], Double> BYTES_TO_DOUBLE;
@@ -171,6 +171,16 @@ abstract public class SrpConverters extends Converters {
return results;
}
};
REPLY_TO_STRING = new Converter<Reply, String>() {
@Override
public String convert(Reply source) {
if (source == null) {
return null;
}
return SrpConverters.toString((byte[]) source.data());
}
};
}
public static Converter<Reply[], List<byte[]>> repliesToBytesList() {
@@ -201,6 +211,10 @@ abstract public class SrpConverters extends Converters {
return BYTES_TO_STRING;
}
public static Converter<Reply, String> replyToString() {
return REPLY_TO_STRING;
}
public static Converter<Reply[], List<Boolean>> repliesToBooleanList() {
return REPLIES_TO_BOOLEAN_LIST;
}
@@ -237,6 +251,10 @@ abstract public class SrpConverters extends Converters {
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 @@ abstract public class SrpConverters extends Converters {
public static List<String> toStringList(String source) {
return Collections.singletonList(source);
}
}

View File

@@ -1720,6 +1720,16 @@ public class DefaultStringRedisConnectionTests {
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<Object> getResults() {
return actual;
}

View File

@@ -123,6 +123,17 @@ public class JedisConnectionUnitTestSuite {
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 class JedisConnectionUnitTestSuite {
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();
}
}
/**

View File

@@ -56,4 +56,13 @@ public class JRedisConnectionUnitTests extends AbstractConnectionUnitTestBase<JR
public void shutdownWithNullShouldThrowUnsupportedOperationException() {
connection.shutdown(null);
}
/**
* @see DATAREDIS-270
*/
@Test(expected = UnsupportedOperationException.class)
public void getClientNameShouldSendRequestCorrectly() {
connection.getClientName();
}
}

View File

@@ -93,6 +93,16 @@ public class LettuceConnectionUnitTestSuite {
verifyNativeConnectionInvocation().clientKill(eq(ipPort));
}
/**
* @see DATAREDIS-270
*/
@Test
public void getClientNameShouldSendRequestCorrectly() {
connection.getClientName();
verifyNativeConnectionInvocation().clientGetname();
}
}
public static class LettucePipelineConnectionUnitTests extends LettuceConnectionUnitTests {

View File

@@ -89,6 +89,16 @@ public class SrpConnectionUnitTestSuite {
verifyNativeConnectionInvocation().client_kill(eq(ipPort));
}
/**
* @see DATAREDIS-270
*/
@Test
public void getClientNameShouldSendRequestCorrectly() {
connection.getClientName();
verifyNativeConnectionInvocation().client_getname();
}
}
public static class SrpConnectionPiplineUnitTests extends AbstractConnectionUnitTestBase<Pipeline> {
@@ -135,6 +145,16 @@ public class SrpConnectionUnitTestSuite {
verifyNativeConnectionInvocation().shutdown("NOSAVE".getBytes(Charsets.UTF_8), null);
}
/**
* @see DATAREDIS-270
*/
@Test
public void getClientNameShouldSendRequestCorrectly() {
connection.getClientName();
verifyNativeConnectionInvocation().client_getname();
}
}
}