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:
Mark Paluch
2016-02-04 15:32:57 +01:00
parent f18def013a
commit 0ac118fcc0
5 changed files with 80 additions and 6 deletions

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.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;
}

View File

@@ -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);

View File

@@ -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);