DATAREDIS-315 - Support password protected Redis Cluster.
Add new config property to configure a password for operations with Redis Cluster. The only driver to support Redis Cluster with password is lettuce but 3.4.Final has a blocker bug that prevents the usage Original pull request: #158.
This commit is contained in:
@@ -27,6 +27,7 @@ import java.util.Set;
|
||||
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.NumberUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -36,6 +37,7 @@ import org.springframework.util.StringUtils;
|
||||
* environment.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @since 1.7
|
||||
*/
|
||||
public class RedisClusterConfiguration {
|
||||
@@ -43,10 +45,12 @@ public class RedisClusterConfiguration {
|
||||
private static final String REDIS_CLUSTER_NODES_CONFIG_PROPERTY = "spring.redis.cluster.nodes";
|
||||
private static final String REDIS_CLUSTER_TIMEOUT_CONFIG_PROPERTY = "spring.redis.cluster.timeout";
|
||||
private static final String REDIS_CLUSTER_MAX_REDIRECTS_CONFIG_PROPERTY = "spring.redis.cluster.max-redirects";
|
||||
private static final String REDIS_CLUSTER_PASSWORD_PROPERTY = "spring.redis.cluster.password";
|
||||
|
||||
private Set<RedisNode> clusterNodes;
|
||||
private Long clusterTimeout;
|
||||
private Integer maxRedirects;
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* Creates new {@link RedisClusterConfiguration}.
|
||||
@@ -69,7 +73,7 @@ public class RedisClusterConfiguration {
|
||||
* {@literal null}.
|
||||
*/
|
||||
public RedisClusterConfiguration(Collection<String> clusterNodes) {
|
||||
this(new MapPropertySource("RedisClusterConfiguration", asMap(clusterNodes, -1, -1)));
|
||||
this(new MapPropertySource("RedisClusterConfiguration", asMap(clusterNodes, -1, -1, null)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,6 +84,7 @@ public class RedisClusterConfiguration {
|
||||
* spring.redis.cluster.nodes=127.0.0.1:23679,127.0.0.1:23680,127.0.0.1:23681
|
||||
* spring.redis.cluster.timeout=5
|
||||
* spring.redis.cluster.max-redirects=3
|
||||
* spring.redis.cluster.password=foobar
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
@@ -103,6 +108,9 @@ public class RedisClusterConfiguration {
|
||||
this.maxRedirects = NumberUtils.parseNumber(
|
||||
propertySource.getProperty(REDIS_CLUSTER_MAX_REDIRECTS_CONFIG_PROPERTY).toString(), Integer.class);
|
||||
}
|
||||
if (propertySource.containsProperty(REDIS_CLUSTER_PASSWORD_PROPERTY)) {
|
||||
this.password = propertySource.getProperty(REDIS_CLUSTER_PASSWORD_PROPERTY).toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,6 +164,14 @@ public class RedisClusterConfiguration {
|
||||
return clusterTimeout != null && clusterTimeout > Long.MIN_VALUE ? clusterTimeout : null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param clusterTimeout
|
||||
*/
|
||||
public void setClusterTimeout(long clusterTimeout) {
|
||||
this.clusterTimeout = clusterTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
@@ -163,6 +179,30 @@ public class RedisClusterConfiguration {
|
||||
return maxRedirects != null && maxRedirects > Integer.MIN_VALUE ? maxRedirects : null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param maxRedirects
|
||||
*/
|
||||
public void setMaxRedirects(int maxRedirects) {
|
||||
Assert.isTrue(maxRedirects >= 0, "MaxRedirects must be greater or equal to 0");
|
||||
this.maxRedirects = maxRedirects;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param password can be {@literal null} or empty.
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param host
|
||||
* @param port
|
||||
@@ -189,11 +229,13 @@ public class RedisClusterConfiguration {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param master must not be {@literal null} or empty.
|
||||
* @param clusterHostAndPorts must not be {@literal null}.
|
||||
* @param clusterHostAndPorts must not be {@literal null} or empty.
|
||||
* @param timeout
|
||||
* @param redirects
|
||||
* @param password can be {@literal null} or empty.
|
||||
* @return
|
||||
*/
|
||||
private static Map<String, Object> asMap(Collection<String> clusterHostAndPorts, long timeout, int redirects) {
|
||||
private static Map<String, Object> asMap(Collection<String> clusterHostAndPorts, long timeout, int redirects, String password) {
|
||||
|
||||
notNull(clusterHostAndPorts, "ClusterHostAndPorts must not be null!");
|
||||
|
||||
@@ -205,6 +247,9 @@ public class RedisClusterConfiguration {
|
||||
if (redirects >= 0) {
|
||||
map.put(REDIS_CLUSTER_MAX_REDIRECTS_CONFIG_PROPERTY, Integer.valueOf(redirects));
|
||||
}
|
||||
if (StringUtils.hasText(password)) {
|
||||
map.put(REDIS_CLUSTER_PASSWORD_PROPERTY, password);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ import redis.clients.util.Pool;
|
||||
* @author Costin Leau
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class JedisConnectionFactory implements InitializingBean, DisposableBean, RedisConnectionFactory {
|
||||
|
||||
@@ -292,8 +293,12 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
|
||||
hostAndPort.add(new HostAndPort(node.getHost(), node.getPort()));
|
||||
}
|
||||
|
||||
int timeout = clusterConfig.getClusterTimeout() != null ? clusterConfig.getClusterTimeout().intValue() : 1;
|
||||
int timeout = clusterConfig.getClusterTimeout() != null ? clusterConfig.getClusterTimeout().intValue() : this.timeout;
|
||||
int redirects = clusterConfig.getMaxRedirects() != null ? clusterConfig.getMaxRedirects().intValue() : 5;
|
||||
|
||||
if (StringUtils.hasText(clusterConfig.getPassword())) {
|
||||
throw new UnsupportedOperationException("Jedis does not support password protected Redis Cluster configurations");
|
||||
}
|
||||
|
||||
if (poolConfig != null) {
|
||||
return new JedisCluster(hostAndPort, timeout, redirects, poolConfig);
|
||||
|
||||
@@ -49,6 +49,7 @@ import com.lambdaworks.redis.RedisException;
|
||||
import com.lambdaworks.redis.RedisFuture;
|
||||
import com.lambdaworks.redis.RedisURI;
|
||||
import com.lambdaworks.redis.cluster.RedisClusterClient;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Connection factory creating <a href="http://github.com/mp911de/lettuce">Lettuce</a>-based connections.
|
||||
@@ -464,7 +465,16 @@ public class LettuceConnectionFactory implements InitializingBean, DisposableBea
|
||||
|
||||
List<RedisURI> initialUris = new ArrayList<RedisURI>();
|
||||
for (RedisNode node : this.clusterConfiguration.getClusterNodes()) {
|
||||
initialUris.add(new RedisURI(node.getHost(), node.getPort(), this.timeout, TimeUnit.MILLISECONDS));
|
||||
long timeout = this.clusterConfiguration.getClusterTimeout() != null ? this.clusterConfiguration.getClusterTimeout() : this.timeout;
|
||||
RedisURI redisURI = new RedisURI(node.getHost(), node.getPort(), timeout, TimeUnit.MILLISECONDS);
|
||||
|
||||
if(StringUtils.hasText(this.clusterConfiguration.getPassword())){
|
||||
redisURI.setPassword(this.clusterConfiguration.getPassword());
|
||||
}else if(StringUtils.hasText(password)){
|
||||
redisURI.setPassword(password);
|
||||
}
|
||||
|
||||
initialUris.add(redisURI);
|
||||
}
|
||||
|
||||
RedisClusterClient clusterClient = new RedisClusterClient(initialUris);
|
||||
|
||||
Reference in New Issue
Block a user