Browse Source
* pr/5311: Add missing tests Polish "Add Lettuce Redis driver autoconfiguration" Add Lettuce Redis driver autoconfigurationpull/9066/head
13 changed files with 879 additions and 281 deletions
@ -0,0 +1,120 @@
@@ -0,0 +1,120 @@
|
||||
/* |
||||
* Copyright 2012-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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.autoconfigure.data.redis; |
||||
|
||||
import java.net.UnknownHostException; |
||||
|
||||
import org.apache.commons.pool2.impl.GenericObjectPool; |
||||
import redis.clients.jedis.Jedis; |
||||
import redis.clients.jedis.JedisPoolConfig; |
||||
|
||||
import org.springframework.beans.factory.ObjectProvider; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.data.redis.connection.RedisClusterConfiguration; |
||||
import org.springframework.data.redis.connection.RedisConnectionFactory; |
||||
import org.springframework.data.redis.connection.RedisSentinelConfiguration; |
||||
import org.springframework.data.redis.connection.jedis.JedisConnection; |
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
/** |
||||
* Redis connection configuration using Jedis. |
||||
* |
||||
* @author Mark Paluch |
||||
* @author Stephane Nicoll |
||||
*/ |
||||
@Configuration |
||||
@ConditionalOnClass({ GenericObjectPool.class, JedisConnection.class, Jedis.class }) |
||||
class JedisConnectionConfiguration extends RedisConnectionConfiguration { |
||||
|
||||
private final RedisProperties properties; |
||||
|
||||
JedisConnectionConfiguration(RedisProperties properties, |
||||
ObjectProvider<RedisSentinelConfiguration> sentinelConfiguration, |
||||
ObjectProvider<RedisClusterConfiguration> clusterConfiguration) { |
||||
super(properties, sentinelConfiguration, clusterConfiguration); |
||||
this.properties = properties; |
||||
} |
||||
|
||||
@Bean |
||||
@ConditionalOnMissingBean(RedisConnectionFactory.class) |
||||
public JedisConnectionFactory redisConnectionFactory() throws UnknownHostException { |
||||
return applyProperties(createJedisConnectionFactory()); |
||||
} |
||||
|
||||
private JedisConnectionFactory applyProperties(JedisConnectionFactory factory) { |
||||
configureConnection(factory); |
||||
if (this.properties.isSsl()) { |
||||
factory.setUseSsl(true); |
||||
} |
||||
factory.setDatabase(this.properties.getDatabase()); |
||||
if (this.properties.getTimeout() > 0) { |
||||
factory.setTimeout(this.properties.getTimeout()); |
||||
} |
||||
return factory; |
||||
} |
||||
|
||||
private void configureConnection(JedisConnectionFactory factory) { |
||||
if (StringUtils.hasText(this.properties.getUrl())) { |
||||
configureConnectionFromUrl(factory); |
||||
} |
||||
else { |
||||
factory.setHostName(this.properties.getHost()); |
||||
factory.setPort(this.properties.getPort()); |
||||
if (this.properties.getPassword() != null) { |
||||
factory.setPassword(this.properties.getPassword()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void configureConnectionFromUrl(JedisConnectionFactory factory) { |
||||
ConnectionInfo connectionInfo = parseUrl(this.properties.getUrl()); |
||||
factory.setUseSsl(connectionInfo.isUseSsl()); |
||||
factory.setHostName(connectionInfo.getHostName()); |
||||
factory.setPort(connectionInfo.getPort()); |
||||
if (connectionInfo.getPassword() != null) { |
||||
factory.setPassword(connectionInfo.getPassword()); |
||||
} |
||||
} |
||||
|
||||
private JedisConnectionFactory createJedisConnectionFactory() { |
||||
RedisProperties.Pool pool = this.properties.getJedis().getPool(); |
||||
JedisPoolConfig poolConfig = pool != null |
||||
? jedisPoolConfig(pool) : new JedisPoolConfig(); |
||||
|
||||
if (getSentinelConfig() != null) { |
||||
return new JedisConnectionFactory(getSentinelConfig(), poolConfig); |
||||
} |
||||
if (getClusterConfiguration() != null) { |
||||
return new JedisConnectionFactory(getClusterConfiguration(), poolConfig); |
||||
} |
||||
return new JedisConnectionFactory(poolConfig); |
||||
} |
||||
|
||||
private JedisPoolConfig jedisPoolConfig(RedisProperties.Pool pool) { |
||||
JedisPoolConfig config = new JedisPoolConfig(); |
||||
config.setMaxTotal(pool.getMaxActive()); |
||||
config.setMaxIdle(pool.getMaxIdle()); |
||||
config.setMinIdle(pool.getMinIdle()); |
||||
config.setMaxWaitMillis(pool.getMaxWait()); |
||||
return config; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,197 @@
@@ -0,0 +1,197 @@
|
||||
/* |
||||
* Copyright 2012-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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.autoconfigure.data.redis; |
||||
|
||||
import java.net.UnknownHostException; |
||||
|
||||
import io.lettuce.core.RedisClient; |
||||
import io.lettuce.core.cluster.RedisClusterClient; |
||||
import io.lettuce.core.resource.ClientResources; |
||||
import io.lettuce.core.resource.DefaultClientResources; |
||||
import org.apache.commons.pool2.impl.GenericObjectPool; |
||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig; |
||||
|
||||
import org.springframework.beans.factory.ObjectProvider; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.data.redis.connection.RedisClusterConfiguration; |
||||
import org.springframework.data.redis.connection.RedisConnectionFactory; |
||||
import org.springframework.data.redis.connection.RedisSentinelConfiguration; |
||||
import org.springframework.data.redis.connection.lettuce.DefaultLettucePool; |
||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
/** |
||||
* Redis connection configuration using Lettuce. |
||||
* |
||||
* @author Mark Paluch |
||||
*/ |
||||
@Configuration |
||||
@ConditionalOnClass({ GenericObjectPool.class, RedisClient.class, RedisClusterClient.class }) |
||||
class LettuceConnectionConfiguration extends RedisConnectionConfiguration { |
||||
|
||||
private final RedisProperties properties; |
||||
|
||||
LettuceConnectionConfiguration(RedisProperties properties, |
||||
ObjectProvider<RedisSentinelConfiguration> sentinelConfigurationProvider, |
||||
ObjectProvider<RedisClusterConfiguration> clusterConfigurationProvider) { |
||||
super(properties, sentinelConfigurationProvider, clusterConfigurationProvider); |
||||
this.properties = properties; |
||||
} |
||||
|
||||
@Bean(destroyMethod = "shutdown") |
||||
@ConditionalOnMissingBean(ClientResources.class) |
||||
public DefaultClientResources lettuceClientResources() { |
||||
return DefaultClientResources.create(); |
||||
} |
||||
|
||||
@Bean |
||||
@ConditionalOnMissingBean(RedisConnectionFactory.class) |
||||
public LettuceConnectionFactory redisConnectionFactory( |
||||
ClientResources clientResources) throws UnknownHostException { |
||||
return applyProperties(createLettuceConnectionFactory(clientResources)); |
||||
} |
||||
|
||||
private LettuceConnectionFactory applyProperties(LettuceConnectionFactory factory) { |
||||
configureConnection(factory); |
||||
if (this.properties.isSsl()) { |
||||
factory.setUseSsl(true); |
||||
} |
||||
if (this.properties.getLettuce() != null) { |
||||
RedisProperties.Lettuce lettuce = this.properties.getLettuce(); |
||||
if (lettuce.getShutdownTimeout() >= 0) { |
||||
factory.setShutdownTimeout( |
||||
this.properties.getLettuce().getShutdownTimeout()); |
||||
} |
||||
} |
||||
return factory; |
||||
} |
||||
|
||||
private void configureConnection(LettuceConnectionFactory factory) { |
||||
if (StringUtils.hasText(this.properties.getUrl())) { |
||||
configureConnectionFromUrl(factory); |
||||
} |
||||
else { |
||||
factory.setHostName(this.properties.getHost()); |
||||
factory.setPort(this.properties.getPort()); |
||||
if (this.properties.getPassword() != null) { |
||||
factory.setPassword(this.properties.getPassword()); |
||||
} |
||||
factory.setDatabase(this.properties.getDatabase()); |
||||
if (this.properties.getTimeout() > 0) { |
||||
factory.setTimeout(this.properties.getTimeout()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void configureConnectionFromUrl(LettuceConnectionFactory factory) { |
||||
ConnectionInfo connectionInfo = parseUrl(this.properties.getUrl()); |
||||
factory.setUseSsl(connectionInfo.isUseSsl()); |
||||
factory.setHostName(connectionInfo.getHostName()); |
||||
factory.setPort(connectionInfo.getPort()); |
||||
if (connectionInfo.getPassword() != null) { |
||||
factory.setPassword(connectionInfo.getPassword()); |
||||
} |
||||
} |
||||
|
||||
private DefaultLettucePool applyProperties(DefaultLettucePool pool) { |
||||
if (StringUtils.hasText(this.properties.getUrl())) { |
||||
configureConnectionFromUrl(pool); |
||||
} |
||||
else { |
||||
pool.setHostName(this.properties.getHost()); |
||||
pool.setPort(this.properties.getPort()); |
||||
if (this.properties.getPassword() != null) { |
||||
pool.setPassword(this.properties.getPassword()); |
||||
} |
||||
pool.setDatabase(this.properties.getDatabase()); |
||||
} |
||||
if (this.properties.getTimeout() > 0) { |
||||
pool.setTimeout(this.properties.getTimeout()); |
||||
} |
||||
pool.afterPropertiesSet(); |
||||
return pool; |
||||
} |
||||
|
||||
private void configureConnectionFromUrl(DefaultLettucePool lettucePool) { |
||||
ConnectionInfo connectionInfo = parseUrl(this.properties.getUrl()); |
||||
lettucePool.setHostName(connectionInfo.getHostName()); |
||||
lettucePool.setPort(connectionInfo.getPort()); |
||||
if (connectionInfo.getPassword() != null) { |
||||
lettucePool.setPassword(connectionInfo.getPassword()); |
||||
} |
||||
} |
||||
|
||||
private LettuceConnectionFactory createLettuceConnectionFactory( |
||||
ClientResources clientResources) { |
||||
|
||||
if (getSentinelConfig() != null) { |
||||
if (this.properties.getLettuce() != null |
||||
&& this.properties.getLettuce().getPool() != null) { |
||||
DefaultLettucePool lettucePool = new DefaultLettucePool( |
||||
getSentinelConfig()); |
||||
return new LettuceConnectionFactory(applyProperties( |
||||
applyClientResources(lettucePool, clientResources))); |
||||
} |
||||
return applyClientResources( |
||||
new LettuceConnectionFactory(getSentinelConfig()), |
||||
clientResources); |
||||
} |
||||
|
||||
if (getClusterConfiguration() != null) { |
||||
return applyClientResources( |
||||
new LettuceConnectionFactory(getClusterConfiguration()), |
||||
clientResources); |
||||
} |
||||
|
||||
if (this.properties.getLettuce() != null |
||||
&& this.properties.getLettuce().getPool() != null) { |
||||
GenericObjectPoolConfig config = lettucePoolConfig( |
||||
this.properties.getLettuce().getPool()); |
||||
DefaultLettucePool lettucePool = new DefaultLettucePool( |
||||
this.properties.getHost(), this.properties.getPort(), config); |
||||
return new LettuceConnectionFactory(applyProperties( |
||||
applyClientResources(lettucePool, clientResources))); |
||||
} |
||||
|
||||
return applyClientResources(new LettuceConnectionFactory(), clientResources); |
||||
} |
||||
|
||||
private DefaultLettucePool applyClientResources(DefaultLettucePool lettucePool, |
||||
ClientResources clientResources) { |
||||
lettucePool.setClientResources(clientResources); |
||||
return lettucePool; |
||||
} |
||||
|
||||
private LettuceConnectionFactory applyClientResources( |
||||
LettuceConnectionFactory factory, ClientResources clientResources) { |
||||
factory.setClientResources(clientResources); |
||||
return factory; |
||||
} |
||||
|
||||
private GenericObjectPoolConfig lettucePoolConfig(RedisProperties.Pool props) { |
||||
GenericObjectPoolConfig config = new GenericObjectPoolConfig(); |
||||
config.setMaxTotal(props.getMaxActive()); |
||||
config.setMaxIdle(props.getMaxIdle()); |
||||
config.setMinIdle(props.getMinIdle()); |
||||
config.setMaxWaitMillis(props.getMaxWait()); |
||||
return config; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,153 @@
@@ -0,0 +1,153 @@
|
||||
/* |
||||
* Copyright 2012-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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.autoconfigure.data.redis; |
||||
|
||||
import java.net.URI; |
||||
import java.net.URISyntaxException; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.beans.factory.ObjectProvider; |
||||
import org.springframework.data.redis.connection.RedisClusterConfiguration; |
||||
import org.springframework.data.redis.connection.RedisNode; |
||||
import org.springframework.data.redis.connection.RedisSentinelConfiguration; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
/** |
||||
* Base Redis connection configuration. |
||||
* |
||||
* @author Mark Paluch |
||||
* @author Stephane Nicoll |
||||
*/ |
||||
abstract class RedisConnectionConfiguration { |
||||
|
||||
private final RedisProperties properties; |
||||
|
||||
private final RedisSentinelConfiguration sentinelConfiguration; |
||||
|
||||
private final RedisClusterConfiguration clusterConfiguration; |
||||
|
||||
protected RedisConnectionConfiguration(RedisProperties properties, |
||||
ObjectProvider<RedisSentinelConfiguration> sentinelConfigurationProvider, |
||||
ObjectProvider<RedisClusterConfiguration> clusterConfigurationProvider) { |
||||
this.properties = properties; |
||||
this.sentinelConfiguration = sentinelConfigurationProvider.getIfAvailable(); |
||||
this.clusterConfiguration = clusterConfigurationProvider.getIfAvailable(); |
||||
} |
||||
|
||||
protected final RedisSentinelConfiguration getSentinelConfig() { |
||||
if (this.sentinelConfiguration != null) { |
||||
return this.sentinelConfiguration; |
||||
} |
||||
RedisProperties.Sentinel sentinelProperties = this.properties.getSentinel(); |
||||
if (sentinelProperties != null) { |
||||
RedisSentinelConfiguration config = new RedisSentinelConfiguration(); |
||||
config.master(sentinelProperties.getMaster()); |
||||
config.setSentinels(createSentinels(sentinelProperties)); |
||||
return config; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Create a {@link RedisClusterConfiguration} if necessary. |
||||
* @return {@literal null} if no cluster settings are set. |
||||
*/ |
||||
protected final RedisClusterConfiguration getClusterConfiguration() { |
||||
if (this.clusterConfiguration != null) { |
||||
return this.clusterConfiguration; |
||||
} |
||||
if (this.properties.getCluster() == null) { |
||||
return null; |
||||
} |
||||
RedisProperties.Cluster clusterProperties = this.properties.getCluster(); |
||||
RedisClusterConfiguration config = new RedisClusterConfiguration( |
||||
clusterProperties.getNodes()); |
||||
if (clusterProperties.getMaxRedirects() != null) { |
||||
config.setMaxRedirects(clusterProperties.getMaxRedirects()); |
||||
} |
||||
return config; |
||||
} |
||||
|
||||
private List<RedisNode> createSentinels(RedisProperties.Sentinel sentinel) { |
||||
List<RedisNode> nodes = new ArrayList<>(); |
||||
for (String node : StringUtils |
||||
.commaDelimitedListToStringArray(sentinel.getNodes())) { |
||||
try { |
||||
String[] parts = StringUtils.split(node, ":"); |
||||
Assert.state(parts.length == 2, "Must be defined as 'host:port'"); |
||||
nodes.add(new RedisNode(parts[0], Integer.valueOf(parts[1]))); |
||||
} |
||||
catch (RuntimeException ex) { |
||||
throw new IllegalStateException( |
||||
"Invalid redis sentinel " + "property '" + node + "'", ex); |
||||
} |
||||
} |
||||
return nodes; |
||||
} |
||||
|
||||
protected ConnectionInfo parseUrl(String url) { |
||||
try { |
||||
URI uri = new URI(url); |
||||
boolean useSsl = (url.startsWith("rediss://")); |
||||
String password = null; |
||||
if (uri.getUserInfo() != null) { |
||||
password = uri.getUserInfo(); |
||||
int index = password.lastIndexOf(":"); |
||||
if (index >= 0) { |
||||
password = password.substring(index + 1); |
||||
} |
||||
} |
||||
return new ConnectionInfo(uri, useSsl, password); |
||||
} |
||||
catch (URISyntaxException ex) { |
||||
throw new IllegalArgumentException("Malformed url '" + url + "'", ex); |
||||
} |
||||
} |
||||
|
||||
protected static class ConnectionInfo { |
||||
|
||||
private final URI uri; |
||||
private final boolean useSsl; |
||||
private final String password; |
||||
|
||||
public ConnectionInfo(URI uri, boolean useSsl, String password) { |
||||
this.uri = uri; |
||||
this.useSsl = useSsl; |
||||
this.password = password; |
||||
} |
||||
|
||||
public boolean isUseSsl() { |
||||
return this.useSsl; |
||||
} |
||||
|
||||
public String getHostName() { |
||||
return this.uri.getHost(); |
||||
} |
||||
|
||||
public int getPort() { |
||||
return this.uri.getPort(); |
||||
} |
||||
|
||||
public String getPassword() { |
||||
return this.password; |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,176 @@
@@ -0,0 +1,176 @@
|
||||
/* |
||||
* Copyright 2012-2016 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.autoconfigure.data.redis; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
|
||||
import org.junit.After; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import redis.clients.jedis.Jedis; |
||||
|
||||
import org.springframework.boot.junit.runner.classpath.ClassPathExclusions; |
||||
import org.springframework.boot.junit.runner.classpath.ModifiedClassPathRunner; |
||||
import org.springframework.boot.test.util.EnvironmentTestUtils; |
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext; |
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Tests for {@link RedisAutoConfiguration} when Lettuce is not on the classpath. |
||||
* |
||||
* @author Mark Paluch |
||||
* @author Stephane Nicoll |
||||
*/ |
||||
@RunWith(ModifiedClassPathRunner.class) |
||||
@ClassPathExclusions("lettuce-core-*.jar") |
||||
public class RedisAutoConfigurationJedisTests { |
||||
|
||||
private AnnotationConfigApplicationContext context; |
||||
|
||||
@After |
||||
public void close() { |
||||
if (this.context != null) { |
||||
this.context.close(); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void testOverrideRedisConfiguration() throws Exception { |
||||
load("spring.redis.host:foo", "spring.redis.database:1"); |
||||
JedisConnectionFactory cf = this.context.getBean(JedisConnectionFactory.class); |
||||
assertThat(cf.getHostName()).isEqualTo("foo"); |
||||
assertThat(cf.getDatabase()).isEqualTo(1); |
||||
assertThat(cf.getPassword()).isNull(); |
||||
assertThat(cf.isUseSsl()).isFalse(); |
||||
} |
||||
|
||||
@Test |
||||
public void testRedisUrlConfiguration() throws Exception { |
||||
load("spring.redis.host:foo", |
||||
"spring.redis.url:redis://user:password@example:33"); |
||||
JedisConnectionFactory cf = this.context.getBean(JedisConnectionFactory.class); |
||||
assertThat(cf.getHostName()).isEqualTo("example"); |
||||
assertThat(cf.getPort()).isEqualTo(33); |
||||
assertThat(cf.getPassword()).isEqualTo("password"); |
||||
assertThat(cf.isUseSsl()).isFalse(); |
||||
} |
||||
|
||||
@Test |
||||
public void testOverrideUrlRedisConfiguration() throws Exception { |
||||
load("spring.redis.host:foo", "spring.redis.password:xyz", |
||||
"spring.redis.port:1000", "spring.redis.ssl:false", |
||||
"spring.redis.url:rediss://user:password@example:33"); |
||||
JedisConnectionFactory cf = this.context.getBean(JedisConnectionFactory.class); |
||||
assertThat(cf.getHostName()).isEqualTo("example"); |
||||
assertThat(cf.getPort()).isEqualTo(33); |
||||
assertThat(cf.getPassword()).isEqualTo("password"); |
||||
assertThat(cf.isUseSsl()).isTrue(); |
||||
} |
||||
|
||||
@Test |
||||
public void testRedisConfigurationWithPool() throws Exception { |
||||
load("spring.redis.host:foo", "spring.redis.jedis.pool.min-idle:1", |
||||
"spring.redis.jedis.pool.max-idle:4", |
||||
"spring.redis.jedis.pool.max-active:16", |
||||
"spring.redis.jedis.pool.max-wait:2000"); |
||||
JedisConnectionFactory cf = this.context.getBean(JedisConnectionFactory.class); |
||||
assertThat(cf.getHostName()).isEqualTo("foo"); |
||||
assertThat(cf.getPoolConfig().getMinIdle()).isEqualTo(1); |
||||
assertThat(cf.getPoolConfig().getMaxIdle()).isEqualTo(4); |
||||
assertThat(cf.getPoolConfig().getMaxTotal()).isEqualTo(16); |
||||
assertThat(cf.getPoolConfig().getMaxWaitMillis()) |
||||
.isEqualTo(2000); |
||||
} |
||||
|
||||
@Test |
||||
public void testRedisConfigurationWithTimeout() throws Exception { |
||||
load("spring.redis.host:foo", "spring.redis.timeout:100"); |
||||
JedisConnectionFactory cf = this.context.getBean(JedisConnectionFactory.class); |
||||
assertThat(cf.getHostName()).isEqualTo("foo"); |
||||
assertThat(cf.getTimeout()).isEqualTo(100); |
||||
} |
||||
|
||||
@Test |
||||
public void testRedisConfigurationWithSentinel() throws Exception { |
||||
List<String> sentinels = Arrays.asList("127.0.0.1:26379", "127.0.0.1:26380"); |
||||
if (isAtLeastOneNodeAvailable(sentinels)) { |
||||
load("spring.redis.sentinel.master:mymaster", "spring.redis.sentinel.nodes:" |
||||
+ StringUtils.collectionToCommaDelimitedString(sentinels)); |
||||
assertThat(this.context.getBean(JedisConnectionFactory.class) |
||||
.isRedisSentinelAware()).isTrue(); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void testRedisConfigurationWithCluster() throws Exception { |
||||
List<String> clusterNodes = Arrays.asList("127.0.0.1:27379", "127.0.0.1:27380"); |
||||
if (isAtLeastOneNodeAvailable(clusterNodes)) { |
||||
load("spring.redis.cluster.nodes[0]:" + clusterNodes.get(0), |
||||
"spring.redis.cluster.nodes[1]:" + clusterNodes.get(1)); |
||||
assertThat(this.context.getBean(JedisConnectionFactory.class) |
||||
.getClusterConnection()).isNotNull(); |
||||
} |
||||
} |
||||
|
||||
private void load(String... environment) { |
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); |
||||
EnvironmentTestUtils.addEnvironment(ctx, environment); |
||||
ctx.register(RedisAutoConfiguration.class); |
||||
ctx.refresh(); |
||||
this.context = ctx; |
||||
} |
||||
|
||||
private boolean isAtLeastOneNodeAvailable(List<String> nodes) { |
||||
for (String node : nodes) { |
||||
if (isAvailable(node)) { |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
private boolean isAvailable(String node) { |
||||
Jedis jedis = null; |
||||
try { |
||||
String[] hostAndPort = node.split(":"); |
||||
jedis = new Jedis(hostAndPort[0], Integer.valueOf(hostAndPort[1])); |
||||
jedis.connect(); |
||||
jedis.ping(); |
||||
return true; |
||||
} |
||||
catch (Exception ex) { |
||||
return false; |
||||
} |
||||
finally { |
||||
if (jedis != null) { |
||||
try { |
||||
jedis.disconnect(); |
||||
jedis.close(); |
||||
} |
||||
catch (Exception ex) { |
||||
// Continue
|
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue