DATAREDIS-692 - Introduce usage of nullable annotations for API validation.

Mark all packages with Spring Frameworks @NonNullApi. Add Spring's @Nullable to methods, parameters and fields that take or produce null values. Adapted using code to make sure the IDE can evaluate the null flow properly. Fix Javadoc in places where an invalid null handling policy was advertised. Strengthened null requirements for types that expose null-instances.

Resolve some of the inherited null invariants, align Converters to null contract.

Original pull request: #277.
This commit is contained in:
Christoph Strobl
2017-09-13 10:36:38 +02:00
committed by Mark Paluch
parent ddb5ca7c28
commit 1b2e74c82f
189 changed files with 2285 additions and 1396 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-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.
@@ -16,6 +16,7 @@
package org.springframework.data.redis;
import org.springframework.dao.DataAccessException;
import org.springframework.lang.Nullable;
/**
* Potentially translates an {@link Exception} into appropriate {@link DataAccessException}.
@@ -28,10 +29,11 @@ public interface ExceptionTranslationStrategy {
/**
* Potentially translate the given {@link Exception} into {@link DataAccessException}.
*
* @param e
* @return
*
* @param e must not be {@literal null}.
* @return can be {@literal null} if given {@link Exception} cannot be translated.
*/
@Nullable
DataAccessException translate(Exception e);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-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.
@@ -18,6 +18,8 @@ package org.springframework.data.redis;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.lang.Nullable;
/**
* Central class for reading version string (eg. {@literal 1.3.1}) into {@link Version}.
*
@@ -31,10 +33,11 @@ public class VersionParser {
/**
* Parse version string {@literal eg. 1.1.1} to {@link Version}.
*
* @param version
* @return
* @param version can be {@literal null}.
* @return never {@literal null}.
*/
public static Version parseVersion(String version) {
public static Version parseVersion(@Nullable String version) {
if (version == null) {
return Version.UNKNOWN;
}
@@ -47,6 +50,7 @@ public class VersionParser {
return new Version(Integer.parseInt(major), minor != null ? Integer.parseInt(minor) : 0,
patch != null ? Integer.parseInt(patch) : 0);
}
return Version.UNKNOWN;
}

View File

@@ -17,6 +17,8 @@ package org.springframework.data.redis.cache;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Collections;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -26,6 +28,7 @@ import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -70,17 +73,16 @@ class DefaultRedisCacheWriter implements RedisCacheWriter {
this.sleepTime = sleepTime;
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.redis.cache.RedisCacheWriter#put(java.lang.String, byte[], byte[], java.time.Duration)
*/
@Override
public void put(String name, byte[] key, byte[] value, Duration ttl) {
public void put(String name, byte[] key, byte[] value, @Nullable Duration ttl) {
Assert.notNull(name, "Name must not be null!");
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
Assert.notNull(ttl, "Ttl must not be null!");
execute(name, connection -> {
@@ -94,7 +96,7 @@ class DefaultRedisCacheWriter implements RedisCacheWriter {
});
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.redis.cache.RedisCacheWriter#get(java.lang.String, byte[])
*/
@@ -107,17 +109,16 @@ class DefaultRedisCacheWriter implements RedisCacheWriter {
return execute(name, connection -> connection.get(key));
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.redis.cache.RedisCacheWriter#putIfAbsent(java.lang.String, byte[], byte[], java.time.Duration)
*/
@Override
public byte[] putIfAbsent(String name, byte[] key, byte[] value, Duration ttl) {
public byte[] putIfAbsent(String name, byte[] key, byte[] value, @Nullable Duration ttl) {
Assert.notNull(name, "Name must not be null!");
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
Assert.notNull(ttl, "Ttl must not be null!");
return execute(name, connection -> {
@@ -178,7 +179,8 @@ class DefaultRedisCacheWriter implements RedisCacheWriter {
wasLocked = true;
}
byte[][] keys = connection.keys(pattern).toArray(new byte[0][]);
byte[][] keys = Optional.ofNullable(connection.keys(pattern)).orElse(Collections.emptySet())
.toArray(new byte[0][]);
if (keys.length > 0) {
connection.del(keys);
@@ -275,7 +277,7 @@ class DefaultRedisCacheWriter implements RedisCacheWriter {
}
}
private static boolean shouldExpireWithin(Duration ttl) {
private static boolean shouldExpireWithin(@Nullable Duration ttl) {
return ttl != null && !ttl.isZero() && !ttl.isNegative();
}

View File

@@ -26,6 +26,7 @@ import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.util.ByteUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
@@ -129,7 +130,7 @@ public class RedisCache extends AbstractValueAdaptingCache {
* @see org.springframework.cache.Cache#put(java.lang.Object, java.lang.Object)
*/
@Override
public void put(Object key, Object value) {
public void put(Object key, @Nullable Object value) {
Object cacheValue = preProcessCacheValue(value);
@@ -148,7 +149,7 @@ public class RedisCache extends AbstractValueAdaptingCache {
* @see org.springframework.cache.Cache#putIfAbsent(java.lang.Object, java.lang.Object)
*/
@Override
public ValueWrapper putIfAbsent(Object key, Object value) {
public ValueWrapper putIfAbsent(Object key, @Nullable Object value) {
Object cacheValue = preProcessCacheValue(value);
@@ -202,7 +203,8 @@ public class RedisCache extends AbstractValueAdaptingCache {
* @param value can be {@literal null}.
* @return preprocessed value. Can be {@literal null}.
*/
protected Object preProcessCacheValue(Object value) {
@Nullable
protected Object preProcessCacheValue(@Nullable Object value) {
if (value != null) {
return value;
@@ -242,6 +244,7 @@ public class RedisCache extends AbstractValueAdaptingCache {
* @param value must not be {@literal null}.
* @return can be {@literal null}.
*/
@Nullable
protected Object deserializeCacheValue(byte[] value) {
if (isAllowNullValues() && ObjectUtils.nullSafeEquals(value, BINARY_NULL_VALUE)) {

View File

@@ -27,6 +27,7 @@ import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer
import org.springframework.data.redis.serializer.RedisSerializationContext.SerializationPair;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.format.support.DefaultFormattingConversionService;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -43,7 +44,7 @@ public class RedisCacheConfiguration {
private final Duration ttl;
private final boolean cacheNullValues;
private final String keyPrefix;
private final @Nullable String keyPrefix;
private final boolean usePrefix;
private final SerializationPair<String> keySerializationPair;
@@ -52,7 +53,7 @@ public class RedisCacheConfiguration {
private final ConversionService conversionService;
@SuppressWarnings("unchecked")
private RedisCacheConfiguration(Duration ttl, Boolean cacheNullValues, Boolean usePrefix, String keyPrefix,
private RedisCacheConfiguration(Duration ttl, Boolean cacheNullValues, Boolean usePrefix, @Nullable String keyPrefix,
SerializationPair<String> keySerializationPair, SerializationPair<?> valueSerializationPair,
ConversionService conversionService) {

View File

@@ -26,6 +26,7 @@ import java.util.Set;
import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -205,7 +206,7 @@ public class RedisCacheManager extends AbstractTransactionSupportingCacheManager
* @param cacheConfig can be {@literal null}.
* @return never {@literal null}.
*/
protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
protected RedisCache createRedisCache(String name, @Nullable RedisCacheConfiguration cacheConfig) {
return new RedisCache(name, cacheWriter, cacheConfig != null ? cacheConfig : defaultCacheConfig);
}

View File

@@ -18,6 +18,7 @@ package org.springframework.data.redis.cache;
import java.time.Duration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -66,7 +67,7 @@ public interface RedisCacheWriter {
* @param value The value stored for the key. Must not be {@literal null}.
* @param ttl Optional expiration time. Can be {@literal null}.
*/
void put(String name, byte[] key, byte[] value, Duration ttl);
void put(String name, byte[] key, byte[] value, @Nullable Duration ttl);
/**
* Get the binary value representation from Redis stored for the given key.
@@ -75,7 +76,7 @@ public interface RedisCacheWriter {
* @param key must not be {@literal null}.
* @return {@literal null} if key does not exist.
*/
@Nullable
byte[] get(String name, byte[] key);
/**
@@ -87,7 +88,8 @@ public interface RedisCacheWriter {
* @param ttl Optional expiration time. Can be {@literal null}.
* @return {@literal null} if the value has been written, the value stored for the key if it already exists.
*/
byte[] putIfAbsent(String name, byte[] key, byte[] value, Duration ttl);
@Nullable
byte[] putIfAbsent(String name, byte[] key, byte[] value, @Nullable Duration ttl);
/**
* Remove the given key from Redis.

View File

@@ -1,5 +1,6 @@
/**
* Package providing a Redis implementation for Spring <a href="http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html">cache abstraction</a>.
* Package providing a Redis implementation for Spring
* <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html">cache abstraction</a>.
*/
@org.springframework.lang.NonNullApi
package org.springframework.data.redis.cache;

View File

@@ -33,6 +33,7 @@ class RedisCollectionParser extends AbstractSimpleBeanDefinitionParser {
}
protected void postProcess(BeanDefinitionBuilder beanDefinition, Element element) {
String template = element.getAttribute("template");
if (StringUtils.hasText(template)) {
beanDefinition.addPropertyReference("template", template);

View File

@@ -0,0 +1,5 @@
/**
* Namespace and configuration.
*/
@org.springframework.lang.NonNullApi
package org.springframework.data.redis.config;

View File

@@ -22,6 +22,8 @@ import org.springframework.dao.DataAccessException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
import org.springframework.data.redis.RedisSystemException;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* @author Christoph Strobl
@@ -30,7 +32,7 @@ import org.springframework.data.redis.RedisSystemException;
*/
public abstract class AbstractRedisConnection implements DefaultedRedisConnection {
private RedisSentinelConfiguration sentinelConfiguration;
private @Nullable RedisSentinelConfiguration sentinelConfiguration;
private ConcurrentHashMap<RedisNode, RedisSentinelConnection> connectionCache = new ConcurrentHashMap<>();
/*
@@ -63,6 +65,8 @@ public abstract class AbstractRedisConnection implements DefaultedRedisConnectio
private RedisNode selectActiveSentinel() {
Assert.state(hasRedisSentinelConfigured(), "Sentinel configuration missing!");
for (RedisNode node : this.sentinelConfiguration.getSentinels()) {
if (isActive(node)) {
return node;

View File

@@ -29,6 +29,7 @@ import org.springframework.data.redis.ExceptionTranslationStrategy;
import org.springframework.data.redis.TooManyClusterRedirectionsException;
import org.springframework.data.redis.connection.util.ByteArraySet;
import org.springframework.data.redis.connection.util.ByteArrayWrapper;
import org.springframework.lang.Nullable;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@@ -73,10 +74,10 @@ public class ClusterCommandExecutor implements DisposableBean {
* @param topologyProvider must not be {@literal null}.
* @param resourceProvider must not be {@literal null}.
* @param exceptionTranslation must not be {@literal null}.
* @param executor can be {@literal null}.
* @param executor can be {@literal null}. Defaulted to {@link ThreadPoolTaskExecutor}.
*/
public ClusterCommandExecutor(ClusterTopologyProvider topologyProvider, ClusterNodeResourceProvider resourceProvider,
ExceptionTranslationStrategy exceptionTranslation, AsyncTaskExecutor executor) {
ExceptionTranslationStrategy exceptionTranslation, @Nullable AsyncTaskExecutor executor) {
this(topologyProvider, resourceProvider, exceptionTranslation);
this.executor = executor;
@@ -94,7 +95,7 @@ public class ClusterCommandExecutor implements DisposableBean {
* Run {@link ClusterCommandCallback} on a random node.
*
* @param cmd must not be {@literal null}.
* @return
* @return never {@literal null}.
*/
public <T> NodeResult<T> executeCommandOnArbitraryNode(ClusterCommandCallback<?, T> cmd) {
@@ -325,6 +326,7 @@ public class ClusterCommandExecutor implements DisposableBean {
return this.topologyProvider.getTopology();
}
@Nullable
private DataAccessException convertToDataAccessExeption(Exception e) {
return exceptionTranslationStrategy.translate(e);
}
@@ -455,27 +457,27 @@ public class ClusterCommandExecutor implements DisposableBean {
public static class NodeResult<T> {
private RedisClusterNode node;
private T value;
private @Nullable T value;
private ByteArrayWrapper key;
/**
* Create new {@link NodeResult}.
*
* @param node
* @param value
* @param node must not be {@literal null}.
* @param value can be {@literal null}.
*/
public NodeResult(RedisClusterNode node, T value) {
public NodeResult(RedisClusterNode node, @Nullable T value) {
this(node, value, new byte[] {});
}
/**
* Create new {@link NodeResult}.
*
* @param node
* @param value
* @parm key
* @param node must not be {@literal null}.
* @param value can be {@literal null}.
* @param key must not be {@literal null}.
*/
public NodeResult(RedisClusterNode node, T value, byte[] key) {
public NodeResult(RedisClusterNode node, @Nullable T value, byte[] key) {
this.node = node;
this.value = value;
@@ -488,6 +490,7 @@ public class ClusterCommandExecutor implements DisposableBean {
*
* @return can be {@literal null}.
*/
@Nullable
public T getValue() {
return value;
}
@@ -557,9 +560,10 @@ public class ClusterCommandExecutor implements DisposableBean {
/**
* @param returnValue can be {@literal null}.
* @return
* @return can be {@litearl null}.
*/
public T getFirstNonNullNotEmptyOrDefault(T returnValue) {
@Nullable
public T getFirstNonNullNotEmptyOrDefault(@Nullable T returnValue) {
for (NodeResult<T> nodeResult : nodeResults) {
if (nodeResult.getValue() != null) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-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.
@@ -18,6 +18,7 @@ package org.springframework.data.redis.connection;
import java.util.Properties;
import org.springframework.data.redis.core.types.RedisClientInfo.INFO;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -32,8 +33,8 @@ public class ClusterInfo {
public static enum Info {
STATE("cluster_state"), SLOTS_ASSIGNED("cluster_slots_assigned"), SLOTS_OK("cluster_slots_ok"), SLOTS_PFAIL(
"cluster_slots_pfail"), SLOTS_FAIL("cluster_slots_fail"), KNOWN_NODES("cluster_known_nodes"), SIZE(
"cluster_size"), CURRENT_EPOCH("cluster_current_epoch"), MY_EPOCH("cluster_my_epoch"), MESSAGES_SENT(
"cluster_stats_messages_sent"), MESSAGES_RECEIVED("cluster_stats_messages_received");
"cluster_size"), CURRENT_EPOCH("cluster_current_epoch"), MY_EPOCH("cluster_my_epoch"), MESSAGES_SENT(
"cluster_stats_messages_sent"), MESSAGES_RECEIVED("cluster_stats_messages_received");
String key;
@@ -57,80 +58,90 @@ public class ClusterInfo {
/**
* @see Info#STATE
* @return
* @return {@literal null} if no entry found for requested {@link Info#STATE}.
*/
@Nullable
public String getState() {
return get(Info.STATE);
}
/**
* @see Info#SLOTS_ASSIGNED
* @return
* @return {@literal null} if no entry found for requested {@link Info#SLOTS_ASSIGNED}.
*/
@Nullable
public Long getSlotsAssigned() {
return getLongValueOf(Info.SLOTS_ASSIGNED);
}
/**
* @see Info#SLOTS_OK
* @return
* @return {@literal null} if no entry found for requested {@link Info#SLOTS_OK}.
*/
@Nullable
public Long getSlotsOk() {
return getLongValueOf(Info.SLOTS_OK);
}
/**
* @see Info#SLOTS_PFAIL
* @return
* @return {@literal null} if no entry found for requested {@link Info#SLOTS_PFAIL}.
*/
@Nullable
public Long getSlotsPfail() {
return getLongValueOf(Info.SLOTS_PFAIL);
}
/**
* @see Info#SLOTS_FAIL
* @return
* @return {@literal null} if no entry found for requested {@link Info#SLOTS_FAIL}.
*/
@Nullable
public Long getSlotsFail() {
return getLongValueOf(Info.SLOTS_FAIL);
}
/**
* @see Info#KNOWN_NODES
* @return
* @return {@literal null} if no entry found for requested {@link Info#KNOWN_NODES}.
*/
@Nullable
public Long getKnownNodes() {
return getLongValueOf(Info.KNOWN_NODES);
}
/**
* @see Info#SIZE
* @return
* @return {@literal null} if no entry found for requested {@link Info#SIZE}.
*/
@Nullable
public Long getClusterSize() {
return getLongValueOf(Info.SIZE);
}
/**
* @see Info#CURRENT_EPOCH
* @return
* @return {@literal null} if no entry found for requested {@link Info#CURRENT_EPOCH}.
*/
@Nullable
public Long getCurrentEpoch() {
return getLongValueOf(Info.CURRENT_EPOCH);
}
/**
* @see Info#MESSAGES_SENT
* @return
* @return {@literal null} if no entry found for requested {@link Info#MESSAGES_SENT}.
*/
@Nullable
public Long getMessagesSent() {
return getLongValueOf(Info.MESSAGES_SENT);
}
/**
* @see Info#MESSAGES_RECEIVED
* @return
* @return {@literal null} if no entry found for requested {@link Info#MESSAGES_RECEIVED}.
*/
@Nullable
public Long getMessagesReceived() {
return getLongValueOf(Info.MESSAGES_RECEIVED);
}
@@ -139,6 +150,7 @@ public class ClusterInfo {
* @param info must not be null
* @return {@literal null} if no entry found for requested {@link INFO}.
*/
@Nullable
public String get(Info info) {
Assert.notNull(info, "Cannot retrieve cluster information for 'null'.");
@@ -149,12 +161,14 @@ public class ClusterInfo {
* @param key must not be {@literal null} or {@literal empty}.
* @return {@literal null} if no entry found for requested {@code key}.
*/
@Nullable
public String get(String key) {
Assert.hasText(key, "Cannot get cluster information for 'empty' / 'null' key.");
return this.clusterProperties.getProperty(key);
}
@Nullable
private Long getLongValueOf(Info info) {
String value = get(info);

View File

@@ -28,7 +28,8 @@ public interface ClusterNodeResourceProvider {
* Get the client resource for the given node.
*
* @param node must not be {@literal null}.
* @return
* @return never {@literal null}.
* @throws org.springframework.dao.DataAccessResourceFailureException if node is not known to the cluster.
*/
<S> S getResourceForSpecificNode(RedisClusterNode node);

View File

@@ -20,6 +20,7 @@ import java.util.LinkedHashSet;
import java.util.Set;
import org.springframework.data.redis.ClusterStateFailureException;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -39,7 +40,7 @@ public class ClusterTopology {
*
* @param nodes can be {@literal null}.
*/
public ClusterTopology(Set<RedisClusterNode> nodes) {
public ClusterTopology(@Nullable Set<RedisClusterNode> nodes) {
this.nodes = nodes != null ? nodes : Collections.emptySet();
}
@@ -153,7 +154,7 @@ public class ClusterTopology {
public RedisClusterNode lookup(String host, int port) {
for (RedisClusterNode node : nodes) {
if (host.equals(node.getHost()) && port == node.getPort()) {
if (host.equals(node.getHost()) && (node.getPort() != null && port == node.getPort())) {
return node;
}
}
@@ -199,7 +200,7 @@ public class ClusterTopology {
return node;
}
if (StringUtils.hasText(node.getHost())) {
if (StringUtils.hasText(node.getHost()) && node.getPort() != null) {
return lookup(node.getHost(), node.getPort());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-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.
@@ -17,7 +17,7 @@ package org.springframework.data.redis.connection;
/**
* {@link ClusterTopologyProvider} manages the current cluster topology and makes sure to refresh cluster information.
*
*
* @author Christoph Strobl
* @since 1.7
*/
@@ -25,7 +25,7 @@ public interface ClusterTopologyProvider {
/**
* Get the current known {@link ClusterTopology}.
*
*
* @return never {@null}.
*/
ClusterTopology getTopology();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2013 the original author or authors.
* 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.
@@ -15,31 +15,44 @@
*/
package org.springframework.data.redis.connection;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Default message implementation.
*
* @author Costin Leau
* @author Christoph Strobl
*/
public class DefaultMessage implements Message {
private final byte[] channel;
private final byte[] body;
private String toString;
private @Nullable String toString;
public DefaultMessage(byte[] channel, byte[] body) {
Assert.notNull(channel, "Channel must not be null!");
Assert.notNull(body, "Body must not be null!");
this.body = body;
this.channel = channel;
}
/**
* @return
*/
public byte[] getChannel() {
return (channel != null ? channel.clone() : null);
return channel.clone();
}
public byte[] getBody() {
return (body != null ? body.clone() : null);
return body.clone();
}
@Override
public String toString() {
if (toString == null) {
toString = new String(body);
}

View File

@@ -48,6 +48,7 @@ import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.core.types.RedisClientInfo;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -3242,8 +3243,7 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
@Override
public Cursor<Entry<String, String>> hScan(String key, ScanOptions options) {
return new ConvertingCursor<>(
this.delegate.hScan(this.serialize(key), options),
return new ConvertingCursor<>(this.delegate.hScan(this.serialize(key), options),
source -> new Entry<String, String>() {
@Override
@@ -3278,8 +3278,7 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
*/
@Override
public Cursor<StringTuple> zScan(String key, ScanOptions options) {
return new ConvertingCursor<>(delegate.zScan(this.serialize(key), options),
new TupleConverter());
return new ConvertingCursor<>(delegate.zScan(this.serialize(key), options), new TupleConverter());
}
/*
@@ -3440,7 +3439,7 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
* @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) {
public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option) {
delegate.migrate(key, target, dbIndex, option);
}
@@ -3449,7 +3448,7 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
* @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) {
public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option, long timeout) {
delegate.migrate(key, target, dbIndex, option, timeout);
}
@@ -3467,10 +3466,13 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
private <T> T convertAndReturn(Object value, Converter converter) {
if (isFutureConversion()) {
addResultConverter(converter);
return null;
}
return ObjectUtils.nullSafeEquals(converter, identityConverter) ? (T) value : (T) converter.convert(value);
return value == null ? null : ObjectUtils.nullSafeEquals(converter, identityConverter) ? (T) value : (T) converter.convert(value);
}
private void addResultConverter(Converter<?, ?> converter) {
@@ -3497,7 +3499,9 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
}
List<Object> convertedResults = new ArrayList<>(results.size());
for (Object result : results) {
convertedResults.add(converters.remove().convert(result));
Converter converter = converters.remove();
convertedResults.add(result == null ? null : converter.convert(result));
}
return convertedResults;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2013 the original author or authors.
* 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.
@@ -21,8 +21,9 @@ import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
/**
* Default implementation for {@link Tuple} interface.
*
*
* @author Costin Leau
* @author Christoph Strobl
*/
public class DefaultTuple implements Tuple {
@@ -36,14 +37,23 @@ public class DefaultTuple implements Tuple {
* @param score
*/
public DefaultTuple(byte[] value, Double score) {
this.score = score;
this.value = value;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands.Tuple#getScore()
*/
public Double getScore() {
return score;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands.Tuple#getValue()
*/
public byte[] getValue() {
return value;
}

View File

@@ -31,6 +31,7 @@ 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;
import org.springframework.lang.Nullable;
/**
* {@link DefaultedRedisConnection} provides method delegates to {@code Redis*Command} interfaces accessible via
@@ -1184,14 +1185,14 @@ public interface DefaultedRedisConnection extends RedisConnection {
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
@Override
@Deprecated
default void migrate(byte[] key, RedisNode target, int dbIndex, MigrateOption option) {
default void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable 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) {
default void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option, long timeout) {
serverCommands().migrate(key, target, dbIndex, option, timeout);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-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.
@@ -16,11 +16,13 @@
package org.springframework.data.redis.connection;
import org.springframework.core.convert.converter.Converter;
import org.springframework.lang.Nullable;
/**
* The result of an asynchronous operation
*
* @author Jennifer Hickey
* @author Christoph Strobl
* @param <T> The data type of the object that holds the future result (usually of type Future)
*/
abstract public class FutureResult<T> {
@@ -29,7 +31,8 @@ abstract public class FutureResult<T> {
protected boolean status = false;
@SuppressWarnings("rawtypes") protected Converter converter;
@SuppressWarnings("rawtypes") //
protected @Nullable Converter converter;
public FutureResult(T resultHolder) {
this.resultHolder = resultHolder;
@@ -48,18 +51,22 @@ abstract public class FutureResult<T> {
/**
* Converts the given result if a converter is specified, else returns the result
*
* @param result The result to convert
* @return The converted result
* @param result The result to convert. Can be {@literal null}.
* @return The converted result or {@literal null}.
*/
@SuppressWarnings("unchecked")
public Object convert(Object result) {
if (converter != null) {
return converter.convert(result);
@Nullable
public Object convert(@Nullable Object result) {
if (result == null) {
return null;
}
return result;
return (converter != null) ? converter.convert(result) : result;
}
@SuppressWarnings("rawtypes")
@Nullable
public Converter getConverter() {
return converter;
}
@@ -81,7 +88,8 @@ abstract public class FutureResult<T> {
}
/**
* @return The result of the operation
* @return The result of the operation. Can be {@literal null}.
*/
@Nullable
abstract public Object get();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2013 the original author or authors.
* 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.
@@ -17,24 +17,27 @@ package org.springframework.data.redis.connection;
import java.io.Serializable;
import org.springframework.lang.Nullable;
/**
* Class encapsulating a Redis message body and its properties.
*
*
* @author Costin Leau
* @author Christoph Strobl
*/
public interface Message extends Serializable {
/**
* Returns the body (or the payload) of the message.
*
* @return message body
*
* @return message body. Never {@literal null}.
*/
byte[] getBody();
/**
* Returns the channel associated with the message.
*
* @return message channel.
*
* @return message channel. Never {@literal null}.
*/
byte[] getChannel();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2013 the original author or authors.
* 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.
@@ -15,18 +15,21 @@
*/
package org.springframework.data.redis.connection;
import org.springframework.lang.Nullable;
/**
* Listener of messages published in Redis.
*
*
* @author Costin Leau
* @author Christoph Strobl
*/
public interface MessageListener {
/**
* Callback for processing received objects through Redis.
*
* @param message message
* @param pattern pattern matching the channel (if specified) - can be null
*
* @param message message must not be {@literal null}.
* @param pattern pattern matching the channel (if specified) - can be {@literal null}.
*/
void onMessage(Message message, byte[] pattern);
void onMessage(Message message, @Nullable byte[] pattern);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-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,11 +15,17 @@
*/
package org.springframework.data.redis.connection;
import org.springframework.lang.Nullable;
/**
* @author Christoph Strobl
* @since 1.4
*/
public interface NamedNode {
/**
* @return the node name. Can be {@literal null}.
*/
@Nullable
String getName();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-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.
@@ -16,27 +16,30 @@
package org.springframework.data.redis.connection;
import org.springframework.core.NestedRuntimeException;
import org.springframework.lang.Nullable;
/**
* Exception thrown when there are issues with a resource pool
*
* @author Jennifer Hickey
* @author Christoph Strobl
*/
@SuppressWarnings("serial")
public class PoolException extends NestedRuntimeException {
/**
* Constructs a new <code>PoolException</code> instance.
*
*
* @param msg
* @param cause
*/
public PoolException(String msg, Throwable cause) {
public PoolException(@Nullable String msg, @Nullable Throwable cause) {
super(msg, cause);
}
/**
* Constructs a new <code>PoolException</code> instance.
*
*
* @param msg
*/
public PoolException(String msg) {

View File

@@ -41,6 +41,7 @@ import org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit;
import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation;
import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs;
import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs.Flag;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -62,7 +63,7 @@ public interface ReactiveGeoCommands {
private final List<GeoLocation<ByteBuffer>> geoLocations;
private GeoAddCommand(ByteBuffer key, List<GeoLocation<ByteBuffer>> geoLocations) {
private GeoAddCommand(@Nullable ByteBuffer key, List<GeoLocation<ByteBuffer>> geoLocations) {
super(key);
@@ -184,7 +185,8 @@ public interface ReactiveGeoCommands {
private final ByteBuffer to;
private final Metric metric;
private GeoDistCommand(ByteBuffer key, ByteBuffer from, ByteBuffer to, Metric metric) {
private GeoDistCommand(@Nullable ByteBuffer key, @Nullable ByteBuffer from, @Nullable ByteBuffer to,
Metric metric) {
super(key);
@@ -274,21 +276,23 @@ public interface ReactiveGeoCommands {
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public ByteBuffer getFrom() {
return from;
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public ByteBuffer getTo() {
return to;
}
/**
* @return
* @return never {@literal null}.
*/
public Optional<Metric> getMetric() {
return Optional.ofNullable(metric);
@@ -305,7 +309,7 @@ public interface ReactiveGeoCommands {
* @see <a href="http://redis.io/commands/geodist">Redis Documentation: GEODIST</a>
*/
default Mono<Distance> geoDist(ByteBuffer key, ByteBuffer from, ByteBuffer to) {
return geoDist(key, from, to, null);
return geoDist(key, from, to, DistanceUnit.METERS);
}
/**
@@ -314,7 +318,7 @@ public interface ReactiveGeoCommands {
* @param key must not be {@literal null}.
* @param from must not be {@literal null}.
* @param to must not be {@literal null}.
* @param metric can be {@literal null} and defaults to {@link DistanceUnit#METERS}.
* @param metric must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/geodist">Redis Documentation: GEODIST</a>
*/
@@ -323,6 +327,7 @@ public interface ReactiveGeoCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(from, "From must not be null!");
Assert.notNull(to, "To must not be null!");
Assert.notNull(metric, "Metric must not be null!");
return geoDist(Mono.just(GeoDistCommand.units(metric).between(from).and(to).forKey(key))) //
.next() //
@@ -348,7 +353,7 @@ public interface ReactiveGeoCommands {
private final List<ByteBuffer> members;
private GeoHashCommand(ByteBuffer key, List<ByteBuffer> members) {
private GeoHashCommand(@Nullable ByteBuffer key, List<ByteBuffer> members) {
super(key);
@@ -395,7 +400,7 @@ public interface ReactiveGeoCommands {
}
/**
* @return
* @return never {@literal null}.
*/
public List<ByteBuffer> getMembers() {
return members;
@@ -455,7 +460,7 @@ public interface ReactiveGeoCommands {
private final List<ByteBuffer> members;
private GeoPosCommand(ByteBuffer key, List<ByteBuffer> members) {
private GeoPosCommand(@Nullable ByteBuffer key, List<ByteBuffer> members) {
super(key);
@@ -502,7 +507,7 @@ public interface ReactiveGeoCommands {
}
/**
* @return
* @return never {@literal null}.
*/
public List<ByteBuffer> getMembers() {
return members;
@@ -559,19 +564,19 @@ public interface ReactiveGeoCommands {
class GeoRadiusCommand extends KeyCommand {
private final Distance distance;
private final Point point;
private final @Nullable Point point;
private final GeoRadiusCommandArgs args;
private final ByteBuffer store;
private final ByteBuffer storeDist;
private final @Nullable ByteBuffer store;
private final @Nullable ByteBuffer storeDist;
private GeoRadiusCommand(ByteBuffer key, Point point, Distance distance, GeoRadiusCommandArgs args,
ByteBuffer store, ByteBuffer storeDist) {
private GeoRadiusCommand(@Nullable ByteBuffer key, @Nullable Point point, Distance distance,
GeoRadiusCommandArgs args, @Nullable ByteBuffer store, @Nullable ByteBuffer storeDist) {
super(key);
this.distance = distance;
this.point = point;
this.args = args == null ? GeoRadiusCommandArgs.newGeoRadiusArgs() : args;
this.args = args;
this.store = store;
this.storeDist = storeDist;
}
@@ -586,7 +591,7 @@ public interface ReactiveGeoCommands {
Assert.notNull(distance, "Distance must not be null!");
return new GeoRadiusCommand(null, null, distance, null, null, null);
return new GeoRadiusCommand(null, null, distance, GeoRadiusCommandArgs.newGeoRadiusArgs(), null, null);
}
/**
@@ -694,11 +699,14 @@ public interface ReactiveGeoCommands {
* Applies command {@link GeoRadiusCommandArgs}. Constructs a new command instance with all previously configured
* properties.
*
* @param args can be {@literal null}.
* @param args must not be {@literal null}.
* @return a new {@link GeoRadiusCommand} with {@link GeoRadiusCommandArgs} applied.
*/
public GeoRadiusCommand withArgs(GeoRadiusCommandArgs args) {
return new GeoRadiusCommand(getKey(), point, distance, args, store, storeDist);
Assert.notNull(args, "Args must not be null!");
return new GeoRadiusCommand(getKey(), point, distance,
args == null ? GeoRadiusCommandArgs.newGeoRadiusArgs() : args, store, storeDist);
}
/**
@@ -766,74 +774,79 @@ public interface ReactiveGeoCommands {
/**
* <b>NOTE:</b> STORE option is not compatible with WITHDIST, WITHHASH and WITHCOORDS options.
*
* @param key
* @return
* @param key must not be {@literal null}.
* @return new instance of {@link GeoRadiusCommand}.
*/
public GeoRadiusCommand storeAt(ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return new GeoRadiusCommand(getKey(), point, distance, args, key, storeDist);
}
/**
* <b>NOTE:</b> STOREDIST option is not compatible with WITHDIST, WITHHASH and WITHCOORDS options.
*
* @param key
* @return
* @param key must not be {@literal null}.
* @return new instance of {@link GeoRadiusCommand}.
*/
public GeoRadiusCommand storeDistAt(ByteBuffer key) {
public GeoRadiusCommand storeDistAt(@Nullable ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return new GeoRadiusCommand(getKey(), point, distance, args, store, key);
}
/**
* @return
* @return never {@literal null}.
*/
public Optional<Direction> getDirection() {
return Optional.ofNullable(args.getSortDirection());
}
/**
* @return
* @return never {@literal null}.
*/
public Distance getDistance() {
return distance;
}
/**
* @return
* @return never {@literal null}.
*/
public Set<Flag> getFlags() {
return args.getFlags();
}
/**
* @return
* @return never {@literal null}.
*/
public Optional<Long> getLimit() {
return Optional.ofNullable(args.getLimit());
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public Point getPoint() {
return point;
}
/**
* @return
* @return never {@literal null}.
*/
public Optional<ByteBuffer> getStore() {
return Optional.ofNullable(store);
}
/**
* @return
* @return never {@literal null}.
*/
public Optional<ByteBuffer> getStoreDist() {
return Optional.ofNullable(storeDist);
}
/**
* @return
* @return never {@literal null}.
*/
public Optional<GeoRadiusCommandArgs> getArgs() {
return Optional.ofNullable(args);
@@ -858,7 +871,7 @@ public interface ReactiveGeoCommands {
* @see <a href="http://redis.io/commands/georadius">Redis Documentation: GEORADIUS</a>
*/
default Flux<GeoResult<GeoLocation<ByteBuffer>>> geoRadius(ByteBuffer key, Circle circle) {
return geoRadius(key, circle, null);
return geoRadius(key, circle, GeoRadiusCommandArgs.newGeoRadiusArgs());
}
/**
@@ -866,7 +879,7 @@ public interface ReactiveGeoCommands {
*
* @param key must not be {@literal null}.
* @param circle must not be {@literal null}.
* @param geoRadiusArgs can be {@literal null}.
* @param geoRadiusArgs must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/georadius">Redis Documentation: GEORADIUS</a>
*/
@@ -875,6 +888,7 @@ public interface ReactiveGeoCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(circle, "Circle must not be null!");
Assert.notNull(geoRadiusArgs, "GeoRadiusArgs must not be null!");
return geoRadius(Mono.just(GeoRadiusCommand.within(circle).withArgs(geoRadiusArgs).forKey(key)))
.flatMap(CommandResponse::getOutput);
@@ -899,19 +913,19 @@ public interface ReactiveGeoCommands {
class GeoRadiusByMemberCommand extends KeyCommand {
private final Distance distance;
private final ByteBuffer member;
private final @Nullable ByteBuffer member;
private final GeoRadiusCommandArgs args;
private final ByteBuffer store;
private final ByteBuffer storeDist;
private final @Nullable ByteBuffer store;
private final @Nullable ByteBuffer storeDist;
private GeoRadiusByMemberCommand(ByteBuffer key, ByteBuffer member, Distance distance, GeoRadiusCommandArgs args,
ByteBuffer store, ByteBuffer storeDist) {
private GeoRadiusByMemberCommand(@Nullable ByteBuffer key, @Nullable ByteBuffer member, Distance distance,
GeoRadiusCommandArgs args, @Nullable ByteBuffer store, @Nullable ByteBuffer storeDist) {
super(key);
this.distance = distance;
this.member = member;
this.args = args == null ? GeoRadiusCommandArgs.newGeoRadiusArgs() : args;
this.args = args;
this.store = store;
this.storeDist = storeDist;
}
@@ -1020,11 +1034,12 @@ public interface ReactiveGeoCommands {
* Applies command {@link GeoRadiusCommandArgs}. Constructs a new command instance with all previously configured
* properties.
*
* @param args can be {@literal null}.
* @param args must not be {@literal null}.
* @return a new {@link GeoRadiusByMemberCommand} with {@link GeoRadiusCommandArgs} applied.
*/
public GeoRadiusByMemberCommand withArgs(GeoRadiusCommandArgs args) {
Assert.notNull(args, "Args must not be null!");
return new GeoRadiusByMemberCommand(getKey(), member, distance, args, store, storeDist);
}
@@ -1084,80 +1099,87 @@ public interface ReactiveGeoCommands {
* @return a new {@link GeoRadiusByMemberCommand} with {@literal key} applied.
*/
public GeoRadiusByMemberCommand forKey(ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return new GeoRadiusByMemberCommand(key, member, distance, args, store, storeDist);
}
/**
* <b>NOTE:</b> STORE option is not compatible with WITHDIST, WITHHASH and WITHCOORDS options.
*
* @param key
* @return
* @param key must not be {@literal null}.
* @return new instance of {@link GeoRadiusByMemberCommand}.
*/
public GeoRadiusByMemberCommand storeAt(ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return new GeoRadiusByMemberCommand(getKey(), member, distance, args, key, storeDist);
}
/**
* <b>NOTE:</b> STOREDIST option is not compatible with WITHDIST, WITHHASH and WITHCOORDS options.
*
* @param key
* @return
* @param key must not be {@literal null}.
* @return new instance of {@link GeoRadiusByMemberCommand}.
*/
public GeoRadiusByMemberCommand storeDistAt(ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return new GeoRadiusByMemberCommand(getKey(), member, distance, args, store, key);
}
/**
* @return
* @return never {@literal null}.
*/
public Optional<Direction> getDirection() {
return Optional.ofNullable(args.getSortDirection());
}
/**
* @return
* @return never {@literal null}.
*/
public Distance getDistance() {
return distance;
}
/**
* @return
* @return never {@literal null}.
*/
public Set<Flag> getFlags() {
return args.getFlags();
}
/**
* @return
* @return never {@literal null}.
*/
public Optional<Long> getLimit() {
return Optional.ofNullable(args.getLimit());
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public ByteBuffer getMember() {
return member;
}
/**
* @return
* @return never {@literal null}.
*/
public Optional<ByteBuffer> getStore() {
return Optional.ofNullable(store);
}
/**
* @return
* @return never {@literal null}.
*/
public Optional<ByteBuffer> getStoreDist() {
return Optional.ofNullable(storeDist);
}
/**
* @return
* @return never {@literal null}.
*/
public Optional<GeoRadiusCommandArgs> getArgs() {
return Optional.ofNullable(args);
@@ -1183,7 +1205,7 @@ public interface ReactiveGeoCommands {
*/
default Flux<GeoResult<GeoLocation<ByteBuffer>>> geoRadiusByMember(ByteBuffer key, ByteBuffer member,
Distance distance) {
return geoRadiusByMember(key, member, distance, null);
return geoRadiusByMember(key, member, distance, GeoRadiusCommandArgs.newGeoRadiusArgs());
}
/**
@@ -1191,7 +1213,7 @@ public interface ReactiveGeoCommands {
*
* @param key must not be {@literal null}.
* @param member must not be {@literal null}.
* @param geoRadiusArgs can be {@literal null}.
* @param geoRadiusArgs must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/georadiusbymember">Redis Documentation: GEORADIUSBYMEMBER</a>
*/
@@ -1201,6 +1223,7 @@ public interface ReactiveGeoCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(member, "Member must not be null!");
Assert.notNull(distance, "Distance must not be null!");
Assert.notNull(geoRadiusArgs, "GeoRadiusArgs must not be null!");
return geoRadiusByMember(
Mono.just(GeoRadiusByMemberCommand.within(distance).from(member).forKey(key).withArgs(geoRadiusArgs)))

View File

@@ -33,6 +33,7 @@ import org.springframework.data.redis.connection.ReactiveRedisConnection.Command
import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyCommand;
import org.springframework.data.redis.connection.ReactiveRedisConnection.MultiValueResponse;
import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -56,7 +57,7 @@ public interface ReactiveHashCommands {
private final Map<ByteBuffer, ByteBuffer> fieldValueMap;
private final boolean upsert;
private HSetCommand(ByteBuffer key, Map<ByteBuffer, ByteBuffer> keyValueMap, boolean upsert) {
private HSetCommand(@Nullable ByteBuffer key, Map<ByteBuffer, ByteBuffer> keyValueMap, boolean upsert) {
super(key);
@@ -137,7 +138,7 @@ public interface ReactiveHashCommands {
}
/**
* @return
* @return never {@literal null}.
*/
public Map<ByteBuffer, ByteBuffer> getFieldValueMap() {
return fieldValueMap;
@@ -217,7 +218,7 @@ public interface ReactiveHashCommands {
private List<ByteBuffer> fields;
private HGetCommand(ByteBuffer key, List<ByteBuffer> fields) {
private HGetCommand(@Nullable ByteBuffer key, List<ByteBuffer> fields) {
super(key);
@@ -264,7 +265,7 @@ public interface ReactiveHashCommands {
}
/**
* @return
* @return never {@literal null}.
*/
public List<ByteBuffer> getFields() {
return fields;
@@ -318,7 +319,7 @@ public interface ReactiveHashCommands {
private final ByteBuffer field;
private HExistsCommand(ByteBuffer key, ByteBuffer field) {
private HExistsCommand(@Nullable ByteBuffer key, ByteBuffer field) {
super(key);
@@ -352,7 +353,7 @@ public interface ReactiveHashCommands {
}
/**
* @return
* @return never {@literal null}.
*/
public ByteBuffer getField() {
return field;
@@ -392,7 +393,7 @@ public interface ReactiveHashCommands {
private final List<ByteBuffer> fields;
private HDelCommand(ByteBuffer key, List<ByteBuffer> fields) {
private HDelCommand(@Nullable ByteBuffer key, List<ByteBuffer> fields) {
super(key);
@@ -439,7 +440,7 @@ public interface ReactiveHashCommands {
}
/**
* @return
* @return never {@literal null}.
*/
public List<ByteBuffer> getFields() {
return fields;

View File

@@ -29,6 +29,7 @@ import org.springframework.data.redis.connection.ReactiveRedisConnection.Command
import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyCommand;
import org.springframework.data.redis.connection.ReactiveRedisConnection.MultiValueResponse;
import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -125,9 +126,9 @@ public interface ReactiveKeyCommands {
*/
class RenameCommand extends KeyCommand {
private ByteBuffer newName;
private @Nullable ByteBuffer newName;
private RenameCommand(ByteBuffer key, ByteBuffer newName) {
private RenameCommand(ByteBuffer key, @Nullable ByteBuffer newName) {
super(key);
@@ -161,8 +162,9 @@ public interface ReactiveKeyCommands {
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public ByteBuffer getNewName() {
return newName;
}
@@ -271,9 +273,9 @@ public interface ReactiveKeyCommands {
*/
class ExpireCommand extends KeyCommand {
private Duration timeout;
private @Nullable Duration timeout;
private ExpireCommand(ByteBuffer key, Duration timeout) {
private ExpireCommand(ByteBuffer key, @Nullable Duration timeout) {
super(key);
@@ -307,8 +309,9 @@ public interface ReactiveKeyCommands {
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public Duration getTimeout() {
return timeout;
}
@@ -375,9 +378,9 @@ public interface ReactiveKeyCommands {
*/
class ExpireAtCommand extends KeyCommand {
private Instant expireAt;
private @Nullable Instant expireAt;
private ExpireAtCommand(ByteBuffer key, Instant expireAt) {
private ExpireAtCommand(ByteBuffer key, @Nullable Instant expireAt) {
super(key);
@@ -411,8 +414,9 @@ public interface ReactiveKeyCommands {
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public Instant getExpireAt() {
return expireAt;
}
@@ -547,9 +551,9 @@ public interface ReactiveKeyCommands {
*/
class MoveCommand extends KeyCommand {
private Integer database;
private @Nullable Integer database;
private MoveCommand(ByteBuffer key, Integer database) {
private MoveCommand(ByteBuffer key, @Nullable Integer database) {
super(key);
@@ -581,8 +585,9 @@ public interface ReactiveKeyCommands {
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public Integer getDatabase() {
return database;
}

View File

@@ -33,6 +33,7 @@ import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyComm
import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse;
import org.springframework.data.redis.connection.ReactiveRedisConnection.RangeCommand;
import org.springframework.data.redis.connection.RedisListCommands.Position;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -65,7 +66,7 @@ public interface ReactiveListCommands {
private boolean upsert;
private Direction direction;
private PushCommand(ByteBuffer key, List<ByteBuffer> values, Direction direction, boolean upsert) {
private PushCommand(@Nullable ByteBuffer key, List<ByteBuffer> values, Direction direction, boolean upsert) {
super(key);
@@ -80,7 +81,7 @@ public interface ReactiveListCommands {
* @return a new {@link PushCommand} for right push ({@literal RPUSH}).
*/
public static PushCommand right() {
return new PushCommand(null, null, Direction.RIGHT, true);
return new PushCommand(null, Collections.emptyList(), Direction.RIGHT, true);
}
/**
@@ -89,7 +90,7 @@ public interface ReactiveListCommands {
* @return a new {@link PushCommand} for left push ({@literal LPUSH}).
*/
public static PushCommand left() {
return new PushCommand(null, null, Direction.LEFT, true);
return new PushCommand(null, Collections.emptyList(), Direction.LEFT, true);
}
/**
@@ -141,7 +142,7 @@ public interface ReactiveListCommands {
}
/**
* @return
* @return never {@literal null}.
*/
public List<ByteBuffer> getValues() {
return values;
@@ -155,7 +156,7 @@ public interface ReactiveListCommands {
}
/**
* @return
* @return never {@literal null}.
*/
public Direction getDirection() {
return direction;
@@ -321,7 +322,7 @@ public interface ReactiveListCommands {
private final Long index;
private LIndexCommand(ByteBuffer key, Long index) {
private LIndexCommand(@Nullable ByteBuffer key, Long index) {
super(key);
this.index = index;
@@ -390,11 +391,12 @@ public interface ReactiveListCommands {
*/
class LInsertCommand extends KeyCommand {
private final Position position;
private final ByteBuffer pivot;
private final @Nullable Position position;
private final @Nullable ByteBuffer pivot;
private final ByteBuffer value;
private LInsertCommand(ByteBuffer key, Position position, ByteBuffer pivot, ByteBuffer value) {
private LInsertCommand(@Nullable ByteBuffer key, @Nullable Position position, @Nullable ByteBuffer pivot,
ByteBuffer value) {
super(key);
@@ -456,22 +458,24 @@ public interface ReactiveListCommands {
}
/**
* @return
* @return never {@literal null}.
*/
public ByteBuffer getValue() {
return value;
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public Position getPosition() {
return position;
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public ByteBuffer getPivot() {
return pivot;
}
@@ -520,9 +524,9 @@ public interface ReactiveListCommands {
class LSetCommand extends KeyCommand {
private final Long index;
private final ByteBuffer value;
private final @Nullable ByteBuffer value;
private LSetCommand(ByteBuffer key, Long index, ByteBuffer value) {
private LSetCommand(@Nullable ByteBuffer key, Long index, @Nullable ByteBuffer value) {
super(key);
this.index = index;
@@ -566,14 +570,15 @@ public interface ReactiveListCommands {
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public ByteBuffer getValue() {
return value;
}
/**
* @return
* @return never {@literal null}.
*/
public Long getIndex() {
return index;
@@ -615,9 +620,9 @@ public interface ReactiveListCommands {
class LRemCommand extends KeyCommand {
private final Long count;
private final ByteBuffer value;
private final @Nullable ByteBuffer value;
private LRemCommand(ByteBuffer key, Long count, ByteBuffer value) {
private LRemCommand(@Nullable ByteBuffer key, Long count, @Nullable ByteBuffer value) {
super(key);
@@ -681,15 +686,16 @@ public interface ReactiveListCommands {
}
/**
* @return
* @return never {@literal null}.
*/
public Long getCount() {
return count;
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public ByteBuffer getValue() {
return value;
}
@@ -751,7 +757,7 @@ public interface ReactiveListCommands {
private final Direction direction;
private PopCommand(ByteBuffer key, Direction direction) {
private PopCommand(@Nullable ByteBuffer key, Direction direction) {
super(key);
@@ -790,7 +796,7 @@ public interface ReactiveListCommands {
}
/**
* @return
* @return never {@literal null}.
*/
public Direction getDirection() {
return direction;
@@ -859,7 +865,7 @@ public interface ReactiveListCommands {
* @return a new {@link BPopCommand} for right push ({@literal BRPOP}).
*/
public static BPopCommand right() {
return new BPopCommand(null, Duration.ZERO, Direction.RIGHT);
return new BPopCommand(Collections.emptyList(), Duration.ZERO, Direction.RIGHT);
}
/**
@@ -868,7 +874,7 @@ public interface ReactiveListCommands {
* @return a new {@link BPopCommand} for right push ({@literal BLPOP}).
*/
public static BPopCommand left() {
return new BPopCommand(null, Duration.ZERO, Direction.LEFT);
return new BPopCommand(Collections.emptyList(), Duration.ZERO, Direction.LEFT);
}
/**
@@ -959,7 +965,6 @@ public interface ReactiveListCommands {
* @author Christoph Strobl
*/
class PopResponse extends CommandResponse<BPopCommand, PopResult> {
public PopResponse(BPopCommand input, PopResult output) {
super(input, output);
}
@@ -1019,9 +1024,9 @@ public interface ReactiveListCommands {
*/
class RPopLPushCommand extends KeyCommand {
private final ByteBuffer destination;
private final @Nullable ByteBuffer destination;
private RPopLPushCommand(ByteBuffer key, ByteBuffer destination) {
private RPopLPushCommand(ByteBuffer key, @Nullable ByteBuffer destination) {
super(key);
this.destination = destination;
@@ -1055,8 +1060,9 @@ public interface ReactiveListCommands {
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public ByteBuffer getDestination() {
return destination;
}
@@ -1098,10 +1104,10 @@ public interface ReactiveListCommands {
*/
class BRPopLPushCommand extends KeyCommand {
private final ByteBuffer destination;
private final @Nullable ByteBuffer destination;
private final Duration timeout;
private BRPopLPushCommand(ByteBuffer key, ByteBuffer destination, Duration timeout) {
private BRPopLPushCommand(ByteBuffer key, @Nullable ByteBuffer destination, Duration timeout) {
super(key);
@@ -1119,7 +1125,7 @@ public interface ReactiveListCommands {
Assert.notNull(sourceKey, "Source key must not be null!");
return new BRPopLPushCommand(sourceKey, null, null);
return new BRPopLPushCommand(sourceKey, null, Duration.ZERO);
}
/**
@@ -1150,14 +1156,15 @@ public interface ReactiveListCommands {
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public ByteBuffer getDestination() {
return destination;
}
/**
* @return
* @return never {@literal null}.
*/
public Duration getTimeout() {
return timeout;

View File

@@ -23,6 +23,7 @@ import java.nio.ByteBuffer;
import org.reactivestreams.Publisher;
import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyCommand;
import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -65,9 +66,10 @@ public interface ReactiveNumberCommands {
*/
class IncrByCommand<T extends Number> extends KeyCommand {
private T value;
private @Nullable T value;
private IncrByCommand(ByteBuffer key, @Nullable T value) {
private IncrByCommand(ByteBuffer key, T value) {
super(key);
this.value = value;
}
@@ -100,8 +102,9 @@ public interface ReactiveNumberCommands {
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public T getValue() {
return value;
}
@@ -141,9 +144,9 @@ public interface ReactiveNumberCommands {
*/
class DecrByCommand<T extends Number> extends KeyCommand {
private T value;
private @Nullable T value;
private DecrByCommand(ByteBuffer key, T value) {
private DecrByCommand(ByteBuffer key, @Nullable T value) {
super(key);
this.value = value;
}
@@ -176,8 +179,9 @@ public interface ReactiveNumberCommands {
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public T getValue() {
return value;
}
@@ -239,9 +243,9 @@ public interface ReactiveNumberCommands {
class HIncrByCommand<T extends Number> extends KeyCommand {
private final ByteBuffer field;
private final T value;
private final @Nullable T value;
private HIncrByCommand(ByteBuffer key, ByteBuffer field, T value) {
private HIncrByCommand(@Nullable ByteBuffer key, ByteBuffer field, @Nullable T value) {
super(key);
@@ -290,14 +294,15 @@ public interface ReactiveNumberCommands {
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public T getValue() {
return value;
}
/**
* @return
* @return never {@literal null}.
*/
public ByteBuffer getField() {
return field;

View File

@@ -24,6 +24,7 @@ import java.util.List;
import org.springframework.data.domain.Range;
import org.springframework.data.domain.Range.Bound;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -148,6 +149,7 @@ public interface ReactiveRedisConnection extends Closeable {
/**
* @return the key related to this command.
*/
@Nullable
ByteBuffer getKey();
/**
@@ -165,18 +167,19 @@ public interface ReactiveRedisConnection extends Closeable {
*/
class KeyCommand implements Command {
private ByteBuffer key;
private @Nullable ByteBuffer key;
/**
* Creates a new {@link KeyCommand} given a {@code key}.
*
* @param key must not be {@literal null}.
* @param key can be {@literal null}.
*/
public KeyCommand(ByteBuffer key) {
public KeyCommand(@Nullable ByteBuffer key) {
this.key = key;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.ReactiveRedisConnection.Command#getKey()
*/
@Override
@@ -196,12 +199,12 @@ public interface ReactiveRedisConnection extends Closeable {
* Creates a new {@link RangeCommand} given a {@code key} and {@link Range}.
*
* @param key must not be {@literal null}.
* @param range may be {@literal null} if unbounded.
* @param range must not be {@literal null}.
*/
private RangeCommand(ByteBuffer key, Range<Long> range) {
super(key);
this.range = range != null ? range : new Range<>(0L, Long.MAX_VALUE);
this.range = range;
}
/**
@@ -211,7 +214,7 @@ public interface ReactiveRedisConnection extends Closeable {
* @return a new {@link RangeCommand} for {@code key}.
*/
public static RangeCommand key(ByteBuffer key) {
return new RangeCommand(key, null);
return new RangeCommand(key, Range.unbounded());
}
/**
@@ -267,7 +270,7 @@ public interface ReactiveRedisConnection extends Closeable {
class CommandResponse<I, O> {
private final I input;
private final O output;
private final @Nullable O output;
/**
* @return {@literal true} if the response is present. An absent {@link CommandResponse} maps to Redis
@@ -293,7 +296,7 @@ public interface ReactiveRedisConnection extends Closeable {
*/
class ByteBufferResponse<I> extends CommandResponse<I, ByteBuffer> {
public ByteBufferResponse(I input, ByteBuffer output) {
public ByteBufferResponse(I input, @Nullable ByteBuffer output) {
super(input, output);
}
}

View File

@@ -32,6 +32,7 @@ import org.springframework.data.redis.connection.ReactiveRedisConnection.Command
import org.springframework.data.redis.connection.ReactiveRedisConnection.CommandResponse;
import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyCommand;
import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -53,7 +54,7 @@ public interface ReactiveSetCommands {
private List<ByteBuffer> values;
private SAddCommand(ByteBuffer key, List<ByteBuffer> values) {
private SAddCommand(@Nullable ByteBuffer key, List<ByteBuffer> values) {
super(key);
@@ -157,7 +158,7 @@ public interface ReactiveSetCommands {
private final List<ByteBuffer> values;
private SRemCommand(ByteBuffer key, List<ByteBuffer> values) {
private SRemCommand(@Nullable ByteBuffer key, List<ByteBuffer> values) {
super(key);
@@ -204,7 +205,7 @@ public interface ReactiveSetCommands {
}
/**
* @return
* @return never {@literal null}.
*/
public List<ByteBuffer> getValues() {
return values;
@@ -261,7 +262,7 @@ public interface ReactiveSetCommands {
private final long count;
private SPopCommand(ByteBuffer key, long count) {
private SPopCommand(@Nullable ByteBuffer key, long count) {
super(key);
this.count = count;
@@ -358,10 +359,10 @@ public interface ReactiveSetCommands {
*/
class SMoveCommand extends KeyCommand {
private final ByteBuffer destination;
private final @Nullable ByteBuffer destination;
private final ByteBuffer value;
private SMoveCommand(ByteBuffer key, ByteBuffer destination, ByteBuffer value) {
private SMoveCommand(@Nullable ByteBuffer key, @Nullable ByteBuffer destination, ByteBuffer value) {
super(key);
this.destination = destination;
@@ -409,14 +410,15 @@ public interface ReactiveSetCommands {
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public ByteBuffer getDestination() {
return destination;
}
/**
* @return
* @return never {@literal null}.
*/
public ByteBuffer getValue() {
return value;
@@ -484,7 +486,7 @@ public interface ReactiveSetCommands {
private final ByteBuffer value;
private SIsMemberCommand(ByteBuffer key, ByteBuffer value) {
private SIsMemberCommand(@Nullable ByteBuffer key, ByteBuffer value) {
super(key);
@@ -577,10 +579,12 @@ public interface ReactiveSetCommands {
return new SInterCommand(new ArrayList<>(keys));
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.ReactiveRedisConnection.Command#getKey()
*/
@Override
@Nullable
public ByteBuffer getKey() {
return null;
}
@@ -626,7 +630,7 @@ public interface ReactiveSetCommands {
private final List<ByteBuffer> keys;
private SInterStoreCommand(ByteBuffer key, List<ByteBuffer> keys) {
private SInterStoreCommand(@Nullable ByteBuffer key, List<ByteBuffer> keys) {
super(key);
@@ -721,10 +725,12 @@ public interface ReactiveSetCommands {
return new SUnionCommand(new ArrayList<>(keys));
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.ReactiveRedisConnection.Command#getKey()
*/
@Override
@Nullable
public ByteBuffer getKey() {
return null;
}
@@ -770,7 +776,7 @@ public interface ReactiveSetCommands {
private final List<ByteBuffer> keys;
private SUnionStoreCommand(ByteBuffer key, List<ByteBuffer> keys) {
private SUnionStoreCommand(@Nullable ByteBuffer key, List<ByteBuffer> keys) {
super(key);
@@ -865,10 +871,12 @@ public interface ReactiveSetCommands {
return new SDiffCommand(new ArrayList<>(keys));
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.ReactiveRedisConnection.Command#getKey()
*/
@Override
@Nullable
public ByteBuffer getKey() {
return null;
}
@@ -914,7 +922,7 @@ public interface ReactiveSetCommands {
private final List<ByteBuffer> keys;
private SDiffStoreCommand(ByteBuffer key, List<ByteBuffer> keys) {
private SDiffStoreCommand(@Nullable ByteBuffer key, List<ByteBuffer> keys) {
super(key);
@@ -1013,9 +1021,9 @@ public interface ReactiveSetCommands {
*/
class SRandMembersCommand extends KeyCommand {
private final Long count;
private final @Nullable Long count;
private SRandMembersCommand(ByteBuffer key, Long count) {
private SRandMembersCommand(@Nullable ByteBuffer key, @Nullable Long count) {
super(key);
this.count = count;

View File

@@ -21,6 +21,7 @@ import reactor.core.publisher.Mono;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -38,6 +39,7 @@ import org.springframework.data.redis.connection.ReactiveRedisConnection.RangeCo
import org.springframework.data.redis.connection.RedisStringCommands.BitOperation;
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -57,11 +59,12 @@ public interface ReactiveStringCommands {
*/
class SetCommand extends KeyCommand {
private ByteBuffer value;
private @Nullable ByteBuffer value;
private Expiration expiration;
private SetOption option;
private SetCommand(ByteBuffer key, ByteBuffer value, Expiration expiration, SetOption option) {
private SetCommand(ByteBuffer key, @Nullable ByteBuffer value, @Nullable Expiration expiration,
@Nullable SetOption option) {
super(key);
@@ -125,6 +128,7 @@ public interface ReactiveStringCommands {
/**
* @return
*/
@Nullable
public ByteBuffer getValue() {
return value;
}
@@ -358,10 +362,12 @@ public interface ReactiveStringCommands {
this.keyValuePairs = keyValuePairs;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.ReactiveRedisConnection.Command#getKey()
*/
@Override
@Nullable
public ByteBuffer getKey() {
return null;
}
@@ -443,9 +449,9 @@ public interface ReactiveStringCommands {
*/
class AppendCommand extends KeyCommand {
private ByteBuffer value;
private @Nullable ByteBuffer value;
private AppendCommand(ByteBuffer key, ByteBuffer value) {
private AppendCommand(ByteBuffer key, @Nullable ByteBuffer value) {
super(key);
this.value = value;
@@ -479,8 +485,9 @@ public interface ReactiveStringCommands {
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public ByteBuffer getValue() {
return value;
}
@@ -546,10 +553,10 @@ public interface ReactiveStringCommands {
*/
class SetRangeCommand extends KeyCommand {
private ByteBuffer value;
private Long offset;
private @Nullable ByteBuffer value;
private @Nullable Long offset;
private SetRangeCommand(ByteBuffer key, ByteBuffer value, Long offset) {
private SetRangeCommand(ByteBuffer key, @Nullable ByteBuffer value, @Nullable Long offset) {
super(key);
this.value = value;
@@ -593,15 +600,17 @@ public interface ReactiveStringCommands {
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public ByteBuffer getValue() {
return value;
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public Long getOffset() {
return offset;
}
@@ -643,9 +652,9 @@ public interface ReactiveStringCommands {
*/
class GetBitCommand extends KeyCommand {
private Long offset;
private @Nullable Long offset;
private GetBitCommand(ByteBuffer key, Long offset) {
private GetBitCommand(ByteBuffer key, @Nullable Long offset) {
super(key);
@@ -676,8 +685,9 @@ public interface ReactiveStringCommands {
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public Long getOffset() {
return offset;
}
@@ -715,7 +725,7 @@ public interface ReactiveStringCommands {
*/
class SetBitCommand extends KeyCommand {
private Long offset;
private @Nullable Long offset;
private boolean value;
private SetBitCommand(ByteBuffer key, Long offset, boolean value) {
@@ -760,14 +770,15 @@ public interface ReactiveStringCommands {
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public Long getOffset() {
return offset;
}
/**
* @return
* @return never {@literal null}.
*/
public boolean getValue() {
return value;
@@ -825,7 +836,7 @@ public interface ReactiveStringCommands {
Assert.notNull(key, "Key must not be null!");
return new BitCountCommand(key, null);
return new BitCountCommand(key, Range.unbounded());
}
/**
@@ -901,9 +912,9 @@ public interface ReactiveStringCommands {
private List<ByteBuffer> keys;
private BitOperation bitOp;
private ByteBuffer destinationKey;
private @Nullable ByteBuffer destinationKey;
private BitOpCommand(List<ByteBuffer> keys, BitOperation bitOp, ByteBuffer destinationKey) {
private BitOpCommand(List<ByteBuffer> keys, BitOperation bitOp, @Nullable ByteBuffer destinationKey) {
this.keys = keys;
this.bitOp = bitOp;
@@ -920,7 +931,7 @@ public interface ReactiveStringCommands {
Assert.notNull(bitOp, "BitOperation must not be null!");
return new BitOpCommand(null, bitOp, null);
return new BitOpCommand(Collections.emptyList(), bitOp, null);
}
/**
@@ -952,22 +963,23 @@ public interface ReactiveStringCommands {
}
/**
* @return
* @return never {@literal null}.
*/
public BitOperation getBitOp() {
return bitOp;
}
/**
* @return
* @return never {@literal null}.
*/
public List<ByteBuffer> getKeys() {
return keys;
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public ByteBuffer getDestinationKey() {
return destinationKey;
}

View File

@@ -35,6 +35,7 @@ import org.springframework.data.redis.connection.RedisZSetCommands.Aggregate;
import org.springframework.data.redis.connection.RedisZSetCommands.Limit;
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
import org.springframework.data.redis.util.ByteUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -59,7 +60,8 @@ public interface ReactiveZSetCommands {
private final boolean returnTotalChanged;
private final boolean incr;
private ZAddCommand(ByteBuffer key, List<Tuple> tuples, boolean upsert, boolean returnTotalChanged, boolean incr) {
private ZAddCommand(@Nullable ByteBuffer key, List<Tuple> tuples, boolean upsert, boolean returnTotalChanged,
boolean incr) {
super(key);
@@ -232,7 +234,7 @@ public interface ReactiveZSetCommands {
private final List<ByteBuffer> values;
private ZRemCommand(ByteBuffer key, List<ByteBuffer> values) {
private ZRemCommand(@Nullable ByteBuffer key, List<ByteBuffer> values) {
super(key);
@@ -335,9 +337,9 @@ public interface ReactiveZSetCommands {
class ZIncrByCommand extends KeyCommand {
private final ByteBuffer value;
private final Number increment;
private final @Nullable Number increment;
private ZIncrByCommand(ByteBuffer key, ByteBuffer value, Number increment) {
private ZIncrByCommand(@Nullable ByteBuffer key, ByteBuffer value, @Nullable Number increment) {
super(key);
@@ -386,15 +388,16 @@ public interface ReactiveZSetCommands {
}
/**
* @return
* @return never {@literal null}.
*/
public ByteBuffer getValue() {
return value;
}
/**
* @return
* @return can be {@literal null}.
*/
@Nullable
public Number getIncrement() {
return increment;
}
@@ -441,7 +444,7 @@ public interface ReactiveZSetCommands {
private final ByteBuffer value;
private final Direction direction;
private ZRankCommand(ByteBuffer key, ByteBuffer value, Direction direction) {
private ZRankCommand(@Nullable ByteBuffer key, ByteBuffer value, Direction direction) {
super(key);
@@ -561,7 +564,7 @@ public interface ReactiveZSetCommands {
private final boolean withScores;
private final Direction direction;
private ZRangeCommand(ByteBuffer key, Range<Long> range, Direction direction, boolean withScores) {
private ZRangeCommand(@Nullable ByteBuffer key, Range<Long> range, Direction direction, boolean withScores) {
super(key);
@@ -730,10 +733,10 @@ public interface ReactiveZSetCommands {
private final Range<Double> range;
private final boolean withScores;
private final Direction direction;
private final Limit limit;
private final @Nullable Limit limit;
private ZRangeByScoreCommand(ByteBuffer key, Range<Double> range, Direction direction, boolean withScores,
Limit limit) {
private ZRangeByScoreCommand(@Nullable ByteBuffer key, Range<Double> range, Direction direction, boolean withScores,
@Nullable Limit limit) {
super(key);
@@ -797,10 +800,12 @@ public interface ReactiveZSetCommands {
/**
* Applies the {@link Limit}. Constructs a new command instance with all previously configured properties.
*
* @param limit can be {@literal null}.
* @param limit must not be {@literal null}.
* @return a new {@link ZRangeByScoreCommand} with {@link Limit} applied.
*/
public ZRangeByScoreCommand limitTo(Limit limit) {
Assert.notNull(limit, "Limit must not be null!");
return new ZRangeByScoreCommand(getKey(), range, direction, withScores, limit);
}
@@ -856,7 +861,7 @@ public interface ReactiveZSetCommands {
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit can be {@literal null}.
* @param limit must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrangebyscore">Redis Documentation: ZRANGEBYSCORE</a>
*/
@@ -864,6 +869,7 @@ public interface ReactiveZSetCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");
Assert.notNull(limit, "Limit must not be null!");
return zRangeByScore(Mono.just(ZRangeByScoreCommand.scoresWithin(range).from(key).limitTo(limit))) //
.flatMap(CommandResponse::getOutput) //
@@ -892,7 +898,7 @@ public interface ReactiveZSetCommands {
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit can be {@literal null}.
* @param limit must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrangebyscore">Redis Documentation: ZRANGEBYSCORE</a>
*/
@@ -900,6 +906,7 @@ public interface ReactiveZSetCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");
Assert.notNull(limit, "Limit must not be null!");
return zRangeByScore(Mono.just(ZRangeByScoreCommand.scoresWithin(range).withScores().from(key).limitTo(limit)))
.flatMap(CommandResponse::getOutput);
@@ -927,7 +934,7 @@ public interface ReactiveZSetCommands {
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit can be {@literal null}.
* @param limit must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrevrangebyscore">Redis Documentation: ZREVRANGEBYSCORE</a>
*/
@@ -935,6 +942,7 @@ public interface ReactiveZSetCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");
Assert.notNull(limit, "Limit must not be null!");
return zRangeByScore(Mono.just(ZRangeByScoreCommand.reverseScoresWithin(range).from(key).limitTo(limit))) //
.flatMap(CommandResponse::getOutput) //
@@ -963,7 +971,7 @@ public interface ReactiveZSetCommands {
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit can be {@literal null}.
* @param limit must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrevrangebyscore">Redis Documentation: ZREVRANGEBYSCORE</a>
*/
@@ -971,6 +979,7 @@ public interface ReactiveZSetCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");
Assert.notNull(limit, "Limit must not be null!");
return zRangeByScore(
Mono.just(ZRangeByScoreCommand.reverseScoresWithin(range).withScores().from(key).limitTo(limit)))
@@ -997,7 +1006,7 @@ public interface ReactiveZSetCommands {
private final Range<Double> range;
private ZCountCommand(ByteBuffer key, Range<Double> range) {
private ZCountCommand(@Nullable ByteBuffer key, Range<Double> range) {
super(key);
this.range = range;
@@ -1099,7 +1108,7 @@ public interface ReactiveZSetCommands {
private final ByteBuffer value;
private ZScoreCommand(ByteBuffer key, ByteBuffer value) {
private ZScoreCommand(@Nullable ByteBuffer key, ByteBuffer value) {
super(key);
this.value = value;
@@ -1250,7 +1259,7 @@ public interface ReactiveZSetCommands {
private final Range<Double> range;
private ZRemRangeByScoreCommand(ByteBuffer key, Range<Double> range) {
private ZRemRangeByScoreCommand(@Nullable ByteBuffer key, Range<Double> range) {
super(key);
this.range = range;
@@ -1323,9 +1332,10 @@ public interface ReactiveZSetCommands {
private final List<ByteBuffer> sourceKeys;
private final List<Double> weights;
private final Aggregate aggregateFunction;
private final @Nullable Aggregate aggregateFunction;
private ZUnionStoreCommand(ByteBuffer key, List<ByteBuffer> sourceKeys, List<Double> weights, Aggregate aggregate) {
private ZUnionStoreCommand(@Nullable ByteBuffer key, List<ByteBuffer> sourceKeys, List<Double> weights,
@Nullable Aggregate aggregate) {
super(key);
this.sourceKeys = sourceKeys;
@@ -1343,7 +1353,7 @@ public interface ReactiveZSetCommands {
Assert.notNull(keys, "Keys must not be null!");
return new ZUnionStoreCommand(null, new ArrayList<>(keys), null, null);
return new ZUnionStoreCommand(null, new ArrayList<>(keys), Collections.emptyList(), null);
}
/**
@@ -1363,7 +1373,8 @@ public interface ReactiveZSetCommands {
* @param aggregateFunction can be {@literal null}.
* @return a new {@link ZUnionStoreCommand} with {@link Aggregate} applied.
*/
public ZUnionStoreCommand aggregateUsing(Aggregate aggregateFunction) {
public ZUnionStoreCommand aggregateUsing(@Nullable Aggregate aggregateFunction) {
return new ZUnionStoreCommand(getKey(), sourceKeys, weights, aggregateFunction);
}
@@ -1382,21 +1393,21 @@ public interface ReactiveZSetCommands {
}
/**
* @return
* @return never {@literal null}.
*/
public List<ByteBuffer> getSourceKeys() {
return sourceKeys;
}
/**
* @return
* @return never {@literal null}.
*/
public List<Double> getWeights() {
return weights == null ? Collections.emptyList() : weights;
return weights;
}
/**
* @return
* @return never {@literal null}.
*/
public Optional<Aggregate> getAggregateFunction() {
return Optional.ofNullable(aggregateFunction);
@@ -1412,7 +1423,7 @@ public interface ReactiveZSetCommands {
* @see <a href="http://redis.io/commands/zunionstore">Redis Documentation: ZUNIONSTORE</a>
*/
default Mono<Long> zUnionStore(ByteBuffer destinationKey, List<ByteBuffer> sets) {
return zUnionStore(destinationKey, sets, null);
return zUnionStore(destinationKey, sets, Collections.emptyList());
}
/**
@@ -1421,7 +1432,7 @@ public interface ReactiveZSetCommands {
*
* @param destinationKey must not be {@literal null}.
* @param sets must not be {@literal null}.
* @param weights can be {@literal null}.
* @param weights must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zunionstore">Redis Documentation: ZUNIONSTORE</a>
*/
@@ -1441,7 +1452,7 @@ public interface ReactiveZSetCommands {
* @see <a href="http://redis.io/commands/zunionstore">Redis Documentation: ZUNIONSTORE</a>
*/
default Mono<Long> zUnionStore(ByteBuffer destinationKey, List<ByteBuffer> sets, List<Double> weights,
Aggregate aggregateFunction) {
@Nullable Aggregate aggregateFunction) {
Assert.notNull(destinationKey, "DestinationKey must not be null!");
Assert.notNull(sets, "Sets must not be null!");
@@ -1471,9 +1482,10 @@ public interface ReactiveZSetCommands {
private final List<ByteBuffer> sourceKeys;
private final List<Double> weights;
private final Aggregate aggregateFunction;
private final @Nullable Aggregate aggregateFunction;
private ZInterStoreCommand(ByteBuffer key, List<ByteBuffer> sourceKeys, List<Double> weights, Aggregate aggregate) {
private ZInterStoreCommand(ByteBuffer key, List<ByteBuffer> sourceKeys, List<Double> weights,
@Nullable Aggregate aggregate) {
super(key);
this.sourceKeys = sourceKeys;
@@ -1491,7 +1503,7 @@ public interface ReactiveZSetCommands {
Assert.notNull(keys, "Keys must not be null!");
return new ZInterStoreCommand(null, new ArrayList<>(keys), null, null);
return new ZInterStoreCommand(null, new ArrayList<>(keys), Collections.emptyList(), null);
}
/**
@@ -1512,7 +1524,8 @@ public interface ReactiveZSetCommands {
* @param aggregateFunction can be {@literal null}.
* @return a new {@link ZInterStoreCommand} with {@link Aggregate} applied.
*/
public ZInterStoreCommand aggregateUsing(Aggregate aggregateFunction) {
public ZInterStoreCommand aggregateUsing(@Nullable Aggregate aggregateFunction) {
return new ZInterStoreCommand(getKey(), sourceKeys, weights, aggregateFunction);
}
@@ -1531,21 +1544,21 @@ public interface ReactiveZSetCommands {
}
/**
* @return
* @return never {@literal null}.
*/
public List<ByteBuffer> getSourceKeys() {
return sourceKeys;
}
/**
* @return
* @return never {@literal null}.
*/
public List<Double> getWeights() {
return weights == null ? Collections.emptyList() : weights;
return weights;
}
/**
* @return
* @return never {@literal null}.ø
*/
public Optional<Aggregate> getAggregateFunction() {
return Optional.ofNullable(aggregateFunction);
@@ -1561,7 +1574,7 @@ public interface ReactiveZSetCommands {
* @see <a href="http://redis.io/commands/zinterstore">Redis Documentation: ZINTERSTORE</a>
*/
default Mono<Long> zInterStore(ByteBuffer destinationKey, List<ByteBuffer> sets) {
return zInterStore(destinationKey, sets, null);
return zInterStore(destinationKey, sets, Collections.emptyList());
}
/**
@@ -1570,7 +1583,7 @@ public interface ReactiveZSetCommands {
*
* @param destinationKey must not be {@literal null}.
* @param sets must not be {@literal null}.
* @param weights can be {@literal null}.
* @param weights must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zinterstore">Redis Documentation: ZINTERSTORE</a>
*/
@@ -1584,13 +1597,13 @@ public interface ReactiveZSetCommands {
*
* @param destinationKey must not be {@literal null}.
* @param sets must not be {@literal null}.
* @param weights can be {@literal null}.
* @param weights must not be {@literal null}.
* @param aggregateFunction can be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zinterstore">Redis Documentation: ZINTERSTORE</a>
*/
default Mono<Long> zInterStore(ByteBuffer destinationKey, List<ByteBuffer> sets, List<Double> weights,
Aggregate aggregateFunction) {
@Nullable Aggregate aggregateFunction) {
Assert.notNull(destinationKey, "DestinationKey must not be null!");
Assert.notNull(sets, "Sets must not be null!");
@@ -1623,7 +1636,7 @@ public interface ReactiveZSetCommands {
private final Direction direction;
private final Limit limit;
private ZRangeByLexCommand(ByteBuffer key, Range<String> range, Direction direction, Limit limit) {
private ZRangeByLexCommand(@Nullable ByteBuffer key, Range<String> range, Direction direction, Limit limit) {
super(key);
this.range = range;
@@ -1642,7 +1655,7 @@ public interface ReactiveZSetCommands {
Assert.notNull(range, "Range must not be null!");
return new ZRangeByLexCommand(null, range, Direction.ASC, null);
return new ZRangeByLexCommand(null, range, Direction.ASC, Limit.unlimited());
}
/**
@@ -1656,7 +1669,7 @@ public interface ReactiveZSetCommands {
Assert.notNull(range, "Range must not be null!");
return new ZRangeByLexCommand(null, range, Direction.DESC, null);
return new ZRangeByLexCommand(null, range, Direction.DESC, Limit.unlimited());
}
/**
@@ -1675,10 +1688,12 @@ public interface ReactiveZSetCommands {
/**
* Applies the {@link Limit}. Constructs a new command instance with all previously configured properties.
*
* @param limit can be {@literal null}.
* @param limit must not be {@literal null}.
* @return a new {@link ZRangeByLexCommand} with {@link Limit} applied.
*/
public ZRangeByLexCommand limitTo(Limit limit) {
Assert.notNull(limit, "Limit must not be null!");
return new ZRangeByLexCommand(getKey(), range, direction, limit);
}
@@ -1713,7 +1728,7 @@ public interface ReactiveZSetCommands {
* @see <a href="http://redis.io/commands/zrangebylex">Redis Documentation: ZRANGEBYLEX</a>
*/
default Flux<ByteBuffer> zRangeByLex(ByteBuffer key, Range<String> range) {
return zRangeByLex(key, range, null);
return zRangeByLex(key, range, Limit.unlimited());
}
/**
@@ -1744,7 +1759,7 @@ public interface ReactiveZSetCommands {
* @see <a href="http://redis.io/commands/zrevrangebylex">Redis Documentation: ZREVRANGEBYLEX</a>
*/
default Flux<ByteBuffer> zRevRangeByLex(ByteBuffer key, Range<String> range) {
return zRevRangeByLex(key, range, null);
return zRevRangeByLex(key, range, Limit.unlimited());
}
/**
@@ -1753,7 +1768,7 @@ public interface ReactiveZSetCommands {
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit can be {@literal null}.
* @param limit must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrevrangebylex">Redis Documentation: ZREVRANGEBYLEX</a>
*/
@@ -1761,6 +1776,7 @@ public interface ReactiveZSetCommands {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");
Assert.notNull(limit, "Limit must not be null!");
return zRangeByLex(Mono.just(ZRangeByLexCommand.reverseStringsWithin(range).from(key).limitTo(limit)))
.flatMap(CommandResponse::getOutput);

View File

@@ -179,7 +179,7 @@ public interface RedisClusterCommands {
*/
void clusterReplicate(RedisClusterNode master, RedisClusterNode slave);
public enum AddSlots {
enum AddSlots {
MIGRATING, IMPORTING, STABLE, NODE
}

View File

@@ -27,6 +27,7 @@ import java.util.Set;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.NumberUtils;
import org.springframework.util.StringUtils;
@@ -46,7 +47,7 @@ public class RedisClusterConfiguration {
private static final String REDIS_CLUSTER_MAX_REDIRECTS_CONFIG_PROPERTY = "spring.redis.cluster.max-redirects";
private Set<RedisNode> clusterNodes;
private Integer maxRedirects;
private @Nullable Integer maxRedirects;
private RedisPassword password = RedisPassword.none();
/**
@@ -213,7 +214,6 @@ public class RedisClusterConfiguration {
/**
* @param clusterHostAndPorts must not be {@literal null} or empty.
* @param redirects the max number of redirects to follow.
* @param password can be {@literal null} or empty.
* @return cluster config map with properties.
*/
private static Map<String, Object> asMap(Collection<String> clusterHostAndPorts, int redirects) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-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.
@@ -17,6 +17,8 @@ package org.springframework.data.redis.connection;
import java.util.Set;
import org.springframework.lang.Nullable;
/**
* {@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
@@ -31,24 +33,27 @@ public interface RedisClusterConnection extends RedisConnection, RedisClusterCom
/**
* @param node must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see RedisConnectionCommands#ping()
*/
@Nullable
String ping(RedisClusterNode node);
/**
* @param node must not be {@literal null}.
* @param pattern must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see RedisKeyCommands#keys(byte[])
*/
@Nullable
Set<byte[]> keys(RedisClusterNode node, byte[] pattern);
/**
* @param node must not be {@literal null}.
* @return
* @return {@literal null} when no keys stored at node or when used in pipeline / transaction.
* @see RedisKeyCommands#randomKey()
*/
@Nullable
byte[] randomKey(RedisClusterNode node);
/**

View File

@@ -20,6 +20,7 @@ import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@@ -33,11 +34,13 @@ import org.springframework.util.CollectionUtils;
public class RedisClusterNode extends RedisNode {
private SlotRange slotRange;
private LinkState linkState;
private @Nullable LinkState linkState;
private Set<Flag> flags;
protected RedisClusterNode() {
super();
flags = Collections.emptySet();
}
/**
@@ -47,7 +50,7 @@ public class RedisClusterNode extends RedisNode {
* @param port
*/
public RedisClusterNode(String host, int port) {
this(host, port, new SlotRange(Collections.<Integer> emptySet()));
this(host, port, SlotRange.empty());
}
/**
@@ -57,7 +60,7 @@ public class RedisClusterNode extends RedisNode {
*/
public RedisClusterNode(String id) {
this(new SlotRange(Collections.<Integer> emptySet()));
this(SlotRange.empty());
Assert.notNull(id, "Id must not be null!");
this.id = id;
}
@@ -67,23 +70,34 @@ public class RedisClusterNode extends RedisNode {
*
* @param host must not be {@literal null}.
* @param port
* @param slotRange can be {@literal null}.
* @param slotRange must not be {@literal null}.
*/
public RedisClusterNode(String host, int port, SlotRange slotRange) {
super(host, port);
this.slotRange = slotRange != null ? slotRange : new SlotRange(Collections.<Integer> emptySet());
Assert.notNull(slotRange, "SlotRange must not be null!");
this.slotRange = slotRange;
}
/**
* Creates new {@link RedisClusterNode} with given {@link SlotRange}.
*
* @param slotRange can be {@literal null}.
* @param slotRange must not be {@literal null}.
*/
public RedisClusterNode(SlotRange slotRange) {
super();
this.slotRange = slotRange != null ? slotRange : new SlotRange(Collections.<Integer> emptySet());
Assert.notNull(slotRange, "SlotRange must not be null!");
this.slotRange = slotRange;
}
{
if (flags == null) {
flags = Collections.emptySet();
}
}
/**
@@ -104,8 +118,9 @@ public class RedisClusterNode extends RedisNode {
}
/**
* @return
* @return can be {@literal null}
*/
@Nullable
public LinkState getLinkState() {
return linkState;
}
@@ -121,7 +136,7 @@ public class RedisClusterNode extends RedisNode {
* @return never {@literal null}.
*/
public Set<Flag> getFlags() {
return flags == null ? Collections.<Flag> emptySet() : flags;
return flags == null ? Collections.emptySet() : flags;
}
/**
@@ -177,8 +192,7 @@ public class RedisClusterNode extends RedisNode {
}
public SlotRange(Collection<Integer> range) {
this.range = CollectionUtils.isEmpty(range) ? Collections.<Integer> emptySet()
: new LinkedHashSet<>(range);
this.range = CollectionUtils.isEmpty(range) ? Collections.emptySet() : new LinkedHashSet<>(range);
}
@Override
@@ -212,13 +226,17 @@ public class RedisClusterNode extends RedisNode {
return slots;
}
public static SlotRange empty() {
return new SlotRange(Collections.emptySet());
}
}
/**
* @author Christoph Strobl
* @since 1.7
*/
public static enum LinkState {
public enum LinkState {
CONNECTED, DISCONNECTED
}
@@ -251,12 +269,12 @@ public class RedisClusterNode extends RedisNode {
*/
public static class RedisClusterNodeBuilder extends RedisNodeBuilder {
Set<Flag> flags;
LinkState linkState;
@Nullable Set<Flag> flags;
@Nullable LinkState linkState;
SlotRange slotRange;
public RedisClusterNodeBuilder() {
this.slotRange = SlotRange.empty();
}
/*

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2016 the original author or authors.
* 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.
@@ -16,6 +16,8 @@
package org.springframework.data.redis.connection;
import org.springframework.lang.Nullable;
/**
* Interface for the commands supported by Redis.
*
@@ -30,10 +32,11 @@ public interface RedisCommands extends RedisKeyCommands, RedisStringCommands, Re
* 'Native' or 'raw' execution of the given command along-side the given arguments. The command is executed as is,
* with as little 'interpretation' as possible - it is up to the caller to take care of any processing of arguments or
* the result.
*
* @param command Command to execute
* @param args Possible command arguments (may be null)
* @return execution result.
*
* @param command Command to execute. must not be {@literal null}.
* @param args Possible command arguments (may be empty).
* @return execution result. Can be {@literal null}.
*/
@Nullable
Object execute(String command, byte[]... args);
}

View File

@@ -15,6 +15,8 @@
*/
package org.springframework.data.redis.connection;
import org.springframework.lang.Nullable;
/**
* Connection-specific commands supported by Redis.
*
@@ -36,16 +38,18 @@ public interface RedisConnectionCommands {
* Returns {@code message} via server roundtrip.
*
* @param message the message to echo.
* @return
* @return the message or {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/echo">Redis Documentation: ECHO</a>
*/
@Nullable
byte[] echo(byte[] message);
/**
* Test connection.
*
* @return Server response message - usually {@literal PONG}.
* @return Server response message - usually {@literal PONG}. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/ping">Redis Documentation: PING</a>
*/
@Nullable
String ping();
}

View File

@@ -29,6 +29,7 @@ import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Metric;
import org.springframework.data.geo.Point;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -47,9 +48,10 @@ public interface RedisGeoCommands {
* @param key must not be {@literal null}.
* @param point must not be {@literal null}.
* @param member must not be {@literal null}.
* @return Number of elements added.
* @return Number of elements added. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/geoadd">Redis Documentation: GEOADD</a>
*/
@Nullable
Long geoAdd(byte[] key, Point point, byte[] member);
/**
@@ -57,9 +59,10 @@ public interface RedisGeoCommands {
*
* @param key must not be {@literal null}.
* @param location must not be {@literal null}.
* @return Number of elements added.
* @return Number of elements added. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/geoadd">Redis Documentation: GEOADD</a>
*/
@Nullable
default Long geoAdd(byte[] key, GeoLocation<byte[]> location) {
Assert.notNull(key, "Key must not be null!");
@@ -73,9 +76,10 @@ public interface RedisGeoCommands {
*
* @param key must not be {@literal null}.
* @param memberCoordinateMap must not be {@literal null}.
* @return Number of elements added.
* @return Number of elements added. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/geoadd">Redis Documentation: GEOADD</a>
*/
@Nullable
Long geoAdd(byte[] key, Map<byte[], Point> memberCoordinateMap);
/**
@@ -83,9 +87,10 @@ public interface RedisGeoCommands {
*
* @param key must not be {@literal null}.
* @param locations must not be {@literal null}.
* @return Number of elements added.
* @return Number of elements added. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/geoadd">Redis Documentation: GEOADD</a>
*/
@Nullable
Long geoAdd(byte[] key, Iterable<GeoLocation<byte[]>> locations);
/**
@@ -94,9 +99,10 @@ public interface RedisGeoCommands {
* @param key must not be {@literal null}.
* @param member1 must not be {@literal null}.
* @param member2 must not be {@literal null}.
* @return can be {@literal null}.
* @return can be {@literal null}. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/geodist">Redis Documentation: GEODIST</a>
*/
@Nullable
Distance geoDist(byte[] key, byte[] member1, byte[] member2);
/**
@@ -106,9 +112,10 @@ public interface RedisGeoCommands {
* @param member1 must not be {@literal null}.
* @param member2 must not be {@literal null}.
* @param metric must not be {@literal null}.
* @return can be {@literal null}.
* @return can be {@literal null}. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/geodist">Redis Documentation: GEODIST</a>
*/
@Nullable
Distance geoDist(byte[] key, byte[] member1, byte[] member2, Metric metric);
/**
@@ -116,9 +123,10 @@ public interface RedisGeoCommands {
*
* @param key must not be {@literal null}.
* @param members must not be {@literal null}.
* @return never {@literal null}.
* @return empty list when key or members do not exists. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/geohash">Redis Documentation: GEOHASH</a>
*/
@Nullable
List<String> geoHash(byte[] key, byte[]... members);
/**
@@ -126,9 +134,10 @@ public interface RedisGeoCommands {
*
* @param key must not be {@literal null}.
* @param members must not be {@literal null}.
* @return never {@literal null}.
* @return empty {@link List} when key of members do not exist. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/geopos">Redis Documentation: GEOPOS</a>
*/
@Nullable
List<Point> geoPos(byte[] key, byte[]... members);
/**
@@ -136,9 +145,10 @@ public interface RedisGeoCommands {
*
* @param key must not be {@literal null}.
* @param within must not be {@literal null}.
* @return never {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/georadius">Redis Documentation: GEORADIUS</a>
*/
@Nullable
GeoResults<GeoLocation<byte[]>> geoRadius(byte[] key, Circle within);
/**
@@ -147,9 +157,10 @@ public interface RedisGeoCommands {
* @param key must not be {@literal null}.
* @param within must not be {@literal null}.
* @param args must not be {@literal null}.
* @return never {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/georadius">Redis Documentation: GEORADIUS</a>
*/
@Nullable
GeoResults<GeoLocation<byte[]>> geoRadius(byte[] key, Circle within, GeoRadiusCommandArgs args);
/**
@@ -159,9 +170,10 @@ public interface RedisGeoCommands {
* @param key must not be {@literal null}.
* @param member must not be {@literal null}.
* @param radius
* @return never {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/georadiusbymember">Redis Documentation: GEORADIUSBYMEMBER</a>
*/
@Nullable
default GeoResults<GeoLocation<byte[]>> geoRadiusByMember(byte[] key, byte[] member, double radius) {
return geoRadiusByMember(key, member, new Distance(radius, DistanceUnit.METERS));
}
@@ -173,9 +185,10 @@ public interface RedisGeoCommands {
* @param key must not be {@literal null}.
* @param member must not be {@literal null}.
* @param radius must not be {@literal null}.
* @return never {@literal null}.
* @return {@literal null} when used in pipeline / transaction..
* @see <a href="http://redis.io/commands/georadiusbymember">Redis Documentation: GEORADIUSBYMEMBER</a>
*/
@Nullable
GeoResults<GeoLocation<byte[]>> geoRadiusByMember(byte[] key, byte[] member, Distance radius);
/**
@@ -186,9 +199,10 @@ public interface RedisGeoCommands {
* @param member must not be {@literal null}.
* @param radius must not be {@literal null}.
* @param args must not be {@literal null}.
* @return never {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/georadiusbymember">Redis Documentation: GEORADIUSBYMEMBER</a>
*/
@Nullable
GeoResults<GeoLocation<byte[]>> geoRadiusByMember(byte[] key, byte[] member, Distance radius,
GeoRadiusCommandArgs args);
@@ -197,9 +211,10 @@ public interface RedisGeoCommands {
*
* @param key must not be {@literal null}.
* @param members must not be {@literal null}.
* @return Number of elements removed.
* @return Number of elements removed. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/zrem">Redis Documentation: ZREM</a>
*/
@Nullable
Long geoRemove(byte[] key, byte[]... members);
/**
@@ -212,8 +227,8 @@ public interface RedisGeoCommands {
class GeoRadiusCommandArgs implements Cloneable {
Set<Flag> flags = new LinkedHashSet<>(2, 1);
Long limit;
Direction sortDirection;
@Nullable Long limit;
@Nullable Direction sortDirection;
private GeoRadiusCommandArgs() {}
@@ -293,6 +308,7 @@ public interface RedisGeoCommands {
/**
* @return can be {@literal null}.
*/
@Nullable
public Long getLimit() {
return limit;
}
@@ -300,6 +316,7 @@ public interface RedisGeoCommands {
/**
* @return can be {@literal null}.
*/
@Nullable
public Direction getSortDirection() {
return sortDirection;
}
@@ -316,7 +333,7 @@ public interface RedisGeoCommands {
return limit != null;
}
public static enum Flag {
public enum Flag {
WITHCOORD, WITHDIST
}

View File

@@ -21,6 +21,7 @@ import java.util.Set;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.lang.Nullable;
/**
* Hash-specific commands supported by Redis.
@@ -36,10 +37,11 @@ public interface RedisHashCommands {
*
* @param key must not be {@literal null}.
* @param field must not be {@literal null}.
* @param value
* @return
* @param value must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/hset">Redis Documentation: HSET</a>
*/
@Nullable
Boolean hSet(byte[] key, byte[] field, byte[] value);
/**
@@ -47,10 +49,11 @@ public interface RedisHashCommands {
*
* @param key must not be {@literal null}.
* @param field must not be {@literal null}.
* @param value
* @return
* @param value must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/hsetnx">Redis Documentation: HSETNX</a>
*/
@Nullable
Boolean hSetNX(byte[] key, byte[] field, byte[] value);
/**
@@ -58,19 +61,21 @@ public interface RedisHashCommands {
*
* @param key must not be {@literal null}.
* @param field must not be {@literal null}.
* @return
* @return {@literal null} when key or field do not exists or when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/hget">Redis Documentation: HGET</a>
*/
@Nullable
byte[] hGet(byte[] key, byte[] field);
/**
* Get values for given {@code fields} from hash at {@code key}.
*
* @param key must not be {@literal null}.
* @param fields must not be {@literal null}.
* @return
* @param fields must not be {@literal empty}.
* @return empty {@link List} if key or fields do not exists. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/hmget">Redis Documentation: HMGET</a>
*/
@Nullable
List<byte[]> hMGet(byte[] key, byte[]... fields);
/**
@@ -88,20 +93,22 @@ public interface RedisHashCommands {
* @param key must not be {@literal null}.
* @param field must not be {@literal null}.
* @param delta
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/hincrby">Redis Documentation: HINCRBY</a>
*/
@Nullable
Long hIncrBy(byte[] key, byte[] field, long delta);
/**
* Increment {@code value} of a hash {@code field} by the given {@code delta}.
*
* @param key must not be {@literal null}.
* @param field
* @param field must not be {@literal null}.
* @param delta
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/hincrbyfloat">Redis Documentation: HINCRBYFLOAT</a>
*/
@Nullable
Double hIncrBy(byte[] key, byte[] field, double delta);
/**
@@ -109,55 +116,61 @@ public interface RedisHashCommands {
*
* @param key must not be {@literal null}.
* @param field must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/hexits">Redis Documentation: HEXISTS</a>
*/
@Nullable
Boolean hExists(byte[] key, byte[] field);
/**
* Delete given hash {@code fields}.
*
* @param key must not be {@literal null}.
* @param fields must not be {@literal null}.
* @return
* @param fields must not be {@literal empty}.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/hdel">Redis Documentation: HDEL</a>
*/
@Nullable
Long hDel(byte[] key, byte[]... fields);
/**
* Get size of hash at {@code key}.
*
* @param key must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/hlen">Redis Documentation: HLEN</a>
*/
@Nullable
Long hLen(byte[] key);
/**
* Get key set (fields) of hash at {@code key}.
*
* @param key must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/hkeys">Redis Documentation: HKEYS</a>?
*/
@Nullable
Set<byte[]> hKeys(byte[] key);
/**
* Get entry set (values) of hash at {@code field}.
*
* @param key must not be {@literal null}.
* @return
* @return empty {@link List} if key does not exist. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/hvals">Redis Documentation: HVALS</a>
*/
@Nullable
List<byte[]> hVals(byte[] key);
/**
* Get entire hash stored at {@code key}.
*
* @param key must not be {@literal null}.
* @return
* @return empty {@link Map} if key does not exist or {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/hgetall">Redis Documentation: HGETALL</a>
*/
@Nullable
Map<byte[], byte[]> hGetAll(byte[] key);
/**

View File

@@ -15,6 +15,8 @@
*/
package org.springframework.data.redis.connection;
import org.springframework.lang.Nullable;
/**
* {@literal HyperLogLog} specific commands supported by Redis.
*
@@ -29,18 +31,20 @@ public interface RedisHyperLogLogCommands {
*
* @param key must not be {@literal null}.
* @param values must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/pfadd">Redis Documentation: PFADD</a>
*/
@Nullable
Long pfAdd(byte[] key, byte[]... values);
/**
* Return the approximated cardinality of the structures observed by the HyperLogLog at {@literal key(s)}.
*
* @param keys must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/pfcount">Redis Documentation: PFCOUNT</a>
*/
@Nullable
Long pfCount(byte[]... keys);
/**

View File

@@ -21,6 +21,7 @@ import java.util.concurrent.TimeUnit;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.lang.Nullable;
/**
* Key-specific commands supported by Redis.
@@ -35,43 +36,47 @@ public interface RedisKeyCommands {
* Determine if given {@code key} exists.
*
* @param key must not be {@literal null}.
* @return
* @return {@literal true} if key exists. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/exists">Redis Documentation: EXISTS</a>
*/
@Nullable
Boolean exists(byte[] key);
/**
* Delete given {@code keys}.
*
* @param keys must not be {@literal null}.
* @return The number of keys that were removed.
* @return The number of keys that were removed. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/del">Redis Documentation: DEL</a>
*/
@Nullable
Long del(byte[]... keys);
/**
* Determine the type stored at {@code key}.
*
* @param key must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/type">Redis Documentation: TYPE</a>
*/
@Nullable
DataType type(byte[] key);
/**
* Find all keys matching the given {@code pattern}.
*
* @param pattern must not be {@literal null}.
* @return
* @return empty {@link Set} if no match found. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/keys">Redis Documentation: KEYS</a>
*/
@Nullable
Set<byte[]> keys(byte[] pattern);
/**
* Use a {@link Cursor} to iterate over keys.
*
* @param options must not be {@literal null}.
* @return
* @return never {@literal null}.
* @since 1.4
* @see <a href="http://redis.io/commands/scan">Redis Documentation: SCAN</a>
*/
@@ -80,9 +85,10 @@ public interface RedisKeyCommands {
/**
* Return a random key from the keyspace.
*
* @return
* @return {@literal null} if no keys available or when used in pipeline or transaction.
* @see <a href="http://redis.io/commands/randomkey">Redis Documentation: RANDOMKEY</a>
*/
@Nullable
byte[] randomKey();
/**
@@ -99,9 +105,10 @@ public interface RedisKeyCommands {
*
* @param oldName must not be {@literal null}.
* @param newName must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/renamenx">Redis Documentation: RENAMENX</a>
*/
@Nullable
Boolean renameNX(byte[] oldName, byte[] newName);
/**
@@ -109,9 +116,10 @@ public interface RedisKeyCommands {
*
* @param key must not be {@literal null}.
* @param seconds
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/expire">Redis Documentation: EXPIRE</a>
*/
@Nullable
Boolean expire(byte[] key, long seconds);
/**
@@ -119,9 +127,10 @@ public interface RedisKeyCommands {
*
* @param key must not be {@literal null}.
* @param millis
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/pexpire">Redis Documentation: PEXPIRE</a>
*/
@Nullable
Boolean pExpire(byte[] key, long millis);
/**
@@ -129,9 +138,10 @@ public interface RedisKeyCommands {
*
* @param key must not be {@literal null}.
* @param unixTime
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/expireat">Redis Documentation: EXPIREAT</a>
*/
@Nullable
Boolean expireAt(byte[] key, long unixTime);
/**
@@ -139,18 +149,20 @@ public interface RedisKeyCommands {
*
* @param key must not be {@literal null}.
* @param unixTimeInMillis
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/pexpireat">Redis Documentation: PEXPIREAT</a>
*/
@Nullable
Boolean pExpireAt(byte[] key, long unixTimeInMillis);
/**
* Remove the expiration from given {@code key}.
*
* @param key must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/persist">Redis Documentation: PERSIST</a>
*/
@Nullable
Boolean persist(byte[] key);
/**
@@ -158,18 +170,20 @@ public interface RedisKeyCommands {
*
* @param key must not be {@literal null}.
* @param dbIndex
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/move">Redis Documentation: MOVE</a>
*/
@Nullable
Boolean move(byte[] key, int dbIndex);
/**
* Get the time to live for {@code key} in seconds.
*
* @param key must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/ttl">Redis Documentation: TTL</a>
*/
@Nullable
Long ttl(byte[] key);
/**
@@ -177,19 +191,21 @@ public interface RedisKeyCommands {
*
* @param key must not be {@literal null}.
* @param timeUnit must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @since 1.8
* @see <a href="http://redis.io/commands/ttl">Redis Documentation: TTL</a>
*/
@Nullable
Long ttl(byte[] key, TimeUnit timeUnit);
/**
* Get the precise time to live for {@code key} in milliseconds.
*
* @param key must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/pttl">Redis Documentation: PTTL</a>
*/
@Nullable
Long pTtl(byte[] key);
/**
@@ -197,10 +213,11 @@ public interface RedisKeyCommands {
*
* @param key must not be {@literal null}.
* @param timeUnit must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @since 1.8
* @see <a href="http://redis.io/commands/pttl">Redis Documentation: PTTL</a>
*/
@Nullable
Long pTtl(byte[] key, TimeUnit timeUnit);
/**
@@ -208,9 +225,10 @@ public interface RedisKeyCommands {
*
* @param key must not be {@literal null}.
* @param params must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/sort">Redis Documentation: SORT</a>
*/
@Nullable
List<byte[]> sort(byte[] key, SortParameters params);
/**
@@ -219,18 +237,20 @@ public interface RedisKeyCommands {
* @param key must not be {@literal null}.
* @param params must not be {@literal null}.
* @param storeKey must not be {@literal null}.
* @return number of values.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/sort">Redis Documentation: SORT</a>
*/
@Nullable
Long sort(byte[] key, SortParameters params, byte[] storeKey);
/**
* Retrieve serialized version of the value stored at {@code key}.
*
* @param key must not be {@literal null}.
* @return
* @return {@literal null} if key does not exist or when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/dump">Redis Documentation: DUMP</a>
*/
@Nullable
byte[] dump(byte[] key);
/**

View File

@@ -17,6 +17,8 @@ package org.springframework.data.redis.connection;
import java.util.List;
import org.springframework.lang.Nullable;
/**
* List-specific commands supported by Redis.
*
@@ -29,7 +31,7 @@ public interface RedisListCommands {
/**
* List insertion position.
*/
public enum Position {
enum Position {
BEFORE, AFTER
}
@@ -37,49 +39,54 @@ public interface RedisListCommands {
* Append {@code values} to {@code key}.
*
* @param key must not be {@literal null}.
* @param values
* @return
* @param values must not be empty.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/rpush">Redis Documentation: RPUSH</a>
*/
@Nullable
Long rPush(byte[] key, byte[]... values);
/**
* Prepend {@code values} to {@code key}.
*
* @param key must not be {@literal null}.
* @param values
* @return
* @param values must not be empty.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/lpush">Redis Documentation: LPUSH</a>
*/
@Nullable
Long lPush(byte[] key, byte[]... values);
/**
* Append {@code values} to {@code key} only if the list exists.
*
* @param key must not be {@literal null}.
* @param value
* @return
* @param value must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/rpushx">Redis Documentation: RPUSHX</a>
*/
@Nullable
Long rPushX(byte[] key, byte[] value);
/**
* Prepend {@code values} to {@code key} only if the list exists.
*
* @param key must not be {@literal null}.
* @param value
* @return
* @param value must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/lpushx">Redis Documentation: LPUSHX</a>
*/
@Nullable
Long lPushX(byte[] key, byte[] value);
/**
* Get the size of list stored at {@code key}.
*
* @param key must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/llen">Redis Documentation: LLEN</a>
*/
@Nullable
Long lLen(byte[] key);
/**
@@ -88,9 +95,11 @@ public interface RedisListCommands {
* @param key must not be {@literal null}.
* @param start
* @param end
* @return
* @return empty {@link List} if key does not exists or range does not contain values. {@literal null} when used in
* pipeline / transaction.
* @see <a href="http://redis.io/commands/lrange">Redis Documentation: LRANGE</a>
*/
@Nullable
List<byte[]> lRange(byte[] key, long start, long end);
/**
@@ -107,10 +116,11 @@ public interface RedisListCommands {
* Get element at {@code index} form list at {@code key}.
*
* @param key must not be {@literal null}.
* @param index
* @return
* @param index zero based index value. Use negative number to designate elements starting at the tail.
* @return {@literal null} when index is out of range or when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/lindex">Redis Documentation: LINDEX</a>
*/
@Nullable
byte[] lIndex(byte[] key, long index);
/**
@@ -118,11 +128,12 @@ public interface RedisListCommands {
*
* @param key must not be {@literal null}.
* @param where must not be {@literal null}.
* @param pivot
* @param value
* @return
* @param pivot must not be {@literal null}.
* @param value must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/linsert">Redis Documentation: LINSERT</a>
*/
@Nullable
Long lInsert(byte[] key, Position where, byte[] pivot, byte[] value);
/**
@@ -141,51 +152,58 @@ public interface RedisListCommands {
* @param key must not be {@literal null}.
* @param count
* @param value
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/lrem">Redis Documentation: LREM</a>
*/
@Nullable
Long lRem(byte[] key, long count, byte[] value);
/**
* Removes and returns first element in list stored at {@code key}.
*
* @param key must not be {@literal null}.
* @return
* @return {@literal null} when key does not exist or used in pipeline / transaction.
* @see <a href="http://redis.io/commands/lpop">Redis Documentation: LPOP</a>
*/
@Nullable
byte[] lPop(byte[] key);
/**
* Removes and returns last element in list stored at {@code key}.
*
* @param key must not be {@literal null}.
* @return
* @return {@literal null} when key does not exist or used in pipeline / transaction.
* @see <a href="http://redis.io/commands/rpop">Redis Documentation: RPOP</a>
*/
@Nullable
byte[] rPop(byte[] key);
/**
* Removes and returns first element from lists stored at {@code keys}. <br>
* <b>Blocks connection</b> until element available or {@code timeout} reached.
*
* @param timeout
* @param timeout seconds to block.
* @param keys must not be {@literal null}.
* @return
* @return empty {@link List} when no element could be popped and the timeout was reached. {@literal null} when used
* in pipeline / transaction.
* @see <a href="http://redis.io/commands/blpop">Redis Documentation: BLPOP</a>
* @see #lPop(byte[])
*/
@Nullable
List<byte[]> bLPop(int timeout, byte[]... keys);
/**
* Removes and returns last element from lists stored at {@code keys}. <br>
* <b>Blocks connection</b> until element available or {@code timeout} reached.
*
* @param timeout
* @param timeout seconds to block.
* @param keys must not be {@literal null}.
* @return
* @return empty {@link List} when no element could be popped and the timeout was reached. {@literal null} when used
* in pipeline / transaction.
* @see <a href="http://redis.io/commands/brpop">Redis Documentation: BRPOP</a>
* @see #rPop(byte[])
*/
@Nullable
List<byte[]> bRPop(int timeout, byte[]... keys);
/**
@@ -193,22 +211,23 @@ public interface RedisListCommands {
*
* @param srcKey must not be {@literal null}.
* @param dstKey must not be {@literal null}.
* @return
* @return can be {@literal null}.
* @see <a href="http://redis.io/commands/rpoplpush">Redis Documentation: RPOPLPUSH</a>
*/
@Nullable
byte[] rPopLPush(byte[] srcKey, byte[] dstKey);
/**
* Remove the last element from list at {@code srcKey}, append it to {@code dstKey} and return its value.
* <br>
* Remove the last element from list at {@code srcKey}, append it to {@code dstKey} and return its value. <br>
* <b>Blocks connection</b> until element available or {@code timeout} reached.
*
* @param timeout
* @param timeout seconds to block.
* @param srcKey must not be {@literal null}.
* @param dstKey must not be {@literal null}.
* @return
* @return can be {@literal null}.
* @see <a href="http://redis.io/commands/brpoplpush">Redis Documentation: BRPOPLPUSH</a>
* @see #rPopLPush(byte[], byte[])
*/
@Nullable
byte[] bRPopLPush(int timeout, byte[] srcKey, byte[] dstKey);
}

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.redis.connection;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -26,12 +27,12 @@ import org.springframework.util.ObjectUtils;
*/
public class RedisNode implements NamedNode {
String id;
String name;
String host;
@Nullable String id;
@Nullable String name;
@Nullable String host;
int port;
NodeType type;
String masterId;
@Nullable NodeType type;
@Nullable String masterId;
/**
* Creates a new {@link RedisNode} with the given {@code host}, {@code port}.
@@ -49,10 +50,18 @@ public class RedisNode implements NamedNode {
protected RedisNode() {}
/**
* @return can be {@literal null}.
*/
@Nullable
public String getHost() {
return host;
}
/**
* @return can be {@literal null}.
*/
@Nullable
public Integer getPort() {
return port;
}
@@ -62,6 +71,7 @@ public class RedisNode implements NamedNode {
}
@Override
@Nullable
public String getName() {
return this.name;
}
@@ -71,23 +81,24 @@ public class RedisNode implements NamedNode {
}
/**
* @return
* @return can be {@literal null}.
* @since 1.7
*/
@Nullable
public String getMasterId() {
return masterId;
}
/**
* @return
* @return can be {@literal null}.
* @since 1.7
*/
@Nullable
public String getId() {
return id;
}
/**
*
* @param id
* @since 1.7
*/
@@ -96,9 +107,10 @@ public class RedisNode implements NamedNode {
}
/**
* @return
* @return can be {@literal null}.
* @since 1.7
*/
@Nullable
public NodeType getType() {
return type;
}

View File

@@ -20,6 +20,7 @@ import java.util.Collections;
import java.util.List;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
import org.springframework.lang.Nullable;
/**
* Exception thrown when executing/closing a pipeline that contains one or multiple invalid/incorrect statements. The
@@ -41,7 +42,7 @@ public class RedisPipelineException extends InvalidDataAccessResourceUsageExcept
* @param cause the cause
* @param pipelineResult the pipeline result
*/
public RedisPipelineException(String msg, Throwable cause, List<Object> pipelineResult) {
public RedisPipelineException(@Nullable String msg, @Nullable Throwable cause, List<Object> pipelineResult) {
super(msg, cause);
results = Collections.unmodifiableList(pipelineResult);
}

View File

@@ -15,34 +15,38 @@
*/
package org.springframework.data.redis.connection;
import org.springframework.lang.Nullable;
/**
* PubSub-specific Redis commands.
*
* @author Costin Leau
* @author Mark Paluch
* @author Christoph Strobl
*/
public interface RedisPubSubCommands {
/**
* Indicates whether the current connection is subscribed (to at least one channel) or not.
*
*
* @return true if the connection is subscribed, false otherwise
*/
boolean isSubscribed();
/**
* Returns the current subscription for this connection or null if the connection is not subscribed.
*
* @return the current subscription, null if none is available
*
* @return the current subscription, {@literal null} if none is available.
*/
@Nullable
Subscription getSubscription();
/**
* Publishes the given message to the given channel.
*
* @param channel the channel to publish to, must not be {@literal null}.
* @param message message to publish
* @return the number of clients that received the message
*
* @param channel the channel to publish to. Must not be {@literal null}.
* @param message message to publish. Must not be {@literal null}.
* @return the number of clients that received the message.
* @see <a href="http://redis.io/commands/publish">Redis Documentation: PUBLISH</a>
*/
Long publish(byte[] channel, byte[] message);
@@ -52,7 +56,7 @@ public interface RedisPubSubCommands {
* subscribe to other channels or unsubscribe. No other commands are accepted until the connection is unsubscribed.
* <p>
* Note that this operation is blocking and the current thread starts waiting for new messages immediately.
*
*
* @param listener message listener, must not be {@literal null}.
* @param channels channel names, must not be {@literal null}.
* @see <a href="http://redis.io/commands/subscribe">Redis Documentation: SUBSCRIBE</a>
@@ -65,7 +69,7 @@ public interface RedisPubSubCommands {
* connection is unsubscribed.
* <p>
* Note that this operation is blocking and the current thread starts waiting for new messages immediately.
*
*
* @param listener message listener, must not be {@literal null}.
* @param patterns channel name patterns, must not be {@literal null}.
* @see <a href="http://redis.io/commands/psubscribe">Redis Documentation: PSUBSCRIBE</a>

View File

@@ -17,9 +17,11 @@ package org.springframework.data.redis.connection;
import java.util.List;
import org.springframework.lang.Nullable;
/**
* Scripting commands.
*
*
* @author Costin Leau
* @author Christoph Strobl
* @author David Liu
@@ -46,18 +48,21 @@ public interface RedisScriptingCommands {
* Execute the script by calling {@link #evalSha(byte[], ReturnType, int, byte[]...)}.
*
* @param script must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/script-load">Redis Documentation: SCRIPT LOAD</a>
*/
@Nullable
String scriptLoad(byte[] script);
/**
* Check if given {@code scriptShas} exist in script cache.
*
* @param scriptShas
* @return one entry per given scriptSha in returned list.
* @return one entry per given scriptSha in returned {@link List} or {@literal null} when used in pipeline /
* transaction.
* @see <a href="http://redis.io/commands/script-exists">Redis Documentation: SCRIPT EXISTS</a>
*/
@Nullable
List<Boolean> scriptExists(String... scriptShas);
/**
@@ -67,9 +72,10 @@ public interface RedisScriptingCommands {
* @param returnType must not be {@literal null}.
* @param numKeys
* @param keysAndArgs must not be {@literal null}.
* @return
* @return script result. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/eval">Redis Documentation: EVAL</a>
*/
@Nullable
<T> T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs);
/**
@@ -79,9 +85,10 @@ public interface RedisScriptingCommands {
* @param returnType must not be {@literal null}.
* @param numKeys
* @param keysAndArgs must not be {@literal null}.
* @return
* @return script result. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/evalsha">Redis Documentation: EVALSHA</a>
*/
@Nullable
<T> T evalSha(String scriptSha, ReturnType returnType, int numKeys, byte[]... keysAndArgs);
/**
@@ -91,9 +98,10 @@ public interface RedisScriptingCommands {
* @param returnType must not be {@literal null}.
* @param numKeys
* @param keysAndArgs must not be {@literal null}.
* @return
* @return script result. {@literal null} when used in pipeline / transaction.
* @since 1.5
* @see <a href="http://redis.io/commands/evalsha">Redis Documentation: EVALSHA</a>
*/
@Nullable
<T> T evalSha(byte[] scriptSha, ReturnType returnType, int numKeys, byte[]... keysAndArgs);
}

View File

@@ -36,7 +36,7 @@ public interface RedisSentinelCommands {
/**
* Get a {@link Collection} of monitored masters and their state.
*
*
* @return Collection of {@link RedisServer}s. Never {@literal null}.
*/
Collection<RedisServer> masters();

View File

@@ -27,6 +27,7 @@ import java.util.Set;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -45,7 +46,7 @@ public class RedisSentinelConfiguration {
private static final String REDIS_SENTINEL_MASTER_CONFIG_PROPERTY = "spring.redis.sentinel.master";
private static final String REDIS_SENTINEL_NODES_CONFIG_PROPERTY = "spring.redis.sentinel.nodes";
private NamedNode master;
private @Nullable NamedNode master;
private Set<RedisNode> sentinels;
private int database;
private RedisPassword password = RedisPassword.none();
@@ -162,8 +163,9 @@ public class RedisSentinelConfiguration {
/**
* Get the {@literal Sentinel} master node.
*
* @return get the master node.
* @return get the master node or {@literal null} if not set.
*/
@Nullable
public NamedNode getMaster() {
return master;
}

View File

@@ -19,6 +19,7 @@ import java.util.List;
import java.util.Properties;
import org.springframework.data.redis.core.types.RedisClientInfo;
import org.springframework.lang.Nullable;
/**
* Server-specific commands supported by Redis.
@@ -30,14 +31,14 @@ import org.springframework.data.redis.core.types.RedisClientInfo;
*/
public interface RedisServerCommands {
public enum ShutdownOption {
enum ShutdownOption {
SAVE, NOSAVE;
}
/**
* @since 1.7
*/
public enum MigrateOption {
enum MigrateOption {
COPY, REPLACE
}
@@ -70,9 +71,10 @@ public interface RedisServerCommands {
/**
* Get time of last {@link #bgSave()} operation in seconds.
*
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/lastsave">Redis Documentation: LASTSAVE</a>
*/
@Nullable
Long lastSave();
/**
@@ -85,9 +87,10 @@ public interface RedisServerCommands {
/**
* Get the total number of available keys in currently selected database.
*
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/dbsize">Redis Documentation: DBSIZE</a>
*/
@Nullable
Long dbSize();
/**
@@ -113,17 +116,19 @@ public interface RedisServerCommands {
* </ul>
* <p>
*
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/info">Redis Documentation: INFO</a>
*/
@Nullable
Properties info();
/**
* Load server information for given {@code selection}.
*
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/info">Redis Documentation: INFO</a>
*/
@Nullable
Properties info(String section);
/**
@@ -145,16 +150,17 @@ public interface RedisServerCommands {
* Load configuration parameters for given {@code pattern} from server.
*
* @param pattern must not be {@literal null}.
* @return never {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/config-get">Redis Documentation: CONFIG GET</a>
*/
@Nullable
Properties getConfig(String pattern);
/**
* Set server configuration for {@code param} to {@code value}.
*
* @param param
* @param value
* @param param must not be {@literal null}.
* @param value must not be {@literal null}.
* @see <a href="http://redis.io/commands/config-set">Redis Documentation: CONFIG SET</a>
*/
void setConfig(String param, String value);
@@ -170,10 +176,11 @@ public interface RedisServerCommands {
/**
* Request server timestamp using {@code TIME} command.
*
* @return current server time in milliseconds.
* @return current server time in milliseconds or {@literal null} when used in pipeline / transaction.
* @since 1.1
* @see <a href="http://redis.io/commands/time">Redis Documentation: TIME</a>
*/
@Nullable
Long time();
/**
@@ -199,18 +206,20 @@ public interface RedisServerCommands {
* Returns the name of the current connection.
*
* @see <a href="http://redis.io/commands/client-getname">Redis Documentation: CLIENT GETNAME</a>
* @return
* @return {@literal null} when used in pipeline / transaction.
* @since 1.3
*/
@Nullable
String getClientName();
/**
* Request information and statistics about connected clients.
*
* @return {@link List} of {@link RedisClientInfo} objects.
* @return {@link List} of {@link RedisClientInfo} objects or {@literal null} when used in pipeline / transaction.
* @since 1.3
* @see <a href="http://redis.io/commands/client-list">Redis Documentation: CLIENT LIST</a>
*/
@Nullable
List<RedisClientInfo> getClientList();
/**
@@ -242,7 +251,7 @@ public interface RedisServerCommands {
* @since 1.7
* @see <a href="http://redis.io/commands/migrate">Redis Documentation: MIGRATE</a>
*/
void migrate(byte[] key, RedisNode target, int dbIndex, MigrateOption option);
void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option);
/**
* Atomically transfer a key from a source Redis instance to a destination Redis instance. On success the key is
@@ -256,5 +265,5 @@ public interface RedisServerCommands {
* @since 1.7
* @see <a href="http://redis.io/commands/migrate">Redis Documentation: MIGRATE</a>
*/
void migrate(byte[] key, RedisNode target, int dbIndex, MigrateOption option, long timeout);
void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option, long timeout);
}

View File

@@ -20,6 +20,7 @@ import java.util.Set;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.lang.Nullable;
/**
* Set-specific commands supported by Redis.
@@ -34,29 +35,32 @@ public interface RedisSetCommands {
* Add given {@code values} to set at {@code key}.
*
* @param key must not be {@literal null}.
* @param values
* @return
* @param values must not be empty.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/sadd">Redis Documentation: SADD</a>
*/
@Nullable
Long sAdd(byte[] key, byte[]... values);
/**
* Remove given {@code values} from set at {@code key} and return the number of removed elements.
*
* @param key must not be {@literal null}.
* @param values
* @return
* @param values must not be empty.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/srem">Redis Documentation: SREM</a>
*/
@Nullable
Long sRem(byte[] key, byte[]... values);
/**
* Remove and return a random member from set at {@code key}.
*
* @param key must not be {@literal null}.
* @return
* @return {@literal null} when key does not exist or used in pipeline / transaction.
* @see <a href="http://redis.io/commands/spop">Redis Documentation: SPOP</a>
*/
@Nullable
byte[] sPop(byte[] key);
/**
@@ -64,10 +68,11 @@ public interface RedisSetCommands {
*
* @param key must not be {@literal null}.
* @param count number of random members to pop from the set.
* @return empty {@link List} if set does not exist. Never {@literal null}.
* @return empty {@link List} if set does not exist. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/spop">Redis Documentation: SPOP</a>
* @since 2.0
*/
@Nullable
List<byte[]> sPop(byte[] key, long count);
/**
@@ -75,38 +80,42 @@ public interface RedisSetCommands {
*
* @param srcKey must not be {@literal null}.
* @param destKey must not be {@literal null}.
* @param value
* @return
* @param value must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/smove">Redis Documentation: SMOVE</a>
*/
@Nullable
Boolean sMove(byte[] srcKey, byte[] destKey, byte[] value);
/**
* Get size of set at {@code key}.
*
* @param key must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/scard">Redis Documentation: SCARD</a>
*/
@Nullable
Long sCard(byte[] key);
/**
* Check if set at {@code key} contains {@code value}.
*
* @param key must not be {@literal null}.
* @param value
* @return
* @param value must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/sismember">Redis Documentation: SISMEMBER</a>
*/
@Nullable
Boolean sIsMember(byte[] key, byte[] value);
/**
* Returns the members intersecting all given sets at {@code keys}.
*
* @param keys must not be {@literal null}.
* @return
* @return empty {@link Set} if no intersection found. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/sinter">Redis Documentation: SINTER</a>
*/
@Nullable
Set<byte[]> sInter(byte[]... keys);
/**
@@ -114,18 +123,20 @@ public interface RedisSetCommands {
*
* @param destKey must not be {@literal null}.
* @param keys must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/sinterstore">Redis Documentation: SINTERSTORE</a>
*/
@Nullable
Long sInterStore(byte[] destKey, byte[]... keys);
/**
* Union all sets at given {@code keys}.
*
* @param keys must not be {@literal null}.
* @return
* @return empty {@link Set} if keys do not exist. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/sunion">Redis Documentation: SUNION</a>
*/
@Nullable
Set<byte[]> sUnion(byte[]... keys);
/**
@@ -133,18 +144,20 @@ public interface RedisSetCommands {
*
* @param destKey must not be {@literal null}.
* @param keys must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/sunionstore">Redis Documentation: SUNIONSTORE</a>
*/
@Nullable
Long sUnionStore(byte[] destKey, byte[]... keys);
/**
* Diff all sets for given {@code keys}.
*
* @param keys must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/sdiff">Redis Documentation: SDIFF</a>
*/
@Nullable
Set<byte[]> sDiff(byte[]... keys);
/**
@@ -152,27 +165,30 @@ public interface RedisSetCommands {
*
* @param destKey must not be {@literal null}.
* @param keys must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/sdiffstore">Redis Documentation: SDIFFSTORE</a>
*/
@Nullable
Long sDiffStore(byte[] destKey, byte[]... keys);
/**
* Get all elements of set at {@code key}.
*
* @param key must not be {@literal null}.
* @return
* @return empty {@link Set} when key does not exist. {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/smembers">Redis Documentation: SMEMBERS</a>
*/
@Nullable
Set<byte[]> sMembers(byte[] key);
/**
* Get random element from set at {@code key}.
*
* @param key must not be {@literal null}.
* @return
* @return can be {@literal null}.
* @see <a href="http://redis.io/commands/srandmember">Redis Documentation: SRANDMEMBER</a>
*/
@Nullable
byte[] sRandMember(byte[] key);
/**
@@ -180,9 +196,10 @@ public interface RedisSetCommands {
*
* @param key must not be {@literal null}.
* @param count
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/srandmember">Redis Documentation: SRANDMEMBER</a>
*/
@Nullable
List<byte[]> sRandMember(byte[] key, long count);
/**
@@ -190,7 +207,7 @@ public interface RedisSetCommands {
*
* @param key must not be {@literal null}.
* @param options must not be {@literal null}.
* @return
* @return never {@literal null}.
* @since 1.4
* @see <a href="http://redis.io/commands/scan">Redis Documentation: SCAN</a>
*/

View File

@@ -19,6 +19,7 @@ import java.util.List;
import java.util.Map;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.lang.Nullable;
/**
* String/Value-specific commands supported by Redis.
@@ -37,28 +38,31 @@ public interface RedisStringCommands {
* Get the value of {@code key}.
*
* @param key must not be {@literal null}.
* @return
* @return {@literal null} when key does not exist or used in pipeline / transaction.
* @see <a href="http://redis.io/commands/get">Redis Documentation: GET</a>
*/
@Nullable
byte[] get(byte[] key);
/**
* Set {@code value} of {@code key} and return its old value.
*
* @param key must not be {@literal null}.
* @param value
* @return
* @param value must not be {@literal null}.
* @return {@literal null} if key did not exist before or when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/getset">Redis Documentation: GETSET</a>
*/
@Nullable
byte[] getSet(byte[] key, byte[] value);
/**
* Get multiple {@code keys}. Values are returned in the order of the requested keys.
*
* @param keys must not be {@literal null}.
* @return
* @param keys must not be {@literal null}.
* @return empty {@link List} if keys do not exist or when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/mget">Redis Documentation: MGET</a>
*/
@Nullable
List<byte[]> mGet(byte[]... keys);
/**
@@ -76,8 +80,8 @@ public interface RedisStringCommands {
*
* @param key must not be {@literal null}.
* @param value must not be {@literal null}.
* @param expiration can be {@literal null}. Defaulted to {@link Expiration#persistent()}.
* @param option can be {@literal null}. Defaulted to {@link SetOption#UPSERT}.
* @param expiration must not be {@literal null}. Use {@link Expiration#persistent()} to not set any ttl.
* @param option must not be {@literal null}. Use {@link SetOption#upsert()} to add non existing.
* @since 1.7
* @see <a href="http://redis.io/commands/set">Redis Documentation: SET</a>
*/
@@ -117,7 +121,7 @@ public interface RedisStringCommands {
/**
* Set multiple keys to multiple values using key-value pairs provided in {@code tuple}.
*
* @param tuple must not be {@literal null}.
* @param tuple must not be {@literal null}.
* @see <a href="http://redis.io/commands/mset">Redis Documentation: MSET</a>
*/
void mSet(Map<byte[], byte[]> tuple);
@@ -164,7 +168,7 @@ public interface RedisStringCommands {
* Decrement an integer value stored as string value of {@code key} by 1.
*
* @param key must not be {@literal null}.
* @return
* @return never {@literal null}.
* @see <a href="http://redis.io/commands/decr">Redis Documentation: DECR</a>
*/
Long decr(byte[] key);
@@ -174,7 +178,7 @@ public interface RedisStringCommands {
*
* @param key must not be {@literal null}.
* @param value
* @return
* @return never {@literal null}.
* @see <a href="http://redis.io/commands/decrby">Redis Documentation: DECRBY</a>
*/
Long decrBy(byte[] key, long value);
@@ -183,8 +187,8 @@ public interface RedisStringCommands {
* Append a {@code value} to {@code key}.
*
* @param key must not be {@literal null}.
* @param value
* @return
* @param value must not be {@literal null}.
* @return never {@literal null}.
* @see <a href="http://redis.io/commands/append">Redis Documentation: APPEND</a>
*/
Long append(byte[] key, byte[] value);
@@ -215,7 +219,7 @@ public interface RedisStringCommands {
*
* @param key must not be {@literal null}.
* @param offset
* @return
* @return never {@literal null}.
* @see <a href="http://redis.io/commands/getbit">Redis Documentation: GETBIT</a>
*/
Boolean getBit(byte[] key, long offset);
@@ -235,7 +239,7 @@ public interface RedisStringCommands {
* Count the number of set bits (population counting) in value stored at {@code key}.
*
* @param key must not be {@literal null}.
* @return
* @return never {@literal null}.
* @see <a href="http://redis.io/commands/bitcount">Redis Documentation: BITCOUNT</a>
*/
Long bitCount(byte[] key);
@@ -247,7 +251,7 @@ public interface RedisStringCommands {
* @param key must not be {@literal null}.
* @param begin
* @param end
* @return
* @return never {@literal null}.
* @see <a href="http://redis.io/commands/bitcount">Redis Documentation: BITCOUNT</a>
*/
Long bitCount(byte[] key, long begin, long end);
@@ -255,10 +259,10 @@ public interface RedisStringCommands {
/**
* Perform bitwise operations between strings.
*
* @param op must not be {@literal null}.
* @param op must not be {@literal null}.
* @param destination must not be {@literal null}.
* @param keys must not be {@literal null}.
* @return
* @return never {@literal null}.
* @see <a href="http://redis.io/commands/bitop">Redis Documentation: BITOP</a>
*/
Long bitOp(BitOperation op, byte[] destination, byte[]... keys);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2013 the original author or authors.
* 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.
@@ -16,11 +16,13 @@
package org.springframework.data.redis.connection;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.lang.Nullable;
/**
* Exception thrown when issuing commands on a connection that is subscribed and waiting for events.
*
* @author Costin Leau
* @author Christoph Strobl
* @see org.springframework.data.redis.connection.RedisPubSubCommands
*/
public class RedisSubscribedConnectionException extends InvalidDataAccessApiUsageException {
@@ -31,7 +33,7 @@ public class RedisSubscribedConnectionException extends InvalidDataAccessApiUsag
* @param msg
* @param cause
*/
public RedisSubscribedConnectionException(String msg, Throwable cause) {
public RedisSubscribedConnectionException(@Nullable String msg, @Nullable Throwable cause) {
super(msg, cause);
}

View File

@@ -19,6 +19,7 @@ import java.util.Set;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -44,8 +45,14 @@ public interface RedisZSetCommands {
*/
interface Tuple extends Comparable<Double> {
/**
* @return the raw value of the member.
*/
byte[] getValue();
/**
* @return the member score value used for sorting.
*/
Double getScore();
}
@@ -57,8 +64,8 @@ public interface RedisZSetCommands {
*/
class Range {
Boundary min;
Boundary max;
@Nullable Boundary min;
@Nullable Boundary max;
/**
* @return new {@link Range}
@@ -81,8 +88,8 @@ public interface RedisZSetCommands {
/**
* Greater Than Equals
*
* @param min
* @return
* @param min must not be {@literal null}.
* @return this.
*/
public Range gte(Object min) {
@@ -94,8 +101,8 @@ public interface RedisZSetCommands {
/**
* Greater Than
*
* @param min
* @return
* @param min must not be {@literal null}.
* @return this.
*/
public Range gt(Object min) {
@@ -107,8 +114,8 @@ public interface RedisZSetCommands {
/**
* Less Then Equals
*
* @param max
* @return
* @param max must not be {@literal null}.
* @return this.
*/
public Range lte(Object max) {
@@ -120,8 +127,8 @@ public interface RedisZSetCommands {
/**
* Less Than
*
* @param max
* @return
* @param max must not be {@literal null}.
* @return this.
*/
public Range lt(Object max) {
@@ -133,6 +140,7 @@ public interface RedisZSetCommands {
/**
* @return {@literal null} if not set.
*/
@Nullable
public Boundary getMin() {
return min;
}
@@ -140,6 +148,7 @@ public interface RedisZSetCommands {
/**
* @return {@literal null} if not set.
*/
@Nullable
public Boundary getMax() {
return max;
}
@@ -150,18 +159,19 @@ public interface RedisZSetCommands {
*/
public static class Boundary {
Object value;
@Nullable Object value;
boolean including;
static Boundary infinite() {
return new Boundary(null, true);
}
Boundary(Object value, boolean including) {
Boundary(@Nullable Object value, boolean including) {
this.value = value;
this.including = including;
}
@Nullable
public Object getValue() {
return value;
}
@@ -179,6 +189,19 @@ public interface RedisZSetCommands {
*/
class Limit {
private static final Limit UNLIMITED = new Limit() {
@Override
public int getCount() {
return -1;
}
@Override
public int getOffset() {
return super.getOffset();
}
};
int offset;
int count;
@@ -203,6 +226,18 @@ public interface RedisZSetCommands {
public int getOffset() {
return offset;
}
public boolean isUnlimited() {
return this.equals(UNLIMITED);
}
/**
* @return new {@link Limit} indicating no limit;
* @since 1.3
*/
public static Limit unlimited() {
return UNLIMITED;
}
}
/**
@@ -211,9 +246,10 @@ public interface RedisZSetCommands {
* @param key must not be {@literal null}.
* @param score the score.
* @param value the value.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/zadd">Redis Documentation: ZADD</a>
*/
@Nullable
Boolean zAdd(byte[] key, double score, byte[] value);
/**
@@ -221,9 +257,10 @@ public interface RedisZSetCommands {
*
* @param key must not be {@literal null}.
* @param tuples must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/zadd">Redis Documentation: ZADD</a>
*/
@Nullable
Long zAdd(byte[] key, Set<Tuple> tuples);
/**
@@ -231,9 +268,10 @@ public interface RedisZSetCommands {
*
* @param key must not be {@literal null}.
* @param values must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/zrem">Redis Documentation: ZREM</a>
*/
@Nullable
Long zRem(byte[] key, byte[]... values);
/**
@@ -242,19 +280,21 @@ public interface RedisZSetCommands {
* @param key must not be {@literal null}.
* @param increment
* @param value the value.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/zincrby">Redis Documentation: ZINCRBY</a>
*/
@Nullable
Double zIncrBy(byte[] key, double increment, byte[] value);
/**
* Determine the index of element with {@code value} in a sorted set.
*
* @param key must not be {@literal null}.
* @param value the value.
* @return
* @param value the value. Must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/zrank">Redis Documentation: ZRANK</a>
*/
@Nullable
Long zRank(byte[] key, byte[] value);
/**
@@ -262,9 +302,10 @@ public interface RedisZSetCommands {
*
* @param key must not be {@literal null}.
* @param value the value.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/zrevrank">Redis Documentation: ZREVRANK</a>
*/
@Nullable
Long zRevRank(byte[] key, byte[] value);
/**
@@ -273,9 +314,11 @@ public interface RedisZSetCommands {
* @param key must not be {@literal null}.
* @param start
* @param end
* @return
* @return empty {@link Set} when key does not exists or no members in range. {@literal null} when used in pipeline /
* transaction.
* @see <a href="http://redis.io/commands/zrange">Redis Documentation: ZRANGE</a>
*/
@Nullable
Set<byte[]> zRange(byte[] key, long start, long end);
/**
@@ -284,9 +327,11 @@ public interface RedisZSetCommands {
* @param key must not be {@literal null}.
* @param start
* @param end
* @return
* @return empty {@link Set} when key does not exists or no members in range. {@literal null} when used in pipeline /
* transaction.
* @see <a href="http://redis.io/commands/zrange">Redis Documentation: ZRANGE</a>
*/
@Nullable
Set<Tuple> zRangeWithScores(byte[] key, long start, long end);
/**
@@ -295,9 +340,11 @@ public interface RedisZSetCommands {
* @param key must not be {@literal null}.
* @param min
* @param max
* @return
* @return empty {@link Set} when key does not exists or no members in range. {@literal null} when used in pipeline /
* transaction.
* @see <a href="http://redis.io/commands/zrangebyscore">Redis Documentation: ZRANGEBYSCORE</a>
*/
@Nullable
default Set<byte[]> zRangeByScore(byte[] key, double min, double max) {
return zRangeByScore(key, new Range().gte(min).lte(max));
}
@@ -307,12 +354,14 @@ public interface RedisZSetCommands {
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @return empty {@link Set} when key does not exists or no members in range. {@literal null} when used in pipeline /
* transaction.
* @since 1.6
* @see <a href="http://redis.io/commands/zrangebyscore">Redis Documentation: ZRANGEBYSCORE</a>
*/
@Nullable
default Set<Tuple> zRangeByScoreWithScores(byte[] key, Range range) {
return zRangeByScoreWithScores(key, range, null);
return zRangeByScoreWithScores(key, range, Limit.unlimited());
}
/**
@@ -321,9 +370,11 @@ public interface RedisZSetCommands {
* @param key must not be {@literal null}.
* @param min
* @param max
* @return
* @return empty {@link Set} when key does not exists or no members in range. {@literal null} when used in pipeline /
* transaction.
* @see <a href="http://redis.io/commands/zrangebyscore">Redis Documentation: ZRANGEBYSCORE</a>
*/
@Nullable
default Set<Tuple> zRangeByScoreWithScores(byte[] key, double min, double max) {
return zRangeByScoreWithScores(key, new Range().gte(min).lte(max));
}
@@ -337,9 +388,11 @@ public interface RedisZSetCommands {
* @param max
* @param offset
* @param count
* @return
* @return empty {@link Set} when key does not exists or no members in range. {@literal null} when used in pipeline /
* transaction.
* @see <a href="http://redis.io/commands/zrangebyscore">Redis Documentation: ZRANGEBYSCORE</a>
*/
@Nullable
default Set<byte[]> zRangeByScore(byte[] key, double min, double max, long offset, long count) {
return zRangeByScore(key, new Range().gte(min).lte(max),
new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue()));
@@ -349,14 +402,16 @@ public interface RedisZSetCommands {
* Get set of {@link Tuple}s in range from {@code start} to {@code end} where score is between {@code min} and
* {@code max} from sorted set.
*
* @param key
* @param key must not be {@literal null}.
* @param min
* @param max
* @param offset
* @param count
* @return
* @return empty {@link Set} when key does not exists or no members in range. {@literal null} when used in pipeline /
* transaction.
* @see <a href="http://redis.io/commands/zrangebyscore">Redis Documentation: ZRANGEBYSCORE</a>
*/
@Nullable
default Set<Tuple> zRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) {
return zRangeByScoreWithScores(key, new Range().gte(min).lte(max),
new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue()));
@@ -368,11 +423,13 @@ public interface RedisZSetCommands {
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit
* @return
* @param limit must not be {@literal null}.
* @return empty {@link Set} when key does not exists or no members in range. {@literal null} when used in pipeline /
* transaction.
* @since 1.6
* @see <a href="http://redis.io/commands/zrangebyscore">Redis Documentation: ZRANGEBYSCORE</a>
*/
@Nullable
Set<Tuple> zRangeByScoreWithScores(byte[] key, Range range, Limit limit);
/**
@@ -381,9 +438,11 @@ public interface RedisZSetCommands {
* @param key must not be {@literal null}.
* @param start
* @param end
* @return
* @return empty {@link Set} when key does not exists or no members in range. {@literal null} when used in pipeline /
* transaction.
* @see <a href="http://redis.io/commands/zrevrange">Redis Documentation: ZREVRANGE</a>
*/
@Nullable
Set<byte[]> zRevRange(byte[] key, long start, long end);
/**
@@ -392,9 +451,11 @@ public interface RedisZSetCommands {
* @param key must not be {@literal null}.
* @param start
* @param end
* @return
* @return empty {@link Set} when key does not exists or no members in range. {@literal null} when used in pipeline /
* transaction.
* @see <a href="http://redis.io/commands/zrevrange">Redis Documentation: ZREVRANGE</a>
*/
@Nullable
Set<Tuple> zRevRangeWithScores(byte[] key, long start, long end);
/**
@@ -403,9 +464,11 @@ public interface RedisZSetCommands {
* @param key must not be {@literal null}.
* @param min
* @param max
* @return
* @return empty {@link Set} when key does not exists or no members in range. {@literal null} when used in pipeline /
* transaction.
* @see <a href="http://redis.io/commands/zrevrange">Redis Documentation: ZREVRANGE</a>
*/
@Nullable
default Set<byte[]> zRevRangeByScore(byte[] key, double min, double max) {
return zRevRangeByScore(key, new Range().gte(min).lte(max));
}
@@ -416,12 +479,14 @@ public interface RedisZSetCommands {
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @return empty {@link Set} when key does not exists or no members in range. {@literal null} when used in pipeline /
* transaction.
* @since 1.6
* @see <a href="http://redis.io/commands/zrevrangebyscore">Redis Documentation: ZREVRANGEBYSCORE</a>
*/
@Nullable
default Set<byte[]> zRevRangeByScore(byte[] key, Range range) {
return zRevRangeByScore(key, range, null);
return zRevRangeByScore(key, range, Limit.unlimited());
}
/**
@@ -431,11 +496,13 @@ public interface RedisZSetCommands {
* @param key must not be {@literal null}.
* @param min
* @param max
* @return
* @return empty {@link Set} when key does not exists or no members in range. {@literal null} when used in pipeline /
* transaction.
* @see <a href="http://redis.io/commands/zrevrangebyscore">Redis Documentation: ZREVRANGEBYSCORE</a>
*/
@Nullable
default Set<Tuple> zRevRangeByScoreWithScores(byte[] key, double min, double max) {
return zRevRangeByScoreWithScores(key, new Range().gte(min).lte(max), null);
return zRevRangeByScoreWithScores(key, new Range().gte(min).lte(max), Limit.unlimited());
}
/**
@@ -447,9 +514,10 @@ public interface RedisZSetCommands {
* @param max
* @param offset
* @param count
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/zrevrangebyscore">Redis Documentation: ZREVRANGEBYSCORE</a>
*/
@Nullable
default Set<byte[]> zRevRangeByScore(byte[] key, double min, double max, long offset, long count) {
return zRevRangeByScore(key, new Range().gte(min).lte(max),
@@ -462,11 +530,12 @@ public interface RedisZSetCommands {
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit
* @return
* @param limit must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @since 1.6
* @see <a href="http://redis.io/commands/zrevrangebyscore">Redis Documentation: ZREVRANGEBYSCORE</a>
*/
@Nullable
Set<byte[]> zRevRangeByScore(byte[] key, Range range, Limit limit);
/**
@@ -478,9 +547,10 @@ public interface RedisZSetCommands {
* @param max
* @param offset
* @param count
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/zrevrangebyscore">Redis Documentation: ZREVRANGEBYSCORE</a>
*/
@Nullable
default Set<Tuple> zRevRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) {
return zRevRangeByScoreWithScores(key, new Range().gte(min).lte(max),
@@ -493,12 +563,13 @@ public interface RedisZSetCommands {
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @since 1.6
* @see <a href="http://redis.io/commands/zrevrangebyscore">Redis Documentation: ZREVRANGEBYSCORE</a>
*/
@Nullable
default Set<Tuple> zRevRangeByScoreWithScores(byte[] key, Range range) {
return zRevRangeByScoreWithScores(key, range, null);
return zRevRangeByScoreWithScores(key, range, Limit.unlimited());
}
/**
@@ -507,11 +578,12 @@ public interface RedisZSetCommands {
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit
* @return
* @param limit must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @since 1.6
* @see <a href="http://redis.io/commands/zrevrangebyscore">Redis Documentation: ZREVRANGEBYSCORE</a>
*/
@Nullable
Set<Tuple> zRevRangeByScoreWithScores(byte[] key, Range range, Limit limit);
/**
@@ -520,9 +592,10 @@ public interface RedisZSetCommands {
* @param key must not be {@literal null}.
* @param min
* @param max
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/zcount">Redis Documentation: ZCOUNT</a>
*/
@Nullable
default Long zCount(byte[] key, double min, double max) {
return zCount(key, new Range().gte(min).lte(max));
}
@@ -532,19 +605,21 @@ public interface RedisZSetCommands {
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @since 1.6
* @see <a href="http://redis.io/commands/zcount">Redis Documentation: ZCOUNT</a>
*/
@Nullable
Long zCount(byte[] key, Range range);
/**
* Get the size of sorted set with {@code key}.
*
* @param key must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/zcard">Redis Documentation: ZCARD</a>
*/
@Nullable
Long zCard(byte[] key);
/**
@@ -552,9 +627,10 @@ public interface RedisZSetCommands {
*
* @param key must not be {@literal null}.
* @param value the value.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/zscore">Redis Documentation: ZSCORE</a>
*/
@Nullable
Double zScore(byte[] key, byte[] value);
/**
@@ -563,9 +639,10 @@ public interface RedisZSetCommands {
* @param key must not be {@literal null}.
* @param start
* @param end
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/zremrangebyrank">Redis Documentation: ZREMRANGEBYRANK</a>
*/
@Nullable
Long zRemRange(byte[] key, long start, long end);
/**
@@ -574,9 +651,10 @@ public interface RedisZSetCommands {
* @param key must not be {@literal null}.
* @param min
* @param max
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/zremrangebyscore">Redis Documentation: ZREMRANGEBYSCORE</a>
*/
@Nullable
default Long zRemRangeByScore(byte[] key, double min, double max) {
return zRemRangeByScore(key, new Range().gte(min).lte(max));
}
@@ -586,10 +664,11 @@ public interface RedisZSetCommands {
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @since 1.6
* @see <a href="http://redis.io/commands/zremrangebyscore">Redis Documentation: ZREMRANGEBYSCORE</a>
*/
@Nullable
Long zRemRangeByScore(byte[] key, Range range);
/**
@@ -597,9 +676,10 @@ public interface RedisZSetCommands {
*
* @param destKey must not be {@literal null}.
* @param sets must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/zunionstore">Redis Documentation: ZUNIONSTORE</a>
*/
@Nullable
Long zUnionStore(byte[] destKey, byte[]... sets);
/**
@@ -609,9 +689,10 @@ public interface RedisZSetCommands {
* @param aggregate must not be {@literal null}.
* @param weights
* @param sets must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/zunionstore">Redis Documentation: ZUNIONSTORE</a>
*/
@Nullable
Long zUnionStore(byte[] destKey, Aggregate aggregate, int[] weights, byte[]... sets);
/**
@@ -619,9 +700,10 @@ public interface RedisZSetCommands {
*
* @param destKey must not be {@literal null}.
* @param sets must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @see <a href="http://redis.io/commands/zinterstore">Redis Documentation: ZINTERSTORE</a>
*/
@Nullable
Long zInterStore(byte[] destKey, byte[]... sets);
/**
@@ -634,6 +716,7 @@ public interface RedisZSetCommands {
* @return
* @see <a href="http://redis.io/commands/zinterstore">Redis Documentation: ZINTERSTORE</a>
*/
@Nullable
Long zInterStore(byte[] destKey, Aggregate aggregate, int[] weights, byte[]... sets);
/**
@@ -653,10 +736,11 @@ public interface RedisZSetCommands {
* @param key must not be {@literal null}.
* @param min
* @param max
* @return
* @return {@literal null} when used in pipeline / transaction.
* @since 1.5
* @see <a href="http://redis.io/commands/zrangebyscore">Redis Documentation: ZRANGEBYSCORE</a>
*/
@Nullable
default Set<byte[]> zRangeByScore(byte[] key, String min, String max) {
return zRangeByScore(key, new Range().gte(min).lte(max));
}
@@ -666,12 +750,13 @@ public interface RedisZSetCommands {
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @since 1.6
* @see <a href="http://redis.io/commands/zrangebyscore">Redis Documentation: ZRANGEBYSCORE</a>
*/
@Nullable
default Set<byte[]> zRangeByScore(byte[] key, Range range) {
return zRangeByScore(key, range, null);
return zRangeByScore(key, range, Limit.unlimited());
}
/**
@@ -683,10 +768,11 @@ public interface RedisZSetCommands {
* @param max must not be {@literal null}.
* @param offset
* @param count
* @return
* @return {@literal null} when used in pipeline / transaction.
* @since 1.5
* @see <a href="http://redis.io/commands/zrangebyscore">Redis Documentation: ZRANGEBYSCORE</a>
*/
@Nullable
Set<byte[]> zRangeByScore(byte[] key, String min, String max, long offset, long count);
/**
@@ -695,21 +781,23 @@ public interface RedisZSetCommands {
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit
* @return
* @param limit must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @since 1.6
* @see <a href="http://redis.io/commands/zrangebyscore">Redis Documentation: ZRANGEBYSCORE</a>
*/
@Nullable
Set<byte[]> zRangeByScore(byte[] key, Range range, Limit limit);
/**
* Get all the elements in the sorted set at {@literal key} in lexicographical ordering.
*
* @param key must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @since 1.6
* @see <a href="http://redis.io/commands/zrangebylex">Redis Documentation: ZRANGEBYLEX</a>
*/
@Nullable
default Set<byte[]> zRangeByLex(byte[] key) {
return zRangeByLex(key, Range.unbounded());
}
@@ -719,12 +807,13 @@ public interface RedisZSetCommands {
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @return {@literal null} when used in pipeline / transaction.
* @since 1.6
* @see <a href="http://redis.io/commands/zrangebylex">Redis Documentation: ZRANGEBYLEX</a>
*/
@Nullable
default Set<byte[]> zRangeByLex(byte[] key, Range range) {
return zRangeByLex(key, range, null);
return zRangeByLex(key, range, Limit.unlimited());
}
/**
@@ -733,11 +822,12 @@ public interface RedisZSetCommands {
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @param range can be {@literal null}.
* @return
* @param limit must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @since 1.6
* @see <a href="http://redis.io/commands/zrangebylex">Redis Documentation: ZRANGEBYLEX</a>
*/
@Nullable
Set<byte[]> zRangeByLex(byte[] key, Range range, Limit limit);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-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.
@@ -17,11 +17,14 @@ package org.springframework.data.redis.connection;
import java.util.List;
import org.springframework.lang.Nullable;
/**
* Represents a data type returned from Redis, currently used to denote the expected return type of Redis scripting
* commands
*
* @author Jennifer Hickey
* @author Christoph Strobl
*/
public enum ReturnType {
@@ -50,7 +53,12 @@ public enum ReturnType {
*/
VALUE;
public static ReturnType fromJavaType(Class<?> javaType) {
/**
* @param javaType can be {@literal null} which translates to {@link ReturnType#STATUS}.
* @return never {@literal null}.
*/
public static ReturnType fromJavaType(@Nullable Class<?> javaType) {
if (javaType == null) {
return ReturnType.STATUS;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2013 the original author or authors.
* 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.
@@ -15,24 +15,28 @@
*/
package org.springframework.data.redis.connection;
import org.springframework.lang.Nullable;
/**
* Entity containing the parameters for the SORT operation.
*
*
* @author Costin Leau
* @author Christoph Strobl
*/
public interface SortParameters {
/**
* Sorting order.
*/
public enum Order {
enum Order {
ASC, DESC
}
/**
* Utility class wrapping the 'LIMIT' setting.
*/
static class Range {
class Range {
private final long start;
private final long count;
@@ -52,37 +56,42 @@ public interface SortParameters {
/**
* Returns the sorting order. Can be null if nothing is specified.
*
* @return sorting order
*
* @return sorting order. {@literal null} if not set.
*/
@Nullable
Order getOrder();
/**
* Indicates if the sorting is numeric (default) or alphabetical (lexicographical). Can be null if nothing is
* specified.
*
* @return the type of sorting
*
* @return the type of sorting. {@literal null} if not set.
*/
@Nullable
Boolean isAlphabetic();
/**
* Returns the pattern (if set) for sorting by external keys (<tt>BY</tt>). Can be null if nothing is specified.
*
* @return <tt>BY</tt> pattern.
*
* @return <tt>BY</tt> pattern. {@literal null} if not set.
*/
@Nullable
byte[] getByPattern();
/**
* Returns the pattern (if set) for retrieving external keys (<tt>GET</tt>). Can be null if nothing is specified.
*
* @return <tt>GET</tt> pattern.
*
* @return <tt>GET</tt> pattern. {@literal null} if not set.
*/
@Nullable
byte[][] getGetPattern();
/**
* Returns the sorting limit (range or pagination). Can be null if nothing is specified.
*
* @return sorting limit/range
*
* @return sorting limit/range. {@literal null} if not set.
*/
@Nullable
Range getLimit();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2013 the original author or authors.
* 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.
@@ -22,20 +22,21 @@ import java.util.Collection;
* threads. Note that once a subscription died, it cannot accept any more subscriptions.
*
* @author Costin Leau
* @author Christoph Strobl
*/
public interface Subscription {
/**
* Adds the given channels to the current subscription.
*
* @param channels channel names
*
* @param channels channel names. Must not be empty.
*/
void subscribe(byte[]... channels) throws RedisInvalidSubscriptionException;
/**
* Adds the given channel patterns to the current subscription.
*
* @param patterns channel patterns
*
* @param patterns channel patterns. Must not be empty.
*/
void pSubscribe(byte[]... patterns) throws RedisInvalidSubscriptionException;
@@ -46,8 +47,8 @@ public interface Subscription {
/**
* Cancels the current subscription for all given channels.
*
* @param channels channel names
*
* @param channels channel names. Must not be empty.
*/
void unsubscribe(byte[]... channels);
@@ -58,35 +59,35 @@ public interface Subscription {
/**
* Cancels the subscription for all channels matching the given patterns.
*
* @param patterns
*
* @param patterns must not be empty.
*/
void pUnsubscribe(byte[]... patterns);
/**
* Returns the (named) channels for this subscription.
*
*
* @return collection of named channels
*/
Collection<byte[]> getChannels();
/**
* Returns the channel patters for this subscription.
*
*
* @return collection of channel patterns
*/
Collection<byte[]> getPatterns();
/**
* Returns the listener used for this subscription.
*
*
* @return the listener used for this subscription.
*/
MessageListener getListener();
/**
* Indicates whether this subscription is still 'alive' or not.
*
*
* @return true if the subscription still applies, false otherwise.
*/
boolean isAlive();

View File

@@ -46,6 +46,7 @@ import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation;
import org.springframework.data.redis.connection.RedisNode.NodeType;
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.NumberUtils;
@@ -95,11 +96,13 @@ abstract public class Converters {
String[] args = source.split(" ");
String[] hostAndPort = StringUtils.split(args[HOST_PORT_INDEX], ":");
Assert.notNull(hostAndPort, "CusterNode information does not define host and port!");
SlotRange range = parseSlotRange(args);
Set<Flag> flags = parseFlags(args);
String portPart = hostAndPort[1];
if (portPart.contains("@")) {
if (portPart != null && portPart.contains("@")) {
portPart = portPart.substring(0, portPart.indexOf('@'));
}
@@ -211,7 +214,9 @@ abstract public class Converters {
}
public static Properties toProperties(Map<?, ?> source) {
return MAP_TO_PROPERTIES.convert(source);
Properties properties = MAP_TO_PROPERTIES.convert(source);
return properties != null ? properties : new Properties();
}
public static Boolean toBoolean(Long source) {
@@ -424,7 +429,11 @@ abstract public class Converters {
INSTANCE;
DistanceConverter forMetric(Metric metric) {
/**
* @param metric can be {@literal null}. Defaults to {@link DistanceUnit#METERS}.
* @return never {@literal null}.
*/
DistanceConverter forMetric(@Nullable Metric metric) {
return new DistanceConverter(
metric == null || ObjectUtils.nullSafeEquals(Metrics.NEUTRAL, metric) ? DistanceUnit.METERS : metric);
}
@@ -433,14 +442,22 @@ abstract public class Converters {
private Metric metric;
public DistanceConverter(Metric metric) {
/**
* @param metric can be {@literal null}. Defaults to {@link DistanceUnit#METERS}.
* @return never {@literal null}.
*/
DistanceConverter(@Nullable Metric metric) {
this.metric = metric == null || ObjectUtils.nullSafeEquals(Metrics.NEUTRAL, metric) ? DistanceUnit.METERS
: metric;
}
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(Object)
*/
@Override
public Distance convert(Double source) {
return source == null ? null : new Distance(source, metric);
return new Distance(source, metric);
}
}
}
@@ -456,13 +473,13 @@ abstract public class Converters {
final RedisSerializer<V> serializer;
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(Object)
*/
@Override
public GeoResults<GeoLocation<V>> convert(GeoResults<GeoLocation<byte[]>> source) {
if (source == null) {
return new GeoResults<>(Collections.<GeoResult<GeoLocation<V>>> emptyList());
}
List<GeoResult<GeoLocation<V>>> values = new ArrayList<>(source.getContent().size());
for (GeoResult<GeoLocation<byte[]>> value : source.getContent()) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 the original author or authors.
* Copyright 2013-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.
@@ -25,6 +25,7 @@ import org.springframework.core.convert.converter.Converter;
*
* @author Jennifer Hickey
* @author Mark Paluch
* @author Christoph Strobl
* @param <S> The type of elements in the List to convert
* @param <T> The type of elements in the converted List
*/
@@ -39,12 +40,13 @@ public class ListConverter<S, T> implements Converter<List<S>, List<T>> {
this.itemConverter = itemConverter;
}
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(Object)
*/
@Override
public List<T> convert(List<S> source) {
if (source == null) {
return null;
}
List<T> results = new ArrayList<>();
for (S result : source) {
results.add(itemConverter.convert(result));

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-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.
@@ -21,11 +21,17 @@ import org.springframework.core.convert.converter.Converter;
* Converts Longs to Booleans
*
* @author Jennifer Hickey
* @author Christoph Strobl
*/
public class LongToBooleanConverter implements Converter<Long, Boolean> {
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(Object)
*/
@Override
public Boolean convert(Long result) {
return result != null ? result == 1 : null;
return result == 1;
}
}

View File

@@ -15,16 +15,18 @@
*/
package org.springframework.data.redis.connection.convert;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.core.convert.converter.Converter;
/**
* Converts a Map of values of one key/value type to a Map of values of another type
*
* @author Jennifer Hickey
* @author Christoph Strobl
* @param <S> The type of keys and values in the Map to convert
* @param <T> The type of keys and values in the converted Map
*/
@@ -33,31 +35,24 @@ public class MapConverter<S, T> implements Converter<Map<S, S>, Map<T, T>> {
private Converter<S, T> itemConverter;
/**
* @param itemConverter The {@link Converter} to use for converting individual Map keys and values
* @param itemConverter The {@link Converter} to use for converting individual Map keys and values. Must not be
* {@literal null}.
*/
public MapConverter(Converter<S, T> itemConverter) {
this.itemConverter = itemConverter;
}
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(Object)
*/
@Override
public Map<T, T> convert(Map<S, S> source) {
if (source == null) {
return null;
}
return source.entrySet().stream()
.collect(Collectors.toMap(e -> itemConverter.convert(e.getKey()), e -> itemConverter.convert(e.getValue()),
(a, b) -> a, source instanceof LinkedHashMap ? LinkedHashMap::new : HashedMap::new));
Map<T, T> results;
if (source instanceof LinkedHashMap) {
results = new LinkedHashMap<>();
} else {
results = new HashMap<>();
}
for (Map.Entry<S, S> result : source.entrySet()) {
results.put(itemConverter.convert(result.getKey()), itemConverter.convert(result.getValue()));
}
return results;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-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.
@@ -25,16 +25,19 @@ import org.springframework.core.convert.converter.Converter;
* @since 1.4
*/
public enum MapToPropertiesConverter implements Converter<Map<?, ?>, Properties> {
INSTANCE;
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(Object)
*/
@Override
public Properties convert(Map<?, ?> source) {
Properties p = new Properties();
if (source != null) {
p.putAll(source);
}
return p;
Properties target = new Properties();
target.putAll(source);
return target;
}
}

View File

@@ -18,13 +18,16 @@ package org.springframework.data.redis.connection.convert;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.core.convert.converter.Converter;
import org.springframework.util.Assert;
/**
* Converts a Set of values of one type to a Set of values of another type
*
* @author Jennifer Hickey
* @author Christoph Strobl
* @param <S> The type of elements in the Set to convert
* @param <T> The type of elements in the converted Set
*/
@@ -33,31 +36,23 @@ public class SetConverter<S, T> implements Converter<Set<S>, Set<T>> {
private Converter<S, T> itemConverter;
/**
* @param itemConverter The {@link Converter} to use for converting individual Set items
* @param itemConverter The {@link Converter} to use for converting individual Set items. Must not be {@literal null}.
*/
public SetConverter(Converter<S, T> itemConverter) {
Assert.notNull(itemConverter, "ItemConverter must not be null!");
this.itemConverter = itemConverter;
}
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(Object)
*/
@Override
public Set<T> convert(Set<S> source) {
if (source == null) {
return null;
}
Set<T> results;
if (source instanceof LinkedHashSet) {
results = new LinkedHashSet<>();
} else {
results = new HashSet<>();
}
for (S result : source) {
results.add(itemConverter.convert(result));
}
return results;
return source.stream().map(itemConverter::convert)
.collect(Collectors.toCollection(source instanceof LinkedHashSet ? LinkedHashSet::new : HashSet::new));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-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.
@@ -20,15 +20,18 @@ import org.springframework.data.redis.connection.DataType;
/**
* Converts Strings to {@link DataType}s
*
*
* @author Jennifer Hickey
* @author Christoph Strobl
*/
public class StringToDataTypeConverter implements Converter<String, DataType> {
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(Object)
*/
@Override
public DataType convert(String source) {
if (source == null) {
return null;
}
return DataType.fromCode(source);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-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.
@@ -23,23 +23,24 @@ import org.springframework.data.redis.RedisSystemException;
/**
* Converts Strings to {@link Properties}
*
*
* @author Jennifer Hickey
* @author Christoph Strobl
*/
public class StringToPropertiesConverter implements Converter<String, Properties> {
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(Object)
*/
@Override
public Properties convert(String source) {
if (source == null) {
return null;
}
Properties info = new Properties();
StringReader stringReader = new StringReader(source);
try {
try (StringReader stringReader = new StringReader(source)) {
info.load(stringReader);
} catch (Exception ex) {
throw new RedisSystemException("Cannot read Redis info", ex);
} finally {
stringReader.close();
}
return info;
}

View File

@@ -16,7 +16,6 @@
package org.springframework.data.redis.connection.convert;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.core.convert.converter.Converter;
@@ -36,19 +35,19 @@ import org.springframework.data.redis.core.types.RedisClientInfo.RedisClientInfo
*/
public class StringToRedisClientInfoConverter implements Converter<String[], List<RedisClientInfo>> {
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(Object)
*/
@Override
public List<RedisClientInfo> convert(String[] lines) {
if (lines == null) {
return Collections.emptyList();
}
List<RedisClientInfo> infos = new ArrayList<>(lines.length);
List<RedisClientInfo> clientInfoList = new ArrayList<>(lines.length);
for (String line : lines) {
infos.add(RedisClientInfoBuilder.fromString(line));
clientInfoList.add(RedisClientInfoBuilder.fromString(line));
}
return infos;
return clientInfoList;
}
}

View File

@@ -22,6 +22,7 @@ import java.util.Queue;
import org.springframework.core.convert.converter.Converter;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.RedisSystemException;
import org.springframework.data.redis.connection.FutureResult;
/**
@@ -29,6 +30,7 @@ import org.springframework.data.redis.connection.FutureResult;
* objects returned in the list as well, using the supplied Exception {@link Converter}
*
* @author Jennifer Hickey
* @author Christoph Strobl
* @param <T> The type of {@link FutureResult} of the individual tx operations
*/
public class TransactionResultConverter<T> implements Converter<List<Object>, List<Object>> {
@@ -39,19 +41,22 @@ public class TransactionResultConverter<T> implements Converter<List<Object>, Li
public TransactionResultConverter(Queue<FutureResult<T>> txResults,
Converter<Exception, DataAccessException> exceptionConverter) {
this.txResults = txResults;
this.exceptionConverter = exceptionConverter;
}
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(Object)
*/
@Override
public List<Object> convert(List<Object> execResults) {
if (execResults == null) {
return null;
}
if (execResults.size() != txResults.size()) {
throw new IllegalArgumentException("Incorrect number of transaction results. Expected: " + txResults.size()
+ " Actual: " + execResults.size());
throw new IllegalArgumentException(
"Incorrect number of transaction results. Expected: " + txResults.size() + " Actual: " + execResults.size());
}
List<Object> convertedResults = new ArrayList<>();
@@ -59,7 +64,11 @@ public class TransactionResultConverter<T> implements Converter<List<Object>, Li
for (Object result : execResults) {
FutureResult<T> futureResult = txResults.remove();
if (result instanceof Exception) {
throw exceptionConverter.convert((Exception) result);
Exception source = (Exception) result;
DataAccessException convertedException = exceptionConverter.convert(source);
throw convertedException != null ? convertedException
: new RedisSystemException("Error reading future result.", source);
}
if (!(futureResult.isStatus())) {
convertedResults.add(futureResult.convert(result));

View File

@@ -0,0 +1,5 @@
/**
* Redis specific converters used for sending data and parsing responses.
*/
@org.springframework.lang.NonNullApi
package org.springframework.data.redis.connection.convert;

View File

@@ -23,11 +23,13 @@ import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocketFactory;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.lang.Nullable;
/**
* Default implementation of {@literal JedisClientConfiguration}.
*
* @author Mark Paluch
* @author Christoph Strobl
* @since 2.0
*/
class DefaultJedisClientConfiguration implements JedisClientConfiguration {
@@ -42,9 +44,10 @@ class DefaultJedisClientConfiguration implements JedisClientConfiguration {
private final Duration readTimeout;
private final Duration connectTimeout;
DefaultJedisClientConfiguration(boolean useSsl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters,
HostnameVerifier hostnameVerifier, boolean usePooling, GenericObjectPoolConfig poolConfig, String clientName,
Duration readTimeout, Duration connectTimeout) {
DefaultJedisClientConfiguration(boolean useSsl, @Nullable SSLSocketFactory sslSocketFactory,
@Nullable SSLParameters sslParameters, @Nullable HostnameVerifier hostnameVerifier, boolean usePooling,
@Nullable GenericObjectPoolConfig poolConfig, @Nullable String clientName, Duration readTimeout,
Duration connectTimeout) {
this.useSsl = useSsl;
this.sslSocketFactory = Optional.ofNullable(sslSocketFactory);
@@ -57,7 +60,8 @@ class DefaultJedisClientConfiguration implements JedisClientConfiguration {
this.connectTimeout = connectTimeout;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.jedis.JedisClientConfiguration#useSsl()
*/
@Override
@@ -65,7 +69,8 @@ class DefaultJedisClientConfiguration implements JedisClientConfiguration {
return useSsl;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.jedis.JedisClientConfiguration#getSslSocketFactory()
*/
@Override
@@ -73,7 +78,8 @@ class DefaultJedisClientConfiguration implements JedisClientConfiguration {
return sslSocketFactory;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.jedis.JedisClientConfiguration#getSslParameters()
*/
@Override
@@ -81,7 +87,8 @@ class DefaultJedisClientConfiguration implements JedisClientConfiguration {
return sslParameters;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.jedis.JedisClientConfiguration#getHostnameVerifier()
*/
@Override
@@ -89,7 +96,8 @@ class DefaultJedisClientConfiguration implements JedisClientConfiguration {
return hostnameVerifier;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.jedis.JedisClientConfiguration#usePooling()
*/
@Override
@@ -97,7 +105,8 @@ class DefaultJedisClientConfiguration implements JedisClientConfiguration {
return usePooling;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.jedis.JedisClientConfiguration#getPoolConfig()
*/
@Override
@@ -105,7 +114,8 @@ class DefaultJedisClientConfiguration implements JedisClientConfiguration {
return poolConfig;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.jedis.JedisClientConfiguration#getClientName()
*/
@Override
@@ -113,7 +123,8 @@ class DefaultJedisClientConfiguration implements JedisClientConfiguration {
return clientName;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.jedis.JedisClientConfiguration#getReadTimeout()
*/
@Override
@@ -121,7 +132,8 @@ class DefaultJedisClientConfiguration implements JedisClientConfiguration {
return readTimeout;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.jedis.JedisClientConfiguration#getConnectTimeout()
*/
@Override

View File

@@ -27,6 +27,7 @@ import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocketFactory;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -263,12 +264,12 @@ public interface JedisClientConfiguration {
JedisPoolingClientConfigurationBuilder, JedisSslClientConfigurationBuilder {
private boolean useSsl;
private SSLSocketFactory sslSocketFactory;
private SSLParameters sslParameters;
private HostnameVerifier hostnameVerifier;
private @Nullable SSLSocketFactory sslSocketFactory;
private @Nullable SSLParameters sslParameters;
private @Nullable HostnameVerifier hostnameVerifier;
private boolean usePooling;
private GenericObjectPoolConfig poolConfig = new JedisPoolConfig();
private String clientName;
private @Nullable String clientName;
private Duration readTimeout = Duration.ofMillis(Protocol.DEFAULT_TIMEOUT);
private Duration connectTimeout = Duration.ofMillis(Protocol.DEFAULT_TIMEOUT);

View File

@@ -15,6 +15,8 @@
*/
package org.springframework.data.redis.connection.jedis;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.lang.Nullable;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.BinaryJedisPubSub;
import redis.clients.jedis.HostAndPort;
@@ -74,7 +76,7 @@ public class JedisClusterConnection implements DefaultedRedisClusterConnection {
private ClusterCommandExecutor clusterCommandExecutor;
private final boolean disposeClusterCommandExecutorOnClose;
private volatile JedisSubscription subscription;
private volatile @Nullable JedisSubscription subscription;
/**
* Create new {@link JedisClusterConnection} utilizing native connections via {@link JedisCluster}.
@@ -810,7 +812,7 @@ public class JedisClusterConnection implements DefaultedRedisClusterConnection {
return connection;
}
throw new IllegalStateException(String.format("Node %s is unknown to cluster", node));
throw new DataAccessResourceFailureException(String.format("Node %s is unknown to cluster", node));
}
private JedisPool getResourcePoolForSpecificNode(RedisClusterNode node) {
@@ -855,7 +857,7 @@ public class JedisClusterConnection implements DefaultedRedisClusterConnection {
private final Object lock = new Object();
private final JedisCluster cluster;
private long time = 0;
private ClusterTopology cached;
private @Nullable ClusterTopology cached;
/**
* Create new {@link JedisClusterTopologyProvider}.s

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.redis.connection.jedis;
import org.springframework.lang.Nullable;
import redis.clients.jedis.BinaryJedis;
import java.util.ArrayList;
@@ -477,7 +478,7 @@ class JedisClusterServerCommands implements RedisClusterServerCommands {
* @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) {
public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option) {
migrate(key, target, dbIndex, option, Long.MAX_VALUE);
}
@@ -486,7 +487,7 @@ class JedisClusterServerCommands implements RedisClusterServerCommands {
* @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,
public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option,
final long timeout) {
final int timeoutToUse = timeout <= Integer.MAX_VALUE ? (int) timeout : Integer.MAX_VALUE;

View File

@@ -156,11 +156,11 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES);
try {
if (limit != null) {
return JedisConverters.toTupleSet(
connection.getCluster().zrangeByScoreWithScores(key, min, max, limit.getOffset(), limit.getCount()));
if (limit.isUnlimited()) {
return JedisConverters.toTupleSet(connection.getCluster().zrangeByScoreWithScores(key, min, max));
}
return JedisConverters.toTupleSet(connection.getCluster().zrangeByScoreWithScores(key, min, max));
return JedisConverters.toTupleSet(
connection.getCluster().zrangeByScoreWithScores(key, min, max, limit.getOffset(), limit.getCount()));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -178,10 +178,10 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES);
try {
if (limit != null) {
return connection.getCluster().zrevrangeByScore(key, max, min, limit.getOffset(), limit.getCount());
if (limit.isUnlimited()) {
return connection.getCluster().zrevrangeByScore(key, max, min);
}
return connection.getCluster().zrevrangeByScore(key, max, min);
return connection.getCluster().zrevrangeByScore(key, max, min, limit.getOffset(), limit.getCount());
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -200,11 +200,11 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES);
try {
if (limit != null) {
return JedisConverters.toTupleSet(
connection.getCluster().zrevrangeByScoreWithScores(key, max, min, limit.getOffset(), limit.getCount()));
if (limit.isUnlimited()) {
return JedisConverters.toTupleSet(connection.getCluster().zrevrangeByScoreWithScores(key, max, min));
}
return JedisConverters.toTupleSet(connection.getCluster().zrevrangeByScoreWithScores(key, max, min));
return JedisConverters.toTupleSet(
connection.getCluster().zrevrangeByScoreWithScores(key, max, min, limit.getOffset(), limit.getCount()));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -262,10 +262,10 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES);
try {
if (limit != null) {
return connection.getCluster().zrangeByScore(key, min, max, limit.getOffset(), limit.getCount());
if (limit.isUnlimited()) {
return connection.getCluster().zrangeByScore(key, min, max);
}
return connection.getCluster().zrangeByScore(key, min, max);
return connection.getCluster().zrangeByScore(key, min, max, limit.getOffset(), limit.getCount());
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
@@ -279,15 +279,16 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
public Set<byte[]> zRangeByLex(byte[] key, Range range, Limit limit) {
Assert.notNull(range, "Range cannot be null for ZRANGEBYLEX.");
Assert.notNull(limit, "Limit must not be null!");
byte[] min = JedisConverters.boundaryToBytesForZRangeByLex(range.getMin(), JedisConverters.toBytes("-"));
byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getMax(), JedisConverters.toBytes("+"));
try {
if (limit != null) {
return connection.getCluster().zrangeByLex(key, min, max, limit.getOffset(), limit.getCount());
if (limit.isUnlimited()) {
return connection.getCluster().zrangeByLex(key, min, max);
}
return connection.getCluster().zrangeByLex(key, min, max);
return connection.getCluster().zrangeByLex(key, min, max, limit.getOffset(), limit.getCount());
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}

View File

@@ -45,6 +45,7 @@ import org.springframework.data.redis.FallbackExceptionTranslationStrategy;
import org.springframework.data.redis.RedisConnectionFailureException;
import org.springframework.data.redis.connection.*;
import org.springframework.data.redis.connection.convert.TransactionResultConverter;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
@@ -100,14 +101,14 @@ public class JedisConnection extends AbstractRedisConnection {
private final Jedis jedis;
private final Client client;
private Transaction transaction;
private @Nullable Transaction transaction;
private final Pool<Jedis> pool;
/**
* flag indicating whether the connection needs to be dropped or not
*/
private boolean broken = false;
private volatile JedisSubscription subscription;
private volatile Pipeline pipeline;
private volatile @Nullable JedisSubscription subscription;
private volatile @Nullable Pipeline pipeline;
private final int dbIndex;
private final String clientName;
private boolean convertPipelineAndTxResults = true;
@@ -125,10 +126,13 @@ public class JedisConnection extends AbstractRedisConnection {
@SuppressWarnings("unchecked")
public Object get() {
if (convertPipelineAndTxResults && converter != null) {
return converter.convert(resultHolder.get());
Object raw = resultHolder.get();
if (!convertPipelineAndTxResults || raw == null) {
return raw;
}
return resultHolder.get();
return converter != null ? converter.convert(raw) : raw;
}
}
@@ -594,10 +598,12 @@ public class JedisConnection extends AbstractRedisConnection {
}
}
@Nullable
public Pipeline getPipeline() {
return pipeline;
}
@Nullable
public Transaction getTransaction() {
return transaction;
}

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.redis.connection.jedis;
import org.springframework.lang.Nullable;
import redis.clients.jedis.Client;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
@@ -91,16 +92,16 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
JedisConverters.exceptionConverter());
private final JedisClientConfiguration clientConfiguration;
private JedisShardInfo shardInfo;
private @Nullable JedisShardInfo shardInfo;
private boolean providedShardInfo = false;
private Pool<Jedis> pool;
private @Nullable Pool<Jedis> pool;
private boolean convertPipelineAndTxResults = true;
private RedisStandaloneConfiguration standaloneConfig = new RedisStandaloneConfiguration("localhost",
Protocol.DEFAULT_PORT);
private RedisSentinelConfiguration sentinelConfig;
private RedisClusterConfiguration clusterConfig;
private JedisCluster cluster;
private ClusterCommandExecutor clusterCommandExecutor;
private @Nullable RedisSentinelConfiguration sentinelConfig;
private @Nullable RedisClusterConfiguration clusterConfig;
private @Nullable JedisCluster cluster;
private @Nullable ClusterCommandExecutor clusterCommandExecutor;
/**
* Constructs a new <code>JedisConnectionFactory</code> instance with default settings (default connection pooling, no
@@ -609,6 +610,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
* @deprecated since 2.0.
*/
@Deprecated
@Nullable
public JedisShardInfo getShardInfo() {
return shardInfo;
}
@@ -896,12 +898,12 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
static class MutableJedisClientConfiguration implements JedisClientConfiguration {
private boolean useSsl;
private SSLSocketFactory sslSocketFactory;
private SSLParameters sslParameters;
private HostnameVerifier hostnameVerifier;
private @Nullable SSLSocketFactory sslSocketFactory;
private @Nullable SSLParameters sslParameters;
private @Nullable HostnameVerifier hostnameVerifier;
private boolean usePooling = true;
private GenericObjectPoolConfig poolConfig = new JedisPoolConfig();
private String clientName;
private @Nullable String clientName;
private Duration readTimeout = Duration.ofMillis(Protocol.DEFAULT_TIMEOUT);
private Duration connectTimeout = Duration.ofMillis(Protocol.DEFAULT_TIMEOUT);

View File

@@ -24,6 +24,7 @@ import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.connection.convert.Converters;
import org.springframework.data.redis.connection.jedis.JedisConnection.JedisResult;
import org.springframework.data.redis.core.types.RedisClientInfo;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -453,7 +454,7 @@ class JedisServerCommands implements RedisServerCommands {
* @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) {
public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option) {
migrate(key, target, dbIndex, option, Long.MAX_VALUE);
}
@@ -462,7 +463,7 @@ class JedisServerCommands implements RedisServerCommands {
* @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) {
public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option, long timeout) {
final int timeoutToUse = timeout <= Integer.MAX_VALUE ? (int) timeout : Integer.MAX_VALUE;

View File

@@ -22,6 +22,7 @@ import java.util.concurrent.TimeUnit;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.connection.jedis.JedisConnection.JedisResult;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
@@ -114,9 +115,12 @@ class JedisStringCommands implements RedisStringCommands {
@Override
public void set(byte[] key, byte[] value, Expiration expiration, SetOption option) {
if (expiration == null || expiration.isPersistent()) {
Assert.notNull(expiration, "Expiration must not be null!");
Assert.notNull(option, "Option must not be null!");
if (option == null || ObjectUtils.nullSafeEquals(SetOption.UPSERT, option)) {
if (expiration.isPersistent()) {
if (ObjectUtils.nullSafeEquals(SetOption.UPSERT, option)) {
set(key, value);
} else {
@@ -143,7 +147,7 @@ class JedisStringCommands implements RedisStringCommands {
} else {
if (option == null || ObjectUtils.nullSafeEquals(SetOption.UPSERT, option)) {
if (ObjectUtils.nullSafeEquals(SetOption.UPSERT, option)) {
if (ObjectUtils.nullSafeEquals(TimeUnit.MILLISECONDS, expiration.getTimeUnit())) {
pSetEx(key, expiration.getExpirationTime(), value);

View File

@@ -1,5 +1,5 @@
/**
* Connection package for <a href="http://github.com/xetorthio/jedis">Jedis</a> library.
*/
@org.springframework.lang.NonNullApi
package org.springframework.data.redis.connection.jedis;

View File

@@ -21,6 +21,8 @@ import io.lettuce.core.resource.ClientResources;
import java.time.Duration;
import java.util.Optional;
import org.springframework.lang.Nullable;
/**
* Default implementation of {@literal LettuceClientConfiguration}.
*
@@ -39,7 +41,8 @@ class DefaultLettuceClientConfiguration implements LettuceClientConfiguration {
private final Duration shutdownTimeout;
DefaultLettuceClientConfiguration(boolean useSsl, boolean verifyPeer, boolean startTls,
ClientResources clientResources, ClientOptions clientOptions, Duration timeout, Duration shutdownTimeout) {
@Nullable ClientResources clientResources, @Nullable ClientOptions clientOptions, Duration timeout,
Duration shutdownTimeout) {
this.useSsl = useSsl;
this.verifyPeer = verifyPeer;

View File

@@ -31,6 +31,7 @@ import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.data.redis.connection.PoolException;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -46,16 +47,16 @@ import org.springframework.util.StringUtils;
public class DefaultLettucePool implements LettucePool, InitializingBean {
@SuppressWarnings("rawtypes") //
private GenericObjectPool<StatefulConnection<byte[], byte[]>> internalPool;
private RedisClient client;
private @Nullable GenericObjectPool<StatefulConnection<byte[], byte[]>> internalPool;
private @Nullable RedisClient client;
private int dbIndex = 0;
private GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
private String hostName = "localhost";
private int port = 6379;
private String password;
private @Nullable String password;
private long timeout = TimeUnit.MILLISECONDS.convert(60, TimeUnit.SECONDS);
private RedisSentinelConfiguration sentinelConfiguration;
private ClientResources clientResources;
private @Nullable RedisSentinelConfiguration sentinelConfiguration;
private @Nullable ClientResources clientResources;
/**
* Constructs a new <code>DefaultLettucePool</code> instance with default settings.
@@ -128,8 +129,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
private RedisURI getRedisURI() {
RedisURI redisUri = isRedisSentinelAware()
? LettuceConverters.sentinelConfigurationToRedisURI(sentinelConfiguration)
: createSimpleHostRedisURI();
? LettuceConverters.sentinelConfigurationToRedisURI(sentinelConfiguration) : createSimpleHostRedisURI();
if (StringUtils.hasText(password)) {
redisUri.setPassword(password);
@@ -202,6 +202,8 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
/**
* @return The Redis client
*/
@Override
@Nullable
public RedisClient getClient() {
return client;
}
@@ -244,6 +246,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
*
* @return password for authentication
*/
@Nullable
public String getPassword() {
return password;
}
@@ -317,6 +320,7 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
* @return {@literal null} if not set.
* @since 1.7
*/
@Nullable
public ClientResources getClientResources() {
return clientResources;
}

View File

@@ -23,6 +23,7 @@ import java.time.Duration;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -129,8 +130,8 @@ public interface LettuceClientConfiguration {
boolean useSsl;
boolean verifyPeer = true;
boolean startTls;
ClientResources clientResources;
ClientOptions clientOptions;
@Nullable ClientResources clientResources;
@Nullable ClientOptions clientOptions;
Duration timeout = Duration.ofSeconds(RedisURI.DEFAULT_TIMEOUT);
Duration shutdownTimeout = Duration.ofMillis(100);

View File

@@ -36,6 +36,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.redis.ExceptionTranslationStrategy;
import org.springframework.data.redis.PassThroughExceptionTranslationStrategy;
@@ -45,6 +46,7 @@ import org.springframework.data.redis.connection.ClusterCommandExecutor.MultiKey
import org.springframework.data.redis.connection.ClusterCommandExecutor.NodeResult;
import org.springframework.data.redis.connection.RedisClusterNode.SlotRange;
import org.springframework.data.redis.connection.convert.Converters;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -608,7 +610,7 @@ public class LettuceClusterConnection extends LettuceConnection implements Defau
static class LettuceClusterNodeResourceProvider implements ClusterNodeResourceProvider, DisposableBean {
private final LettuceConnectionProvider connectionProvider;
private volatile StatefulRedisClusterConnection<byte[], byte[]> connection;
private volatile @Nullable StatefulRedisClusterConnection<byte[], byte[]> connection;
@Override
@SuppressWarnings("unchecked")
@@ -627,12 +629,7 @@ public class LettuceClusterConnection extends LettuceConnection implements Defau
try {
return connection.getConnection(node.getHost(), node.getPort()).sync();
} catch (RedisException e) {
// unwrap cause when cluster node not known in cluster
if (e.getCause() instanceof IllegalArgumentException) {
throw (IllegalArgumentException) e.getCause();
}
throw e;
throw new DataAccessResourceFailureException(e.getMessage(), e);
}
}

View File

@@ -66,6 +66,7 @@ import org.springframework.data.redis.connection.convert.TransactionResultConver
import org.springframework.data.redis.connection.lettuce.LettuceConnectionProvider.TargetAware;
import org.springframework.data.redis.core.RedisCommand;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
@@ -95,7 +96,7 @@ public class LettuceConnection extends AbstractRedisConnection {
private final LettuceConnectionProvider connectionProvider;
private final StatefulConnection<byte[], byte[]> asyncSharedConn;
private StatefulConnection<byte[], byte[]> asyncDedicatedConn;
private @Nullable StatefulConnection<byte[], byte[]> asyncDedicatedConn;
private final long timeout;
@@ -103,9 +104,9 @@ public class LettuceConnection extends AbstractRedisConnection {
private boolean isClosed = false;
private boolean isMulti = false;
private boolean isPipelined = false;
private List<LettuceResult> ppline;
private @Nullable List<LettuceResult> ppline;
private Queue<FutureResult<?>> txResults = new LinkedList<>();
private volatile LettuceSubscription subscription;
private volatile @Nullable LettuceSubscription subscription;
/** flag indicating whether the connection needs to be dropped or not */
private boolean convertPipelineAndTxResults = true;

View File

@@ -42,6 +42,7 @@ import org.springframework.data.redis.ExceptionTranslationStrategy;
import org.springframework.data.redis.PassThroughExceptionTranslationStrategy;
import org.springframework.data.redis.RedisConnectionFailureException;
import org.springframework.data.redis.connection.*;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -81,20 +82,20 @@ public class LettuceConnectionFactory
private final Log log = LogFactory.getLog(getClass());
private final LettuceClientConfiguration clientConfiguration;
private AbstractRedisClient client;
private LettuceConnectionProvider connectionProvider;
private LettuceConnectionProvider reactiveConnectionProvider;
private @Nullable AbstractRedisClient client;
private @Nullable LettuceConnectionProvider connectionProvider;
private @Nullable LettuceConnectionProvider reactiveConnectionProvider;
private boolean validateConnection = false;
private boolean shareNativeConnection = true;
private StatefulRedisConnection<byte[], byte[]> connection;
private LettucePool pool;
private @Nullable StatefulRedisConnection<byte[], byte[]> connection;
private @Nullable LettucePool pool;
/** Synchronization monitor for the shared Connection */
private final Object connectionMonitor = new Object();
private boolean convertPipelineAndTxResults = true;
private RedisStandaloneConfiguration standaloneConfig = new RedisStandaloneConfiguration("localhost", 6379);
private RedisSentinelConfiguration sentinelConfiguration;
private RedisClusterConfiguration clusterConfiguration;
private ClusterCommandExecutor clusterCommandExecutor;
private @Nullable RedisSentinelConfiguration sentinelConfiguration;
private @Nullable RedisClusterConfiguration clusterConfiguration;
private @Nullable ClusterCommandExecutor clusterCommandExecutor;
/**
* Constructs a new {@link LettuceConnectionFactory} instance with default settings.
@@ -697,6 +698,7 @@ public class LettuceConnectionFactory
* @return the {@link RedisStandaloneConfiguration}, may be {@literal null}.
* @since 2.0
*/
@Nullable
public RedisSentinelConfiguration getSentinelConfiguration() {
return sentinelConfiguration;
}
@@ -705,6 +707,7 @@ public class LettuceConnectionFactory
* @return the {@link RedisClusterConfiguration}, may be {@literal null}.
* @since 2.0
*/
@Nullable
public RedisClusterConfiguration getClusterConfiguration() {
return clusterConfiguration;
}
@@ -893,7 +896,7 @@ public class LettuceConnectionFactory
private boolean useSsl;
private boolean verifyPeer = true;
private boolean startTls;
private ClientResources clientResources;
private @Nullable ClientResources clientResources;
private Duration timeout = Duration.ofSeconds(RedisURI.DEFAULT_TIMEOUT);
private Duration shutdownTimeout = Duration.ofMillis(100);

View File

@@ -60,6 +60,7 @@ import org.springframework.data.redis.connection.convert.StringToRedisClientInfo
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.core.types.RedisClientInfo;
import org.springframework.data.redis.util.ByteUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
@@ -721,7 +722,7 @@ abstract public class LettuceConverters extends Converters {
* @param option can be {@literal null}.
* @since 1.7
*/
public static SetArgs toSetArgs(Expiration expiration, SetOption option) {
public static SetArgs toSetArgs(@Nullable Expiration expiration, @Nullable SetOption option) {
SetArgs args = new SetArgs();
if (expiration != null && !expiration.isPersistent()) {

View File

@@ -19,6 +19,7 @@ import io.lettuce.core.AbstractRedisClient;
import io.lettuce.core.api.StatefulConnection;
import org.springframework.data.redis.connection.Pool;
import org.springframework.lang.Nullable;
/**
* Pool of Lettuce {@link StatefulConnection}s
@@ -34,6 +35,7 @@ public interface LettucePool extends Pool<StatefulConnection<byte[], byte[]>> {
/**
* @return The {@link AbstractRedisClient} used to create pooled connections
*/
@Nullable
AbstractRedisClient getClient();
}

View File

@@ -317,7 +317,8 @@ class LettuceReactiveStringCommands implements ReactiveStringCommands {
Assert.notNull(command.getKey(), "Key must not be null!");
Range<Long> range = command.getRange();
return (range != null ? cmd.bitcount(command.getKey(), range.getLowerBound().getValue().orElse(null),
return (!Range.unbounded().equals(range) ? cmd.bitcount(command.getKey(), range.getLowerBound().getValue().orElse(null),
range.getUpperBound().getValue().orElse(null)) : cmd.bitcount(command.getKey()))
.map(responseValue -> new NumericResponse<>(command, responseValue));
}));

View File

@@ -229,7 +229,7 @@ class LettuceReactiveZSetCommands implements ReactiveZSetCommands {
Assert.notNull(command.getKey(), "Key must not be null!");
Assert.notNull(command.getRange(), "Range must not be null!");
boolean isLimited = command.getLimit().isPresent();
boolean isLimited = command.getLimit().isPresent() && !command.getLimit().get().isUnlimited();
Publisher<Tuple> result;
@@ -445,7 +445,7 @@ class LettuceReactiveZSetCommands implements ReactiveZSetCommands {
Flux<ByteBuffer> result;
if (command.getLimit() != null) {
if (!command.getLimit().isUnlimited()) {
if (ObjectUtils.nullSafeEquals(command.getDirection(), Direction.ASC)) {
result = cmd.zrangebylex(command.getKey(), ArgumentConverters.toRange(command.getRange()),

View File

@@ -44,7 +44,7 @@ public class LettuceSentinelConnection implements RedisSentinelConnection {
LettuceConverters.exceptionConverter());
private final LettuceConnectionProvider provider;
private StatefulRedisSentinelConnection<String, String> connection;
private StatefulRedisSentinelConnection<String, String> connection; // no that should not be null
/**
* Creates a {@link LettuceSentinelConnection} with a dedicated client for a supplied {@link RedisNode}.

View File

@@ -28,6 +28,7 @@ import org.springframework.data.redis.connection.convert.Converters;
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.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -494,7 +495,7 @@ class LettuceServerCommands implements RedisServerCommands {
* @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) {
public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option) {
migrate(key, target, dbIndex, option, Long.MAX_VALUE);
}
@@ -503,7 +504,7 @@ class LettuceServerCommands implements RedisServerCommands {
* @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) {
public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option, long timeout) {
try {
if (isPipelined()) {

View File

@@ -27,6 +27,7 @@ import org.springframework.data.redis.connection.RedisStringCommands;
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.Expiration;
import org.springframework.util.Assert;
/**
* @author Christoph Strobl
@@ -80,6 +81,9 @@ class LettuceStringCommands implements RedisStringCommands {
@Override
public void set(byte[] key, byte[] value, Expiration expiration, SetOption option) {
Assert.notNull(expiration, "Expiration must not be null!");
Assert.notNull(option, "Option must not be null!");
try {
if (isPipelined()) {
pipeline(connection.newLettuceStatusResult(

View File

@@ -259,36 +259,37 @@ class LettuceZSetCommands implements RedisZSetCommands {
public Set<byte[]> zRangeByScore(byte[] key, Range range, Limit limit) {
Assert.notNull(range, "Range for ZRANGEBYSCORE must not be null!");
Assert.notNull(limit, "Limit must not be null!");
try {
if (isPipelined()) {
if (limit != null) {
pipeline(connection.newLettuceResult(getAsyncConnection().zrangebyscore(key, LettuceConverters.toRange(range),
LettuceConverters.toLimit(limit)), LettuceConverters.bytesListToBytesSet()));
} else {
if (limit.isUnlimited()) {
pipeline(
connection.newLettuceResult(getAsyncConnection().zrangebyscore(key, LettuceConverters.toRange(range)),
LettuceConverters.bytesListToBytesSet()));
} else {
pipeline(connection.newLettuceResult(getAsyncConnection().zrangebyscore(key, LettuceConverters.toRange(range),
LettuceConverters.toLimit(limit)), LettuceConverters.bytesListToBytesSet()));
}
return null;
}
if (isQueueing()) {
if (limit != null) {
transaction(connection.newLettuceTxResult(
getConnection().zrangebyscore(key, LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
LettuceConverters.bytesListToBytesSet()));
} else {
if (limit.isUnlimited()) {
transaction(
connection.newLettuceTxResult(getConnection().zrangebyscore(key, LettuceConverters.toRange(range)),
LettuceConverters.bytesListToBytesSet()));
} else {
transaction(connection.newLettuceTxResult(
getConnection().zrangebyscore(key, LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
LettuceConverters.bytesListToBytesSet()));
}
return null;
}
if (limit != null) {
return LettuceConverters.toBytesSet(
getConnection().zrangebyscore(key, LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)));
if (limit.isUnlimited()) {
return LettuceConverters.toBytesSet(getConnection().zrangebyscore(key, LettuceConverters.toRange(range)));
}
return LettuceConverters.toBytesSet(getConnection().zrangebyscore(key, LettuceConverters.toRange(range)));
return LettuceConverters.toBytesSet(
getConnection().zrangebyscore(key, LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
@@ -302,38 +303,39 @@ class LettuceZSetCommands implements RedisZSetCommands {
public Set<Tuple> zRangeByScoreWithScores(byte[] key, Range range, Limit limit) {
Assert.notNull(range, "Range for ZRANGEBYSCOREWITHSCORES must not be null!");
Assert.notNull(limit, "Limit must not be null!");
try {
if (isPipelined()) {
if (limit != null) {
pipeline(connection.newLettuceResult(getAsyncConnection().zrangebyscoreWithScores(key,
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
LettuceConverters.scoredValuesToTupleSet()));
} else {
if (limit.isUnlimited()) {
pipeline(connection.newLettuceResult(
getAsyncConnection().zrangebyscoreWithScores(key, LettuceConverters.toRange(range)),
LettuceConverters.scoredValuesToTupleSet()));
} else {
pipeline(connection.newLettuceResult(getAsyncConnection().zrangebyscoreWithScores(key,
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
LettuceConverters.scoredValuesToTupleSet()));
}
return null;
}
if (isQueueing()) {
if (limit != null) {
transaction(connection.newLettuceTxResult(getConnection().zrangebyscoreWithScores(key,
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
LettuceConverters.scoredValuesToTupleSet()));
} else {
if (limit.isUnlimited()) {
transaction(connection.newLettuceTxResult(
getConnection().zrangebyscoreWithScores(key, LettuceConverters.toRange(range)),
LettuceConverters.scoredValuesToTupleSet()));
} else {
transaction(connection.newLettuceTxResult(getConnection().zrangebyscoreWithScores(key,
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
LettuceConverters.scoredValuesToTupleSet()));
}
return null;
}
if (limit != null) {
return LettuceConverters.toTupleSet(getConnection().zrangebyscoreWithScores(key,
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)));
if (limit.isUnlimited()) {
return LettuceConverters
.toTupleSet(getConnection().zrangebyscoreWithScores(key, LettuceConverters.toRange(range)));
}
return LettuceConverters
.toTupleSet(getConnection().zrangebyscoreWithScores(key, LettuceConverters.toRange(range)));
return LettuceConverters.toTupleSet(getConnection().zrangebyscoreWithScores(key, LettuceConverters.toRange(range),
LettuceConverters.toLimit(limit)));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
@@ -370,37 +372,38 @@ class LettuceZSetCommands implements RedisZSetCommands {
public Set<byte[]> zRevRangeByScore(byte[] key, Range range, Limit limit) {
Assert.notNull(range, "Range for ZREVRANGEBYSCORE must not be null!");
Assert.notNull(limit, "Limit must not be null!");
try {
if (isPipelined()) {
if (limit != null) {
pipeline(
connection.newLettuceResult(getAsyncConnection().zrevrangebyscore(key, LettuceConverters.toRange(range),
LettuceConverters.toLimit(limit)), LettuceConverters.bytesListToBytesSet()));
} else {
if (limit.isUnlimited()) {
pipeline(
connection.newLettuceResult(getAsyncConnection().zrevrangebyscore(key, LettuceConverters.toRange(range)),
LettuceConverters.bytesListToBytesSet()));
} else {
pipeline(
connection.newLettuceResult(getAsyncConnection().zrevrangebyscore(key, LettuceConverters.toRange(range),
LettuceConverters.toLimit(limit)), LettuceConverters.bytesListToBytesSet()));
}
return null;
}
if (isQueueing()) {
if (limit != null) {
transaction(connection.newLettuceTxResult(
getConnection().zrevrangebyscore(key, LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
LettuceConverters.bytesListToBytesSet()));
} else {
if (limit.isUnlimited()) {
transaction(
connection.newLettuceTxResult(getConnection().zrevrangebyscore(key, LettuceConverters.toRange(range)),
LettuceConverters.bytesListToBytesSet()));
} else {
transaction(connection.newLettuceTxResult(
getConnection().zrevrangebyscore(key, LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
LettuceConverters.bytesListToBytesSet()));
}
return null;
}
if (limit != null) {
return LettuceConverters.toBytesSet(
getConnection().zrevrangebyscore(key, LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)));
if (limit.isUnlimited()) {
return LettuceConverters.toBytesSet(getConnection().zrevrangebyscore(key, LettuceConverters.toRange(range)));
}
return LettuceConverters.toBytesSet(getConnection().zrevrangebyscore(key, LettuceConverters.toRange(range)));
return LettuceConverters.toBytesSet(
getConnection().zrevrangebyscore(key, LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
@@ -414,38 +417,39 @@ class LettuceZSetCommands implements RedisZSetCommands {
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, Range range, Limit limit) {
Assert.notNull(range, "Range for ZREVRANGEBYSCOREWITHSCORES must not be null!");
Assert.notNull(limit, "Limit must not be null!");
try {
if (isPipelined()) {
if (limit != null) {
pipeline(connection.newLettuceResult(getAsyncConnection().zrevrangebyscoreWithScores(key,
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
LettuceConverters.scoredValuesToTupleSet()));
} else {
if (limit.isUnlimited()) {
pipeline(connection.newLettuceResult(
getAsyncConnection().zrevrangebyscoreWithScores(key, LettuceConverters.toRange(range)),
LettuceConverters.scoredValuesToTupleSet()));
} else {
pipeline(connection.newLettuceResult(getAsyncConnection().zrevrangebyscoreWithScores(key,
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
LettuceConverters.scoredValuesToTupleSet()));
}
return null;
}
if (isQueueing()) {
if (limit != null) {
transaction(connection.newLettuceTxResult(getConnection().zrevrangebyscoreWithScores(key,
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
LettuceConverters.scoredValuesToTupleSet()));
} else {
if (limit.isUnlimited()) {
transaction(connection.newLettuceTxResult(
getConnection().zrevrangebyscoreWithScores(key, LettuceConverters.toRange(range)),
LettuceConverters.scoredValuesToTupleSet()));
} else {
transaction(connection.newLettuceTxResult(getConnection().zrevrangebyscoreWithScores(key,
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
LettuceConverters.scoredValuesToTupleSet()));
}
return null;
}
if (limit != null) {
return LettuceConverters.toTupleSet(getConnection().zrevrangebyscoreWithScores(key,
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)));
if (limit.isUnlimited()) {
return LettuceConverters
.toTupleSet(getConnection().zrevrangebyscoreWithScores(key, LettuceConverters.toRange(range)));
}
return LettuceConverters
.toTupleSet(getConnection().zrevrangebyscoreWithScores(key, LettuceConverters.toRange(range)));
return LettuceConverters.toTupleSet(getConnection().zrevrangebyscoreWithScores(key,
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
@@ -751,38 +755,39 @@ class LettuceZSetCommands implements RedisZSetCommands {
public Set<byte[]> zRangeByLex(byte[] key, Range range, Limit limit) {
Assert.notNull(range, "Range cannot be null for ZRANGEBYLEX.");
Assert.notNull(limit, "Limit must not be null!");
try {
if (isPipelined()) {
if (limit != null) {
pipeline(connection.newLettuceResult(
getAsyncConnection().zrangebylex(key, LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
if (limit.isUnlimited()) {
pipeline(connection.newLettuceResult(getAsyncConnection().zrangebylex(key, LettuceConverters.toRange(range)),
LettuceConverters.bytesListToBytesSet()));
} else {
pipeline(connection.newLettuceResult(getAsyncConnection().zrangebylex(key, LettuceConverters.toRange(range)),
pipeline(connection.newLettuceResult(
getAsyncConnection().zrangebylex(key, LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
LettuceConverters.bytesListToBytesSet()));
}
return null;
}
if (isQueueing()) {
if (limit != null) {
transaction(connection.newLettuceTxResult(
getConnection().zrangebylex(key, LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
if (limit.isUnlimited()) {
transaction(connection.newLettuceTxResult(getConnection().zrangebylex(key, LettuceConverters.toRange(range)),
LettuceConverters.bytesListToBytesSet()));
} else {
transaction(connection.newLettuceTxResult(getConnection().zrangebylex(key, LettuceConverters.toRange(range)),
transaction(connection.newLettuceTxResult(
getConnection().zrangebylex(key, LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
LettuceConverters.bytesListToBytesSet()));
}
return null;
}
if (limit != null) {
return LettuceConverters.bytesListToBytesSet().convert(
getConnection().zrangebylex(key, LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)));
if (limit.isUnlimited()) {
return LettuceConverters.bytesListToBytesSet()
.convert(getConnection().zrangebylex(key, LettuceConverters.toRange(range)));
}
return LettuceConverters.bytesListToBytesSet().convert(
getConnection().zrangebylex(key, LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)));
return LettuceConverters.bytesListToBytesSet()
.convert(getConnection().zrangebylex(key, LettuceConverters.toRange(range)));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}

View File

@@ -1,5 +1,5 @@
/**
* Connection package for <a href="https://github.com/mp911de/lettuce">Lettuce</a> Redis client.
* Connection package for <a href="https://lettuce.io">Lettuce</a> Redis client.
*/
@org.springframework.lang.NonNullApi
package org.springframework.data.redis.connection.lettuce;

View File

@@ -4,5 +4,6 @@
*
* <p>Performs exception translation between the underlying library exceptions to Spring's DAO hierarchy.
*/
@org.springframework.lang.NonNullApi
package org.springframework.data.redis.connection;

View File

@@ -22,6 +22,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisInvalidSubscriptionException;
import org.springframework.data.redis.connection.Subscription;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -30,6 +31,7 @@ import org.springframework.util.ObjectUtils;
* the actual registration/unregistration.
*
* @author Costin Leau
* @author Christoph Strobl
*/
public abstract class AbstractSubscription implements Subscription {
@@ -47,12 +49,14 @@ public abstract class AbstractSubscription implements Subscription {
* subscription w/o triggering a subscription action (as some clients (Jedis) require an initial call before entering
* into listening mode).
*
* @param listener
* @param channels
* @param patterns
* @param listener must not be {@literal null}.
* @param channels can be {@literal null}.
* @param patterns can be {@literal null}.
*/
protected AbstractSubscription(MessageListener listener, byte[][] channels, byte[][] patterns) {
protected AbstractSubscription(MessageListener listener, @Nullable byte[][] channels, @Nullable byte[][] patterns) {
Assert.notNull(listener, "MessageListener must not be null!");
this.listener = listener;
synchronized (this.channels) {
@@ -146,7 +150,7 @@ public abstract class AbstractSubscription implements Subscription {
unsubscribe((byte[][]) null);
}
public void pUnsubscribe(byte[]... patts) {
public void pUnsubscribe(@Nullable byte[]... patts) {
if (!isAlive()) {
return;
}
@@ -173,7 +177,7 @@ public abstract class AbstractSubscription implements Subscription {
closeIfUnsubscribed();
}
public void unsubscribe(byte[]... chans) {
public void unsubscribe(@Nullable byte[]... chans) {
if (!isAlive()) {
return;
}
@@ -225,7 +229,7 @@ public abstract class AbstractSubscription implements Subscription {
return list;
}
private static void add(Collection<ByteArrayWrapper> col, byte[]... bytes) {
private static void add(Collection<ByteArrayWrapper> col, @Nullable byte[]... bytes) {
if (!ObjectUtils.isEmpty(bytes)) {
for (byte[] bs : bytes) {
col.add(new ByteArrayWrapper(bs));
@@ -233,7 +237,7 @@ public abstract class AbstractSubscription implements Subscription {
}
}
private static void remove(Collection<ByteArrayWrapper> col, byte[]... bytes) {
private static void remove(Collection<ByteArrayWrapper> col, @Nullable byte[]... bytes) {
if (!ObjectUtils.isEmpty(bytes)) {
for (byte[] bs : bytes) {
col.remove(new ByteArrayWrapper(bs));

View File

@@ -2,6 +2,8 @@ package org.springframework.data.redis.connection.util;
import java.util.Arrays;
import org.springframework.lang.Nullable;
/**
* A very fast and memory efficient class to encode and decode to and from BASE64 in full accordance with RFC 2045.<br>
* <br>
@@ -12,7 +14,8 @@ import java.util.Arrays;
* On byte arrays the encoder is about 20% faster than Jakarta Commons Base64 Codec for encode and about 50% faster for
* decoding large arrays. This implementation is about twice as fast on very small arrays (&lt 30 bytes). If
* source/destination is a <code>String</code> this version is about three times as fast due to the fact that the
* Commons Codec result has to be recoded to a <code>String</code> from <code>byte[]</code>, which is very expensive.<br>
* Commons Codec result has to be recoded to a <code>String</code> from <code>byte[]</code>, which is very
* expensive.<br>
* <br>
* This encode/decode algorithm doesn't create any temporary arrays as many other codecs do, it only allocates the
* resulting array. This produces less garbage and it is possible to handle arrays twice as large as algorithms that
@@ -76,7 +79,7 @@ class Base64 {
* faster.
* @return A BASE64 encoded array. Never <code>null</code>.
*/
public final static char[] encodeToChar(byte[] sArr, boolean lineSep) {
public final static char[] encodeToChar(@Nullable byte[] sArr, boolean lineSep) {
// Check special case
int sLen = sArr != null ? sArr.length : 0;
if (sLen == 0)
@@ -129,7 +132,8 @@ class Base64 {
* @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters
* (including '=') isn't divideable by 4. (I.e. definitely corrupted).
*/
public final static byte[] decode(char[] sArr) {
@Nullable
public final static byte[] decode(@Nullable char[] sArr) {
// Check special case
int sLen = sArr != null ? sArr.length : 0;
if (sLen == 0)
@@ -256,7 +260,7 @@ class Base64 {
* faster.
* @return A BASE64 encoded array. Never <code>null</code>.
*/
public final static byte[] encodeToByte(byte[] sArr, boolean lineSep) {
public final static byte[] encodeToByte(@Nullable byte[] sArr, boolean lineSep) {
// Check special case
int sLen = sArr != null ? sArr.length : 0;
if (sLen == 0)
@@ -309,6 +313,7 @@ class Base64 {
* @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters
* (including '=') isn't divideable by 4. (I.e. definitely corrupted).
*/
@Nullable
public final static byte[] decode(byte[] sArr) {
// Check special case
int sLen = sArr.length;
@@ -451,7 +456,8 @@ class Base64 {
* @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters
* (including '=') isn't divideable by 4. (I.e. definitely corrupted).
*/
public final static byte[] decode(String str) {
@Nullable
public final static byte[] decode(@Nullable String str) {
// Check special case
int sLen = str != null ? str.length() : 0;
if (sLen == 0)

View File

@@ -23,10 +23,13 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.lang.Nullable;
/**
* Simple class containing various decoding utilities.
*
* @author Costin Leau
* @auhtor Christoph Strobl
*/
public abstract class DecodeUtils {
@@ -42,7 +45,8 @@ public abstract class DecodeUtils {
return result;
}
public static byte[] encode(String string) {
@Nullable
public static byte[] encode(@Nullable String string) {
return (string == null ? null : Base64.decode(string));
}

View File

@@ -1,5 +1,6 @@
/**
* Internal utility package for encoding/decoding Strings to byte[] (using Base64) library.
*/
@org.springframework.lang.NonNullApi
package org.springframework.data.redis.connection.util;

Some files were not shown because too many files have changed in this diff Show More