diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfiguration.java index 618377f8892..5a42e7fd814 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfiguration.java @@ -16,10 +16,14 @@ package org.springframework.boot.autoconfigure.data.redis; +import java.net.URI; +import java.net.URISyntaxException; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.commons.pool2.impl.GenericObjectPool; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPoolConfig; @@ -55,12 +59,15 @@ import org.springframework.util.StringUtils; * @author Phillip Webb * @author Eddú Meléndez * @author Stephane Nicoll + * @author Marco Aust */ @Configuration @ConditionalOnClass({ JedisConnection.class, RedisOperations.class, Jedis.class }) @EnableConfigurationProperties(RedisProperties.class) public class RedisAutoConfiguration { + private static final Log logger = LogFactory.getLog(RedisAutoConfiguration.class); + /** * Redis connection configuration. */ @@ -91,10 +98,31 @@ public class RedisAutoConfiguration { protected final JedisConnectionFactory applyProperties( JedisConnectionFactory factory) { - factory.setHostName(this.properties.getHost()); - factory.setPort(this.properties.getPort()); - if (this.properties.getPassword() != null) { - factory.setPassword(this.properties.getPassword()); + if (StringUtils.hasText(this.properties.getUrl())) { + if (this.properties.getUrl().startsWith("rediss://")) { + factory.setUseSsl(true); + } + 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()); if (this.properties.getTimeout() > 0) { diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisProperties.java index 8c6d3ddfdfe..cd182a485d8 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisProperties.java @@ -26,6 +26,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; * @author Dave Syer * @author Christoph Strobl * @author Eddú Meléndez + * @author Marco Aust */ @ConfigurationProperties(prefix = "spring.redis") public class RedisProperties { @@ -35,6 +36,11 @@ public class RedisProperties { */ private int database = 0; + /** + * Redis url, which will overrule host, port and password if set. + */ + private String url; + /** * Redis server host. */ @@ -50,6 +56,11 @@ public class RedisProperties { */ private int port = 6379; + /** + * Enable SSL. + */ + private boolean ssl; + /** * Connection timeout in milliseconds. */ @@ -69,6 +80,14 @@ public class RedisProperties { this.database = database; } + public String getUrl() { + return this.url; + } + + public void setUrl(String url) { + this.url = url; + } + public String getHost() { return this.host; } @@ -93,6 +112,14 @@ public class RedisProperties { this.port = port; } + public boolean isSsl() { + return this.ssl; + } + + public void setSsl(boolean ssl) { + this.ssl = ssl; + } + public void setTimeout(int timeout) { this.timeout = timeout; } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationTests.java index e75f3e9e855..831e7b28093 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationTests.java @@ -75,6 +75,22 @@ public class RedisAutoConfigurationTests { .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 public void testRedisConfigurationWithPool() throws Exception { load("spring.redis.host:foo", "spring.redis.pool.max-idle:1"); diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index 47008f6b67f..ab2b8b3220f 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -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.nodes= # Comma-separated list of "host:port" pairs to bootstrap from. 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.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-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.