Add support for `spring.redis.url` property

Update `RedisAutoConfiguration` to optionally configure Redis using a
`spring.redis.url` property`.

Closes gh-7395
This commit is contained in:
Marco Aust 2016-11-15 19:44:34 +01:00 committed by Phillip Webb
parent 16ed59e92f
commit 90eb58252e
4 changed files with 77 additions and 4 deletions

View File

@ -16,10 +16,14 @@
package org.springframework.boot.autoconfigure.data.redis; package org.springframework.boot.autoconfigure.data.redis;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.pool2.impl.GenericObjectPool; import org.apache.commons.pool2.impl.GenericObjectPool;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.JedisPoolConfig;
@ -55,12 +59,15 @@ import org.springframework.util.StringUtils;
* @author Phillip Webb * @author Phillip Webb
* @author Eddú Meléndez * @author Eddú Meléndez
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Marco Aust
*/ */
@Configuration @Configuration
@ConditionalOnClass({ JedisConnection.class, RedisOperations.class, Jedis.class }) @ConditionalOnClass({ JedisConnection.class, RedisOperations.class, Jedis.class })
@EnableConfigurationProperties(RedisProperties.class) @EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoConfiguration { public class RedisAutoConfiguration {
private static final Log logger = LogFactory.getLog(RedisAutoConfiguration.class);
/** /**
* Redis connection configuration. * Redis connection configuration.
*/ */
@ -91,10 +98,31 @@ public class RedisAutoConfiguration {
protected final JedisConnectionFactory applyProperties( protected final JedisConnectionFactory applyProperties(
JedisConnectionFactory factory) { JedisConnectionFactory factory) {
factory.setHostName(this.properties.getHost()); if (StringUtils.hasText(this.properties.getUrl())) {
factory.setPort(this.properties.getPort()); if (this.properties.getUrl().startsWith("rediss://")) {
if (this.properties.getPassword() != null) { factory.setUseSsl(true);
factory.setPassword(this.properties.getPassword()); }
try {
URI redisURI = new URI(this.properties.getUrl());
factory.setHostName(redisURI.getHost());
factory.setPort(redisURI.getPort());
if (redisURI.getUserInfo() != null) {
factory.setPassword(redisURI.getUserInfo().split(":", 2)[1]);
}
}
catch (URISyntaxException e) {
logger.error("Incorrect spring.redis.url", e);
}
}
else {
factory.setHostName(this.properties.getHost());
factory.setPort(this.properties.getPort());
if (this.properties.getPassword() != null) {
factory.setPassword(this.properties.getPassword());
}
}
if (this.properties.isSsl()) {
factory.setUseSsl(true);
} }
factory.setDatabase(this.properties.getDatabase()); factory.setDatabase(this.properties.getDatabase());
if (this.properties.getTimeout() > 0) { if (this.properties.getTimeout() > 0) {

View File

@ -26,6 +26,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* @author Dave Syer * @author Dave Syer
* @author Christoph Strobl * @author Christoph Strobl
* @author Eddú Meléndez * @author Eddú Meléndez
* @author Marco Aust
*/ */
@ConfigurationProperties(prefix = "spring.redis") @ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties { public class RedisProperties {
@ -35,6 +36,11 @@ public class RedisProperties {
*/ */
private int database = 0; private int database = 0;
/**
* Redis url, which will overrule host, port and password if set.
*/
private String url;
/** /**
* Redis server host. * Redis server host.
*/ */
@ -50,6 +56,11 @@ public class RedisProperties {
*/ */
private int port = 6379; private int port = 6379;
/**
* Enable SSL.
*/
private boolean ssl;
/** /**
* Connection timeout in milliseconds. * Connection timeout in milliseconds.
*/ */
@ -69,6 +80,14 @@ public class RedisProperties {
this.database = database; this.database = database;
} }
public String getUrl() {
return this.url;
}
public void setUrl(String url) {
this.url = url;
}
public String getHost() { public String getHost() {
return this.host; return this.host;
} }
@ -93,6 +112,14 @@ public class RedisProperties {
this.port = port; this.port = port;
} }
public boolean isSsl() {
return this.ssl;
}
public void setSsl(boolean ssl) {
this.ssl = ssl;
}
public void setTimeout(int timeout) { public void setTimeout(int timeout) {
this.timeout = timeout; this.timeout = timeout;
} }

View File

@ -75,6 +75,22 @@ public class RedisAutoConfigurationTests {
.isEqualTo(1); .isEqualTo(1);
} }
@Test
public void testOverrideURLRedisConfiguration() throws Exception {
load("spring.redis.host:foo", "spring.redis.password:xyz",
"spring.redis.port:1000",
"spring.redis.ssl:true",
"spring.redis.url:redis://user:password@example:33");
assertThat(this.context.getBean(JedisConnectionFactory.class).getHostName())
.isEqualTo("example");
assertThat(this.context.getBean(JedisConnectionFactory.class).getPort())
.isEqualTo(33);
assertThat(this.context.getBean(JedisConnectionFactory.class).getPassword())
.isEqualTo("password");
assertThat(this.context.getBean(JedisConnectionFactory.class).isUseSsl())
.isEqualTo(true);
}
@Test @Test
public void testRedisConfigurationWithPool() throws Exception { public void testRedisConfigurationWithPool() throws Exception {
load("spring.redis.host:foo", "spring.redis.pool.max-idle:1"); load("spring.redis.host:foo", "spring.redis.pool.max-idle:1");

View File

@ -799,8 +799,10 @@ content into your application; rather pick only the properties that you need.
spring.redis.cluster.max-redirects= # Maximum number of redirects to follow when executing commands across the cluster. spring.redis.cluster.max-redirects= # Maximum number of redirects to follow when executing commands across the cluster.
spring.redis.cluster.nodes= # Comma-separated list of "host:port" pairs to bootstrap from. spring.redis.cluster.nodes= # Comma-separated list of "host:port" pairs to bootstrap from.
spring.redis.database=0 # Database index used by the connection factory. spring.redis.database=0 # Database index used by the connection factory.
spring.redis.url= # Connection URL, will override host, port and password (user will be ignored), e.g. redis://user:password@example.com:6379
spring.redis.host=localhost # Redis server host. spring.redis.host=localhost # Redis server host.
spring.redis.password= # Login password of the redis server. spring.redis.password= # Login password of the redis server.
spring.redis.ssl=false # Enable SSL support.
spring.redis.pool.max-active=8 # Max number of connections that can be allocated by the pool at a given time. Use a negative value for no limit. spring.redis.pool.max-active=8 # Max number of connections that can be allocated by the pool at a given time. Use a negative value for no limit.
spring.redis.pool.max-idle=8 # Max number of "idle" connections in the pool. Use a negative value to indicate an unlimited number of idle connections. spring.redis.pool.max-idle=8 # Max number of "idle" connections in the pool. Use a negative value to indicate an unlimited number of idle connections.
spring.redis.pool.max-wait=-1 # Maximum amount of time (in milliseconds) a connection allocation should block before throwing an exception when the pool is exhausted. Use a negative value to block indefinitely. spring.redis.pool.max-wait=-1 # Maximum amount of time (in milliseconds) a connection allocation should block before throwing an exception when the pool is exhausted. Use a negative value to block indefinitely.