DATAREDIS-277 - Add support for 'SLAVEOF'.
'SLAVEOF' and 'SLAVEOF NO ONE' are available via 'RedisConnection' and 'RedisOperations' for 'jedis', 'jredis', 'lettuce' and 'srp'. Original Pull Request: #57
This commit is contained in:
committed by
Thomas Darimont
parent
2b280e57e8
commit
d35375ec74
@@ -138,7 +138,7 @@
|
||||
<row><entry><code>SINTER</code></entry><entry>X</entry></row>
|
||||
<row><entry><code>SINTERSTORE</code></entry><entry>X</entry></row>
|
||||
<row><entry><code>SISMEMBER</code></entry><entry>X</entry></row>
|
||||
<row><entry><code>SLAVEOF</code></entry><entry>-</entry></row>
|
||||
<row><entry><code>SLAVEOF</code></entry><entry>X</entry></row>
|
||||
<row><entry><code>SLOWLOG</code></entry><entry>-</entry></row>
|
||||
<row><entry><code>SMEMBERS</code></entry><entry>X</entry></row>
|
||||
<row><entry><code>SMOVE</code></entry><entry>X</entry></row>
|
||||
|
||||
@@ -2197,6 +2197,24 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
|
||||
return this.delegate.getClientList();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisServerCommands#slaveOf(java.lang.String, int)
|
||||
*/
|
||||
@Override
|
||||
public void slaveOf(String host, int port) {
|
||||
this.delegate.slaveOf(host, port);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisServerCommands#slaveOfNoOne()
|
||||
*/
|
||||
@Override
|
||||
public void slaveOfNoOne() {
|
||||
this.delegate.slaveOfNoOne();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
@@ -165,7 +165,7 @@ public interface RedisServerCommands {
|
||||
Long time();
|
||||
|
||||
/**
|
||||
* Closes a given client connection identified by {@literal ip:port}.
|
||||
* <<<<<<< HEAD Closes a given client connection identified by {@literal ip:port}.
|
||||
*
|
||||
* @param host of connection to close.
|
||||
* @param port of connection to close
|
||||
@@ -197,4 +197,22 @@ public interface RedisServerCommands {
|
||||
* @see http://redis.io/commands/client-list
|
||||
*/
|
||||
List<RedisClientInfo> getClientList();
|
||||
|
||||
/**
|
||||
* Change redis replication setting to new master.
|
||||
*
|
||||
* @param host
|
||||
* @param port
|
||||
* @since 1.3
|
||||
* @see http://redis.io/commands/slaveof
|
||||
*/
|
||||
void slaveOf(String host, int port);
|
||||
|
||||
/**
|
||||
* Change server into master.
|
||||
*
|
||||
* @since 1.3
|
||||
* @see http://redis.io/commands/slaveof
|
||||
*/
|
||||
void slaveOfNoOne();
|
||||
}
|
||||
|
||||
@@ -2051,8 +2051,7 @@ public class JedisConnection implements RedisConnection {
|
||||
|
||||
public Long zInterStore(byte[] destKey, Aggregate aggregate, int[] weights, byte[]... sets) {
|
||||
try {
|
||||
ZParams zparams = new ZParams().weights(weights).aggregate(
|
||||
redis.clients.jedis.ZParams.Aggregate.valueOf(aggregate.name()));
|
||||
ZParams zparams = new ZParams().weights(weights).aggregate(ZParams.Aggregate.valueOf(aggregate.name()));
|
||||
|
||||
if (isPipelined()) {
|
||||
pipeline(new JedisResult(pipeline.zinterstore(destKey, zparams, sets)));
|
||||
@@ -2382,8 +2381,7 @@ public class JedisConnection implements RedisConnection {
|
||||
|
||||
public Long zUnionStore(byte[] destKey, Aggregate aggregate, int[] weights, byte[]... sets) {
|
||||
try {
|
||||
ZParams zparams = new ZParams().weights(weights).aggregate(
|
||||
redis.clients.jedis.ZParams.Aggregate.valueOf(aggregate.name()));
|
||||
ZParams zparams = new ZParams().weights(weights).aggregate(ZParams.Aggregate.valueOf(aggregate.name()));
|
||||
|
||||
if (isPipelined()) {
|
||||
pipeline(new JedisResult(pipeline.zunionstore(destKey, zparams, sets)));
|
||||
@@ -2830,6 +2828,23 @@ public class JedisConnection implements RedisConnection {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.data.redis.connection.RedisServerCommands#slaveOf(java.lang.String, int)
|
||||
*/
|
||||
@Override
|
||||
public void slaveOf(String host, int port) {
|
||||
|
||||
Assert.hasText(host, "Host must not be null for 'SLAVEOF' command.");
|
||||
if (isQueueing() || isPipelined()) {
|
||||
throw new UnsupportedOperationException("'SLAVEOF' cannot be called in pipline / transaction mode.");
|
||||
}
|
||||
try {
|
||||
this.jedis.slaveof(host, port);
|
||||
} catch (Exception e) {
|
||||
throw convertJedisAccessException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.data.redis.connection.RedisServerCommands#setClientName(java.lang.String)
|
||||
*/
|
||||
@@ -2868,6 +2883,23 @@ public class JedisConnection implements RedisConnection {
|
||||
return JedisConverters.toListOfRedisClientInformation(this.jedis.clientList());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisServerCommands#slaveOfNoOne()
|
||||
*/
|
||||
@Override
|
||||
public void slaveOfNoOne() {
|
||||
|
||||
if (isQueueing() || isPipelined()) {
|
||||
throw new UnsupportedOperationException("'SLAVEOF' cannot be called in pipline / transaction mode.");
|
||||
}
|
||||
try {
|
||||
this.jedis.slaveofNoOne();
|
||||
} catch (Exception e) {
|
||||
throw convertJedisAccessException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
@@ -1197,6 +1197,20 @@ public class JredisConnection implements RedisConnection {
|
||||
throw new UnsupportedOperationException("'CLIENT SETNAME' is not supported by the JRedis driver.");
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisServerCommands#slaveOf(java.lang.String, int)
|
||||
*/
|
||||
@Override
|
||||
public void slaveOf(String host, int port) {
|
||||
|
||||
try {
|
||||
this.jredis.slaveof(host, port);
|
||||
} catch (Exception e) {
|
||||
throw convertJredisAccessException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisServerCommands#getClientName()
|
||||
@@ -1209,4 +1223,17 @@ public class JredisConnection implements RedisConnection {
|
||||
public List<RedisClientInfo> getClientList() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.data.redis.connection.RedisServerCommands#slaveOfNoOne()
|
||||
*/
|
||||
@Override
|
||||
public void slaveOfNoOne() {
|
||||
|
||||
try {
|
||||
this.jredis.slaveofnone();
|
||||
} catch (Exception e) {
|
||||
throw convertJredisAccessException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2939,6 +2939,29 @@ public class LettuceConnection implements RedisConnection {
|
||||
getAsyncConnection().clientSetname(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisServerCommands#slaveOf(java.lang.String, int)
|
||||
*/
|
||||
@Override
|
||||
public void slaveOf(String host, int port) {
|
||||
|
||||
Assert.hasText(host, "Host must not be null for 'SLAVEOF' command.");
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(new LettuceStatusResult(getAsyncConnection().slaveof(host, port)));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(new LettuceTxResult(getConnection().slaveof(host, port)));
|
||||
return;
|
||||
}
|
||||
getConnection().slaveof(host, port);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisServerCommands#getClientName()
|
||||
@@ -2978,6 +3001,27 @@ public class LettuceConnection implements RedisConnection {
|
||||
return LettuceConverters.toListOfRedisClientInformation(getConnection().clientList());
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.data.redis.connection.RedisServerCommands#slaveOfNoOne()
|
||||
*/
|
||||
@Override
|
||||
public void slaveOfNoOne() {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(new LettuceStatusResult(getAsyncConnection().slaveofNoOne()));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(new LettuceTxResult(getConnection().slaveofNoOne()));
|
||||
return;
|
||||
}
|
||||
getConnection().slaveofNoOne();
|
||||
} 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
|
||||
|
||||
@@ -2262,6 +2262,25 @@ public class SrpConnection implements RedisConnection {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisServerCommands#slaveOf(java.lang.String, int)
|
||||
*/
|
||||
@Override
|
||||
public void slaveOf(String host, int port) {
|
||||
|
||||
Assert.hasText(host, "Host must not be null for 'SLAVEOF' command.");
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(new SrpStatusResult(pipeline.slaveof(host, port)));
|
||||
return;
|
||||
}
|
||||
client.slaveof(host, port);
|
||||
} catch (Exception e) {
|
||||
throw convertSrpAccessException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisServerCommands#getClientName()
|
||||
@@ -2295,6 +2314,23 @@ public class SrpConnection implements RedisConnection {
|
||||
return SrpConverters.toListOfRedisClientInformation(this.client.client_list());
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.data.redis.connection.RedisServerCommands#slaveOfNoOne()
|
||||
*/
|
||||
@Override
|
||||
public void slaveOfNoOne() {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(new SrpStatusResult(pipeline.slaveof("NO", "ONE")));
|
||||
return;
|
||||
}
|
||||
client.slaveof("NO", "ONE");
|
||||
} catch (Exception e) {
|
||||
throw convertSrpAccessException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Object> closeTransaction() {
|
||||
List<Object> results = Collections.emptyList();
|
||||
if (txTracker != null) {
|
||||
|
||||
@@ -303,4 +303,20 @@ public interface RedisOperations<K, V> {
|
||||
* @since 1.3
|
||||
*/
|
||||
void killClient(String host, int port);
|
||||
|
||||
/**
|
||||
* Change redis replication setting to new master.
|
||||
*
|
||||
* @param host
|
||||
* @param port
|
||||
* @since 1.3
|
||||
*/
|
||||
void slaveOf(String host, int port);
|
||||
|
||||
/**
|
||||
* Change server into master.
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
void slaveOfNoOne();
|
||||
}
|
||||
|
||||
@@ -1019,4 +1019,38 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.data.redis.core.RedisOperations#slaveOf(java.lang.String, int)
|
||||
*/
|
||||
@Override
|
||||
public void slaveOf(final String host, final int port) {
|
||||
|
||||
execute(new RedisCallback<Void>() {
|
||||
@Override
|
||||
public Void doInRedis(RedisConnection connection) throws DataAccessException {
|
||||
|
||||
connection.slaveOf(host, port);
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.RedisOperations#slaveOfNoOne()
|
||||
*/
|
||||
@Override
|
||||
public void slaveOfNoOne() {
|
||||
|
||||
execute(new RedisCallback<Void>() {
|
||||
|
||||
@Override
|
||||
public Void doInRedis(RedisConnection connection) throws DataAccessException {
|
||||
connection.slaveOfNoOne();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,8 @@ public class JedisConnectionUnitTestSuite {
|
||||
}
|
||||
|
||||
/**
|
||||
* <<<<<<< HEAD
|
||||
*
|
||||
* @see DATAREDIS-267
|
||||
*/
|
||||
@Test
|
||||
@@ -134,6 +136,33 @@ public class JedisConnectionUnitTestSuite {
|
||||
verifyNativeConnectionInvocation().clientGetname();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREDIS-277
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void slaveOfShouldThrowExectpionWhenCalledForNullHost() {
|
||||
connection.slaveOf(null, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREDIS-277
|
||||
*/
|
||||
@Test
|
||||
public void slaveOfShouldBeSentCorrectly() {
|
||||
|
||||
connection.slaveOf("127.0.0.1", 1001);
|
||||
verifyNativeConnectionInvocation().slaveof(eq("127.0.0.1"), eq(1001));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREDIS-277
|
||||
*/
|
||||
@Test
|
||||
public void slaveOfNoOneShouldBeSentCorrectly() {
|
||||
|
||||
connection.slaveOfNoOne();
|
||||
verifyNativeConnectionInvocation().slaveofNoOne();
|
||||
}
|
||||
}
|
||||
|
||||
public static class JedisConnectionPipelineUnitTests extends JedisConnectionUnitTests {
|
||||
@@ -179,6 +208,23 @@ public class JedisConnectionUnitTestSuite {
|
||||
super.getClientNameShouldSendRequestCorrectly();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREDIS-277
|
||||
*/
|
||||
@Override
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void slaveOfShouldBeSentCorrectly() {
|
||||
super.slaveOfShouldBeSentCorrectly();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREDIS-277
|
||||
*/
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void slaveOfNoOneShouldBeSentCorrectly() {
|
||||
super.slaveOfNoOneShouldBeSentCorrectly();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -83,6 +83,8 @@ public class LettuceConnectionUnitTestSuite {
|
||||
}
|
||||
|
||||
/**
|
||||
* <<<<<<< HEAD
|
||||
*
|
||||
* @see DATAREDIS-267
|
||||
*/
|
||||
@Test
|
||||
@@ -103,6 +105,33 @@ public class LettuceConnectionUnitTestSuite {
|
||||
verifyNativeConnectionInvocation().clientGetname();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREDIS-277
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void slaveOfShouldThrowExectpionWhenCalledForNullHost() {
|
||||
connection.slaveOf(null, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREDIS-277
|
||||
*/
|
||||
@Test
|
||||
public void slaveOfShouldBeSentCorrectly() {
|
||||
|
||||
connection.slaveOf("127.0.0.1", 1001);
|
||||
verifyNativeConnectionInvocation().slaveof(eq("127.0.0.1"), eq(1001));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREDIS-277
|
||||
*/
|
||||
@Test
|
||||
public void slaveOfNoOneShouldBeSentCorrectly() {
|
||||
|
||||
connection.slaveOfNoOne();
|
||||
verifyNativeConnectionInvocation().slaveofNoOne();
|
||||
}
|
||||
}
|
||||
|
||||
public static class LettucePipelineConnectionUnitTests extends LettuceConnectionUnitTests {
|
||||
|
||||
@@ -79,6 +79,8 @@ public class SrpConnectionUnitTestSuite {
|
||||
}
|
||||
|
||||
/**
|
||||
* <<<<<<< HEAD
|
||||
*
|
||||
* @see DATAREDIS-267
|
||||
*/
|
||||
@Test
|
||||
@@ -99,6 +101,33 @@ public class SrpConnectionUnitTestSuite {
|
||||
verifyNativeConnectionInvocation().client_getname();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREDIS-277
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void slaveOfShouldThrowExectpionWhenCalledForNullHost() {
|
||||
connection.slaveOf(null, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREDIS-277
|
||||
*/
|
||||
@Test
|
||||
public void slaveOfShouldBeSentCorrectly() {
|
||||
|
||||
connection.slaveOf("127.0.0.1", 1001);
|
||||
verifyNativeConnectionInvocation().slaveof(eq("127.0.0.1"), eq(1001));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREDIS-277
|
||||
*/
|
||||
@Test
|
||||
public void slaveOfNoOneShouldBeSentCorrectly() {
|
||||
|
||||
connection.slaveOfNoOne();
|
||||
verifyNativeConnectionInvocation().slaveof(eq("NO"), eq("ONE"));
|
||||
}
|
||||
}
|
||||
|
||||
public static class SrpConnectionPiplineUnitTests extends AbstractConnectionUnitTestBase<Pipeline> {
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class RedisTemplateUnitTests {
|
||||
|
||||
private RedisTemplate<String, String> template;
|
||||
private @Mock RedisConnectionFactory connectionFactoryMock;
|
||||
private @Mock RedisConnection redisConnectionMock;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
template = new RedisTemplate<String, String>();
|
||||
template.setConnectionFactory(connectionFactoryMock);
|
||||
when(connectionFactoryMock.getConnection()).thenReturn(redisConnectionMock);
|
||||
|
||||
template.afterPropertiesSet();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREDIS-277
|
||||
*/
|
||||
@Test
|
||||
public void slaveOfIsDelegatedToConnectionCorrectly() {
|
||||
|
||||
template.slaveOf("127.0.0.1", 1001);
|
||||
verify(redisConnectionMock, times(1)).slaveOf(eq("127.0.0.1"), eq(1001));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREDIS-277
|
||||
*/
|
||||
@Test
|
||||
public void slaveOfNoOneIsDelegatedToConnectionCorrectly() {
|
||||
|
||||
template.slaveOfNoOne();
|
||||
verify(redisConnectionMock, times(1)).slaveOfNoOne();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user