DATAREDIS-626 - Polishing.

Refactor server and scripting commands to their own implementations and interfaces.

Fix JavaDoc indentations. Fix typos. Replace explicit type arguments with diamond syntax. Replace anonymous inner classes with method references and lambdas, where possible. Use shared ClientResources with LettuceConnectionFactory tests.

Align reactive command implementation visibility with blocking command implementation visibility to package-protected. These implementations are not an extension point and subject to be used through their interfaces.

Original pull request: #247.
This commit is contained in:
Mark Paluch
2017-04-25 14:39:30 +02:00
parent c636400104
commit 4e2fb1b7a0
75 changed files with 3601 additions and 3220 deletions

View File

@@ -15,21 +15,8 @@
*/
package org.springframework.data.redis.connection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@@ -215,13 +202,7 @@ public class ClusterCommandExecutor implements DisposableBean {
Map<NodeExecution, Future<NodeResult<T>>> futures = new LinkedHashMap<NodeExecution, Future<NodeResult<T>>>();
for (final RedisClusterNode node : resolvedRedisClusterNodes) {
futures.put(new NodeExecution(node), executor.submit(new Callable<NodeResult<T>>() {
@Override
public NodeResult<T> call() throws Exception {
return executeCommandOnSingleNode(callback, node);
}
}));
futures.put(new NodeExecution(node), executor.submit(() -> executeCommandOnSingleNode(callback, node)));
}
return collectResults(futures);
@@ -310,13 +291,8 @@ public class ClusterCommandExecutor implements DisposableBean {
if (entry.getKey().isMaster()) {
for (final byte[] key : entry.getValue()) {
futures.put(new NodeExecution(entry.getKey(), key), executor.submit(new Callable<NodeResult<T>>() {
@Override
public NodeResult<T> call() throws Exception {
return executeMultiKeyCommandOnSingleNode(cmd, entry.getKey(), key);
}
}));
futures.put(new NodeExecution(entry.getKey(), key),
executor.submit(() -> executeMultiKeyCommandOnSingleNode(cmd, entry.getKey(), key)));
}
}
}

View File

@@ -15,10 +15,120 @@
*/
package org.springframework.data.redis.connection;
import java.util.List;
import java.util.Properties;
import org.springframework.data.redis.core.types.RedisClientInfo;
/**
* @author Christoph Strobl
* @author Mark Paluch
* @since 2.0
*/
public interface DefaultedRedisClusterConnection extends RedisClusterConnection, DefaultedRedisConnection {
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void bgReWriteAof(RedisClusterNode node) {
serverCommands().bgReWriteAof(node);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void bgSave(RedisClusterNode node) {
serverCommands().bgSave(node);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default Long lastSave(RedisClusterNode node) {
return serverCommands().lastSave(node);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void save(RedisClusterNode node) {
serverCommands().save(node);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default Long dbSize(RedisClusterNode node) {
return serverCommands().dbSize(node);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void flushDb(RedisClusterNode node) {
serverCommands().flushDb(node);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void flushAll(RedisClusterNode node) {
serverCommands().flushAll(node);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default Properties info(RedisClusterNode node) {
return serverCommands().info(node);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default Properties info(RedisClusterNode node, String section) {
return serverCommands().info(node, section);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void shutdown(RedisClusterNode node) {
serverCommands().shutdown(node);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default List<String> getConfig(RedisClusterNode node, String pattern) {
return serverCommands().getConfig(node, pattern);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void setConfig(RedisClusterNode node, String param, String value) {
serverCommands().setConfig(node, param, value);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void resetConfigStats(RedisClusterNode node) {
serverCommands().resetConfigStats(node);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default Long time(RedisClusterNode node) {
return serverCommands().time(node);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default List<RedisClientInfo> getClientList(RedisClusterNode node) {
return serverCommands().getClientList(node);
}
}

View File

@@ -18,6 +18,7 @@ package org.springframework.data.redis.connection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -29,12 +30,16 @@ import org.springframework.data.geo.Point;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.core.types.RedisClientInfo;
/**
* {@link DefaultedRedisConnection} provides method delegates to {@code Redis*Command} interfaces accessible via {@link RedisConnection}.
* This allows us to maintain backwards compatibility while moving the actual implementation and stay in sync with {@link ReactiveRedisConnection}.
* Going forward the {@link RedisCommands} extension is likely to be removed from {@link RedisConnection}.
* {@link DefaultedRedisConnection} provides method delegates to {@code Redis*Command} interfaces accessible via
* {@link RedisConnection}. This allows us to maintain backwards compatibility while moving the actual implementation
* and stay in sync with {@link ReactiveRedisConnection}. Going forward the {@link RedisCommands} extension is likely to
* be removed from {@link RedisConnection}.
*
* @author Christoph Strobl
* @author Mark Paluch
* @since 2.0
*/
public interface DefaultedRedisConnection extends RedisConnection {
@@ -1012,4 +1017,225 @@ public interface DefaultedRedisConnection extends RedisConnection {
default void pfMerge(byte[] destinationKey, byte[]... sourceKeys) {
hyperLogLogCommands().pfMerge(destinationKey, sourceKeys);
}
// SERVER COMMANDS
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void bgWriteAof() {
serverCommands().bgWriteAof();
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void bgReWriteAof() {
serverCommands().bgReWriteAof();
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void bgSave() {
serverCommands().bgSave();
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default Long lastSave() {
return serverCommands().lastSave();
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void save() {
serverCommands().save();
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default Long dbSize() {
return serverCommands().dbSize();
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void flushDb() {
serverCommands().flushDb();
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void flushAll() {
serverCommands().flushAll();
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default Properties info() {
return serverCommands().info();
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default Properties info(String section) {
return serverCommands().info(section);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void shutdown() {
serverCommands().shutdown();
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void shutdown(ShutdownOption option) {
serverCommands().shutdown(option);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default List<String> getConfig(String pattern) {
return serverCommands().getConfig(pattern);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void setConfig(String param, String value) {
serverCommands().setConfig(param, value);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void resetConfigStats() {
serverCommands().resetConfigStats();
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default Long time() {
return serverCommands().time();
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void killClient(String host, int port) {
serverCommands().killClient(host, port);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void setClientName(byte[] name) {
serverCommands().setClientName(name);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default String getClientName() {
return serverCommands().getClientName();
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default List<RedisClientInfo> getClientList() {
return serverCommands().getClientList();
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void slaveOf(String host, int port) {
serverCommands().slaveOf(host, port);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void slaveOfNoOne() {
serverCommands().slaveOfNoOne();
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void migrate(byte[] key, RedisNode target, int dbIndex, MigrateOption option) {
serverCommands().migrate(key, target, dbIndex, option);
}
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void migrate(byte[] key, RedisNode target, int dbIndex, MigrateOption option, long timeout) {
serverCommands().migrate(key, target, dbIndex, option, timeout);
}
// SCRIPTING COMMANDS
/** @deprecated in favor of {@link RedisConnection#scriptingCommands()}. */
@Override
@Deprecated
default void scriptFlush() {
scriptingCommands().scriptFlush();
}
/** @deprecated in favor of {@link RedisConnection#scriptingCommands()}. */
@Override
@Deprecated
default void scriptKill() {
scriptingCommands().scriptKill();
}
/** @deprecated in favor of {@link RedisConnection#scriptingCommands()}. */
@Override
@Deprecated
default String scriptLoad(byte[] script) {
return scriptingCommands().scriptLoad(script);
}
/** @deprecated in favor of {@link RedisConnection#scriptingCommands()}. */
@Override
@Deprecated
default List<Boolean> scriptExists(String... scriptShas) {
return scriptingCommands().scriptExists(scriptShas);
}
/** @deprecated in favor of {@link RedisConnection#scriptingCommands()}. */
@Override
@Deprecated
default <T> T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
return scriptingCommands().eval(script, returnType, numKeys, keysAndArgs);
}
/** @deprecated in favor of {@link RedisConnection#scriptingCommands()}. */
@Override
@Deprecated
default <T> T evalSha(String scriptSha, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
return scriptingCommands().evalSha(scriptSha, returnType, numKeys, keysAndArgs);
}
/** @deprecated in favor of {@link RedisConnection#scriptingCommands()}. */
@Override
@Deprecated
default <T> T evalSha(byte[] scriptSha, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
return scriptingCommands().evalSha(scriptSha, returnType, numKeys, keysAndArgs);
}
}

View File

@@ -15,23 +15,19 @@
*/
package org.springframework.data.redis.connection;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import org.springframework.data.redis.core.types.RedisClientInfo;
/**
* {@link RedisClusterConnection} allows sending commands to dedicated nodes within the cluster. A
* {@link RedisClusterNode} can be obtained from {@link #clusterGetNodes()} or it can be constructed using either
* {@link RedisClusterNode#getHost() host} and {@link RedisClusterNode#getPort()} or the {@link RedisClusterNode#getId()
* node Id}.
*
*
* @author Christoph Strobl
* @author Mark Paluch
* @since 1.7
*/
public interface RedisClusterConnection extends RedisConnection, RedisClusterCommands {
public interface RedisClusterConnection extends RedisConnection, RedisClusterCommands, RedisClusterServerCommands {
/**
* @param node must not be {@literal null}.
@@ -40,65 +36,6 @@ public interface RedisClusterConnection extends RedisConnection, RedisClusterCom
*/
String ping(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @see RedisServerCommands#bgReWriteAof()
*/
void bgReWriteAof(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @see RedisServerCommands#bgSave()
*/
void bgSave(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @return
* @see RedisServerCommands#lastSave()
*/
Long lastSave(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @see RedisServerCommands#save()
*/
void save(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @return
* @see RedisServerCommands#dbSize()
*/
Long dbSize(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @see RedisServerCommands#flushDb()
*/
void flushDb(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @see RedisServerCommands#flushAll()
*/
void flushAll(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @return
* @see RedisServerCommands#info()
*/
Properties info(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @param section
* @return
* @see RedisServerCommands#info(String)
*/
Properties info(RedisClusterNode node, String section);
/**
* @param node must not be {@literal null}.
* @param pattern must not be {@literal null}.
@@ -115,45 +52,12 @@ public interface RedisClusterConnection extends RedisConnection, RedisClusterCom
byte[] randomKey(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @see RedisServerCommands#shutdown()
* Get {@link RedisClusterServerCommands}.
*
* @return never {@literal null}.
* @since 2.0
*/
void shutdown(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @param pattern
* @return
* @see RedisServerCommands#getConfig(String)
*/
List<String> getConfig(RedisClusterNode node, String pattern);
/**
* @param node must not be {@literal null}.
* @param param
* @param value
* @see RedisServerCommands#setConfig(String, String)
*/
void setConfig(RedisClusterNode node, String param, String value);
/**
* @param node must not be {@literal null}.
* @see RedisServerCommands#resetConfigStats()
*/
void resetConfigStats(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @return
* @see RedisServerCommands#time()
*/
Long time(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @return
* @see RedisServerCommands#getClientList()
*/
public List<RedisClientInfo> getClientList(RedisClusterNode node);
default RedisClusterServerCommands serverCommands() {
return this;
}
}

View File

@@ -0,0 +1,129 @@
/*
* Copyright 2017 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.connection;
import java.util.List;
import java.util.Properties;
import org.springframework.data.redis.core.types.RedisClientInfo;
/**
* @author Mark Paluch
* @since 2.0
*/
public interface RedisClusterServerCommands extends RedisServerCommands {
/**
* @param node must not be {@literal null}.
* @see RedisServerCommands#bgReWriteAof()
*/
void bgReWriteAof(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @see RedisServerCommands#bgSave()
*/
void bgSave(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @return
* @see RedisServerCommands#lastSave()
*/
Long lastSave(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @see RedisServerCommands#save()
*/
void save(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @return
* @see RedisServerCommands#dbSize()
*/
Long dbSize(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @see RedisServerCommands#flushDb()
*/
void flushDb(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @see RedisServerCommands#flushAll()
*/
void flushAll(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @return
* @see RedisServerCommands#info()
*/
Properties info(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @param section
* @return
* @see RedisServerCommands#info(String)
*/
Properties info(RedisClusterNode node, String section);
/**
* @param node must not be {@literal null}.
* @see RedisServerCommands#shutdown()
*/
void shutdown(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @param pattern
* @return
* @see RedisServerCommands#getConfig(String)
*/
List<String> getConfig(RedisClusterNode node, String pattern);
/**
* @param node must not be {@literal null}.
* @param param
* @param value
* @see RedisServerCommands#setConfig(String, String)
*/
void setConfig(RedisClusterNode node, String param, String value);
/**
* @param node must not be {@literal null}.
* @see RedisServerCommands#resetConfigStats()
*/
void resetConfigStats(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @return
* @see RedisServerCommands#time()
*/
Long time(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @return
* @see RedisServerCommands#getClientList()
*/
List<RedisClientInfo> getClientList(RedisClusterNode node);
}

View File

@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.redis.connection;
import java.util.List;
@@ -24,9 +23,10 @@ import org.springframework.dao.DataAccessException;
* A connection to a Redis server. Acts as an common abstraction across various Redis client libraries (or drivers).
* Additionally performs exception translation between the underlying Redis client library and Spring DAO exceptions.
* The methods follow as much as possible the Redis names and conventions.
*
*
* @author Costin Leau
* @author Christoph Strobl
* @author Mark Paluch
*/
public interface RedisConnection extends RedisCommands {
@@ -34,6 +34,7 @@ public interface RedisConnection extends RedisCommands {
* Get {@link RedisGeoCommands}.
*
* @return never {@literal null}.
* @since 2.0
*/
default RedisGeoCommands geoCommands() {
return this;
@@ -53,6 +54,7 @@ public interface RedisConnection extends RedisCommands {
* Get {@link RedisHyperLogLogCommands}.
*
* @return never {@literal null}.
* @since 2.0
*/
default RedisHyperLogLogCommands hyperLogLogCommands() {
return this;
@@ -88,6 +90,26 @@ public interface RedisConnection extends RedisCommands {
return this;
}
/**
* Get {@link RedisScriptingCommands}.
*
* @return never {@literal null}.
* @since 2.0
*/
default RedisScriptingCommands scriptingCommands() {
return this;
}
/**
* Get {@link RedisServerCommands}.
*
* @return never {@literal null}.
* @since 2.0
*/
default RedisServerCommands serverCommands() {
return this;
}
/**
* Get {@link RedisStringCommands}.
*
@@ -110,21 +132,21 @@ public interface RedisConnection extends RedisCommands {
/**
* Closes (or quits) the connection.
*
*
* @throws DataAccessException
*/
void close() throws DataAccessException;
/**
* Indicates whether the underlying connection is closed or not.
*
*
* @return true if the connection is closed, false otherwise.
*/
boolean isClosed();
/**
* Returns the native connection (the underlying library/driver object).
*
*
* @return underlying, native object
*/
Object getNativeConnection();
@@ -133,14 +155,14 @@ public interface RedisConnection extends RedisCommands {
* Indicates whether the connection is in "queue"(or "MULTI") mode or not. When queueing, all commands are postponed
* until EXEC or DISCARD commands are issued. Since in queueing no results are returned, the connection will return
* NULL on all operations that interact with the data.
*
*
* @return true if the connection is in queue/MULTI mode, false otherwise
*/
boolean isQueueing();
/**
* Indicates whether the connection is currently pipelined or not.
*
*
* @return true if the connection is pipelined, false otherwise
* @see #openPipeline()
* @see #isQueueing()
@@ -158,7 +180,7 @@ public interface RedisConnection extends RedisCommands {
* </p>
* Consider doing some performance testing before using this feature since in many cases the performance benefits are
* minimal yet the impact on usage are not.
*
*
* @see #multi()
*/
void openPipeline();
@@ -166,7 +188,7 @@ public interface RedisConnection extends RedisCommands {
/**
* Executes the commands in the pipeline and returns their result. If the connection is not pipelined, an empty
* collection is returned.
*
*
* @throws RedisPipelineException if the pipeline contains any incorrect/invalid statements
* @return the result of the executed commands.
*/

View File

@@ -1,12 +1,12 @@
/*
* Copyright 2011-2017 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.
@@ -22,7 +22,7 @@ import org.springframework.data.redis.core.types.RedisClientInfo;
/**
* Server-specific commands supported by Redis.
*
*
* @author Costin Leau
* @author Christoph Strobl
* @author Thomas Darimont
@@ -43,12 +43,14 @@ public interface RedisServerCommands {
/**
* Start an {@literal Append Only File} rewrite process on server.
*
*
* @deprecated As of 1.3, use {@link #bgReWriteAof}.
* @see <a href="http://redis.io/commands/bgrewriteaof">Redis Documentation: BGREWRITEAOF</a>
*/
@Deprecated
void bgWriteAof();
default void bgWriteAof() {
bgReWriteAof();
}
/**
* Start an {@literal Append Only File} rewrite process on server.
@@ -110,7 +112,7 @@ public interface RedisServerCommands {
* <li>replication</li>
* </ul>
* <p>
*
*
* @return
* @see <a href="http://redis.io/commands/info">Redis Documentation: INFO</a>
*/
@@ -167,7 +169,7 @@ public interface RedisServerCommands {
/**
* Request server timestamp using {@code TIME} command.
*
*
* @return current server time in milliseconds.
* @since 1.1
* @see <a href="http://redis.io/commands/time">Redis Documentation: TIME</a>
@@ -176,7 +178,7 @@ public interface RedisServerCommands {
/**
* Closes a given client connection identified by {@literal host:port}.
*
*
* @param host of connection to close.
* @param port of connection to close
* @since 1.3
@@ -186,7 +188,7 @@ public interface RedisServerCommands {
/**
* Assign given name to current connection.
*
*
* @param name
* @since 1.3
* @see <a href="http://redis.io/commands/client-setname">Redis Documentation: CLIENT SETNAME</a>
@@ -232,7 +234,7 @@ public interface RedisServerCommands {
/**
* Atomically transfer a key from a source Redis instance to a destination Redis instance. On success the key is
* deleted from the original instance and is guaranteed to exist in the target instance.
*
*
* @param key must not be {@literal null}.
* @param target must not be {@literal null}.
* @param dbIndex

View File

@@ -72,7 +72,7 @@ class JedisClusterGeoCommands implements RedisGeoCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(memberCoordinateMap, "MemberCoordinateMap must not be null!");
Map<byte[], GeoCoordinate> redisGeoCoordinateMap = new HashMap<byte[], GeoCoordinate>();
Map<byte[], GeoCoordinate> redisGeoCoordinateMap = new HashMap<>();
for (byte[] mapKey : memberCoordinateMap.keySet()) {
redisGeoCoordinateMap.put(mapKey, JedisConverters.toGeoCoordinate(memberCoordinateMap.get(mapKey)));
}
@@ -94,7 +94,7 @@ class JedisClusterGeoCommands implements RedisGeoCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(locations, "Locations must not be null!");
Map<byte[], redis.clients.jedis.GeoCoordinate> redisGeoCoordinateMap = new HashMap<byte[], GeoCoordinate>();
Map<byte[], redis.clients.jedis.GeoCoordinate> redisGeoCoordinateMap = new HashMap<>();
for (GeoLocation<byte[]> location : locations) {
redisGeoCoordinateMap.put(location.getName(), JedisConverters.toGeoCoordinate(location.getPoint()));
}

View File

@@ -203,7 +203,7 @@ class JedisClusterHashCommands implements RedisHashCommands {
public List<byte[]> hVals(byte[] key) {
try {
return new ArrayList<byte[]>(connection.getCluster().hvals(key));
return new ArrayList<>(connection.getCluster().hvals(key));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}

View File

@@ -15,15 +15,13 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import org.springframework.dao.DataAccessException;
@@ -71,14 +69,10 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
}
}
return Long.valueOf(
connection.getClusterCommandExecutor().executeMuliKeyCommand(new JedisMultiKeyClusterCommandCallback<Long>() {
@Override
public Long doInCluster(Jedis client, byte[] key) {
return client.del(key);
}
}, Arrays.asList(keys)).resultsAsList().size());
return (long) connection.getClusterCommandExecutor()
.executeMuliKeyCommand((JedisMultiKeyClusterCommandCallback<Long>) (client, key) -> client.del(key),
Arrays.asList(keys))
.resultsAsList().size();
}
/*
@@ -105,15 +99,10 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
Assert.notNull(pattern, "Pattern must not be null!");
Collection<Set<byte[]>> keysPerNode = connection.getClusterCommandExecutor()
.executeCommandOnAllNodes(new JedisClusterCommandCallback<Set<byte[]>>() {
.executeCommandOnAllNodes((JedisClusterCommandCallback<Set<byte[]>>) client -> client.keys(pattern))
.resultsAsList();
@Override
public Set<byte[]> doInCluster(Jedis client) {
return client.keys(pattern);
}
}).resultsAsList();
Set<byte[]> keys = new HashSet<byte[]>();
Set<byte[]> keys = new HashSet<>();
for (Set<byte[]> keySet : keysPerNode) {
keys.addAll(keySet);
}
@@ -129,13 +118,8 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
Assert.notNull(pattern, "Pattern must not be null!");
return connection.getClusterCommandExecutor()
.executeCommandOnSingleNode(new JedisClusterCommandCallback<Set<byte[]>>() {
@Override
public Set<byte[]> doInCluster(Jedis client) {
return client.keys(pattern);
}
}, node).getValue();
.executeCommandOnSingleNode((JedisClusterCommandCallback<Set<byte[]>>) client -> client.keys(pattern), node)
.getValue();
}
/*
@@ -144,7 +128,7 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
*/
@Override
public Cursor<byte[]> scan(ScanOptions options) {
throw new InvalidDataAccessApiUsageException("Scan is not supported accros multiple nodes within a cluster");
throw new InvalidDataAccessApiUsageException("Scan is not supported across multiple nodes within a cluster");
}
/*
@@ -154,16 +138,16 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
@Override
public byte[] randomKey() {
List<RedisClusterNode> nodes = new ArrayList<RedisClusterNode>(
List<RedisClusterNode> nodes = new ArrayList<>(
connection.getTopologyProvider().getTopology().getActiveMasterNodes());
Set<RedisNode> inspectedNodes = new HashSet<RedisNode>(nodes.size());
Set<RedisNode> inspectedNodes = new HashSet<>(nodes.size());
do {
RedisClusterNode node = nodes.get(new Random().nextInt(nodes.size()));
RedisClusterNode node = nodes.get(ThreadLocalRandom.current().nextInt(nodes.size()));
while (inspectedNodes.contains(node)) {
node = nodes.get(new Random().nextInt(nodes.size()));
node = nodes.get(ThreadLocalRandom.current().nextInt(nodes.size()));
}
inspectedNodes.add(node);
byte[] key = randomKey(node);
@@ -182,13 +166,9 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
*/
public byte[] randomKey(RedisClusterNode node) {
return connection.getClusterCommandExecutor().executeCommandOnSingleNode(new JedisClusterCommandCallback<byte[]>() {
@Override
public byte[] doInCluster(Jedis client) {
return client.randomBinaryKey();
}
}, node).getValue();
return connection.getClusterCommandExecutor()
.executeCommandOnSingleNode((JedisClusterCommandCallback<byte[]>) client -> client.randomBinaryKey(), node)
.getValue();
}
/*
@@ -361,13 +341,10 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
@Override
public Long pTtl(final byte[] key) {
return connection.getClusterCommandExecutor().executeCommandOnSingleNode(new JedisClusterCommandCallback<Long>() {
@Override
public Long doInCluster(Jedis client) {
return client.pttl(key);
}
}, connection.getTopologyProvider().getTopology().getKeyServingMasterNode(key)).getValue();
return connection.getClusterCommandExecutor()
.executeCommandOnSingleNode((JedisClusterCommandCallback<Long>) client -> client.pttl(key),
connection.getTopologyProvider().getTopology().getKeyServingMasterNode(key))
.getValue();
}
/*
@@ -377,13 +354,11 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
@Override
public Long pTtl(final byte[] key, final TimeUnit timeUnit) {
return connection.getClusterCommandExecutor().executeCommandOnSingleNode(new JedisClusterCommandCallback<Long>() {
@Override
public Long doInCluster(Jedis client) {
return Converters.millisecondsToTimeUnit(client.pttl(key), timeUnit);
}
}, connection.getTopologyProvider().getTopology().getKeyServingMasterNode(key)).getValue();
return connection.getClusterCommandExecutor()
.executeCommandOnSingleNode(
(JedisClusterCommandCallback<Long>) client -> Converters.millisecondsToTimeUnit(client.pttl(key), timeUnit),
connection.getTopologyProvider().getTopology().getKeyServingMasterNode(key))
.getValue();
}
/*
@@ -393,13 +368,10 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
@Override
public byte[] dump(final byte[] key) {
return connection.getClusterCommandExecutor().executeCommandOnSingleNode(new JedisClusterCommandCallback<byte[]>() {
@Override
public byte[] doInCluster(Jedis client) {
return client.dump(key);
}
}, connection.getTopologyProvider().getTopology().getKeyServingMasterNode(key)).getValue();
return connection.getClusterCommandExecutor()
.executeCommandOnSingleNode((JedisClusterCommandCallback<byte[]>) client -> client.dump(key),
connection.getTopologyProvider().getTopology().getKeyServingMasterNode(key))
.getValue();
}
/*
@@ -413,13 +385,9 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
throw new UnsupportedOperationException("Jedis does not support ttlInMillis exceeding Integer.MAX_VALUE.");
}
connection.getClusterCommandExecutor().executeCommandOnSingleNode(new JedisClusterCommandCallback<String>() {
@Override
public String doInCluster(Jedis client) {
return client.restore(key, Long.valueOf(ttlInMillis).intValue(), serializedValue);
}
}, connection.clusterGetNodeForKey(key));
connection.getClusterCommandExecutor()
.executeCommandOnSingleNode((JedisClusterCommandCallback<String>) client -> client.restore(key,
Long.valueOf(ttlInMillis).intValue(), serializedValue), connection.clusterGetNodeForKey(key));
}
/*

View File

@@ -15,8 +15,6 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.Jedis;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -237,13 +235,10 @@ class JedisClusterListCommands implements RedisListCommands {
}
return connection.getClusterCommandExecutor()
.executeMuliKeyCommand(new JedisMultiKeyClusterCommandCallback<List<byte[]>>() {
@Override
public List<byte[]> doInCluster(Jedis client, byte[] key) {
return client.blpop(timeout, key);
}
}, Arrays.asList(keys)).getFirstNonNullNotEmptyOrDefault(Collections.<byte[]> emptyList());
.executeMuliKeyCommand(
(JedisMultiKeyClusterCommandCallback<List<byte[]>>) (client, key) -> client.blpop(timeout, key),
Arrays.asList(keys))
.getFirstNonNullNotEmptyOrDefault(Collections.<byte[]> emptyList());
}
/*
@@ -254,13 +249,10 @@ class JedisClusterListCommands implements RedisListCommands {
public List<byte[]> bRPop(final int timeout, byte[]... keys) {
return connection.getClusterCommandExecutor()
.executeMuliKeyCommand(new JedisMultiKeyClusterCommandCallback<List<byte[]>>() {
@Override
public List<byte[]> doInCluster(Jedis client, byte[] key) {
return client.brpop(timeout, key);
}
}, Arrays.asList(keys)).getFirstNonNullNotEmptyOrDefault(Collections.<byte[]> emptyList());
.executeMuliKeyCommand(
(JedisMultiKeyClusterCommandCallback<List<byte[]>>) (client, key) -> client.brpop(timeout, key),
Arrays.asList(keys))
.getFirstNonNullNotEmptyOrDefault(Collections.<byte[]> emptyList());
}
/*

View File

@@ -0,0 +1,94 @@
/*
* Copyright 2017 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.connection.jedis;
import java.util.List;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.redis.connection.RedisScriptingCommands;
import org.springframework.data.redis.connection.ReturnType;
/**
* @author Mark Paluch
* @since 2.0
*/
enum JedisClusterScriptingCommands implements RedisScriptingCommands {
INSTANCE;
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#scriptFlush()
*/
@Override
public void scriptFlush() {
throw new InvalidDataAccessApiUsageException("ScriptFlush is not supported in cluster environment.");
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#scriptKill()
*/
@Override
public void scriptKill() {
throw new InvalidDataAccessApiUsageException("ScriptKill is not supported in cluster environment.");
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#scriptLoad(byte[])
*/
@Override
public String scriptLoad(byte[] script) {
throw new InvalidDataAccessApiUsageException("ScriptLoad is not supported in cluster environment.");
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#scriptExists(java.lang.String[])
*/
@Override
public List<Boolean> scriptExists(String... scriptShas) {
throw new InvalidDataAccessApiUsageException("ScriptExists is not supported in cluster environment.");
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#eval(byte[], org.springframework.data.redis.connection.ReturnType, int, byte[][])
*/
@Override
public <T> T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
throw new InvalidDataAccessApiUsageException("Eval is not supported in cluster environment.");
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#evalSha(java.lang.String, org.springframework.data.redis.connection.ReturnType, int, byte[][])
*/
@Override
public <T> T evalSha(String scriptSha, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
throw new InvalidDataAccessApiUsageException("EvalSha is not supported in cluster environment.");
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#evalSha(byte[], org.springframework.data.redis.connection.ReturnType, int, byte[][])
*/
@Override
public <T> T evalSha(byte[] scriptSha, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
throw new InvalidDataAccessApiUsageException("EvalSha is not supported in cluster environment.");
}
}

View File

@@ -0,0 +1,515 @@
/*
* Copyright 2017 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.connection.jedis;
import redis.clients.jedis.BinaryJedis;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;
import java.util.Properties;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.redis.connection.ClusterCommandExecutor.MulitNodeResult;
import org.springframework.data.redis.connection.ClusterCommandExecutor.NodeResult;
import org.springframework.data.redis.connection.RedisClusterNode;
import org.springframework.data.redis.connection.RedisClusterServerCommands;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.convert.Converters;
import org.springframework.data.redis.connection.jedis.JedisClusterConnection.JedisClusterCommandCallback;
import org.springframework.data.redis.core.types.RedisClientInfo;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
/**
* @author Mark Paluch
* @since 2.0
*/
class JedisClusterServerCommands implements RedisClusterServerCommands {
private final JedisClusterConnection connection;
public JedisClusterServerCommands(JedisClusterConnection connection) {
this.connection = connection;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#bgReWriteAof(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void bgReWriteAof(RedisClusterNode node) {
executeCommandOnSingleNode(BinaryJedis::bgrewriteaof, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#bgReWriteAof()
*/
@Override
public void bgReWriteAof() {
connection.getClusterCommandExecutor()
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) BinaryJedis::bgrewriteaof);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#bgSave()
*/
@Override
public void bgSave() {
connection.getClusterCommandExecutor()
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) BinaryJedis::bgsave);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#bgSave(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void bgSave(RedisClusterNode node) {
executeCommandOnSingleNode(BinaryJedis::bgsave, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#lastSave()
*/
@Override
public Long lastSave() {
List<Long> result = new ArrayList<>(executeCommandOnAllNodes(BinaryJedis::lastsave).resultsAsList());
if (CollectionUtils.isEmpty(result)) {
return null;
}
Collections.sort(result, Collections.reverseOrder());
return result.get(0);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#lastSave(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public Long lastSave(RedisClusterNode node) {
return executeCommandOnSingleNode(BinaryJedis::lastsave, node).getValue();
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#save()
*/
@Override
public void save() {
executeCommandOnAllNodes(BinaryJedis::save);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#save(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void save(RedisClusterNode node) {
executeCommandOnSingleNode(BinaryJedis::save, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#dbSize()
*/
@Override
public Long dbSize() {
Collection<Long> dbSizes = executeCommandOnAllNodes(BinaryJedis::dbSize).resultsAsList();
if (CollectionUtils.isEmpty(dbSizes)) {
return 0L;
}
Long size = 0L;
for (Long value : dbSizes) {
size += value;
}
return size;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#dbSize(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public Long dbSize(RedisClusterNode node) {
return executeCommandOnSingleNode(BinaryJedis::dbSize, node).getValue();
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#flushDb()
*/
@Override
public void flushDb() {
executeCommandOnAllNodes(BinaryJedis::flushDB);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#flushDb(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void flushDb(RedisClusterNode node) {
executeCommandOnSingleNode(BinaryJedis::flushDB, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#flushAll()
*/
@Override
public void flushAll() {
connection.getClusterCommandExecutor()
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) BinaryJedis::flushAll);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#flushAll(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void flushAll(RedisClusterNode node) {
executeCommandOnSingleNode(BinaryJedis::flushAll, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#info()
*/
@Override
public Properties info() {
Properties infos = new Properties();
List<NodeResult<Properties>> nodeResults = connection.getClusterCommandExecutor()
.executeCommandOnAllNodes(
(JedisClusterCommandCallback<Properties>) client -> JedisConverters.toProperties(client.info()))
.getResults();
for (NodeResult<Properties> nodeProperties : nodeResults) {
for (Entry<Object, Object> entry : nodeProperties.getValue().entrySet()) {
infos.put(nodeProperties.getNode().asString() + "." + entry.getKey(), entry.getValue());
}
}
return infos;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#info(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public Properties info(RedisClusterNode node) {
return JedisConverters.toProperties(executeCommandOnSingleNode(BinaryJedis::info, node).getValue());
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#info(java.lang.String)
*/
@Override
public Properties info(final String section) {
Properties infos = new Properties();
List<NodeResult<Properties>> nodeResults = connection.getClusterCommandExecutor()
.executeCommandOnAllNodes(
(JedisClusterCommandCallback<Properties>) client -> JedisConverters.toProperties(client.info(section)))
.getResults();
for (NodeResult<Properties> nodeProperties : nodeResults) {
for (Entry<Object, Object> entry : nodeProperties.getValue().entrySet()) {
infos.put(nodeProperties.getNode().asString() + "." + entry.getKey(), entry.getValue());
}
}
return infos;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#info(org.springframework.data.redis.connection.RedisClusterNode, java.lang.String)
*/
@Override
public Properties info(RedisClusterNode node, final String section) {
return JedisConverters.toProperties(executeCommandOnSingleNode(client -> client.info(section), node).getValue());
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#shutdown()
*/
@Override
public void shutdown() {
connection.getClusterCommandExecutor()
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) BinaryJedis::shutdown);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#shutdown(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void shutdown(RedisClusterNode node) {
executeCommandOnSingleNode(BinaryJedis::shutdown, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#shutdown(org.springframework.data.redis.connection.RedisServerCommands.ShutdownOption)
*/
@Override
public void shutdown(ShutdownOption option) {
if (option == null) {
shutdown();
return;
}
throw new IllegalArgumentException("Shutdown with options is not supported for jedis.");
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#getConfig(java.lang.String)
*/
@Override
public List<String> getConfig(final String pattern) {
List<NodeResult<List<String>>> mapResult = connection.getClusterCommandExecutor()
.executeCommandOnAllNodes((JedisClusterCommandCallback<List<String>>) client -> client.configGet(pattern))
.getResults();
List<String> result = new ArrayList<>();
for (NodeResult<List<String>> entry : mapResult) {
String prefix = entry.getNode().asString();
int i = 0;
for (String value : entry.getValue()) {
result.add((i++ % 2 == 0 ? (prefix + ".") : "") + value);
}
}
return result;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#getConfig(org.springframework.data.redis.connection.RedisClusterNode, java.lang.String)
*/
@Override
public List<String> getConfig(RedisClusterNode node, final String pattern) {
return connection.getClusterCommandExecutor().executeCommandOnSingleNode(
(JedisClusterCommandCallback<List<String>>) client -> client.configGet(pattern), node).getValue();
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#setConfig(java.lang.String, java.lang.String)
*/
@Override
public void setConfig(final String param, final String value) {
connection.getClusterCommandExecutor()
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) client -> client.configSet(param, value));
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#setConfig(org.springframework.data.redis.connection.RedisClusterNode, java.lang.String, java.lang.String)
*/
@Override
public void setConfig(RedisClusterNode node, final String param, final String value) {
executeCommandOnSingleNode(client -> client.configSet(param, value), node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#resetConfigStats()
*/
@Override
public void resetConfigStats() {
connection.getClusterCommandExecutor()
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) BinaryJedis::configResetStat);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#resetConfigStats(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void resetConfigStats(RedisClusterNode node) {
executeCommandOnSingleNode(BinaryJedis::configResetStat, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#time()
*/
@Override
public Long time() {
return convertListOfStringToTime(connection.getClusterCommandExecutor()
.executeCommandOnArbitraryNode((JedisClusterCommandCallback<List<String>>) BinaryJedis::time).getValue());
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#time(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public Long time(RedisClusterNode node) {
return convertListOfStringToTime(connection.getClusterCommandExecutor()
.executeCommandOnSingleNode((JedisClusterCommandCallback<List<String>>) BinaryJedis::time, node).getValue());
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#killClient(java.lang.String, int)
*/
@Override
public void killClient(String host, int port) {
final String hostAndPort = String.format("%s:%s", host, port);
connection.getClusterCommandExecutor()
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) client -> client.clientKill(hostAndPort));
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#setClientName(byte[])
*/
@Override
public void setClientName(byte[] name) {
throw new InvalidDataAccessApiUsageException("CLIENT SETNAME is not supported in cluster environment.");
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#getClientName()
*/
@Override
public String getClientName() {
throw new InvalidDataAccessApiUsageException("CLIENT GETNAME is not supported in cluster environment.");
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#getClientList()
*/
@Override
public List<RedisClientInfo> getClientList() {
Collection<String> map = connection.getClusterCommandExecutor()
.executeCommandOnAllNodes((JedisClusterCommandCallback<String>) BinaryJedis::clientList).resultsAsList();
ArrayList<RedisClientInfo> result = new ArrayList<>();
for (String infos : map) {
result.addAll(JedisConverters.toListOfRedisClientInformation(infos));
}
return result;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#getClientList(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public List<RedisClientInfo> getClientList(RedisClusterNode node) {
return JedisConverters
.toListOfRedisClientInformation(executeCommandOnSingleNode(BinaryJedis::clientList, node).getValue());
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#slaveOf(java.lang.String, int)
*/
@Override
public void slaveOf(String host, int port) {
throw new InvalidDataAccessApiUsageException(
"SlaveOf is not supported in cluster environment. Please use CLUSTER REPLICATE.");
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#slaveOfNoOne()
*/
@Override
public void slaveOfNoOne() {
throw new InvalidDataAccessApiUsageException(
"SlaveOf is not supported in cluster environment. Please use CLUSTER REPLICATE.");
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#migrate(byte[], org.springframework.data.redis.connection.RedisNode, int, org.springframework.data.redis.connection.RedisServerCommands.MigrateOption)
*/
@Override
public void migrate(byte[] key, RedisNode target, int dbIndex, MigrateOption option) {
migrate(key, target, dbIndex, option, Long.MAX_VALUE);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#migrate(byte[], org.springframework.data.redis.connection.RedisNode, int, org.springframework.data.redis.connection.RedisServerCommands.MigrateOption, long)
*/
@Override
public void migrate(final byte[] key, final RedisNode target, final int dbIndex, final MigrateOption option,
final long timeout) {
final int timeoutToUse = timeout <= Integer.MAX_VALUE ? (int) timeout : Integer.MAX_VALUE;
RedisClusterNode node = connection.getTopologyProvider().getTopology().lookup(target.getHost(), target.getPort());
executeCommandOnSingleNode(client -> client.migrate(JedisConverters.toBytes(target.getHost()), target.getPort(),
key, dbIndex, timeoutToUse), node);
}
private Long convertListOfStringToTime(List<String> serverTimeInformation) {
Assert.notEmpty(serverTimeInformation, "Received invalid result from server. Expected 2 items in collection.");
Assert.isTrue(serverTimeInformation.size() == 2,
"Received invalid number of arguments from redis server. Expected 2 received " + serverTimeInformation.size());
return Converters.toTimeMillis(serverTimeInformation.get(0), serverTimeInformation.get(1));
}
private <T> NodeResult<T> executeCommandOnSingleNode(JedisClusterCommandCallback<T> cmd, RedisClusterNode node) {
return connection.getClusterCommandExecutor().executeCommandOnSingleNode(cmd, node);
}
private <T> MulitNodeResult<T> executeCommandOnAllNodes(JedisClusterCommandCallback<T> cmd) {
return connection.getClusterCommandExecutor().executeCommandOnAllNodes(cmd);
}
}

View File

@@ -15,8 +15,6 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.Jedis;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -87,13 +85,9 @@ class JedisClusterStringCommands implements RedisStringCommands {
}
return connection.getClusterCommandExecutor()
.executeMuliKeyCommand(new JedisMultiKeyClusterCommandCallback<byte[]>() {
@Override
public byte[] doInCluster(Jedis client, byte[] key) {
return client.get(key);
}
}, Arrays.asList(keys)).resultsAsListSortBy(keys);
.executeMuliKeyCommand((JedisMultiKeyClusterCommandCallback<byte[]>) (client, key) -> client.get(key),
Arrays.asList(keys))
.resultsAsListSortBy(keys);
}
/*
@@ -196,13 +190,9 @@ class JedisClusterStringCommands implements RedisStringCommands {
throw new IllegalArgumentException("Milliseconds have cannot exceed Integer.MAX_VALUE!");
}
connection.getClusterCommandExecutor().executeCommandOnSingleNode(new JedisClusterCommandCallback<String>() {
@Override
public String doInCluster(Jedis client) {
return client.psetex(key, milliseconds, value);
}
}, connection.getTopologyProvider().getTopology().getKeyServingMasterNode(key));
connection.getClusterCommandExecutor().executeCommandOnSingleNode(
(JedisClusterCommandCallback<String>) client -> client.psetex(key, milliseconds, value),
connection.getTopologyProvider().getTopology().getKeyServingMasterNode(key));
}
/*

View File

@@ -635,7 +635,7 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
redis.clients.jedis.ScanResult<redis.clients.jedis.Tuple> result = connection.getCluster().zscan(key,
JedisConverters.toBytes(cursorId), params);
return new ScanIteration<Tuple>(Long.valueOf(result.getStringCursor()),
return new ScanIteration<>(Long.valueOf(result.getStringCursor()),
JedisConverters.tuplesToTuples().convert(result.getResult()));
}
}.open();

View File

@@ -1,12 +1,12 @@
/*
* Copyright 2011-2017 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.
@@ -35,7 +35,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.Queue;
import org.springframework.core.convert.converter.Converter;
@@ -44,24 +43,8 @@ import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.redis.ExceptionTranslationStrategy;
import org.springframework.data.redis.FallbackExceptionTranslationStrategy;
import org.springframework.data.redis.RedisConnectionFailureException;
import org.springframework.data.redis.connection.AbstractRedisConnection;
import org.springframework.data.redis.connection.FutureResult;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.connection.RedisHashCommands;
import org.springframework.data.redis.connection.RedisHyperLogLogCommands;
import org.springframework.data.redis.connection.RedisKeyCommands;
import org.springframework.data.redis.connection.RedisListCommands;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisPipelineException;
import org.springframework.data.redis.connection.RedisSetCommands;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.connection.RedisSubscribedConnectionException;
import org.springframework.data.redis.connection.RedisZSetCommands;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.connection.Subscription;
import org.springframework.data.redis.connection.*;
import org.springframework.data.redis.connection.convert.TransactionResultConverter;
import org.springframework.data.redis.core.types.RedisClientInfo;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
@@ -89,8 +72,6 @@ public class JedisConnection extends AbstractRedisConnection {
private static final Method SEND_COMMAND;
private static final Method GET_RESPONSE;
private static final String SHUTDOWN_SCRIPT = "return redis.call('SHUTDOWN','%s')";
private static final ExceptionTranslationStrategy EXCEPTION_TRANSLATION = new FallbackExceptionTranslationStrategy(
JedisConverters.exceptionConverter());
@@ -130,8 +111,8 @@ public class JedisConnection extends AbstractRedisConnection {
private final int dbIndex;
private final String clientName;
private boolean convertPipelineAndTxResults = true;
private List<FutureResult<Response<?>>> pipelinedResults = new ArrayList<FutureResult<Response<?>>>();
private Queue<FutureResult<Response<?>>> txResults = new LinkedList<FutureResult<Response<?>>>();
private List<FutureResult<Response<?>>> pipelinedResults = new ArrayList<>();
private Queue<FutureResult<Response<?>>> txResults = new LinkedList<>();
class JedisResult extends FutureResult<Response<?>> {
public <T> JedisResult(Response<T> resultHolder, Converter<T, ?> converter) {
@@ -224,7 +205,7 @@ public class JedisConnection extends AbstractRedisConnection {
return exception;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisConnection#keyCommands()
@@ -288,6 +269,24 @@ public class JedisConnection extends AbstractRedisConnection {
return new JedisGeoCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisConnection#scriptingCommands()
*/
@Override
public RedisScriptingCommands scriptingCommands() {
return new JedisScriptingCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisConnection#serverCommands()
*/
@Override
public RedisServerCommands serverCommands() {
return new JedisServerCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisConnection#hyperLogLogCommands()
@@ -305,7 +304,7 @@ public class JedisConnection extends AbstractRedisConnection {
public Object execute(String command, byte[]... args) {
Assert.hasText(command, "a valid command needs to be specified");
try {
List<byte[]> mArgs = new ArrayList<byte[]>();
List<byte[]> mArgs = new ArrayList<>();
if (!ObjectUtils.isEmpty(args)) {
Collections.addAll(mArgs, args);
}
@@ -467,7 +466,7 @@ public class JedisConnection extends AbstractRedisConnection {
}
private List<Object> convertPipelineResults() {
List<Object> results = new ArrayList<Object>();
List<Object> results = new ArrayList<>();
pipeline.sync();
Exception cause = null;
for (FutureResult<Response<?>> result : pipelinedResults) {
@@ -507,300 +506,6 @@ public class JedisConnection extends AbstractRedisConnection {
txResults.add(result);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#dbSize()
*/
@Override
public Long dbSize() {
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.dbSize()));
return null;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.dbSize()));
return null;
}
return jedis.dbSize();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#flushDb()
*/
@Override
public void flushDb() {
try {
if (isPipelined()) {
pipeline(new JedisStatusResult(pipeline.flushDB()));
return;
}
if (isQueueing()) {
transaction(new JedisStatusResult(transaction.flushDB()));
return;
}
jedis.flushDB();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#flushAll()
*/
@Override
public void flushAll() {
try {
if (isPipelined()) {
pipeline(new JedisStatusResult(pipeline.flushAll()));
return;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.flushAll()));
return;
}
jedis.flushAll();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#bgSave()
*/
@Override
public void bgSave() {
try {
if (isPipelined()) {
pipeline(new JedisStatusResult(pipeline.bgsave()));
return;
}
if (isQueueing()) {
transaction(new JedisStatusResult(transaction.bgsave()));
return;
}
jedis.bgsave();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#bgReWriteAof()
*/
@Override
public void bgReWriteAof() {
try {
if (isPipelined()) {
pipeline(new JedisStatusResult(pipeline.bgrewriteaof()));
return;
}
if (isQueueing()) {
transaction(new JedisStatusResult(transaction.bgrewriteaof()));
return;
}
jedis.bgrewriteaof();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/**
* @deprecated As of 1.3, use {@link #bgReWriteAof}.
*/
@Deprecated
public void bgWriteAof() {
bgReWriteAof();
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#save()
*/
@Override
public void save() {
try {
if (isPipelined()) {
pipeline(new JedisStatusResult(pipeline.save()));
return;
}
if (isQueueing()) {
transaction(new JedisStatusResult(transaction.save()));
return;
}
jedis.save();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#getConfig(java.lang.String)
*/
@Override
public List<String> getConfig(String param) {
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.configGet(param)));
return null;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.configGet(param)));
return null;
}
return jedis.configGet(param);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#info()
*/
@Override
public Properties info() {
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.info(), JedisConverters.stringToProps()));
return null;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.info(), JedisConverters.stringToProps()));
return null;
}
return JedisConverters.toProperties(jedis.info());
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#info(java.lang.String)
*/
@Override
public Properties info(String section) {
if (isPipelined()) {
throw new UnsupportedOperationException();
}
if (isQueueing()) {
throw new UnsupportedOperationException();
}
try {
return JedisConverters.toProperties(jedis.info(section));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#lastSave()
*/
@Override
public Long lastSave() {
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.lastsave()));
return null;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.lastsave()));
return null;
}
return jedis.lastsave();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#setConfig(java.lang.String, java.lang.String)
*/
@Override
public void setConfig(String param, String value) {
try {
if (isPipelined()) {
pipeline(new JedisStatusResult(pipeline.configSet(param, value)));
return;
}
if (isQueueing()) {
transaction(new JedisStatusResult(transaction.configSet(param, value)));
return;
}
jedis.configSet(param, value);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#resetConfigStats()
*/
@Override
public void resetConfigStats() {
try {
if (isPipelined()) {
pipeline(new JedisStatusResult(pipeline.configResetStat()));
return;
}
if (isQueueing()) {
transaction(new JedisStatusResult(transaction.configResetStat()));
return;
}
jedis.configResetStat();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#shutdown()
*/
@Override
public void shutdown() {
try {
if (isPipelined()) {
pipeline(new JedisStatusResult(pipeline.shutdown()));
return;
}
if (isQueueing()) {
transaction(new JedisStatusResult(transaction.shutdown()));
return;
}
jedis.shutdown();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#shutdown(org.springframework.data.redis.connection.RedisServerCommands.ShutdownOption)
*/
@Override
public void shutdown(ShutdownOption option) {
if (option == null) {
shutdown();
return;
}
eval(String.format(SHUTDOWN_SCRIPT, option.name()).getBytes(), ReturnType.STATUS, 0);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisConnectionCommands#echo(byte[])
@@ -871,8 +576,8 @@ public class JedisConnection extends AbstractRedisConnection {
public List<Object> exec() {
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.exec(), new TransactionResultConverter<Response<?>>(
new LinkedList<FutureResult<Response<?>>>(txResults), JedisConverters.exceptionConverter())));
pipeline(new JedisResult(pipeline.exec(),
new TransactionResultConverter<>(new LinkedList<>(txResults), JedisConverters.exceptionConverter())));
return null;
}
@@ -881,8 +586,7 @@ public class JedisConnection extends AbstractRedisConnection {
}
List<Object> results = transaction.exec();
return convertPipelineAndTxResults && !CollectionUtils.isEmpty(results)
? new TransactionResultConverter<Response<?>>(txResults, JedisConverters.exceptionConverter())
.convert(results)
? new TransactionResultConverter<>(txResults, JedisConverters.exceptionConverter()).convert(results)
: results;
} catch (Exception ex) {
throw convertJedisAccessException(ex);
@@ -904,7 +608,6 @@ public class JedisConnection extends AbstractRedisConnection {
return jedis;
}
JedisResult newJedisResult(Response<?> response) {
return new JedisResult(response);
}
@@ -1093,253 +796,6 @@ public class JedisConnection extends AbstractRedisConnection {
}
}
//
// Scripting commands
//
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#scriptFlush()
*/
@Override
public void scriptFlush() {
if (isQueueing()) {
throw new UnsupportedOperationException();
}
if (isPipelined()) {
throw new UnsupportedOperationException();
}
try {
jedis.scriptFlush();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#scriptKill()
*/
@Override
public void scriptKill() {
if (isQueueing()) {
throw new UnsupportedOperationException();
}
if (isPipelined()) {
throw new UnsupportedOperationException();
}
try {
jedis.scriptKill();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#scriptLoad(byte[])
*/
@Override
public String scriptLoad(byte[] script) {
if (isQueueing()) {
throw new UnsupportedOperationException();
}
if (isPipelined()) {
throw new UnsupportedOperationException();
}
try {
return JedisConverters.toString(jedis.scriptLoad(script));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#scriptExists(java.lang.String[])
*/
@Override
public List<Boolean> scriptExists(String... scriptSha1) {
if (isQueueing()) {
throw new UnsupportedOperationException();
}
if (isPipelined()) {
throw new UnsupportedOperationException();
}
try {
return jedis.scriptExists(scriptSha1);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#eval(byte[], org.springframework.data.redis.connection.ReturnType, int, byte[][])
*/
@Override
@SuppressWarnings("unchecked")
public <T> T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
if (isQueueing()) {
throw new UnsupportedOperationException();
}
if (isPipelined()) {
throw new UnsupportedOperationException();
}
try {
return (T) new JedisScriptReturnConverter(returnType)
.convert(jedis.eval(script, JedisConverters.toBytes(numKeys), keysAndArgs));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#evalSha(java.lang.String, org.springframework.data.redis.connection.ReturnType, int, byte[][])
*/
@Override
public <T> T evalSha(String scriptSha1, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
return evalSha(JedisConverters.toBytes(scriptSha1), returnType, numKeys, keysAndArgs);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#evalSha(byte[], org.springframework.data.redis.connection.ReturnType, int, byte[][])
*/
@Override
@SuppressWarnings("unchecked")
public <T> T evalSha(byte[] scriptSha1, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
if (isQueueing()) {
throw new UnsupportedOperationException();
}
if (isPipelined()) {
throw new UnsupportedOperationException();
}
try {
return (T) new JedisScriptReturnConverter(returnType).convert(jedis.evalsha(scriptSha1, numKeys, keysAndArgs));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#time()
*/
@Override
public Long time() {
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.time(), JedisConverters.toTimeConverter()));
return null;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.time(), JedisConverters.toTimeConverter()));
return null;
}
return JedisConverters.toTimeConverter().convert(jedis.time());
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#killClient(byte[])
*/
@Override
public void killClient(String host, int port) {
Assert.hasText(host, "Host for 'CLIENT KILL' must not be 'null' or 'empty'.");
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'CLIENT KILL' is not supported in transaction / pipline mode.");
}
try {
this.jedis.clientKill(String.format("%s:%s", host, port));
} catch (Exception e) {
throw convertJedisAccessException(e);
}
}
/*
* @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)
*/
@Override
public void setClientName(byte[] name) {
if (isPipelined() || isQueueing()) {
throw new UnsupportedOperationException("'CLIENT SETNAME' is not suppored in transacton / pipeline mode.");
}
jedis.clientSetname(name);
}
/*
* @see org.springframework.data.redis.connection.RedisServerCommands#getClientName()
*/
@Override
public String getClientName() {
if (isPipelined() || isQueueing()) {
throw new UnsupportedOperationException();
}
return jedis.clientGetname();
}
/*
* @see org.springframework.data.redis.connection.RedisServerCommands#getClientName()
*/
@Override
public List<RedisClientInfo> getClientList() {
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'CLIENT LIST' is not supported in in pipeline / multi mode.");
}
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
@@ -1396,41 +852,4 @@ public class JedisConnection extends AbstractRedisConnection {
return jedis;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#migrate(byte[], org.springframework.data.redis.connection.RedisNode, int, org.springframework.data.redis.connection.RedisServerCommands.MigrateOption)
*/
@Override
public void migrate(byte[] key, RedisNode target, int dbIndex, MigrateOption option) {
migrate(key, target, dbIndex, option, Long.MAX_VALUE);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#migrate(byte[], org.springframework.data.redis.connection.RedisNode, int, org.springframework.data.redis.connection.RedisServerCommands.MigrateOption, long)
*/
@Override
public void migrate(byte[] key, RedisNode target, int dbIndex, MigrateOption option, long timeout) {
final int timeoutToUse = timeout <= Integer.MAX_VALUE ? (int) timeout : Integer.MAX_VALUE;
try {
if (isPipelined()) {
pipeline(new JedisResult(
pipeline.migrate(JedisConverters.toBytes(target.getHost()), target.getPort(), key, dbIndex, timeoutToUse)));
return;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.migrate(JedisConverters.toBytes(target.getHost()), target.getPort(),
key, dbIndex, timeoutToUse)));
return;
}
jedis.migrate(JedisConverters.toBytes(target.getHost()), target.getPort(), key, dbIndex, timeoutToUse);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
}

View File

@@ -58,7 +58,7 @@ import org.springframework.util.StringUtils;
/**
* Connection factory creating <a href="http://github.com/xetorthio/jedis">Jedis</a> based connections.
*
*
* @author Costin Leau
* @author Thomas Darimont
* @author Christoph Strobl
@@ -118,7 +118,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Constructs a new <code>JedisConnectionFactory</code> instance. Will override the other connection parameters passed
* to the factory.
*
*
* @param shardInfo shard information
*/
public JedisConnectionFactory(JedisShardInfo shardInfo) {
@@ -127,7 +127,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Constructs a new <code>JedisConnectionFactory</code> instance using the given pool configuration.
*
*
* @param poolConfig pool configuration
*/
public JedisConnectionFactory(JedisPoolConfig poolConfig) {
@@ -137,7 +137,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Constructs a new {@link JedisConnectionFactory} instance using the given {@link JedisPoolConfig} applied to
* {@link JedisSentinelPool}.
*
*
* @param sentinelConfig
* @since 1.4
*/
@@ -148,7 +148,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Constructs a new {@link JedisConnectionFactory} instance using the given {@link JedisPoolConfig} applied to
* {@link JedisSentinelPool}.
*
*
* @param sentinelConfig
* @param poolConfig pool configuration. Defaulted to new instance if {@literal null}.
* @since 1.4
@@ -161,7 +161,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Constructs a new {@link JedisConnectionFactory} instance using the given {@link RedisClusterConfiguration} applied
* to create a {@link JedisCluster}.
*
*
* @param clusterConfig
* @since 1.7
*/
@@ -172,7 +172,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Constructs a new {@link JedisConnectionFactory} instance using the given {@link RedisClusterConfiguration} applied
* to create a {@link JedisCluster}.
*
*
* @param clusterConfig
* @since 1.7
*/
@@ -184,7 +184,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Returns a Jedis instance to be used as a Redis connection. The instance can be newly created or retrieved from a
* pool.
*
*
* @return Jedis instance ready for wrapping into a {@link RedisConnection}.
*/
protected Jedis fetchJedisConnector() {
@@ -208,7 +208,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Post process a newly retrieved connection. Useful for decorating or executing initialization commands on a new
* connection. This implementation simply returns the connection.
*
*
* @param connection
* @return processed connection
*/
@@ -252,7 +252,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Creates {@link JedisSentinelPool}.
*
*
* @param config
* @return
* @since 1.4
@@ -265,7 +265,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Creates {@link JedisPool}.
*
*
* @return
* @since 1.4
*/
@@ -286,7 +286,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Creates {@link JedisCluster} for given {@link RedisClusterConfiguration} and {@link GenericObjectPoolConfig}.
*
*
* @param clusterConfig must not be {@literal null}.
* @param poolConfig can be {@literal null}.
* @return
@@ -296,7 +296,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
Assert.notNull(clusterConfig, "Cluster configuration must not be null!");
Set<HostAndPort> hostAndPort = new HashSet<HostAndPort>();
Set<HostAndPort> hostAndPort = new HashSet<>();
for (RedisNode node : clusterConfig.getClusterNodes()) {
hostAndPort.add(new HostAndPort(node.getHost(), node.getPort()));
}
@@ -365,7 +365,6 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
return new JedisClusterConnection(cluster, clusterCommandExecutor);
}
/*
* (non-Javadoc)
* @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException)
@@ -376,7 +375,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Returns the Redis hostName.
*
*
* @return the hostName.
*/
public String getHostName() {
@@ -385,7 +384,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Sets the Redis hostName.
*
*
* @param hostName the hostName to set.
*/
public void setHostName(String hostName) {
@@ -414,7 +413,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Returns the password used for authenticating with the Redis server.
*
*
* @return password for authentication.
*/
public String getPassword() {
@@ -423,7 +422,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Sets the password used for authenticating with the Redis server.
*
*
* @param password the password to set.
*/
public void setPassword(String password) {
@@ -432,7 +431,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Returns the port used to connect to the Redis instance.
*
*
* @return the Redis port.
*/
public int getPort() {
@@ -441,7 +440,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Sets the port used to connect to the Redis instance.
*
*
* @param port the Redis port.
*/
public void setPort(int port) {
@@ -450,7 +449,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Returns the shardInfo.
*
*
* @return the shardInfo.
*/
public JedisShardInfo getShardInfo() {
@@ -459,7 +458,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Sets the shard info for this factory.
*
*
* @param shardInfo the shardInfo to set.
*/
public void setShardInfo(JedisShardInfo shardInfo) {
@@ -468,7 +467,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Returns the timeout.
*
*
* @return the timeout.
*/
public int getTimeout() {
@@ -486,7 +485,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Indicates the use of a connection pool.
*
*
* @return the use of connection pooling.
*/
public boolean getUsePool() {
@@ -495,7 +494,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Turns on or off the use of connection pooling.
*
*
* @param usePool the usePool to set.
*/
public void setUsePool(boolean usePool) {
@@ -504,7 +503,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Returns the poolConfig.
*
*
* @return the poolConfig
*/
public JedisPoolConfig getPoolConfig() {
@@ -513,7 +512,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Sets the pool configuration for this factory.
*
*
* @param poolConfig the poolConfig to set.
*/
public void setPoolConfig(JedisPoolConfig poolConfig) {
@@ -522,7 +521,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Returns the index of the database.
*
*
* @return the database index.
*/
public int getDatabase() {
@@ -531,7 +530,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
/**
* Sets the index of the database used by this connection factory. Default is 0.
*
*
* @param index database index.
*/
public void setDatabase(int index) {
@@ -563,7 +562,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
* Specifies if pipelined results should be converted to the expected data type. If false, results of
* {@link JedisConnection#closePipeline()} and {@link JedisConnection#exec()} will be of the type returned by the
* Jedis driver.
*
*
* @return Whether or not to convert pipeline and tx results.
*/
public boolean getConvertPipelineAndTxResults() {
@@ -574,7 +573,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
* Specifies if pipelined results should be converted to the expected data type. If false, results of
* {@link JedisConnection#closePipeline()} and {@link JedisConnection#exec()} will be of the type returned by the
* Jedis driver.
*
*
* @param convertPipelineAndTxResults Whether or not to convert pipeline and tx results.
*/
public void setConvertPipelineAndTxResults(boolean convertPipelineAndTxResults) {
@@ -626,7 +625,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
return Collections.emptySet();
}
Set<String> convertedNodes = new LinkedHashSet<String>(nodes.size());
Set<String> convertedNodes = new LinkedHashSet<>(nodes.size());
for (RedisNode node : nodes) {
if (node != null) {
convertedNodes.add(node.asString());

View File

@@ -15,6 +15,16 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.jedis.BitOP;
import redis.clients.jedis.GeoCoordinate;
import redis.clients.jedis.GeoRadiusResponse;
import redis.clients.jedis.GeoUnit;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.SortingParams;
import redis.clients.jedis.params.geo.GeoRadiusParam;
import redis.clients.util.SafeEncoder;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
@@ -60,19 +70,9 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.jedis.BitOP;
import redis.clients.jedis.GeoCoordinate;
import redis.clients.jedis.GeoRadiusResponse;
import redis.clients.jedis.GeoUnit;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.SortingParams;
import redis.clients.jedis.params.geo.GeoRadiusParam;
import redis.clients.util.SafeEncoder;
/**
* Jedis type converters.
*
*
* @author Jennifer Hickey
* @author Christoph Strobl
* @author Thomas Darimont
@@ -118,24 +118,24 @@ abstract public class JedisConverters extends Converters {
return source == null ? null : SafeEncoder.encode(source);
}
};
BYTES_LIST_TO_STRING_LIST_CONVERTER = new ListConverter<byte[], String>(BYTES_TO_STRING_CONVERTER);
BYTES_LIST_TO_STRING_LIST_CONVERTER = new ListConverter<>(BYTES_TO_STRING_CONVERTER);
STRING_TO_BYTES = new Converter<String, byte[]>() {
public byte[] convert(String source) {
return source == null ? null : SafeEncoder.encode(source);
}
};
STRING_LIST_TO_BYTE_LIST = new ListConverter<String, byte[]>(STRING_TO_BYTES);
STRING_SET_TO_BYTE_SET = new SetConverter<String, byte[]>(STRING_TO_BYTES);
STRING_MAP_TO_BYTE_MAP = new MapConverter<String, byte[]>(STRING_TO_BYTES);
STRING_LIST_TO_BYTE_LIST = new ListConverter<>(STRING_TO_BYTES);
STRING_SET_TO_BYTE_SET = new SetConverter<>(STRING_TO_BYTES);
STRING_MAP_TO_BYTE_MAP = new MapConverter<>(STRING_TO_BYTES);
TUPLE_CONVERTER = new Converter<redis.clients.jedis.Tuple, Tuple>() {
public Tuple convert(redis.clients.jedis.Tuple source) {
return source != null ? new DefaultTuple(source.getBinaryElement(), source.getScore()) : null;
}
};
TUPLE_SET_TO_TUPLE_SET = new SetConverter<redis.clients.jedis.Tuple, Tuple>(TUPLE_CONVERTER);
TUPLE_LIST_TO_TUPLE_LIST_CONVERTER = new ListConverter<redis.clients.jedis.Tuple, Tuple>(TUPLE_CONVERTER);
TUPLE_SET_TO_TUPLE_SET = new SetConverter<>(TUPLE_CONVERTER);
TUPLE_LIST_TO_TUPLE_LIST_CONVERTER = new ListConverter<>(TUPLE_CONVERTER);
PLUS_BYTES = toBytes("+");
MINUS_BYTES = toBytes("-");
POSITIVE_INFINITY_BYTES = toBytes("+inf");
@@ -214,8 +214,7 @@ abstract public class JedisConverters extends Converters {
return geoCoordinate != null ? new Point(geoCoordinate.getLongitude(), geoCoordinate.getLatitude()) : null;
}
};
LIST_GEO_COORDINATE_TO_POINT_CONVERTER = new ListConverter<redis.clients.jedis.GeoCoordinate, Point>(
GEO_COORDINATE_TO_POINT_CONVERTER);
LIST_GEO_COORDINATE_TO_POINT_CONVERTER = new ListConverter<>(GEO_COORDINATE_TO_POINT_CONVERTER);
}
public static Converter<String, byte[]> stringToBytes() {
@@ -224,7 +223,7 @@ abstract public class JedisConverters extends Converters {
/**
* {@link ListConverter} converting jedis {@link redis.clients.jedis.Tuple} to {@link Tuple}.
*
*
* @return
* @since 1.4
*/
@@ -322,7 +321,7 @@ abstract public class JedisConverters extends Converters {
return Collections.emptyList();
}
List<RedisServer> sentinels = new ArrayList<RedisServer>();
List<RedisServer> sentinels = new ArrayList<>();
for (Map<String, String> info : source) {
sentinels.add(RedisServer.newServerFrom(Converters.toProperties(info)));
}
@@ -394,7 +393,7 @@ abstract public class JedisConverters extends Converters {
/**
* Converts a given {@link Boundary} to its binary representation suitable for {@literal ZRANGEBY*} commands, despite
* {@literal ZRANGEBYLEX}.
*
*
* @param boundary
* @param defaultValue
* @return
@@ -411,7 +410,7 @@ abstract public class JedisConverters extends Converters {
/**
* Converts a given {@link Boundary} to its binary representation suitable for ZRANGEBYLEX command.
*
*
* @param boundary
* @return
* @since 1.6
@@ -433,7 +432,7 @@ abstract public class JedisConverters extends Converters {
* <dt>{@link TimeUnit#MILLISECONDS}</dt>
* <dd>{@code PX}</dd>
* </dl>
*
*
* @param expiration
* @return
* @since 1.7
@@ -452,7 +451,7 @@ abstract public class JedisConverters extends Converters {
* <dt>{@link SetOption#SET_IF_PRESENT}</dt>
* <dd>{@code XX}</dd>
* </dl>
*
*
* @param option
* @return
* @since 1.7
@@ -537,7 +536,7 @@ abstract public class JedisConverters extends Converters {
/**
* Get a {@link Converter} capable of converting {@link GeoRadiusResponse} into {@link GeoResults}.
*
*
* @param metric
* @return
* @since 1.8
@@ -549,7 +548,7 @@ abstract public class JedisConverters extends Converters {
/**
* Convert {@link Metric} into {@link GeoUnit}.
*
*
* @param metric
* @return
* @since 1.8
@@ -563,7 +562,7 @@ abstract public class JedisConverters extends Converters {
/**
* Convert {@link Point} into {@link GeoCoordinate}.
*
*
* @param source
* @return
* @since 1.8
@@ -574,7 +573,7 @@ abstract public class JedisConverters extends Converters {
/**
* Convert {@link GeoRadiusCommandArgs} into {@link GeoRadiusParam}.
*
*
* @param source
* @return
* @since 1.8
@@ -642,7 +641,7 @@ abstract public class JedisConverters extends Converters {
@Override
public GeoResults<GeoLocation<byte[]>> convert(List<GeoRadiusResponse> source) {
List<GeoResult<GeoLocation<byte[]>>> results = new ArrayList<GeoResult<GeoLocation<byte[]>>>(source.size());
List<GeoResult<GeoLocation<byte[]>>> results = new ArrayList<>(source.size());
Converter<redis.clients.jedis.GeoRadiusResponse, GeoResult<GeoLocation<byte[]>>> converter = GeoResultConverterFactory.INSTANCE
.forMetric(metric);
@@ -650,7 +649,7 @@ abstract public class JedisConverters extends Converters {
results.add(converter.convert(result));
}
return new GeoResults<GeoLocation<byte[]>>(results, metric);
return new GeoResults<>(results, metric);
}
}
}
@@ -681,7 +680,7 @@ abstract public class JedisConverters extends Converters {
Point point = GEO_COORDINATE_TO_POINT_CONVERTER.convert(source.getCoordinate());
return new GeoResult<GeoLocation<byte[]>>(new GeoLocation<byte[]>(source.getMember(), point),
return new GeoResult<>(new GeoLocation<>(source.getMember(), point),
new Distance(source.getDistance(), metric));
}
}

View File

@@ -83,7 +83,7 @@ class JedisGeoCommands implements RedisGeoCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(memberCoordinateMap, "MemberCoordinateMap must not be null!");
Map<byte[], GeoCoordinate> redisGeoCoordinateMap = new HashMap<byte[], GeoCoordinate>();
Map<byte[], GeoCoordinate> redisGeoCoordinateMap = new HashMap<>();
for (byte[] mapKey : memberCoordinateMap.keySet()) {
redisGeoCoordinateMap.put(mapKey, JedisConverters.toGeoCoordinate(memberCoordinateMap.get(mapKey)));
@@ -115,7 +115,7 @@ class JedisGeoCommands implements RedisGeoCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(locations, "Locations must not be null!");
Map<byte[], redis.clients.jedis.GeoCoordinate> redisGeoCoordinateMap = new HashMap<byte[], redis.clients.jedis.GeoCoordinate>();
Map<byte[], redis.clients.jedis.GeoCoordinate> redisGeoCoordinateMap = new HashMap<>();
for (GeoLocation<byte[]> location : locations) {
redisGeoCoordinateMap.put(location.getName(), JedisConverters.toGeoCoordinate(location.getPoint()));

View File

@@ -90,7 +90,6 @@ class JedisHashCommands implements RedisHashCommands {
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisHashCommands#hDel(byte[], byte[][])

View File

@@ -161,7 +161,7 @@ class JedisKeyCommands implements RedisKeyCommands {
ScanParams params = JedisConverters.toScanParams(options);
redis.clients.jedis.ScanResult<String> result = connection.getJedis().scan(Long.toString(cursorId), params);
return new ScanIteration<byte[]>(Long.valueOf(result.getStringCursor()),
return new ScanIteration<>(Long.valueOf(result.getStringCursor()),
JedisConverters.stringListToByteList().convert(result.getResult()));
}

View File

@@ -15,14 +15,14 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.util.SafeEncoder;
import java.util.ArrayList;
import java.util.List;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.redis.connection.ReturnType;
import redis.clients.util.SafeEncoder;
/**
* Converts the value returned by Jedis script eval to the expected {@link ReturnType}
*
@@ -54,7 +54,7 @@ public class JedisScriptReturnConverter implements Converter<Object, Object> {
}
if (returnType == ReturnType.MULTI) {
List<Object> resultList = (List<Object>) result;
List<Object> convertedResults = new ArrayList<Object>();
List<Object> convertedResults = new ArrayList<>();
for (Object res : resultList) {
if (res instanceof String) {
// evalsha converts byte[] to String. Convert back for

View File

@@ -0,0 +1,174 @@
/*
* Copyright 2017 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.connection.jedis;
import java.util.List;
import org.springframework.data.redis.connection.RedisScriptingCommands;
import org.springframework.data.redis.connection.ReturnType;
/**
* @author Mark Paluch
* @since 2.0
*/
class JedisScriptingCommands implements RedisScriptingCommands {
private final JedisConnection connection;
public JedisScriptingCommands(JedisConnection connection) {
this.connection = connection;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#scriptFlush()
*/
@Override
public void scriptFlush() {
if (isQueueing()) {
throw new UnsupportedOperationException();
}
if (isPipelined()) {
throw new UnsupportedOperationException();
}
try {
connection.getJedis().scriptFlush();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#scriptKill()
*/
@Override
public void scriptKill() {
if (isQueueing()) {
throw new UnsupportedOperationException();
}
if (isPipelined()) {
throw new UnsupportedOperationException();
}
try {
connection.getJedis().scriptKill();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#scriptLoad(byte[])
*/
@Override
public String scriptLoad(byte[] script) {
if (isQueueing()) {
throw new UnsupportedOperationException();
}
if (isPipelined()) {
throw new UnsupportedOperationException();
}
try {
return JedisConverters.toString(connection.getJedis().scriptLoad(script));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#scriptExists(java.lang.String[])
*/
@Override
public List<Boolean> scriptExists(String... scriptSha1) {
if (isQueueing()) {
throw new UnsupportedOperationException();
}
if (isPipelined()) {
throw new UnsupportedOperationException();
}
try {
return connection.getJedis().scriptExists(scriptSha1);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#eval(byte[], org.springframework.data.redis.connection.ReturnType, int, byte[][])
*/
@Override
@SuppressWarnings("unchecked")
public <T> T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
if (isQueueing()) {
throw new UnsupportedOperationException();
}
if (isPipelined()) {
throw new UnsupportedOperationException();
}
try {
return (T) new JedisScriptReturnConverter(returnType)
.convert(connection.getJedis().eval(script, JedisConverters.toBytes(numKeys), keysAndArgs));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#evalSha(java.lang.String, org.springframework.data.redis.connection.ReturnType, int, byte[][])
*/
@Override
public <T> T evalSha(String scriptSha1, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
return evalSha(JedisConverters.toBytes(scriptSha1), returnType, numKeys, keysAndArgs);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#evalSha(byte[], org.springframework.data.redis.connection.ReturnType, int, byte[][])
*/
@Override
@SuppressWarnings("unchecked")
public <T> T evalSha(byte[] scriptSha1, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
if (isQueueing()) {
throw new UnsupportedOperationException();
}
if (isPipelined()) {
throw new UnsupportedOperationException();
}
try {
return (T) new JedisScriptReturnConverter(returnType)
.convert(connection.getJedis().evalsha(scriptSha1, numKeys, keysAndArgs));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
private boolean isPipelined() {
return connection.isPipelined();
}
private boolean isQueueing() {
return connection.isQueueing();
}
private RuntimeException convertJedisAccessException(Exception ex) {
return connection.convertJedisAccessException(ex);
}
}

View File

@@ -0,0 +1,505 @@
/*
* Copyright 2017 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.connection.jedis;
import java.util.List;
import java.util.Properties;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.connection.jedis.JedisConnection.JedisResult;
import org.springframework.data.redis.core.types.RedisClientInfo;
import org.springframework.util.Assert;
/**
* @author Mark Paluch
* @since 2.0
*/
class JedisServerCommands implements RedisServerCommands {
private static final String SHUTDOWN_SCRIPT = "return redis.call('SHUTDOWN','%s')";
private final JedisConnection connection;
public JedisServerCommands(JedisConnection connection) {
this.connection = connection;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#bgReWriteAof()
*/
@Override
public void bgReWriteAof() {
try {
if (isPipelined()) {
pipeline(connection.newStatusResult(connection.getPipeline().bgrewriteaof()));
return;
}
if (isQueueing()) {
transaction(connection.newStatusResult(connection.getTransaction().bgrewriteaof()));
return;
}
connection.getJedis().bgrewriteaof();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#bgSave()
*/
@Override
public void bgSave() {
try {
if (isPipelined()) {
pipeline(connection.newStatusResult(connection.getPipeline().bgsave()));
return;
}
if (isQueueing()) {
transaction(connection.newStatusResult(connection.getTransaction().bgsave()));
return;
}
connection.getJedis().bgsave();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#lastSave()
*/
@Override
public Long lastSave() {
try {
if (isPipelined()) {
pipeline(connection.newJedisResult(connection.getPipeline().lastsave()));
return null;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction().lastsave()));
return null;
}
return connection.getJedis().lastsave();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#save()
*/
@Override
public void save() {
try {
if (isPipelined()) {
pipeline(connection.newStatusResult(connection.getPipeline().save()));
return;
}
if (isQueueing()) {
transaction(connection.newStatusResult(connection.getTransaction().save()));
return;
}
connection.getJedis().save();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#dbSize()
*/
@Override
public Long dbSize() {
try {
if (isPipelined()) {
pipeline(connection.newJedisResult(connection.getPipeline().dbSize()));
return null;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction().dbSize()));
return null;
}
return connection.getJedis().dbSize();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#flushDb()
*/
@Override
public void flushDb() {
try {
if (isPipelined()) {
pipeline(connection.newStatusResult(connection.getPipeline().flushDB()));
return;
}
if (isQueueing()) {
transaction(connection.newStatusResult(connection.getTransaction().flushDB()));
return;
}
connection.getJedis().flushDB();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#flushAll()
*/
@Override
public void flushAll() {
try {
if (isPipelined()) {
pipeline(connection.newStatusResult(connection.getPipeline().flushAll()));
return;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction().flushAll()));
return;
}
connection.getJedis().flushAll();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#info()
*/
@Override
public Properties info() {
try {
if (isPipelined()) {
pipeline(connection.newJedisResult(connection.getPipeline().info(), JedisConverters.stringToProps()));
return null;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction().info(), JedisConverters.stringToProps()));
return null;
}
return JedisConverters.toProperties(connection.getJedis().info());
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#info(java.lang.String)
*/
@Override
public Properties info(String section) {
if (isPipelined()) {
throw new UnsupportedOperationException();
}
if (isQueueing()) {
throw new UnsupportedOperationException();
}
try {
return JedisConverters.toProperties(connection.getJedis().info(section));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#shutdown()
*/
@Override
public void shutdown() {
try {
if (isPipelined()) {
pipeline(connection.newStatusResult(connection.getPipeline().shutdown()));
return;
}
if (isQueueing()) {
transaction(connection.newStatusResult(connection.getTransaction().shutdown()));
return;
}
connection.getJedis().shutdown();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#shutdown(org.springframework.data.redis.connection.RedisServerCommands.ShutdownOption)
*/
@Override
public void shutdown(ShutdownOption option) {
if (option == null) {
shutdown();
return;
}
connection.eval(String.format(SHUTDOWN_SCRIPT, option.name()).getBytes(), ReturnType.STATUS, 0);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#getConfig(java.lang.String)
*/
@Override
public List<String> getConfig(String param) {
try {
if (isPipelined()) {
pipeline(connection.newJedisResult(connection.getPipeline().configGet(param)));
return null;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction().configGet(param)));
return null;
}
return connection.getJedis().configGet(param);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#setConfig(java.lang.String, java.lang.String)
*/
@Override
public void setConfig(String param, String value) {
try {
if (isPipelined()) {
pipeline(connection.newStatusResult(connection.getPipeline().configSet(param, value)));
return;
}
if (isQueueing()) {
transaction(connection.newStatusResult(connection.getTransaction().configSet(param, value)));
return;
}
connection.getJedis().configSet(param, value);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#resetConfigStats()
*/
@Override
public void resetConfigStats() {
try {
if (isPipelined()) {
pipeline(connection.newStatusResult(connection.getPipeline().configResetStat()));
return;
}
if (isQueueing()) {
transaction(connection.newStatusResult(connection.getTransaction().configResetStat()));
return;
}
connection.getJedis().configResetStat();
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#time()
*/
@Override
public Long time() {
try {
if (isPipelined()) {
pipeline(connection.newJedisResult(connection.getPipeline().time(), JedisConverters.toTimeConverter()));
return null;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction().time(), JedisConverters.toTimeConverter()));
return null;
}
return JedisConverters.toTimeConverter().convert(connection.getJedis().time());
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#killClient(java.lang.String, int)
*/
@Override
public void killClient(String host, int port) {
Assert.hasText(host, "Host for 'CLIENT KILL' must not be 'null' or 'empty'.");
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'CLIENT KILL' is not supported in transaction / pipline mode.");
}
try {
this.connection.getJedis().clientKill(String.format("%s:%s", host, port));
} catch (Exception e) {
throw convertJedisAccessException(e);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#setClientName(byte[])
*/
@Override
public void setClientName(byte[] name) {
if (isPipelined() || isQueueing()) {
throw new UnsupportedOperationException("'CLIENT SETNAME' is not suppored in transacton / pipeline mode.");
}
connection.getJedis().clientSetname(name);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#getClientName()
*/
@Override
public String getClientName() {
if (isPipelined() || isQueueing()) {
throw new UnsupportedOperationException();
}
return connection.getJedis().clientGetname();
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#getClientList()
*/
@Override
public List<RedisClientInfo> getClientList() {
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'CLIENT LIST' is not supported in in pipeline / multi mode.");
}
return JedisConverters.toListOfRedisClientInformation(this.connection.getJedis().clientList());
}
/*
* (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.");
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'SLAVEOF' cannot be called in pipline / transaction mode.");
}
try {
this.connection.getJedis().slaveof(host, port);
} catch (Exception e) {
throw convertJedisAccessException(e);
}
}
/*
* (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.connection.getJedis().slaveofNoOne();
} catch (Exception e) {
throw convertJedisAccessException(e);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#migrate(byte[], org.springframework.data.redis.connection.RedisNode, int, org.springframework.data.redis.connection.RedisServerCommands.MigrateOption)
*/
@Override
public void migrate(byte[] key, RedisNode target, int dbIndex, MigrateOption option) {
migrate(key, target, dbIndex, option, Long.MAX_VALUE);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#migrate(byte[], org.springframework.data.redis.connection.RedisNode, int, org.springframework.data.redis.connection.RedisServerCommands.MigrateOption, long)
*/
@Override
public void migrate(byte[] key, RedisNode target, int dbIndex, MigrateOption option, long timeout) {
final int timeoutToUse = timeout <= Integer.MAX_VALUE ? (int) timeout : Integer.MAX_VALUE;
try {
if (isPipelined()) {
pipeline(connection.newJedisResult(connection.getPipeline().migrate(JedisConverters.toBytes(target.getHost()),
target.getPort(), key, dbIndex, timeoutToUse)));
return;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction()
.migrate(JedisConverters.toBytes(target.getHost()), target.getPort(), key, dbIndex, timeoutToUse)));
return;
}
connection.getJedis().migrate(JedisConverters.toBytes(target.getHost()), target.getPort(), key, dbIndex,
timeoutToUse);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
private boolean isPipelined() {
return connection.isPipelined();
}
private void pipeline(JedisResult result) {
connection.pipeline(result);
}
private boolean isQueueing() {
return connection.isQueueing();
}
private void transaction(JedisResult result) {
connection.transaction(result);
}
private RuntimeException convertJedisAccessException(Exception ex) {
return connection.convertJedisAccessException(ex);
}
}

View File

@@ -15,6 +15,8 @@
*/
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.ScanParams;
import java.util.List;
import java.util.Set;
@@ -24,7 +26,6 @@ import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.KeyBoundCursor;
import org.springframework.data.redis.core.ScanIteration;
import org.springframework.data.redis.core.ScanOptions;
import redis.clients.jedis.ScanParams;
/**
* @author Christoph Strobl
@@ -214,11 +215,13 @@ class JedisSetCommands implements RedisSetCommands {
public Boolean sMove(byte[] srcKey, byte[] destKey, byte[] value) {
try {
if (isPipelined()) {
pipeline(connection.newJedisResult(connection.getPipeline().smove(srcKey, destKey, value), JedisConverters.longToBoolean()));
pipeline(connection.newJedisResult(connection.getPipeline().smove(srcKey, destKey, value),
JedisConverters.longToBoolean()));
return null;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction().smove(srcKey, destKey, value), JedisConverters.longToBoolean()));
transaction(connection.newJedisResult(connection.getTransaction().smove(srcKey, destKey, value),
JedisConverters.longToBoolean()));
return null;
}
return JedisConverters.toBoolean(connection.getJedis().smove(srcKey, destKey, value));
@@ -387,7 +390,8 @@ class JedisSetCommands implements RedisSetCommands {
ScanParams params = JedisConverters.toScanParams(options);
redis.clients.jedis.ScanResult<byte[]> result = connection.getJedis().sscan(key, JedisConverters.toBytes(cursorId), params);
redis.clients.jedis.ScanResult<byte[]> result = connection.getJedis().sscan(key,
JedisConverters.toBytes(cursorId), params);
return new ScanIteration<>(Long.valueOf(result.getStringCursor()), result.getResult());
}

View File

@@ -77,7 +77,6 @@ class JedisStringCommands implements RedisStringCommands {
@Override
public List<byte[]> mGet(byte[]... keys) {
try {
if (isPipelined()) {
pipeline(connection.newJedisResult(connection.getPipeline().mget(keys)));
@@ -164,7 +163,8 @@ class JedisStringCommands implements RedisStringCommands {
"Expiration.expirationTime must be less than Integer.MAX_VALUE for pipeline in Jedis.");
}
pipeline(connection.newStatusResult(connection.getPipeline().set(key, value, nxxx, expx, (int) expiration.getExpirationTime())));
pipeline(connection.newStatusResult(
connection.getPipeline().set(key, value, nxxx, expx, (int) expiration.getExpirationTime())));
return;
}
if (isQueueing()) {
@@ -174,8 +174,8 @@ class JedisStringCommands implements RedisStringCommands {
"Expiration.expirationTime must be less than Integer.MAX_VALUE for transactions in Jedis.");
}
transaction(
connection.newStatusResult(connection.getTransaction().set(key, value, nxxx, expx, (int) expiration.getExpirationTime())));
transaction(connection.newStatusResult(
connection.getTransaction().set(key, value, nxxx, expx, (int) expiration.getExpirationTime())));
return;
}
@@ -188,18 +188,18 @@ class JedisStringCommands implements RedisStringCommands {
}
}
@Override
public Boolean setNX(byte[] key, byte[] value) {
try {
if (isPipelined()) {
pipeline(connection.newJedisResult(connection.getPipeline().setnx(key, value), JedisConverters.longToBoolean()));
pipeline(
connection.newJedisResult(connection.getPipeline().setnx(key, value), JedisConverters.longToBoolean()));
return null;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction().setnx(key, value), JedisConverters.longToBoolean()));
transaction(
connection.newJedisResult(connection.getTransaction().setnx(key, value), JedisConverters.longToBoolean()));
return null;
}
return JedisConverters.toBoolean(connection.getJedis().setnx(key, value));
@@ -271,13 +271,13 @@ class JedisStringCommands implements RedisStringCommands {
try {
if (isPipelined()) {
pipeline(
connection.newJedisResult(connection.getPipeline().msetnx(JedisConverters.toByteArrays(tuples)), JedisConverters.longToBoolean()));
pipeline(connection.newJedisResult(connection.getPipeline().msetnx(JedisConverters.toByteArrays(tuples)),
JedisConverters.longToBoolean()));
return null;
}
if (isQueueing()) {
transaction(
connection.newJedisResult(connection.getTransaction().msetnx(JedisConverters.toByteArrays(tuples)), JedisConverters.longToBoolean()));
transaction(connection.newJedisResult(connection.getTransaction().msetnx(JedisConverters.toByteArrays(tuples)),
JedisConverters.longToBoolean()));
return null;
}
return JedisConverters.toBoolean(connection.getJedis().msetnx(JedisConverters.toByteArrays(tuples)));
@@ -406,11 +406,13 @@ class JedisStringCommands implements RedisStringCommands {
try {
if (isPipelined()) {
pipeline(connection.newJedisResult(connection.getPipeline().substr(key, (int) start, (int) end), JedisConverters.stringToBytes()));
pipeline(connection.newJedisResult(connection.getPipeline().substr(key, (int) start, (int) end),
JedisConverters.stringToBytes()));
return null;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction().substr(key, (int) start, (int) end), JedisConverters.stringToBytes()));
transaction(connection.newJedisResult(connection.getTransaction().substr(key, (int) start, (int) end),
JedisConverters.stringToBytes()));
return null;
}
return connection.getJedis().substr(key, (int) start, (int) end);
@@ -472,7 +474,8 @@ class JedisStringCommands implements RedisStringCommands {
return null;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction().setbit(key, offset, JedisConverters.toBit(value))));
transaction(
connection.newJedisResult(connection.getTransaction().setbit(key, offset, JedisConverters.toBit(value))));
return null;
}
return connection.getJedis().setbit(key, offset, JedisConverters.toBit(value));
@@ -521,17 +524,18 @@ class JedisStringCommands implements RedisStringCommands {
@Override
public Long bitOp(BitOperation op, byte[] destination, byte[]... keys) {
if (op == BitOperation.NOT && keys.length > 1) {
throw new UnsupportedOperationException("Bitop NOT should only be performed against one key");
}
try {
if (isPipelined()) {
pipeline(connection.newJedisResult(connection.getPipeline().bitop(JedisConverters.toBitOp(op), destination, keys)));
pipeline(
connection.newJedisResult(connection.getPipeline().bitop(JedisConverters.toBitOp(op), destination, keys)));
return null;
}
if (isQueueing()) {
transaction(connection.newJedisResult(connection.getTransaction().bitop(JedisConverters.toBitOp(op), destination, keys)));
transaction(connection
.newJedisResult(connection.getTransaction().bitop(JedisConverters.toBitOp(op), destination, keys)));
return null;
}
return connection.getJedis().bitop(JedisConverters.toBitOp(op), destination, keys);

View File

@@ -16,6 +16,15 @@
package org.springframework.data.redis.connection.jedis;
import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.jedis.BinaryJedisPubSub;
import redis.clients.jedis.Protocol;
import redis.clients.jedis.SortingParams;
import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.exceptions.JedisException;
import redis.clients.util.SafeEncoder;
import java.io.IOException;
import java.io.StringReader;
import java.net.UnknownHostException;
@@ -34,23 +43,14 @@ import org.springframework.data.redis.RedisConnectionFailureException;
import org.springframework.data.redis.RedisSystemException;
import org.springframework.data.redis.connection.DefaultTuple;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.connection.RedisListCommands.Position;
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.connection.SortParameters;
import org.springframework.data.redis.connection.SortParameters.Order;
import org.springframework.data.redis.connection.SortParameters.Range;
import org.springframework.util.Assert;
import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.jedis.BinaryJedisPubSub;
import redis.clients.jedis.Protocol;
import redis.clients.jedis.SortingParams;
import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.exceptions.JedisException;
import redis.clients.util.SafeEncoder;
/**
* Helper class featuring methods for Jedis connection handling, providing support for exception translation. Deprecated
* in favor of {@link JedisConverters}
@@ -126,7 +126,7 @@ public abstract class JedisUtils {
*/
@Deprecated
static Set<Tuple> convertJedisTuple(Set<redis.clients.jedis.Tuple> tuples) {
Set<Tuple> value = new LinkedHashSet<Tuple>(tuples.size());
Set<Tuple> value = new LinkedHashSet<>(tuples.size());
for (redis.clients.jedis.Tuple tuple : tuples) {
value.add(new DefaultTuple(tuple.getBinaryElement(), tuple.getScore()));
}
@@ -150,7 +150,7 @@ public abstract class JedisUtils {
*/
@Deprecated
static Map<String, String> convert(String[] fields, String[] values) {
Map<String, String> result = new LinkedHashMap<String, String>(fields.length);
Map<String, String> result = new LinkedHashMap<>(fields.length);
for (int i = 0; i < values.length; i++) {
result.put(fields[i], values[i]);
@@ -256,7 +256,7 @@ public abstract class JedisUtils {
}
static byte[][] bXPopArgs(int timeout, byte[]... keys) {
final List<byte[]> args = new ArrayList<byte[]>();
final List<byte[]> args = new ArrayList<>();
for (final byte[] arg : keys) {
args.add(arg);
}
@@ -298,7 +298,7 @@ public abstract class JedisUtils {
}
if (returnType == ReturnType.MULTI) {
List<Object> resultList = (List<Object>) result;
List<Object> convertedResults = new ArrayList<Object>();
List<Object> convertedResults = new ArrayList<>();
for (Object res : resultList) {
if (res instanceof String) {
// evalsha converts byte[] to String. Convert back for consistency

View File

@@ -811,7 +811,7 @@ class JedisZSetCommands implements RedisZSetCommands {
private Map<byte[], Double> zAddArgs(Set<Tuple> tuples) {
Map<byte[], Double> args = new LinkedHashMap<>(tuples.size(), 1);
Set<Double> scores = new HashSet<Double>(tuples.size(), 1);
Set<Double> scores = new HashSet<>(tuples.size(), 1);
boolean isAtLeastJedis24 = JedisVersionUtil.atLeastJedis24();

View File

@@ -36,7 +36,7 @@ import org.springframework.util.StringUtils;
/**
* Default implementation of {@link LettucePool}.
*
*
* @author Jennifer Hickey
* @author Christoph Strobl
* @author Mark Paluch
@@ -62,7 +62,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
/**
* Uses the {@link Config} and {@link RedisClient} defaults for configuring the connection pool
*
*
* @param hostName The Redis host
* @param port The Redis port
*/
@@ -84,7 +84,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
/**
* Uses the {@link RedisClient} defaults for configuring the connection pool
*
*
* @param hostName The Redis host
* @param port The Redis port
* @param poolConfig The pool {@link GenericObjectPoolConfig}
@@ -117,8 +117,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
}
client.setDefaultTimeout(timeout, TimeUnit.MILLISECONDS);
this.internalPool = new GenericObjectPool<StatefulConnection<byte[], byte[]>>(new LettuceFactory(client, dbIndex),
poolConfig);
this.internalPool = new GenericObjectPool<>(new LettuceFactory(client, dbIndex), poolConfig);
}
/**
@@ -220,7 +219,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
/**
* Returns the index of the database.
*
*
* @return Returns the database index
*/
public int getDatabase() {
@@ -229,7 +228,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
/**
* Sets the index of the database used by this connection pool. Default is 0.
*
*
* @param index database index
*/
public void setDatabase(int index) {
@@ -239,7 +238,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
/**
* Returns the password used for authenticating with the Redis server.
*
*
* @return password for authentication
*/
public String getPassword() {
@@ -248,7 +247,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
/**
* Sets the password used for authenticating with the Redis server.
*
*
* @param password the password to set
*/
public void setPassword(String password) {
@@ -257,7 +256,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
/**
* Returns the current host.
*
*
* @return the host
*/
public String getHostName() {
@@ -266,7 +265,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
/**
* Sets the host.
*
*
* @param host the host to set
*/
public void setHostName(String host) {
@@ -275,7 +274,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
/**
* Returns the current port.
*
*
* @return the port
*/
public int getPort() {
@@ -284,7 +283,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
/**
* Sets the port.
*
*
* @param port the port to set
*/
public void setPort(int port) {
@@ -293,7 +292,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
/**
* Returns the connection timeout (in milliseconds).
*
*
* @return connection timeout
*/
public long getTimeout() {
@@ -302,7 +301,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
/**
* Sets the connection timeout (in milliseconds).
*
*
* @param timeout connection timeout
*/
public void setTimeout(long timeout) {
@@ -311,7 +310,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
/**
* Get the {@link ClientResources} to reuse infrastructure.
*
*
* @return {@literal null} if not set.
* @since 1.7
*/
@@ -322,7 +321,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
/**
* Sets the {@link ClientResources} to reuse the client infrastructure. <br />
* Set to {@literal null} to not share resources.
*
*
* @param clientResources can be {@literal null}.
* @since 1.7
*/
@@ -399,7 +398,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
*/
@Override
public PooledObject<StatefulConnection<byte[], byte[]>> wrap(StatefulConnection<byte[], byte[]> obj) {
return new DefaultPooledObject<StatefulConnection<byte[], byte[]>>(obj);
return new DefaultPooledObject<>(obj);
}
}
}

View File

@@ -17,6 +17,7 @@ package org.springframework.data.redis.connection.lettuce;
import io.lettuce.core.RedisException;
import io.lettuce.core.api.StatefulConnection;
import io.lettuce.core.api.sync.BaseRedisCommands;
import io.lettuce.core.cluster.RedisClusterClient;
import io.lettuce.core.cluster.SlotHash;
import io.lettuce.core.cluster.api.StatefulRedisClusterConnection;
@@ -31,8 +32,6 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import org.springframework.beans.DirectFieldAccessor;
@@ -40,28 +39,13 @@ import org.springframework.beans.factory.DisposableBean;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.redis.ExceptionTranslationStrategy;
import org.springframework.data.redis.PassThroughExceptionTranslationStrategy;
import org.springframework.data.redis.connection.ClusterCommandExecutor;
import org.springframework.data.redis.connection.*;
import org.springframework.data.redis.connection.ClusterCommandExecutor.ClusterCommandCallback;
import org.springframework.data.redis.connection.ClusterCommandExecutor.MultiKeyClusterCommandCallback;
import org.springframework.data.redis.connection.ClusterCommandExecutor.NodeResult;
import org.springframework.data.redis.connection.ClusterInfo;
import org.springframework.data.redis.connection.ClusterNodeResourceProvider;
import org.springframework.data.redis.connection.ClusterTopology;
import org.springframework.data.redis.connection.ClusterTopologyProvider;
import org.springframework.data.redis.connection.RedisClusterNode;
import org.springframework.data.redis.connection.RedisClusterNode.SlotRange;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.connection.RedisHashCommands;
import org.springframework.data.redis.connection.RedisHyperLogLogCommands;
import org.springframework.data.redis.connection.RedisKeyCommands;
import org.springframework.data.redis.connection.RedisListCommands;
import org.springframework.data.redis.connection.RedisSetCommands;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.connection.RedisZSetCommands;
import org.springframework.data.redis.connection.convert.Converters;
import org.springframework.data.redis.core.types.RedisClientInfo;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
/**
@@ -69,8 +53,7 @@ import org.springframework.util.ObjectUtils;
* @author Mark Paluch
* @since 1.7
*/
public class LettuceClusterConnection extends LettuceConnection
implements org.springframework.data.redis.connection.RedisClusterConnection {
public class LettuceClusterConnection extends LettuceConnection implements DefaultedRedisClusterConnection {
static final ExceptionTranslationStrategy exceptionConverter = new PassThroughExceptionTranslationStrategy(
new LettuceExceptionConverter());
@@ -82,7 +65,7 @@ public class LettuceClusterConnection extends LettuceConnection
/**
* Creates new {@link LettuceClusterConnection} using {@link RedisClusterClient}.
*
*
* @param clusterClient must not be {@literal null}.
*/
public LettuceClusterConnection(RedisClusterClient clusterClient) {
@@ -116,21 +99,37 @@ public class LettuceClusterConnection extends LettuceConnection
clusterCommandExecutor = executor;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#geoCommands()
*/
@Override
public RedisGeoCommands geoCommands() {
return new LettuceClusterGeoCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#hashCommands()
*/
@Override
public RedisHashCommands hashCommands() {
return new LettuceClusterHashCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#hyperLogLogCommands()
*/
@Override
public RedisHyperLogLogCommands hyperLogLogCommands() {
return new LettuceClusterHyperLogLogCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#keyCommands()
*/
@Override
public RedisKeyCommands keyCommands() {
return doGetClusterKeyCommands();
@@ -140,21 +139,37 @@ public class LettuceClusterConnection extends LettuceConnection
return new LettuceClusterKeyCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#listCommands()
*/
@Override
public RedisListCommands listCommands() {
return new LettuceClusterListCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#stringCommands()
*/
@Override
public RedisStringCommands stringCommands() {
return new LettuceClusterStringCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#setCommands()
*/
@Override
public RedisSetCommands setCommands() {
return new LettuceClusterSetCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#zSetCommands()
*/
@Override
public RedisZSetCommands zSetCommands() {
return new LettuceClusterZSetCommands(this);
@@ -162,128 +177,11 @@ public class LettuceClusterConnection extends LettuceConnection
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#flushAll()
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#serverCommands()
*/
@Override
public void flushAll() {
clusterCommandExecutor.executeCommandOnAllNodes(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.flushall();
}
});
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#flushDb()
*/
@Override
public void flushDb() {
clusterCommandExecutor.executeCommandOnAllNodes(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.flushdb();
}
});
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#dbSize()
*/
@Override
public Long dbSize() {
Collection<Long> dbSizes = clusterCommandExecutor
.executeCommandOnAllNodes(new LettuceClusterCommandCallback<Long>() {
@Override
public Long doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.dbsize();
}
}).resultsAsList();
if (CollectionUtils.isEmpty(dbSizes)) {
return 0L;
}
Long size = 0L;
for (Long value : dbSizes) {
size += value;
}
return size;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#info()
*/
@Override
public Properties info() {
Properties infos = new Properties();
List<NodeResult<Properties>> nodeResults = clusterCommandExecutor
.executeCommandOnAllNodes(new LettuceClusterCommandCallback<Properties>() {
@Override
public Properties doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return LettuceConverters.toProperties(client.info());
}
}).getResults();
for (NodeResult<Properties> nodePorperties : nodeResults) {
for (Entry<Object, Object> entry : nodePorperties.getValue().entrySet()) {
infos.put(nodePorperties.getNode().asString() + "." + entry.getKey(), entry.getValue());
}
}
return infos;
}
@Override
public Properties info(final String section) {
Properties infos = new Properties();
List<NodeResult<Properties>> nodeResults = clusterCommandExecutor
.executeCommandOnAllNodes(new LettuceClusterCommandCallback<Properties>() {
@Override
public Properties doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return LettuceConverters.toProperties(client.info(section));
}
}).getResults();
for (NodeResult<Properties> nodePorperties : nodeResults) {
for (Entry<Object, Object> entry : nodePorperties.getValue().entrySet()) {
infos.put(nodePorperties.getNode().asString() + "." + entry.getKey(), entry.getValue());
}
}
return infos;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterConnection#info(org.springframework.data.redis.connection.RedisClusterNode, java.lang.String)
*/
@Override
public Properties info(RedisClusterNode node, final String section) {
return LettuceConverters
.toProperties(clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.info(section);
}
}, node).getValue());
public RedisClusterServerCommands serverCommands() {
return new LettuceClusterServerCommands(this);
}
/*
@@ -298,13 +196,9 @@ public class LettuceClusterConnection extends LettuceConnection
final RedisClusterNode nodeToUse = topologyProvider.getTopology().lookup(master);
return clusterCommandExecutor
.executeCommandOnSingleNode(new LettuceClusterCommandCallback<Set<RedisClusterNode>>() {
@Override
public Set<RedisClusterNode> doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return LettuceConverters.toSetOfRedisClusterNodes(client.clusterSlaves(nodeToUse.getId()));
}
}, master).getValue();
.executeCommandOnSingleNode((LettuceClusterCommandCallback<Set<RedisClusterNode>>) client -> LettuceConverters
.toSetOfRedisClusterNodes(client.clusterSlaves(nodeToUse.getId())), master)
.getValue();
}
/*
@@ -344,13 +238,10 @@ public class LettuceClusterConnection extends LettuceConnection
@Override
public ClusterInfo clusterGetClusterInfo() {
return clusterCommandExecutor.executeCommandOnArbitraryNode(new LettuceClusterCommandCallback<ClusterInfo>() {
@Override
public ClusterInfo doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return new ClusterInfo(LettuceConverters.toProperties(client.clusterInfo()));
}
}).getValue();
return clusterCommandExecutor
.executeCommandOnArbitraryNode((LettuceClusterCommandCallback<ClusterInfo>) client -> new ClusterInfo(
LettuceConverters.toProperties(client.clusterInfo())))
.getValue();
}
/*
@@ -360,13 +251,8 @@ public class LettuceClusterConnection extends LettuceConnection
@Override
public void clusterAddSlots(RedisClusterNode node, final int... slots) {
clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.clusterAddSlots(slots);
}
}, node);
clusterCommandExecutor.executeCommandOnSingleNode(
(LettuceClusterCommandCallback<String>) client -> client.clusterAddSlots(slots), node);
}
@@ -388,14 +274,8 @@ public class LettuceClusterConnection extends LettuceConnection
*/
@Override
public void clusterDeleteSlots(RedisClusterNode node, final int... slots) {
clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.clusterDelSlots(slots);
}
}, node);
clusterCommandExecutor.executeCommandOnSingleNode(
(LettuceClusterCommandCallback<String>) client -> client.clusterDelSlots(slots), node);
}
/*
@@ -417,18 +297,12 @@ public class LettuceClusterConnection extends LettuceConnection
@Override
public void clusterForget(final RedisClusterNode node) {
List<RedisClusterNode> nodes = new ArrayList<RedisClusterNode>(clusterGetNodes());
List<RedisClusterNode> nodes = new ArrayList<>(clusterGetNodes());
final RedisClusterNode nodeToRemove = topologyProvider.getTopology().lookup(node);
nodes.remove(nodeToRemove);
this.clusterCommandExecutor.executeCommandAsyncOnNodes(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.clusterForget(nodeToRemove.getId());
}
}, nodes);
this.clusterCommandExecutor.executeCommandAsyncOnNodes(
(LettuceClusterCommandCallback<String>) client -> client.clusterForget(nodeToRemove.getId()), nodes);
}
/*
@@ -442,13 +316,8 @@ public class LettuceClusterConnection extends LettuceConnection
Assert.hasText(node.getHost(), "Node to meet cluster must have a host!");
Assert.isTrue(node.getPort() > 0, "Node to meet cluster must have a port greater 0!");
this.clusterCommandExecutor.executeCommandOnAllNodes(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.clusterMeet(node.getHost(), node.getPort());
}
});
this.clusterCommandExecutor.executeCommandOnAllNodes(
(LettuceClusterCommandCallback<String>) client -> client.clusterMeet(node.getHost(), node.getPort()));
}
/*
@@ -464,22 +333,18 @@ public class LettuceClusterConnection extends LettuceConnection
final RedisClusterNode nodeToUse = topologyProvider.getTopology().lookup(node);
final String nodeId = nodeToUse.getId();
clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
switch (mode) {
case MIGRATING:
return client.clusterSetSlotMigrating(slot, nodeId);
case IMPORTING:
return client.clusterSetSlotImporting(slot, nodeId);
case NODE:
return client.clusterSetSlotNode(slot, nodeId);
case STABLE:
return client.clusterSetSlotStable(slot);
default:
throw new InvalidDataAccessApiUsageException("Invalid import mode for cluster slot: " + slot);
}
clusterCommandExecutor.executeCommandOnSingleNode((LettuceClusterCommandCallback<String>) client -> {
switch (mode) {
case MIGRATING:
return client.clusterSetSlotMigrating(slot, nodeId);
case IMPORTING:
return client.clusterSetSlotImporting(slot, nodeId);
case NODE:
return client.clusterSetSlotNode(slot, nodeId);
case STABLE:
return client.clusterSetSlotStable(slot);
default:
throw new InvalidDataAccessApiUsageException("Invalid import mode for cluster slot: " + slot);
}
}, node);
}
@@ -520,13 +385,8 @@ public class LettuceClusterConnection extends LettuceConnection
public void clusterReplicate(final RedisClusterNode master, RedisClusterNode slave) {
final RedisClusterNode masterNode = topologyProvider.getTopology().lookup(master);
clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.clusterReplicate(masterNode.getId());
}
}, slave);
clusterCommandExecutor.executeCommandOnSingleNode(
(LettuceClusterCommandCallback<String>) client -> client.clusterReplicate(masterNode.getId()), slave);
}
/*
@@ -536,13 +396,7 @@ public class LettuceClusterConnection extends LettuceConnection
@Override
public String ping() {
Collection<String> ping = clusterCommandExecutor
.executeCommandOnAllNodes(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> connection) {
return connection.ping();
}
}).resultsAsList();
.executeCommandOnAllNodes((LettuceClusterCommandCallback<String>) BaseRedisCommands::ping).resultsAsList();
for (String result : ping) {
if (!ObjectUtils.nullSafeEquals("PONG", result)) {
@@ -560,144 +414,8 @@ public class LettuceClusterConnection extends LettuceConnection
@Override
public String ping(RedisClusterNode node) {
return clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.ping();
}
}, node).getValue();
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterConnection#bgReWriteAof(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void bgReWriteAof(RedisClusterNode node) {
clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.bgrewriteaof();
}
}, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterConnection#bgSave(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void bgSave(RedisClusterNode node) {
clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.bgsave();
}
}, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterConnection#lastSave(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public Long lastSave(RedisClusterNode node) {
return clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<Long>() {
@Override
public Long doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.lastsave().getTime();
}
}, node).getValue();
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterConnection#save(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void save(RedisClusterNode node) {
clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.save();
}
}, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterConnection#dbSize(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public Long dbSize(RedisClusterNode node) {
return clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<Long>() {
@Override
public Long doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.dbsize();
}
}, node).getValue();
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterConnection#flushDb(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void flushDb(RedisClusterNode node) {
clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.flushdb();
}
}, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterConnection#flushAll(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void flushAll(RedisClusterNode node) {
clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.flushall();
}
}, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterConnection#info(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public Properties info(RedisClusterNode node) {
return LettuceConverters
.toProperties(clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.info();
}
}, node).getValue());
return clusterCommandExecutor
.executeCommandOnSingleNode((LettuceClusterCommandCallback<String>) BaseRedisCommands::ping, node).getValue();
}
/*
@@ -713,23 +431,6 @@ public class LettuceClusterConnection extends LettuceConnection
return doGetClusterKeyCommands().randomKey(node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterConnection#shutdown(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void shutdown(RedisClusterNode node) {
clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<Void>() {
@Override
public Void doInCluster(RedisClusterCommands<byte[], byte[]> client) {
client.shutdown(true);
return null;
}
}, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisConnectionCommands#select(int)
@@ -789,200 +490,6 @@ public class LettuceClusterConnection extends LettuceConnection
throw new InvalidDataAccessApiUsageException("MULTI is currently not supported in cluster mode.");
}
/*
*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#getConfig(java.lang.String)
*/
@Override
public List<String> getConfig(final String pattern) {
List<NodeResult<List<String>>> mapResult = clusterCommandExecutor
.executeCommandOnAllNodes(new LettuceClusterCommandCallback<List<String>>() {
@Override
public List<String> doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.configGet(pattern);
}
}).getResults();
List<String> result = new ArrayList<String>();
for (NodeResult<List<String>> entry : mapResult) {
String prefix = entry.getNode().asString();
int i = 0;
for (String value : entry.getValue()) {
result.add((i++ % 2 == 0 ? (prefix + ".") : "") + value);
}
}
return result;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterConnection#getConfig(org.springframework.data.redis.connection.RedisClusterNode, java.lang.String)
*/
@Override
public List<String> getConfig(RedisClusterNode node, final String pattern) {
return clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<List<String>>() {
@Override
public List<String> doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.configGet(pattern);
}
}, node).getValue();
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#setConfig(java.lang.String, java.lang.String)
*/
@Override
public void setConfig(final String param, final String value) {
clusterCommandExecutor.executeCommandOnAllNodes(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.configSet(param, value);
}
});
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterConnection#setConfig(org.springframework.data.redis.connection.RedisClusterNode, java.lang.String, java.lang.String)
*/
@Override
public void setConfig(RedisClusterNode node, final String param, final String value) {
clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.configSet(param, value);
}
}, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#resetConfigStats()
*/
@Override
public void resetConfigStats() {
clusterCommandExecutor.executeCommandOnAllNodes(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.configResetstat();
}
});
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterConnection#resetConfigStats(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void resetConfigStats(RedisClusterNode node) {
clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.configResetstat();
}
}, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#time()
*/
@Override
public Long time() {
return convertListOfStringToTime(
clusterCommandExecutor.executeCommandOnArbitraryNode(new LettuceClusterCommandCallback<List<byte[]>>() {
@Override
public List<byte[]> doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.time();
}
}).getValue());
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterConnection#time(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public Long time(RedisClusterNode node) {
return convertListOfStringToTime(
clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<List<byte[]>>() {
@Override
public List<byte[]> doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.time();
}
}, node).getValue());
}
private Long convertListOfStringToTime(List<byte[]> serverTimeInformation) {
Assert.notEmpty(serverTimeInformation, "Received invalid result from server. Expected 2 items in collection.");
Assert.isTrue(serverTimeInformation.size() == 2,
"Received invalid number of arguments from redis server. Expected 2 received " + serverTimeInformation.size());
return Converters.toTimeMillis(LettuceConverters.toString(serverTimeInformation.get(0)),
LettuceConverters.toString(serverTimeInformation.get(1)));
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#getClientList()
*/
@Override
public List<RedisClientInfo> getClientList() {
List<String> map = clusterCommandExecutor.executeCommandOnAllNodes(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.clientList();
}
}).resultsAsList();
ArrayList<RedisClientInfo> result = new ArrayList<RedisClientInfo>();
for (String infos : map) {
result.addAll(LettuceConverters.toListOfRedisClientInformation(infos));
}
return result;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterConnection#getClientList(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public List<RedisClientInfo> getClientList(RedisClusterNode node) {
return LettuceConverters.toListOfRedisClientInformation(
clusterCommandExecutor.executeCommandOnSingleNode(new LettuceClusterCommandCallback<String>() {
@Override
public String doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.clientList();
}
}, node).getValue());
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterCommands#clusterGetMasterSlaveMap()
@@ -991,15 +498,13 @@ public class LettuceClusterConnection extends LettuceConnection
public Map<RedisClusterNode, Collection<RedisClusterNode>> clusterGetMasterSlaveMap() {
List<NodeResult<Collection<RedisClusterNode>>> nodeResults = clusterCommandExecutor
.executeCommandAsyncOnNodes(new LettuceClusterCommandCallback<Collection<RedisClusterNode>>() {
.executeCommandAsyncOnNodes(
(LettuceClusterCommandCallback<Collection<RedisClusterNode>>) client -> Converters
.toSetOfRedisClusterNodes(client.clusterSlaves(client.clusterMyId())),
topologyProvider.getTopology().getActiveMasterNodes())
.getResults();
@Override
public Set<RedisClusterNode> doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return Converters.toSetOfRedisClusterNodes(client.clusterSlaves(client.clusterMyId()));
}
}, topologyProvider.getTopology().getActiveMasterNodes()).getResults();
Map<RedisClusterNode, Collection<RedisClusterNode>> result = new LinkedHashMap<RedisClusterNode, Collection<RedisClusterNode>>();
Map<RedisClusterNode, Collection<RedisClusterNode>> result = new LinkedHashMap<>();
for (NodeResult<Collection<RedisClusterNode>> nodeResult : nodeResults) {
result.put(nodeResult.getNode(), nodeResult.getValue());
@@ -1114,7 +619,7 @@ public class LettuceClusterConnection extends LettuceConnection
@Override
public ClusterTopology getTopology() {
return new ClusterTopology(
new LinkedHashSet<RedisClusterNode>(LettuceConverters.partitionsToClusterNodes(client.getPartitions())));
new LinkedHashSet<>(LettuceConverters.partitionsToClusterNodes(client.getPartitions())));
}
}

View File

@@ -15,13 +15,11 @@
*/
package org.springframework.data.redis.connection.lettuce;
import io.lettuce.core.cluster.api.sync.RedisClusterCommands;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.redis.connection.ClusterSlotHashUtil;
@@ -53,13 +51,13 @@ class LettuceClusterKeyCommands extends LettuceKeyCommands {
*/
@Override
public Cursor<byte[]> scan(long cursorId, ScanOptions options) {
throw new InvalidDataAccessApiUsageException("Scan is not supported accros multiple nodes within a cluster.");
throw new InvalidDataAccessApiUsageException("Scan is not supported across multiple nodes within a cluster.");
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#randomKey()
*/
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#randomKey()
*/
@Override
public byte[] randomKey() {
@@ -68,10 +66,10 @@ class LettuceClusterKeyCommands extends LettuceKeyCommands {
do {
RedisClusterNode node = nodes.get(new Random().nextInt(nodes.size()));
RedisClusterNode node = nodes.get(ThreadLocalRandom.current().nextInt(nodes.size()));
while (inspectedNodes.contains(node)) {
node = nodes.get(new Random().nextInt(nodes.size()));
node = nodes.get(ThreadLocalRandom.current().nextInt(nodes.size()));
}
inspectedNodes.add(node);
byte[] key = randomKey(node);
@@ -177,13 +175,8 @@ class LettuceClusterKeyCommands extends LettuceKeyCommands {
public byte[] randomKey(RedisClusterNode node) {
return connection.getClusterCommandExecutor()
.executeCommandOnSingleNode(new LettuceClusterCommandCallback<byte[]>() {
@Override
public byte[] doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.randomkey();
}
}, node).getValue();
.executeCommandOnSingleNode((LettuceClusterCommandCallback<byte[]>) client -> client.randomkey(), node)
.getValue();
}
/*
@@ -193,13 +186,8 @@ class LettuceClusterKeyCommands extends LettuceKeyCommands {
public Set<byte[]> keys(RedisClusterNode node, final byte[] pattern) {
return LettuceConverters.toBytesSet(connection.getClusterCommandExecutor()
.executeCommandOnSingleNode(new LettuceClusterCommandCallback<List<byte[]>>() {
@Override
public List<byte[]> doInCluster(RedisClusterCommands<byte[], byte[]> client) {
return client.keys(pattern);
}
}, node).getValue());
.executeCommandOnSingleNode((LettuceClusterCommandCallback<List<byte[]>>) client -> client.keys(pattern), node)
.getValue());
}
/*

View File

@@ -40,9 +40,9 @@ class LettuceClusterListCommands extends LettuceListCommands {
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#bLPop(int, byte[][])
*/
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceConnection#bLPop(int, byte[][])
*/
@Override
public List<byte[]> bLPop(final int timeout, byte[]... keys) {

View File

@@ -0,0 +1,378 @@
/*
* Copyright 2017 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.connection.lettuce;
import io.lettuce.core.api.sync.RedisServerCommands;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
import java.util.Properties;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.redis.connection.ClusterCommandExecutor.MulitNodeResult;
import org.springframework.data.redis.connection.ClusterCommandExecutor.NodeResult;
import org.springframework.data.redis.connection.RedisClusterNode;
import org.springframework.data.redis.connection.RedisClusterServerCommands;
import org.springframework.data.redis.connection.convert.Converters;
import org.springframework.data.redis.connection.lettuce.LettuceClusterConnection.LettuceClusterCommandCallback;
import org.springframework.data.redis.core.types.RedisClientInfo;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
/**
* @author Mark Paluch
* @since 2.0
*/
class LettuceClusterServerCommands extends LettuceServerCommands implements RedisClusterServerCommands {
private final LettuceClusterConnection connection;
public LettuceClusterServerCommands(LettuceClusterConnection connection) {
super(connection);
this.connection = connection;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#bgReWriteAof(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void bgReWriteAof(RedisClusterNode node) {
executeCommandOnSingleNode(RedisServerCommands::bgrewriteaof, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#bgSave(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void bgSave(RedisClusterNode node) {
executeCommandOnSingleNode(RedisServerCommands::bgsave, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#lastSave(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public Long lastSave(RedisClusterNode node) {
return executeCommandOnSingleNode(client -> client.lastsave().getTime(), node).getValue();
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#save(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void save(RedisClusterNode node) {
executeCommandOnSingleNode(RedisServerCommands::save, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceServerCommands#dbSize()
*/
@Override
public Long dbSize() {
Collection<Long> dbSizes = executeCommandOnAllNodes(RedisServerCommands::dbsize).resultsAsList();
if (CollectionUtils.isEmpty(dbSizes)) {
return 0L;
}
Long size = 0L;
for (Long value : dbSizes) {
size += value;
}
return size;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#dbSize(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public Long dbSize(RedisClusterNode node) {
return executeCommandOnSingleNode(RedisServerCommands::dbsize, node).getValue();
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceServerCommands#flushDb()
*/
@Override
public void flushDb() {
executeCommandOnAllNodes(RedisServerCommands::flushdb);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#flushDb(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void flushDb(RedisClusterNode node) {
executeCommandOnSingleNode(RedisServerCommands::flushdb, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceServerCommands#flushAll()
*/
@Override
public void flushAll() {
executeCommandOnAllNodes(RedisServerCommands::flushall);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#flushAll(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void flushAll(RedisClusterNode node) {
executeCommandOnSingleNode(RedisServerCommands::flushall, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#info(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public Properties info(RedisClusterNode node) {
return LettuceConverters.toProperties(executeCommandOnSingleNode(RedisServerCommands::info, node).getValue());
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceServerCommands#info()
*/
@Override
public Properties info() {
Properties infos = new Properties();
List<NodeResult<Properties>> nodeResults = executeCommandOnAllNodes(
client -> LettuceConverters.toProperties(client.info())).getResults();
for (NodeResult<Properties> nodePorperties : nodeResults) {
for (Entry<Object, Object> entry : nodePorperties.getValue().entrySet()) {
infos.put(nodePorperties.getNode().asString() + "." + entry.getKey(), entry.getValue());
}
}
return infos;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceServerCommands#info(java.lang.String)
*/
@Override
public Properties info(final String section) {
Properties infos = new Properties();
List<NodeResult<Properties>> nodeResults = executeCommandOnAllNodes(
client -> LettuceConverters.toProperties(client.info(section))).getResults();
for (NodeResult<Properties> nodePorperties : nodeResults) {
for (Entry<Object, Object> entry : nodePorperties.getValue().entrySet()) {
infos.put(nodePorperties.getNode().asString() + "." + entry.getKey(), entry.getValue());
}
}
return infos;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#info(org.springframework.data.redis.connection.RedisClusterNode, java.lang.String)
*/
@Override
public Properties info(RedisClusterNode node, final String section) {
return LettuceConverters.toProperties(executeCommandOnSingleNode(client -> client.info(section), node).getValue());
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#shutdown(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void shutdown(RedisClusterNode node) {
executeCommandOnSingleNode((LettuceClusterCommandCallback<Void>) client -> {
client.shutdown(true);
return null;
}, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceServerCommands#getConfig(java.lang.String)
*/
@Override
public List<String> getConfig(final String pattern) {
List<NodeResult<List<String>>> mapResult = executeCommandOnAllNodes(client -> client.configGet(pattern))
.getResults();
List<String> result = new ArrayList<>();
for (NodeResult<List<String>> entry : mapResult) {
String prefix = entry.getNode().asString();
int i = 0;
for (String value : entry.getValue()) {
result.add((i++ % 2 == 0 ? (prefix + ".") : "") + value);
}
}
return result;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#getConfig(org.springframework.data.redis.connection.RedisClusterNode, java.lang.String)
*/
@Override
public List<String> getConfig(RedisClusterNode node, final String pattern) {
return executeCommandOnSingleNode(client -> client.configGet(pattern), node).getValue();
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceServerCommands#setConfig(java.lang.String, java.lang.String)
*/
@Override
public void setConfig(final String param, final String value) {
executeCommandOnAllNodes(client -> client.configSet(param, value));
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#setConfig(org.springframework.data.redis.connection.RedisClusterNode, java.lang.String, java.lang.String)
*/
@Override
public void setConfig(RedisClusterNode node, final String param, final String value) {
executeCommandOnSingleNode(client -> client.configSet(param, value), node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceServerCommands#resetConfigStats()
*/
@Override
public void resetConfigStats() {
executeCommandOnAllNodes(RedisServerCommands::configResetstat);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#resetConfigStats(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public void resetConfigStats(RedisClusterNode node) {
executeCommandOnSingleNode(RedisServerCommands::configResetstat, node);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceServerCommands#time()
*/
@Override
public Long time() {
return convertListOfStringToTime(connection.getClusterCommandExecutor()
.executeCommandOnArbitraryNode((LettuceClusterCommandCallback<List<byte[]>>) RedisServerCommands::time)
.getValue());
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#time(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public Long time(RedisClusterNode node) {
return convertListOfStringToTime(executeCommandOnSingleNode(RedisServerCommands::time, node).getValue());
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceServerCommands#getClientList()
*/
@Override
public List<RedisClientInfo> getClientList() {
List<String> map = executeCommandOnAllNodes(RedisServerCommands::clientList).resultsAsList();
ArrayList<RedisClientInfo> result = new ArrayList<>();
for (String infos : map) {
result.addAll(LettuceConverters.toListOfRedisClientInformation(infos));
}
return result;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#getClientList(org.springframework.data.redis.connection.RedisClusterNode)
*/
@Override
public List<RedisClientInfo> getClientList(RedisClusterNode node) {
return LettuceConverters
.toListOfRedisClientInformation(executeCommandOnSingleNode(RedisServerCommands::clientList, node).getValue());
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceServerCommands#slaveOf(java.lang.String, int)
*/
@Override
public void slaveOf(String host, int port) {
throw new InvalidDataAccessApiUsageException(
"SlaveOf is not supported in cluster environment. Please use CLUSTER REPLICATE.");
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.lettuce.LettuceServerCommands#slaveOfNoOne()
*/
@Override
public void slaveOfNoOne() {
throw new InvalidDataAccessApiUsageException(
"SlaveOf is not supported in cluster environment. Please use CLUSTER REPLICATE.");
}
private <T> NodeResult<T> executeCommandOnSingleNode(LettuceClusterCommandCallback<T> command,
RedisClusterNode node) {
return connection.getClusterCommandExecutor().executeCommandOnSingleNode(command, node);
}
private <T> MulitNodeResult<T> executeCommandOnAllNodes(final LettuceClusterCommandCallback<T> cmd) {
return connection.getClusterCommandExecutor().executeCommandOnAllNodes(cmd);
}
private static Long convertListOfStringToTime(List<byte[]> serverTimeInformation) {
Assert.notEmpty(serverTimeInformation, "Received invalid result from server. Expected 2 items in collection.");
Assert.isTrue(serverTimeInformation.size() == 2,
"Received invalid number of arguments from redis server. Expected 2 received " + serverTimeInformation.size());
return Converters.toTimeMillis(LettuceConverters.toString(serverTimeInformation.get(0)),
LettuceConverters.toString(serverTimeInformation.get(1)));
}
}

View File

@@ -15,6 +15,8 @@
*/
package org.springframework.data.redis.connection.lettuce;
import io.lettuce.core.api.sync.RedisSetCommands;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -70,8 +72,7 @@ class LettuceClusterSetCommands extends LettuceSetCommands {
}
Collection<Set<byte[]>> nodeResult = connection.getClusterCommandExecutor()
.executeMuliKeyCommand(
(LettuceMultiKeyClusterCommandCallback<Set<byte[]>>) (client, key) -> client.smembers(key),
.executeMuliKeyCommand((LettuceMultiKeyClusterCommandCallback<Set<byte[]>>) RedisSetCommands::smembers,
Arrays.asList(keys))
.resultsAsList();
@@ -89,7 +90,7 @@ class LettuceClusterSetCommands extends LettuceSetCommands {
}
}
if (result.isEmpty()) {
if (result == null || result.isEmpty()) {
return Collections.emptySet();
}
@@ -128,8 +129,7 @@ class LettuceClusterSetCommands extends LettuceSetCommands {
}
Collection<Set<byte[]>> nodeResult = connection.getClusterCommandExecutor()
.executeMuliKeyCommand(
(LettuceMultiKeyClusterCommandCallback<Set<byte[]>>) (client, key) -> client.smembers(key),
.executeMuliKeyCommand((LettuceMultiKeyClusterCommandCallback<Set<byte[]>>) RedisSetCommands::smembers,
Arrays.asList(keys))
.resultsAsList();
@@ -181,8 +181,7 @@ class LettuceClusterSetCommands extends LettuceSetCommands {
ByteArraySet values = new ByteArraySet(sMembers(source));
Collection<Set<byte[]>> nodeResult = connection.getClusterCommandExecutor()
.executeMuliKeyCommand(
(LettuceMultiKeyClusterCommandCallback<Set<byte[]>>) (client, key) -> client.smembers(key),
.executeMuliKeyCommand((LettuceMultiKeyClusterCommandCallback<Set<byte[]>>) RedisSetCommands::smembers,
Arrays.asList(others))
.resultsAsList();

View File

@@ -34,20 +34,7 @@ import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands;
import io.lettuce.core.cluster.api.sync.RedisClusterCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import io.lettuce.core.codec.RedisCodec;
import io.lettuce.core.output.BooleanOutput;
import io.lettuce.core.output.ByteArrayOutput;
import io.lettuce.core.output.CommandOutput;
import io.lettuce.core.output.DateOutput;
import io.lettuce.core.output.DoubleOutput;
import io.lettuce.core.output.IntegerOutput;
import io.lettuce.core.output.KeyListOutput;
import io.lettuce.core.output.KeyValueOutput;
import io.lettuce.core.output.MapOutput;
import io.lettuce.core.output.MultiOutput;
import io.lettuce.core.output.StatusOutput;
import io.lettuce.core.output.ValueListOutput;
import io.lettuce.core.output.ValueOutput;
import io.lettuce.core.output.ValueSetOutput;
import io.lettuce.core.output.*;
import io.lettuce.core.protocol.Command;
import io.lettuce.core.protocol.CommandArgs;
import io.lettuce.core.protocol.CommandType;
@@ -56,13 +43,11 @@ import io.lettuce.core.sentinel.api.StatefulRedisSentinelConnection;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
@@ -76,27 +61,10 @@ import org.springframework.dao.QueryTimeoutException;
import org.springframework.data.redis.ExceptionTranslationStrategy;
import org.springframework.data.redis.FallbackExceptionTranslationStrategy;
import org.springframework.data.redis.RedisConnectionFailureException;
import org.springframework.data.redis.connection.AbstractRedisConnection;
import org.springframework.data.redis.connection.FutureResult;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.connection.RedisHashCommands;
import org.springframework.data.redis.connection.RedisHyperLogLogCommands;
import org.springframework.data.redis.connection.RedisKeyCommands;
import org.springframework.data.redis.connection.RedisListCommands;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisPipelineException;
import org.springframework.data.redis.connection.RedisSentinelConnection;
import org.springframework.data.redis.connection.RedisSetCommands;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.connection.RedisSubscribedConnectionException;
import org.springframework.data.redis.connection.RedisZSetCommands;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.connection.Subscription;
import org.springframework.data.redis.connection.*;
import org.springframework.data.redis.connection.convert.TransactionResultConverter;
import org.springframework.data.redis.core.RedisCommand;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.types.RedisClientInfo;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
@@ -104,7 +72,7 @@ import org.springframework.util.ObjectUtils;
/**
* {@code RedisConnection} implementation on top of <a href="https://github.com/mp911de/lettuce">Lettuce</a> Redis
* client.
*
*
* @author Costin Leau
* @author Jennifer Hickey
* @author Christoph Strobl
@@ -134,7 +102,7 @@ public class LettuceConnection extends AbstractRedisConnection {
private boolean isMulti = false;
private boolean isPipelined = false;
private List<LettuceResult> ppline;
private Queue<FutureResult<?>> txResults = new LinkedList<FutureResult<?>>();
private Queue<FutureResult<?>> txResults = new LinkedList<>();
private AbstractRedisClient client;
private volatile LettuceSubscription subscription;
private LettucePool pool;
@@ -240,30 +208,9 @@ public class LettuceConnection extends AbstractRedisConnection {
}
}
private class LettuceEvalResultsConverter<T> implements Converter<Object, T> {
private ReturnType returnType;
public LettuceEvalResultsConverter(ReturnType returnType) {
this.returnType = returnType;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public T convert(Object source) {
if (returnType == ReturnType.MULTI) {
List resultList = (List) source;
for (Object obj : resultList) {
if (obj instanceof Exception) {
throw convertLettuceAccessException((Exception) obj);
}
}
}
return (T) source;
}
}
/**
* Instantiates a new lettuce connection.
*
*
* @param timeout The connection timeout (in milliseconds)
* @param client The {@link RedisClient} to use when instantiating a native connection
*/
@@ -273,7 +220,7 @@ public class LettuceConnection extends AbstractRedisConnection {
/**
* Instantiates a new lettuce connection.
*
*
* @param timeout The connection timeout (in milliseconds) * @param client The {@link RedisClient} to use when
* instantiating a pub/sub connection
* @param pool The connection pool to use for all other native connections
@@ -284,7 +231,7 @@ public class LettuceConnection extends AbstractRedisConnection {
/**
* Instantiates a new lettuce connection.
*
*
* @param sharedConnection A native connection that is shared with other {@link LettuceConnection}s. Will not be used
* for transactions or blocking operations
* @param timeout The connection timeout (in milliseconds)
@@ -296,7 +243,7 @@ public class LettuceConnection extends AbstractRedisConnection {
/**
* Instantiates a new lettuce connection.
*
*
* @param sharedConnection A native connection that is shared with other {@link LettuceConnection}s. Should not be
* used for transactions or blocking operations
* @param timeout The connection timeout (in milliseconds)
@@ -339,41 +286,91 @@ public class LettuceConnection extends AbstractRedisConnection {
return exception;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisConnection#geoCommands()
*/
@Override
public RedisGeoCommands geoCommands() {
return new LettuceGeoCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisConnection#hashCommands()
*/
@Override
public RedisHashCommands hashCommands() {
return new LettuceHashCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisConnection#hyperLogLogCommands()
*/
@Override
public RedisHyperLogLogCommands hyperLogLogCommands() {
return new LettuceHyperLogLogCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisConnection#keyCommands()
*/
@Override
public RedisKeyCommands keyCommands() {
return new LettuceKeyCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisConnection#listCommands()
*/
@Override
public RedisListCommands listCommands() {
return new LettuceListCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisConnection#setCommands()
*/
@Override
public RedisSetCommands setCommands() {
return new LettuceSetCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisConnection#scriptingCommands()
*/
@Override
public RedisScriptingCommands scriptingCommands() {
return new LettuceScriptingCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisConnection#stringCommands()
*/
@Override
public RedisStringCommands stringCommands() {
return new LettuceStringCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisConnection#serverCommands()
*/
@Override
public RedisServerCommands serverCommands() {
return new LettuceServerCommands(this);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisConnection#zSetCommands()
*/
@Override
public RedisZSetCommands zSetCommands() {
return new LettuceZSetCommands(this);
@@ -412,7 +409,7 @@ public class LettuceConnection extends AbstractRedisConnection {
validateCommandIfRunningInTransactionMode(commandType, args);
CommandArgs<byte[], byte[]> cmdArg = new CommandArgs<byte[], byte[]>(CODEC);
CommandArgs<byte[], byte[]> cmdArg = new CommandArgs<>(CODEC);
if (!ObjectUtils.isEmpty(args)) {
cmdArg.addKeys(args);
}
@@ -497,7 +494,7 @@ public class LettuceConnection extends AbstractRedisConnection {
public void openPipeline() {
if (!isPipelined) {
isPipelined = true;
ppline = new ArrayList<LettuceResult>();
ppline = new ArrayList<>();
}
}
@@ -505,7 +502,7 @@ public class LettuceConnection extends AbstractRedisConnection {
if (isPipelined) {
isPipelined = false;
List<io.lettuce.core.protocol.RedisCommand<?, ?, ?>> futures = new ArrayList<io.lettuce.core.protocol.RedisCommand<?, ?, ?>>();
List<io.lettuce.core.protocol.RedisCommand<?, ?, ?>> futures = new ArrayList<>();
for (LettuceResult result : ppline) {
futures.add(result.getResultHolder());
}
@@ -514,7 +511,7 @@ public class LettuceConnection extends AbstractRedisConnection {
boolean done = LettuceFutures.awaitAll(timeout, TimeUnit.MILLISECONDS,
futures.toArray(new RedisFuture[futures.size()]));
List<Object> results = new ArrayList<Object>(futures.size());
List<Object> results = new ArrayList<>(futures.size());
Exception problem = null;
@@ -560,241 +557,11 @@ public class LettuceConnection extends AbstractRedisConnection {
return Collections.emptyList();
}
public Long dbSize() {
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().dbsize()));
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().dbsize()));
return null;
}
return getConnection().dbsize();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public void flushDb() {
try {
if (isPipelined()) {
pipeline(new LettuceStatusResult(getAsyncConnection().flushdb()));
return;
}
if (isQueueing()) {
transaction(new LettuceTxStatusResult(getConnection().flushdb()));
return;
}
getConnection().flushdb();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public void flushAll() {
try {
if (isPipelined()) {
pipeline(new LettuceStatusResult(getAsyncConnection().flushall()));
return;
}
if (isQueueing()) {
transaction(new LettuceTxStatusResult(getConnection().flushall()));
return;
}
getConnection().flushall();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public void bgSave() {
try {
if (isPipelined()) {
pipeline(new LettuceStatusResult(getAsyncConnection().bgsave()));
return;
}
if (isQueueing()) {
transaction(new LettuceTxStatusResult(getConnection().bgsave()));
return;
}
getConnection().bgsave();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public void bgReWriteAof() {
try {
if (isPipelined()) {
pipeline(new LettuceStatusResult(getAsyncConnection().bgrewriteaof()));
return;
}
if (isQueueing()) {
transaction(new LettuceTxStatusResult(getConnection().bgrewriteaof()));
return;
}
getConnection().bgrewriteaof();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/**
* @deprecated As of 1.3, use {@link #bgReWriteAof}.
*/
@Deprecated
public void bgWriteAof() {
bgReWriteAof();
}
public void save() {
try {
if (isPipelined()) {
pipeline(new LettuceStatusResult(getAsyncConnection().save()));
return;
}
if (isQueueing()) {
transaction(new LettuceTxStatusResult(getConnection().save()));
return;
}
getConnection().save();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public List<String> getConfig(String param) {
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().configGet(param)));
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().configGet(param)));
return null;
}
return getConnection().configGet(param);
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public Properties info() {
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().info(), LettuceConverters.stringToProps()));
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().info(), LettuceConverters.stringToProps()));
return null;
}
return LettuceConverters.toProperties(getConnection().info());
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public Properties info(String section) {
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().info(section), LettuceConverters.stringToProps()));
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().info(section), LettuceConverters.stringToProps()));
return null;
}
return LettuceConverters.toProperties(getConnection().info(section));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public Long lastSave() {
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().lastsave(), LettuceConverters.dateToLong()));
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().lastsave(), LettuceConverters.dateToLong()));
return null;
}
return LettuceConverters.toLong(getConnection().lastsave());
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public void setConfig(String param, String value) {
try {
if (isPipelined()) {
pipeline(new LettuceStatusResult(getAsyncConnection().configSet(param, value)));
return;
}
if (isQueueing()) {
transaction(new LettuceTxStatusResult(getConnection().configSet(param, value)));
return;
}
getConnection().configSet(param, value);
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public void resetConfigStats() {
try {
if (isPipelined()) {
pipeline(new LettuceStatusResult(getAsyncConnection().configResetstat()));
return;
}
if (isQueueing()) {
transaction(new LettuceTxStatusResult(getConnection().configResetstat()));
return;
}
getConnection().configResetstat();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public void shutdown() {
try {
if (isPipelined()) {
getAsyncConnection().shutdown(true);
return;
}
getConnection().shutdown(true);
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#shutdown(org.springframework.data.redis.connection.RedisServerCommands.ShutdownOption)
*/
@Override
public void shutdown(ShutdownOption option) {
if (option == null) {
shutdown();
return;
}
boolean save = ShutdownOption.SAVE.equals(option);
try {
if (isPipelined()) {
getAsyncConnection().shutdown(save);
return;
}
getConnection().shutdown(save);
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public byte[] echo(byte[] message) {
try {
@@ -943,129 +710,6 @@ public class LettuceConnection extends AbstractRedisConnection {
}
}
//
// Scripting commands
//
public void scriptFlush() {
try {
if (isPipelined()) {
pipeline(new LettuceStatusResult(getAsyncConnection().scriptFlush()));
return;
}
if (isQueueing()) {
transaction(new LettuceTxStatusResult(getConnection().scriptFlush()));
return;
}
getConnection().scriptFlush();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public void scriptKill() {
if (isQueueing()) {
throw new UnsupportedOperationException("Script kill not permitted in a transaction");
}
try {
if (isPipelined()) {
pipeline(new LettuceStatusResult(getAsyncConnection().scriptKill()));
return;
}
if (isQueueing()) {
transaction(new LettuceTxStatusResult(getConnection().scriptKill()));
return;
}
getConnection().scriptKill();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public String scriptLoad(byte[] script) {
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().scriptLoad(script)));
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().scriptLoad(script)));
return null;
}
return getConnection().scriptLoad(script);
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public List<Boolean> scriptExists(String... scriptSha1) {
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().scriptExists(scriptSha1)));
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().scriptExists(scriptSha1)));
return null;
}
return getConnection().scriptExists(scriptSha1);
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public <T> T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
try {
byte[][] keys = extractScriptKeys(numKeys, keysAndArgs);
byte[][] args = extractScriptArgs(numKeys, keysAndArgs);
String convertedScript = LettuceConverters.toString(script);
if (isPipelined()) {
pipeline(new LettuceResult(
getAsyncConnection().eval(convertedScript, LettuceConverters.toScriptOutputType(returnType), keys, args),
new LettuceEvalResultsConverter<T>(returnType)));
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(
getConnection().eval(convertedScript, LettuceConverters.toScriptOutputType(returnType), keys, args),
new LettuceEvalResultsConverter<T>(returnType)));
return null;
}
return new LettuceEvalResultsConverter<T>(returnType)
.convert(getConnection().eval(convertedScript, LettuceConverters.toScriptOutputType(returnType), keys, args));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public <T> T evalSha(String scriptSha1, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
try {
byte[][] keys = extractScriptKeys(numKeys, keysAndArgs);
byte[][] args = extractScriptArgs(numKeys, keysAndArgs);
if (isPipelined()) {
pipeline(new LettuceResult(
getAsyncConnection().evalsha(scriptSha1, LettuceConverters.toScriptOutputType(returnType), keys, args),
new LettuceEvalResultsConverter<T>(returnType)));
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(
getConnection().evalsha(scriptSha1, LettuceConverters.toScriptOutputType(returnType), keys, args),
new LettuceEvalResultsConverter<T>(returnType)));
return null;
}
return new LettuceEvalResultsConverter<T>(returnType)
.convert(getConnection().evalsha(scriptSha1, LettuceConverters.toScriptOutputType(returnType), keys, args));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public <T> T evalSha(byte[] scriptSha1, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
return evalSha(LettuceConverters.toString(scriptSha1), returnType, numKeys, keysAndArgs);
}
//
// Pub/Sub functionality
//
@@ -1126,145 +770,6 @@ public class LettuceConnection extends AbstractRedisConnection {
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#time()
*/
@Override
public Long time() {
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().time(), LettuceConverters.toTimeConverter()));
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().time(), LettuceConverters.toTimeConverter()));
return null;
}
return LettuceConverters.toTimeConverter().convert(getConnection().time());
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
@Override
public void killClient(String host, int port) {
Assert.hasText(host, "Host for 'CLIENT KILL' must not be 'null' or 'empty'.");
String client = String.format("%s:%s", host, port);
try {
if (isPipelined()) {
pipeline(new LettuceStatusResult(getAsyncConnection().clientKill(client)));
return;
}
getConnection().clientKill(client);
} catch (Exception e) {
throw convertLettuceAccessException(e);
}
}
@Override
public void setClientName(byte[] name) {
if (isQueueing()) {
pipeline(new LettuceStatusResult(getAsyncConnection().clientSetname(name)));
return;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().clientSetname(name)));
return;
}
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()
*/
@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);
}
}
@Override
public List<RedisClientInfo> getClientList() {
if (isPipelined()) {
throw new UnsupportedOperationException("Cannot be called in pipeline mode.");
}
if (isQueueing()) {
transaction(
new LettuceTxResult(getAsyncConnection().clientList(), LettuceConverters.stringToRedisClientListConverter()));
return null;
}
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);
}
}
@SuppressWarnings("unchecked")
<T> T failsafeReadScanValues(List<?> source, @SuppressWarnings("rawtypes") Converter converter) {
@@ -1279,7 +784,7 @@ public class LettuceConnection extends AbstractRedisConnection {
/**
* 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
*
*
* @param convertPipelineAndTxResults Whether or not to convert pipeline and tx results
*/
public void setConvertPipelineAndTxResults(boolean convertPipelineAndTxResults) {
@@ -1401,20 +906,6 @@ public class LettuceConnection extends AbstractRedisConnection {
String.format("%s is not a supported connection type.", asyncDedicatedConn.getClass().getName()));
}
private byte[][] extractScriptKeys(int numKeys, byte[]... keysAndArgs) {
if (numKeys > 0) {
return Arrays.copyOfRange(keysAndArgs, 0, numKeys);
}
return new byte[0][0];
}
private byte[][] extractScriptArgs(int numKeys, byte[]... keysAndArgs) {
if (keysAndArgs.length > numKeys) {
return Arrays.copyOfRange(keysAndArgs, numKeys, keysAndArgs.length);
}
return new byte[0][0];
}
io.lettuce.core.ScanCursor getScanCursor(long cursorId) {
return io.lettuce.core.ScanCursor.of(Long.toString(cursorId));
}
@@ -1493,16 +984,16 @@ public class LettuceConnection extends AbstractRedisConnection {
/**
* {@link TypeHints} provide {@link CommandOutput} information for a given {@link CommandType}.
*
*
* @since 1.2.1
*/
static class TypeHints {
@SuppressWarnings("rawtypes") //
private static final Map<CommandType, Class<? extends CommandOutput>> COMMAND_OUTPUT_TYPE_MAPPING = new HashMap<CommandType, Class<? extends CommandOutput>>();
private static final Map<CommandType, Class<? extends CommandOutput>> COMMAND_OUTPUT_TYPE_MAPPING = new HashMap<>();
@SuppressWarnings("rawtypes") //
private static final Map<Class<?>, Constructor<CommandOutput>> CONSTRUCTORS = new ConcurrentHashMap<Class<?>, Constructor<CommandOutput>>();
private static final Map<Class<?>, Constructor<CommandOutput>> CONSTRUCTORS = new ConcurrentHashMap<>();
{
// INTEGER
@@ -1654,18 +1145,18 @@ public class LettuceConnection extends AbstractRedisConnection {
/**
* Returns the {@link CommandOutput} mapped for given {@link CommandType} or {@link ByteArrayOutput} as default.
*
*
* @param type
* @return {@link ByteArrayOutput} as default when no matching {@link CommandOutput} available.
*/
@SuppressWarnings("rawtypes")
public CommandOutput getTypeHint(CommandType type) {
return getTypeHint(type, new ByteArrayOutput<byte[], byte[]>(CODEC));
return getTypeHint(type, new ByteArrayOutput<>(CODEC));
}
/**
* Returns the {@link CommandOutput} mapped for given {@link CommandType} given {@link CommandOutput} as default.
*
*
* @param type
* @return
*/
@@ -1691,38 +1182,4 @@ public class LettuceConnection extends AbstractRedisConnection {
return BeanUtils.instantiateClass(constructor, CODEC);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#migrate(byte[], org.springframework.data.redis.connection.RedisNode, int, org.springframework.data.redis.connection.RedisServerCommands.MigrateOption)
*/
@Override
public void migrate(byte[] key, RedisNode target, int dbIndex, MigrateOption option) {
migrate(key, target, dbIndex, option, Long.MAX_VALUE);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#migrate(byte[], org.springframework.data.redis.connection.RedisNode, int, org.springframework.data.redis.connection.RedisServerCommands.MigrateOption, long)
*/
@Override
public void migrate(byte[] key, RedisNode target, int dbIndex, MigrateOption option, long timeout) {
try {
if (isPipelined()) {
pipeline(
new LettuceResult(getAsyncConnection().migrate(target.getHost(), target.getPort(), key, dbIndex, timeout)));
return;
}
if (isQueueing()) {
transaction(
new LettuceTxResult(getConnection().migrate(target.getHost(), target.getPort(), key, dbIndex, timeout)));
return;
}
getConnection().migrate(target.getHost(), target.getPort(), key, dbIndex, timeout);
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
}

View File

@@ -594,7 +594,7 @@ public class LettuceConnectionFactory
if (isClusterAware()) {
List<RedisURI> initialUris = new ArrayList<RedisURI>();
List<RedisURI> initialUris = new ArrayList<>();
for (RedisNode node : this.clusterConfiguration.getClusterNodes()) {
initialUris.add(createRedisURIAndApplySettings(node.getHost(), node.getPort()));
}

View File

@@ -15,34 +15,13 @@
*/
package org.springframework.data.redis.connection.lettuce;
import io.lettuce.core.GeoArgs;
import io.lettuce.core.GeoCoordinates;
import io.lettuce.core.GeoWithin;
import io.lettuce.core.KeyValue;
import io.lettuce.core.Limit;
import io.lettuce.core.Range;
import io.lettuce.core.RedisURI;
import io.lettuce.core.ScoredValue;
import io.lettuce.core.ScriptOutputType;
import io.lettuce.core.SetArgs;
import io.lettuce.core.SortArgs;
import io.lettuce.core.TransactionResult;
import io.lettuce.core.*;
import io.lettuce.core.cluster.models.partitions.Partitions;
import io.lettuce.core.cluster.models.partitions.RedisClusterNode.NodeFlag;
import io.lettuce.core.protocol.LettuceCharsets;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -88,7 +67,7 @@ import org.springframework.util.StringUtils;
/**
* Lettuce type converters
*
*
* @author Jennifer Hickey
* @author Christoph Strobl
* @author Thomas Darimont
@@ -134,7 +113,7 @@ abstract public class LettuceConverters extends Converters {
};
BYTES_LIST_TO_BYTES_SET = new Converter<List<byte[]>, Set<byte[]>>() {
public Set<byte[]> convert(List<byte[]> results) {
return results != null ? new LinkedHashSet<byte[]>(results) : null;
return results != null ? new LinkedHashSet<>(results) : null;
}
};
BYTES_TO_STRING = new Converter<byte[], String>() {
@@ -159,7 +138,7 @@ abstract public class LettuceConverters extends Converters {
};
BYTES_SET_TO_BYTES_LIST = new Converter<Set<byte[]>, List<byte[]>>() {
public List<byte[]> convert(Set<byte[]> results) {
return results != null ? new ArrayList<byte[]>(results) : null;
return results != null ? new ArrayList<>(results) : null;
}
};
BYTES_COLLECTION_TO_BYTES_LIST = new Converter<Collection<byte[]>, List<byte[]>>() {
@@ -167,7 +146,7 @@ abstract public class LettuceConverters extends Converters {
if (results instanceof List) {
return (List<byte[]>) results;
}
return results != null ? new ArrayList<byte[]>(results) : null;
return results != null ? new ArrayList<>(results) : null;
}
};
KEY_VALUE_TO_BYTES_LIST = new Converter<KeyValue<byte[], byte[]>, List<byte[]>>() {
@@ -175,7 +154,7 @@ abstract public class LettuceConverters extends Converters {
if (source == null) {
return null;
}
List<byte[]> list = new ArrayList<byte[]>(2);
List<byte[]> list = new ArrayList<>(2);
list.add(source.getKey());
list.add(source.getValue());
return list;
@@ -190,7 +169,7 @@ abstract public class LettuceConverters extends Converters {
return Collections.emptyMap();
}
Map<byte[], byte[]> target = new LinkedHashMap<byte[], byte[]>();
Map<byte[], byte[]> target = new LinkedHashMap<>();
Iterator<byte[]> kv = source.iterator();
while (kv.hasNext()) {
@@ -205,7 +184,7 @@ abstract public class LettuceConverters extends Converters {
if (source == null) {
return null;
}
Set<Tuple> tuples = new LinkedHashSet<Tuple>(source.size());
Set<Tuple> tuples = new LinkedHashSet<>(source.size());
for (ScoredValue<byte[]> value : source) {
tuples.add(LettuceConverters.toTuple(value));
}
@@ -218,7 +197,7 @@ abstract public class LettuceConverters extends Converters {
if (source == null) {
return null;
}
List<Tuple> tuples = new ArrayList<Tuple>(source.size());
List<Tuple> tuples = new ArrayList<>(source.size());
for (ScoredValue<byte[]> value : source) {
tuples.add(LettuceConverters.toTuple(value));
}
@@ -239,7 +218,7 @@ abstract public class LettuceConverters extends Converters {
return Collections.emptyList();
}
List<Tuple> tuples = new ArrayList<Tuple>();
List<Tuple> tuples = new ArrayList<>();
Iterator<byte[]> it = source.iterator();
while (it.hasNext()) {
tuples.add(
@@ -257,7 +236,7 @@ abstract public class LettuceConverters extends Converters {
if (source == null) {
return Collections.emptyList();
}
List<RedisClusterNode> nodes = new ArrayList<RedisClusterNode>();
List<RedisClusterNode> nodes = new ArrayList<>();
for (io.lettuce.core.cluster.models.partitions.RedisClusterNode node : source.getPartitions()) {
nodes.add(CLUSTER_NODE_TO_CLUSTER_NODE_CONVERTER.convert(node));
}
@@ -283,7 +262,7 @@ abstract public class LettuceConverters extends Converters {
private Set<Flag> parseFlags(Set<NodeFlag> source) {
Set<Flag> flags = new LinkedHashSet<Flag>(source != null ? source.size() : 8, 1);
Set<Flag> flags = new LinkedHashSet<>(source != null ? source.size() : 8, 1);
for (NodeFlag flag : source) {
switch (flag) {
case NOFLAGS:
@@ -342,8 +321,7 @@ abstract public class LettuceConverters extends Converters {
: null;
}
};
GEO_COORDINATE_LIST_TO_POINT_LIST_CONVERTER = new ListConverter<GeoCoordinates, Point>(
GEO_COORDINATE_TO_POINT_CONVERTER);
GEO_COORDINATE_LIST_TO_POINT_LIST_CONVERTER = new ListConverter<>(GEO_COORDINATE_TO_POINT_CONVERTER);
KEY_VALUE_UNWRAPPER = new Converter<KeyValue<Object, Object>, Object>() {
@@ -658,7 +636,7 @@ abstract public class LettuceConverters extends Converters {
return Collections.emptyList();
}
List<RedisServer> sentinels = new ArrayList<RedisServer>();
List<RedisServer> sentinels = new ArrayList<>();
for (Map<String, String> info : source) {
sentinels.add(RedisServer.newServerFrom(Converters.toProperties(info)));
}
@@ -783,7 +761,7 @@ abstract public class LettuceConverters extends Converters {
/**
* Converts a given {@link Expiration} and {@link SetOption} to the according {@link SetArgs}.<br />
*
*
* @param expiration can be {@literal null}.
* @param option can be {@literal null}.
* @since 1.7
@@ -825,7 +803,7 @@ abstract public class LettuceConverters extends Converters {
/**
* Convert {@link Metric} into {@link GeoArgs.Unit}.
*
*
* @param metric
* @return
* @since 1.8
@@ -839,7 +817,7 @@ abstract public class LettuceConverters extends Converters {
/**
* Convert {@link GeoRadiusCommandArgs} into {@link GeoArgs}.
*
*
* @param args
* @return
* @since 1.8
@@ -880,7 +858,7 @@ abstract public class LettuceConverters extends Converters {
/**
* Get {@link Converter} capable of {@link Set} of {@link Byte} into {@link GeoResults}.
*
*
* @return
* @since 1.8
*/
@@ -891,22 +869,22 @@ abstract public class LettuceConverters extends Converters {
public GeoResults<GeoLocation<byte[]>> convert(Set<byte[]> source) {
if (CollectionUtils.isEmpty(source)) {
return new GeoResults<GeoLocation<byte[]>>(Collections.<GeoResult<GeoLocation<byte[]>>> emptyList());
return new GeoResults<>(Collections.<GeoResult<GeoLocation<byte[]>>> emptyList());
}
List<GeoResult<GeoLocation<byte[]>>> results = new ArrayList<GeoResult<GeoLocation<byte[]>>>(source.size());
List<GeoResult<GeoLocation<byte[]>>> results = new ArrayList<>(source.size());
Iterator<byte[]> it = source.iterator();
while (it.hasNext()) {
results.add(new GeoResult<GeoLocation<byte[]>>(new GeoLocation<byte[]>(it.next(), null), new Distance(0D)));
results.add(new GeoResult<>(new GeoLocation<>(it.next(), null), new Distance(0D)));
}
return new GeoResults<GeoLocation<byte[]>>(results);
return new GeoResults<>(results);
}
};
}
/**
* Get {@link Converter} capable of convering {@link GeoWithin} into {@link GeoResults}.
*
*
* @param metric
* @return
* @since 1.8
@@ -962,7 +940,7 @@ abstract public class LettuceConverters extends Converters {
@Override
public GeoResults<GeoLocation<byte[]>> convert(List<GeoWithin<byte[]>> source) {
List<GeoResult<GeoLocation<byte[]>>> results = new ArrayList<GeoResult<GeoLocation<byte[]>>>(source.size());
List<GeoResult<GeoLocation<byte[]>>> results = new ArrayList<>(source.size());
Converter<GeoWithin<byte[]>, GeoResult<GeoLocation<byte[]>>> converter = GeoResultConverterFactory.INSTANCE
.forMetric(metric);
@@ -970,7 +948,7 @@ abstract public class LettuceConverters extends Converters {
results.add(converter.convert(result));
}
return new GeoResults<GeoLocation<byte[]>>(results, metric);
return new GeoResults<>(results, metric);
}
}
}
@@ -1000,7 +978,7 @@ abstract public class LettuceConverters extends Converters {
Point point = GEO_COORDINATE_TO_POINT_CONVERTER.convert(source.getCoordinates());
return new GeoResult<GeoLocation<byte[]>>(new GeoLocation<byte[]>(source.getMember(), point),
return new GeoResult<>(new GeoLocation<>(source.getMember(), point),
new Distance(source.getDistance() != null ? source.getDistance() : 0D, metric));
}
}

View File

@@ -117,7 +117,7 @@ class LettuceGeoCommands implements RedisGeoCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(memberCoordinateMap, "MemberCoordinateMap must not be null!");
List<Object> values = new ArrayList<Object>();
List<Object> values = new ArrayList<>();
for (Entry<byte[], Point> entry : memberCoordinateMap.entrySet()) {
values.add(entry.getValue().getX());
@@ -138,7 +138,7 @@ class LettuceGeoCommands implements RedisGeoCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(locations, "Locations must not be null!");
List<Object> values = new ArrayList<Object>();
List<Object> values = new ArrayList<>();
for (GeoLocation<byte[]> location : locations) {
values.add(location.getPoint().getX());
@@ -438,7 +438,7 @@ class LettuceGeoCommands implements RedisGeoCommands {
connection.transaction(result);
}
RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
private RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
return connection.getAsyncConnection();
}

View File

@@ -380,7 +380,7 @@ class LettuceHashCommands implements RedisHashCommands {
connection.transaction(result);
}
RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
private RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
return connection.getAsyncConnection();
}

View File

@@ -143,7 +143,7 @@ class LettuceHyperLogLogCommands implements RedisHyperLogLogCommands {
connection.transaction(result);
}
RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
private RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
return connection.getAsyncConnection();
}

View File

@@ -589,7 +589,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
connection.transaction(result);
}
RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
private RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
return connection.getAsyncConnection();
}

View File

@@ -418,7 +418,7 @@ class LettuceListCommands implements RedisListCommands {
connection.transaction(result);
}
RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
private RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
return connection.getAsyncConnection();
}

View File

@@ -21,8 +21,7 @@ import org.springframework.data.redis.connection.ReactiveClusterGeoCommands;
* @author Christoph Strobl
* @since 2.0
*/
public class LettuceReactiveClusterGeoCommands extends LettuceReactiveGeoCommands
implements ReactiveClusterGeoCommands {
class LettuceReactiveClusterGeoCommands extends LettuceReactiveGeoCommands implements ReactiveClusterGeoCommands {
/**
* Create new {@link LettuceReactiveGeoCommands}.

View File

@@ -21,8 +21,7 @@ import org.springframework.data.redis.connection.ReactiveClusterHashCommands;
* @author Christoph Strobl
* @since 2.0
*/
public class LettuceReactiveClusterHashCommands extends LettuceReactiveHashCommands
implements ReactiveClusterHashCommands {
class LettuceReactiveClusterHashCommands extends LettuceReactiveHashCommands implements ReactiveClusterHashCommands {
/**
* Create new {@link LettuceReactiveHashCommands}.

View File

@@ -15,6 +15,9 @@
*/
package org.springframework.data.redis.connection.lettuce;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
@@ -27,14 +30,11 @@ import org.springframework.data.redis.connection.ReactiveRedisConnection.Boolean
import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse;
import org.springframework.util.Assert;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* @author Christoph Strobl
* @since @since 2.0
*/
public class LettuceReactiveClusterHyperLogLogCommands extends LettuceReactiveHyperLogLogCommands
class LettuceReactiveClusterHyperLogLogCommands extends LettuceReactiveHyperLogLogCommands
implements ReactiveClusterHyperLogLogCommands {
/**

View File

@@ -36,8 +36,7 @@ import org.springframework.util.Assert;
* @author Mark Paluch
* @since 2.0
*/
public class LettuceReactiveClusterKeyCommands extends LettuceReactiveKeyCommands
implements ReactiveClusterKeyCommands {
class LettuceReactiveClusterKeyCommands extends LettuceReactiveKeyCommands implements ReactiveClusterKeyCommands {
private LettuceReactiveRedisClusterConnection connection;

View File

@@ -15,6 +15,9 @@
*/
package org.springframework.data.redis.connection.lettuce;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.nio.ByteBuffer;
import org.reactivestreams.Publisher;
@@ -24,16 +27,12 @@ import org.springframework.data.redis.connection.ReactiveClusterListCommands;
import org.springframework.data.redis.connection.ReactiveRedisConnection.ByteBufferResponse;
import org.springframework.util.Assert;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* @author Christoph Strobl
* @author Mark Paluch
* @since 2.0
*/
public class LettuceReactiveClusterListCommands extends LettuceReactiveListCommands
implements ReactiveClusterListCommands {
class LettuceReactiveClusterListCommands extends LettuceReactiveListCommands implements ReactiveClusterListCommands {
/**
* Create new {@link LettuceReactiveListCommands}.

View File

@@ -21,7 +21,7 @@ import org.springframework.data.redis.connection.ReactiveClusterNumberCommands;
* @author Christoph Strobl
* @since 2.0
*/
public class LettuceReactiveClusterNumberCommands extends LettuceReactiveNumberCommands
class LettuceReactiveClusterNumberCommands extends LettuceReactiveNumberCommands
implements ReactiveClusterNumberCommands {
/**

View File

@@ -36,8 +36,7 @@ import org.springframework.util.Assert;
* @author Mark Paluch
* @since 2.0
*/
public class LettuceReactiveClusterSetCommands extends LettuceReactiveSetCommands
implements ReactiveClusterSetCommands {
class LettuceReactiveClusterSetCommands extends LettuceReactiveSetCommands implements ReactiveClusterSetCommands {
/**
* Create new {@link LettuceReactiveSetCommands}.

View File

@@ -15,6 +15,9 @@
*/
package org.springframework.data.redis.connection.lettuce;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
@@ -25,14 +28,11 @@ import org.springframework.data.redis.connection.ClusterSlotHashUtil;
import org.springframework.data.redis.connection.ReactiveClusterStringCommands;
import org.springframework.data.redis.connection.ReactiveRedisConnection;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* @author Christoph Strobl
* @since 2.0
*/
public class LettuceReactiveClusterStringCommands extends LettuceReactiveStringCommands
class LettuceReactiveClusterStringCommands extends LettuceReactiveStringCommands
implements ReactiveClusterStringCommands {
/**

View File

@@ -15,6 +15,9 @@
*/
package org.springframework.data.redis.connection.lettuce;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.reactivestreams.Publisher;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.redis.connection.ClusterSlotHashUtil;
@@ -22,15 +25,11 @@ import org.springframework.data.redis.connection.ReactiveClusterZSetCommands;
import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse;
import org.springframework.util.Assert;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* @author Christoph Strobl
* @since @since 2.0
*/
public class LettuceReactiveClusterZSetCommands extends LettuceReactiveZSetCommands
implements ReactiveClusterZSetCommands {
class LettuceReactiveClusterZSetCommands extends LettuceReactiveZSetCommands implements ReactiveClusterZSetCommands {
/**
* Create new {@link LettuceReactiveSetCommands}.

View File

@@ -45,7 +45,7 @@ import org.springframework.util.Assert;
* @author Christoph Strobl
* @since 2.0
*/
public class LettuceReactiveGeoCommands implements ReactiveGeoCommands {
class LettuceReactiveGeoCommands implements ReactiveGeoCommands {
private final LettuceReactiveRedisConnection connection;

View File

@@ -41,7 +41,7 @@ import org.springframework.util.ObjectUtils;
* @author Mark Paluch
* @since 2.0
*/
public class LettuceReactiveHashCommands implements ReactiveHashCommands {
class LettuceReactiveHashCommands implements ReactiveHashCommands {
private final LettuceReactiveRedisConnection connection;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-2017 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.
@@ -15,6 +15,8 @@
*/
package org.springframework.data.redis.connection.lettuce;
import reactor.core.publisher.Flux;
import java.nio.ByteBuffer;
import org.reactivestreams.Publisher;
@@ -23,13 +25,11 @@ import org.springframework.data.redis.connection.ReactiveRedisConnection.Boolean
import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse;
import org.springframework.util.Assert;
import reactor.core.publisher.Flux;
/**
* @author Christoph Strobl
* @since 2.0
*/
public class LettuceReactiveHyperLogLogCommands implements ReactiveHyperLogLogCommands {
class LettuceReactiveHyperLogLogCommands implements ReactiveHyperLogLogCommands {
private final LettuceReactiveRedisConnection connection;

View File

@@ -38,7 +38,7 @@ import org.springframework.util.Assert;
* @author Mark Paluch
* @since 2.0
*/
public class LettuceReactiveKeyCommands implements ReactiveKeyCommands {
class LettuceReactiveKeyCommands implements ReactiveKeyCommands {
private final LettuceReactiveRedisConnection connection;

View File

@@ -40,7 +40,7 @@ import org.springframework.util.ObjectUtils;
* @author Mark Paluch
* @since 2.0
*/
public class LettuceReactiveListCommands implements ReactiveListCommands {
class LettuceReactiveListCommands implements ReactiveListCommands {
private final LettuceReactiveRedisConnection connection;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-2017 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.
@@ -15,6 +15,9 @@
*/
package org.springframework.data.redis.connection.lettuce;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.reactivestreams.Publisher;
import org.springframework.data.redis.connection.ReactiveNumberCommands;
import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyCommand;
@@ -22,15 +25,12 @@ import org.springframework.data.redis.connection.ReactiveRedisConnection.Numeric
import org.springframework.util.Assert;
import org.springframework.util.NumberUtils;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* @author Christoph Strobl
* @author Mark Paluch
* @since 2.0
*/
public class LettuceReactiveNumberCommands implements ReactiveNumberCommands {
class LettuceReactiveNumberCommands implements ReactiveNumberCommands {
private final LettuceReactiveRedisConnection connection;

View File

@@ -33,7 +33,7 @@ import org.springframework.util.StringUtils;
* @author Mark Paluch
* @since 2.0
*/
public class LettuceReactiveRedisClusterConnection extends LettuceReactiveRedisConnection
class LettuceReactiveRedisClusterConnection extends LettuceReactiveRedisConnection
implements ReactiveRedisClusterConnection {
public LettuceReactiveRedisClusterConnection(RedisClusterClient client) {

View File

@@ -31,7 +31,16 @@ import java.util.function.Function;
import org.reactivestreams.Publisher;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
import org.springframework.data.redis.connection.*;
import org.springframework.data.redis.connection.ReactiveGeoCommands;
import org.springframework.data.redis.connection.ReactiveHashCommands;
import org.springframework.data.redis.connection.ReactiveHyperLogLogCommands;
import org.springframework.data.redis.connection.ReactiveKeyCommands;
import org.springframework.data.redis.connection.ReactiveListCommands;
import org.springframework.data.redis.connection.ReactiveNumberCommands;
import org.springframework.data.redis.connection.ReactiveRedisConnection;
import org.springframework.data.redis.connection.ReactiveSetCommands;
import org.springframework.data.redis.connection.ReactiveStringCommands;
import org.springframework.data.redis.connection.ReactiveZSetCommands;
import org.springframework.util.Assert;
/**
@@ -39,7 +48,7 @@ import org.springframework.util.Assert;
* @author Mark Paluch
* @since 2.0
*/
public class LettuceReactiveRedisConnection implements ReactiveRedisConnection {
class LettuceReactiveRedisConnection implements ReactiveRedisConnection {
private StatefulConnection<ByteBuffer, ByteBuffer> connection;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-2017 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.
@@ -34,7 +34,7 @@ import org.springframework.util.Assert;
* @author Mark Paluch
* @since 2.0
*/
public class LettuceReactiveSetCommands implements ReactiveSetCommands {
class LettuceReactiveSetCommands implements ReactiveSetCommands {
private final LettuceReactiveRedisConnection connection;

View File

@@ -38,7 +38,7 @@ import org.springframework.util.Assert;
* @author Mark Paluch
* @since 2.0
*/
public class LettuceReactiveStringCommands implements ReactiveStringCommands {
class LettuceReactiveStringCommands implements ReactiveStringCommands {
private final static ByteBuffer EMPTY_BYTE_BUFFER = ByteBuffer.wrap(new byte[0]);
private final LettuceReactiveRedisConnection connection;

View File

@@ -48,7 +48,7 @@ import org.springframework.util.StringUtils;
* @author Mark Paluch
* @since 2.0
*/
public class LettuceReactiveZSetCommands implements ReactiveZSetCommands {
class LettuceReactiveZSetCommands implements ReactiveZSetCommands {
private final LettuceReactiveRedisConnection connection;

View File

@@ -0,0 +1,259 @@
/*
* Copyright 2017 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.connection.lettuce;
import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands;
import io.lettuce.core.cluster.api.sync.RedisClusterCommands;
import java.util.Arrays;
import java.util.List;
import org.springframework.core.convert.converter.Converter;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisScriptingCommands;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.connection.lettuce.LettuceConnection.LettuceResult;
import org.springframework.data.redis.connection.lettuce.LettuceConnection.LettuceTxResult;
/**
* @author Mark Paluch
* @since 2.0
*/
class LettuceScriptingCommands implements RedisScriptingCommands {
private final LettuceConnection connection;
public LettuceScriptingCommands(LettuceConnection connection) {
this.connection = connection;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#scriptFlush()
*/
@Override
public void scriptFlush() {
try {
if (isPipelined()) {
pipeline(connection.newLettuceStatusResult(getAsyncConnection().scriptFlush()));
return;
}
if (isQueueing()) {
transaction(connection.newLettuceTxStatusResult(getConnection().scriptFlush()));
return;
}
getConnection().scriptFlush();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#scriptKill()
*/
@Override
public void scriptKill() {
if (isQueueing()) {
throw new UnsupportedOperationException("Script kill not permitted in a transaction");
}
try {
if (isPipelined()) {
pipeline(connection.newLettuceStatusResult(getAsyncConnection().scriptKill()));
return;
}
if (isQueueing()) {
transaction(connection.newLettuceTxStatusResult(getConnection().scriptKill()));
return;
}
getConnection().scriptKill();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#scriptLoad(byte[])
*/
@Override
public String scriptLoad(byte[] script) {
try {
if (isPipelined()) {
pipeline(connection.newLettuceResult(getAsyncConnection().scriptLoad(script)));
return null;
}
if (isQueueing()) {
transaction(connection.newLettuceTxResult(getConnection().scriptLoad(script)));
return null;
}
return getConnection().scriptLoad(script);
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#scriptExists(java.lang.String[])
*/
@Override
public List<Boolean> scriptExists(String... scriptSha1) {
try {
if (isPipelined()) {
pipeline(connection.newLettuceResult(getAsyncConnection().scriptExists(scriptSha1)));
return null;
}
if (isQueueing()) {
transaction(connection.newLettuceTxResult(getConnection().scriptExists(scriptSha1)));
return null;
}
return getConnection().scriptExists(scriptSha1);
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#eval(byte[], org.springframework.data.redis.connection.ReturnType, int, byte[][])
*/
@Override
public <T> T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
try {
byte[][] keys = extractScriptKeys(numKeys, keysAndArgs);
byte[][] args = extractScriptArgs(numKeys, keysAndArgs);
String convertedScript = LettuceConverters.toString(script);
if (isPipelined()) {
pipeline(connection.newLettuceResult(
getAsyncConnection().eval(convertedScript, LettuceConverters.toScriptOutputType(returnType), keys, args),
new LettuceEvalResultsConverter<T>(returnType)));
return null;
}
if (isQueueing()) {
transaction(connection.newLettuceTxResult(
getConnection().eval(convertedScript, LettuceConverters.toScriptOutputType(returnType), keys, args),
new LettuceEvalResultsConverter<T>(returnType)));
return null;
}
return new LettuceEvalResultsConverter<T>(returnType)
.convert(getConnection().eval(convertedScript, LettuceConverters.toScriptOutputType(returnType), keys, args));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#evalSha(java.lang.String, org.springframework.data.redis.connection.ReturnType, int, byte[][])
*/
@Override
public <T> T evalSha(String scriptSha1, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
try {
byte[][] keys = extractScriptKeys(numKeys, keysAndArgs);
byte[][] args = extractScriptArgs(numKeys, keysAndArgs);
if (isPipelined()) {
pipeline(connection.newLettuceResult(
getAsyncConnection().evalsha(scriptSha1, LettuceConverters.toScriptOutputType(returnType), keys, args),
new LettuceEvalResultsConverter<T>(returnType)));
return null;
}
if (isQueueing()) {
transaction(connection.newLettuceTxResult(
getConnection().evalsha(scriptSha1, LettuceConverters.toScriptOutputType(returnType), keys, args),
new LettuceEvalResultsConverter<T>(returnType)));
return null;
}
return new LettuceEvalResultsConverter<T>(returnType)
.convert(getConnection().evalsha(scriptSha1, LettuceConverters.toScriptOutputType(returnType), keys, args));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisScriptingCommands#evalSha(byte[], org.springframework.data.redis.connection.ReturnType, int, byte[][])
*/
@Override
public <T> T evalSha(byte[] scriptSha1, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
return evalSha(LettuceConverters.toString(scriptSha1), returnType, numKeys, keysAndArgs);
}
private boolean isPipelined() {
return connection.isPipelined();
}
private boolean isQueueing() {
return connection.isQueueing();
}
private void pipeline(LettuceResult result) {
connection.pipeline(result);
}
private void transaction(LettuceTxResult result) {
connection.transaction(result);
}
private RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
return connection.getAsyncConnection();
}
public RedisClusterCommands<byte[], byte[]> getConnection() {
return connection.getConnection();
}
private DataAccessException convertLettuceAccessException(Exception ex) {
return connection.convertLettuceAccessException(ex);
}
private static byte[][] extractScriptKeys(int numKeys, byte[]... keysAndArgs) {
if (numKeys > 0) {
return Arrays.copyOfRange(keysAndArgs, 0, numKeys);
}
return new byte[0][0];
}
private static byte[][] extractScriptArgs(int numKeys, byte[]... keysAndArgs) {
if (keysAndArgs.length > numKeys) {
return Arrays.copyOfRange(keysAndArgs, numKeys, keysAndArgs.length);
}
return new byte[0][0];
}
private class LettuceEvalResultsConverter<T> implements Converter<Object, T> {
private ReturnType returnType;
public LettuceEvalResultsConverter(ReturnType returnType) {
this.returnType = returnType;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public T convert(Object source) {
if (returnType == ReturnType.MULTI) {
List resultList = (List) source;
for (Object obj : resultList) {
if (obj instanceof Exception) {
throw convertLettuceAccessException((Exception) obj);
}
}
}
return (T) source;
}
}
}

View File

@@ -0,0 +1,549 @@
/*
* Copyright 2017 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.connection.lettuce;
import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands;
import io.lettuce.core.cluster.api.sync.RedisClusterCommands;
import java.util.List;
import java.util.Properties;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.data.redis.connection.lettuce.LettuceConnection.LettuceResult;
import org.springframework.data.redis.connection.lettuce.LettuceConnection.LettuceTxResult;
import org.springframework.data.redis.core.types.RedisClientInfo;
import org.springframework.util.Assert;
/**
* @author Mark Paluch
* @since 2.0
*/
class LettuceServerCommands implements RedisServerCommands {
private final LettuceConnection connection;
public LettuceServerCommands(LettuceConnection connection) {
this.connection = connection;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#bgReWriteAof()
*/
@Override
public void bgReWriteAof() {
try {
if (isPipelined()) {
pipeline(connection.newLettuceStatusResult(getAsyncConnection().bgrewriteaof()));
return;
}
if (isQueueing()) {
transaction(connection.newLettuceTxStatusResult(getConnection().bgrewriteaof()));
return;
}
getConnection().bgrewriteaof();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#bgSave()
*/
@Override
public void bgSave() {
try {
if (isPipelined()) {
pipeline(connection.newLettuceStatusResult(getAsyncConnection().bgsave()));
return;
}
if (isQueueing()) {
transaction(connection.newLettuceTxStatusResult(getConnection().bgsave()));
return;
}
getConnection().bgsave();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#lastSave()
*/
@Override
public Long lastSave() {
try {
if (isPipelined()) {
pipeline(connection.newLettuceResult(getAsyncConnection().lastsave(), LettuceConverters.dateToLong()));
return null;
}
if (isQueueing()) {
transaction(connection.newLettuceTxResult(getConnection().lastsave(), LettuceConverters.dateToLong()));
return null;
}
return LettuceConverters.toLong(getConnection().lastsave());
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#save()
*/
@Override
public void save() {
try {
if (isPipelined()) {
pipeline(connection.newLettuceStatusResult(getAsyncConnection().save()));
return;
}
if (isQueueing()) {
transaction(connection.newLettuceTxStatusResult(getConnection().save()));
return;
}
getConnection().save();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#dbSize()
*/
@Override
public Long dbSize() {
try {
if (isPipelined()) {
pipeline(connection.newLettuceResult(getAsyncConnection().dbsize()));
return null;
}
if (isQueueing()) {
transaction(connection.newLettuceTxResult(getConnection().dbsize()));
return null;
}
return getConnection().dbsize();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#flushDb()
*/
@Override
public void flushDb() {
try {
if (isPipelined()) {
pipeline(connection.newLettuceStatusResult(getAsyncConnection().flushdb()));
return;
}
if (isQueueing()) {
transaction(connection.newLettuceTxStatusResult(getConnection().flushdb()));
return;
}
getConnection().flushdb();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#flushAll()
*/
@Override
public void flushAll() {
try {
if (isPipelined()) {
pipeline(connection.newLettuceStatusResult(getAsyncConnection().flushall()));
return;
}
if (isQueueing()) {
transaction(connection.newLettuceTxResult(getConnection().flushall()));
return;
}
getConnection().flushall();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#info()
*/
@Override
public Properties info() {
try {
if (isPipelined()) {
pipeline(connection.newLettuceResult(getAsyncConnection().info(), LettuceConverters.stringToProps()));
return null;
}
if (isQueueing()) {
transaction(connection.newLettuceTxResult(getConnection().info(), LettuceConverters.stringToProps()));
return null;
}
return LettuceConverters.toProperties(getConnection().info());
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#info(java.lang.String)
*/
@Override
public Properties info(String section) {
try {
if (isPipelined()) {
pipeline(connection.newLettuceResult(getAsyncConnection().info(section), LettuceConverters.stringToProps()));
return null;
}
if (isQueueing()) {
transaction(connection.newLettuceTxResult(getConnection().info(section), LettuceConverters.stringToProps()));
return null;
}
return LettuceConverters.toProperties(getConnection().info(section));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#shutdown()
*/
@Override
public void shutdown() {
try {
if (isPipelined()) {
getAsyncConnection().shutdown(true);
return;
}
getConnection().shutdown(true);
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#shutdown(org.springframework.data.redis.connection.RedisServerCommands.ShutdownOption)
*/
@Override
public void shutdown(ShutdownOption option) {
if (option == null) {
shutdown();
return;
}
boolean save = ShutdownOption.SAVE.equals(option);
try {
if (isPipelined()) {
getAsyncConnection().shutdown(save);
return;
}
getConnection().shutdown(save);
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#getConfig(java.lang.String)
*/
@Override
public List<String> getConfig(String param) {
try {
if (isPipelined()) {
pipeline(connection.newLettuceResult(getAsyncConnection().configGet(param)));
return null;
}
if (isQueueing()) {
transaction(connection.newLettuceTxResult(getConnection().configGet(param)));
return null;
}
return getConnection().configGet(param);
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#setConfig(java.lang.String, java.lang.String)
*/
@Override
public void setConfig(String param, String value) {
try {
if (isPipelined()) {
pipeline(connection.newLettuceStatusResult(getAsyncConnection().configSet(param, value)));
return;
}
if (isQueueing()) {
transaction(connection.newLettuceTxStatusResult(getConnection().configSet(param, value)));
return;
}
getConnection().configSet(param, value);
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#resetConfigStats()
*/
@Override
public void resetConfigStats() {
try {
if (isPipelined()) {
pipeline(connection.newLettuceStatusResult(getAsyncConnection().configResetstat()));
return;
}
if (isQueueing()) {
transaction(connection.newLettuceTxStatusResult(getConnection().configResetstat()));
return;
}
getConnection().configResetstat();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#time()
*/
@Override
public Long time() {
try {
if (isPipelined()) {
pipeline(connection.newLettuceResult(getAsyncConnection().time(), LettuceConverters.toTimeConverter()));
return null;
}
if (isQueueing()) {
transaction(connection.newLettuceTxResult(getConnection().time(), LettuceConverters.toTimeConverter()));
return null;
}
return LettuceConverters.toTimeConverter().convert(getConnection().time());
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#killClient(java.lang.String, int)
*/
@Override
public void killClient(String host, int port) {
Assert.hasText(host, "Host for 'CLIENT KILL' must not be 'null' or 'empty'.");
String client = String.format("%s:%s", host, port);
try {
if (isPipelined()) {
pipeline(connection.newLettuceStatusResult(getAsyncConnection().clientKill(client)));
return;
}
getConnection().clientKill(client);
} catch (Exception e) {
throw convertLettuceAccessException(e);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#setClientName(byte[])
*/
@Override
public void setClientName(byte[] name) {
if (isQueueing()) {
pipeline(connection.newLettuceStatusResult(getAsyncConnection().clientSetname(name)));
return;
}
if (isQueueing()) {
transaction(connection.newLettuceTxStatusResult(getConnection().clientSetname(name)));
return;
}
getAsyncConnection().clientSetname(name);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#getClientName()
*/
@Override
public String getClientName() {
try {
if (isPipelined()) {
pipeline(connection.newLettuceResult(getAsyncConnection().clientGetname(), LettuceConverters.bytesToString()));
return null;
}
if (isQueueing()) {
transaction(connection.newLettuceTxResult(getConnection().clientGetname(), LettuceConverters.bytesToString()));
return null;
}
return LettuceConverters.toString(getConnection().clientGetname());
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#getClientList()
*/
@Override
public List<RedisClientInfo> getClientList() {
if (isPipelined()) {
throw new UnsupportedOperationException("Cannot be called in pipeline mode.");
}
if (isQueueing()) {
transaction(connection.newLettuceTxResult(getAsyncConnection().clientList(),
LettuceConverters.stringToRedisClientListConverter()));
return null;
}
return LettuceConverters.toListOfRedisClientInformation(getConnection().clientList());
}
/*
* (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(connection.newLettuceStatusResult(getAsyncConnection().slaveof(host, port)));
return;
}
if (isQueueing()) {
transaction(connection.newLettuceTxResult(getConnection().slaveof(host, port)));
return;
}
getConnection().slaveof(host, port);
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#slaveOfNoOne()
*/
@Override
public void slaveOfNoOne() {
try {
if (isPipelined()) {
pipeline(connection.newLettuceStatusResult(getAsyncConnection().slaveofNoOne()));
return;
}
if (isQueueing()) {
transaction(connection.newLettuceTxResult(getConnection().slaveofNoOne()));
return;
}
getConnection().slaveofNoOne();
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#migrate(byte[], org.springframework.data.redis.connection.RedisNode, int, org.springframework.data.redis.connection.RedisServerCommands.MigrateOption)
*/
@Override
public void migrate(byte[] key, RedisNode target, int dbIndex, MigrateOption option) {
migrate(key, target, dbIndex, option, Long.MAX_VALUE);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisServerCommands#migrate(byte[], org.springframework.data.redis.connection.RedisNode, int, org.springframework.data.redis.connection.RedisServerCommands.MigrateOption, long)
*/
@Override
public void migrate(byte[] key, RedisNode target, int dbIndex, MigrateOption option, long timeout) {
try {
if (isPipelined()) {
pipeline(connection
.newLettuceResult(getAsyncConnection().migrate(target.getHost(), target.getPort(), key, dbIndex, timeout)));
return;
}
if (isQueueing()) {
transaction(connection
.newLettuceTxResult(getConnection().migrate(target.getHost(), target.getPort(), key, dbIndex, timeout)));
return;
}
getConnection().migrate(target.getHost(), target.getPort(), key, dbIndex, timeout);
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
private boolean isPipelined() {
return connection.isPipelined();
}
private boolean isQueueing() {
return connection.isQueueing();
}
private void pipeline(LettuceResult result) {
connection.pipeline(result);
}
private void transaction(LettuceTxResult result) {
connection.transaction(result);
}
private RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
return connection.getAsyncConnection();
}
public RedisClusterCommands<byte[], byte[]> getConnection() {
return connection.getConnection();
}
private DataAccessException convertLettuceAccessException(Exception ex) {
return connection.convertLettuceAccessException(ex);
}
}

View File

@@ -684,7 +684,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
List<ScoredValue<byte[]>> result = scoredValueScanCursor.getValues();
List<Tuple> values = connection.failsafeReadScanValues(result, LettuceConverters.scoredValuesToTupleList());
return new ScanIteration<Tuple>(Long.valueOf(nextCursorId), values);
return new ScanIteration<>(Long.valueOf(nextCursorId), values);
}
protected void doClose() {