Polish Redis sentinel support
This commit is contained in:
		
							parent
							
								
									b129bc261a
								
							
						
					
					
						commit
						26ac68df05
					
				| 
						 | 
					@ -38,6 +38,7 @@ import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
 | 
				
			||||||
import org.springframework.data.redis.core.RedisOperations;
 | 
					import org.springframework.data.redis.core.RedisOperations;
 | 
				
			||||||
import org.springframework.data.redis.core.RedisTemplate;
 | 
					import org.springframework.data.redis.core.RedisTemplate;
 | 
				
			||||||
import org.springframework.data.redis.core.StringRedisTemplate;
 | 
					import org.springframework.data.redis.core.StringRedisTemplate;
 | 
				
			||||||
 | 
					import org.springframework.util.Assert;
 | 
				
			||||||
import org.springframework.util.StringUtils;
 | 
					import org.springframework.util.StringUtils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import redis.clients.jedis.Jedis;
 | 
					import redis.clients.jedis.Jedis;
 | 
				
			||||||
| 
						 | 
					@ -50,6 +51,7 @@ import redis.clients.jedis.JedisPoolConfig;
 | 
				
			||||||
 * @author Andy Wilkinson
 | 
					 * @author Andy Wilkinson
 | 
				
			||||||
 * @author Christian Dupuis
 | 
					 * @author Christian Dupuis
 | 
				
			||||||
 * @author Christoph Strobl
 | 
					 * @author Christoph Strobl
 | 
				
			||||||
 | 
					 * @author Phillip Webb
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@Configuration
 | 
					@Configuration
 | 
				
			||||||
@ConditionalOnClass({ JedisConnection.class, RedisOperations.class, Jedis.class })
 | 
					@ConditionalOnClass({ JedisConnection.class, RedisOperations.class, Jedis.class })
 | 
				
			||||||
| 
						 | 
					@ -62,7 +64,10 @@ public class RedisAutoConfiguration {
 | 
				
			||||||
		return new RedisProperties();
 | 
							return new RedisProperties();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected abstract static class RedisHAConnectionConfiguration {
 | 
						/**
 | 
				
			||||||
 | 
						 * Base class for Redis configurations.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						protected static abstract class AbstractRedisConfiguration {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		@Autowired
 | 
							@Autowired
 | 
				
			||||||
		protected RedisProperties properties;
 | 
							protected RedisProperties properties;
 | 
				
			||||||
| 
						 | 
					@ -70,78 +75,87 @@ public class RedisAutoConfiguration {
 | 
				
			||||||
		@Autowired(required = false)
 | 
							@Autowired(required = false)
 | 
				
			||||||
		private RedisSentinelConfiguration sentinelConfiguration;
 | 
							private RedisSentinelConfiguration sentinelConfiguration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		protected RedisSentinelConfiguration potentiallyGetSentinelConfig() {
 | 
							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());
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								factory.setDatabase(this.properties.getDatabase());
 | 
				
			||||||
 | 
								return factory;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (this.sentinelConfiguration == null
 | 
							protected final RedisSentinelConfiguration getSentinelConfig() {
 | 
				
			||||||
					&& this.properties.getSentinel() == null) {
 | 
								if (this.sentinelConfiguration != null) {
 | 
				
			||||||
 | 
									return this.sentinelConfiguration;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								Sentinel sentinelProperties = this.properties.getSentinel();
 | 
				
			||||||
 | 
								if (sentinelProperties != null) {
 | 
				
			||||||
 | 
									RedisSentinelConfiguration config = new RedisSentinelConfiguration();
 | 
				
			||||||
 | 
									config.master(sentinelProperties.getMaster());
 | 
				
			||||||
 | 
									config.setSentinels(createSentinels(sentinelProperties));
 | 
				
			||||||
 | 
									return config;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			return null;
 | 
								return null;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			RedisSentinelConfiguration sentinelConfig = this.sentinelConfiguration;
 | 
							private List<RedisNode> createSentinels(Sentinel sentinel) {
 | 
				
			||||||
			if (sentinelConfig == null && this.properties.getSentinel() != null) {
 | 
								List<RedisNode> sentinels = new ArrayList<RedisNode>();
 | 
				
			||||||
				sentinelConfig = new RedisSentinelConfiguration().master(this.properties
 | 
								String nodes = sentinel.getNodes();
 | 
				
			||||||
						.getSentinel().getMaster());
 | 
								for (String node : StringUtils.commaDelimitedListToStringArray(nodes)) {
 | 
				
			||||||
				sentinelConfig.setSentinels(createRedisNodesForSentinel(this.properties
 | 
									try {
 | 
				
			||||||
						.getSentinel()));
 | 
										String[] parts = StringUtils.split(node, ":");
 | 
				
			||||||
 | 
										Assert.state(parts.length == 2, "Must be defined as 'host:port'");
 | 
				
			||||||
 | 
										sentinels.add(new RedisNode(parts[0], Integer.valueOf(parts[1])));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			return sentinelConfig;
 | 
									catch (RuntimeException ex) {
 | 
				
			||||||
 | 
										throw new IllegalStateException("Invalid redis sentinel "
 | 
				
			||||||
 | 
												+ "property '" + node + "'", ex);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		private List<RedisNode> createRedisNodesForSentinel(Sentinel sentinel) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			String[] nodeStrings = StringUtils.commaDelimitedListToStringArray(sentinel
 | 
					 | 
				
			||||||
					.getNodes());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			List<RedisNode> nodes = new ArrayList<RedisNode>(nodeStrings.length);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			for (String hostAndPort : nodeStrings) {
 | 
					 | 
				
			||||||
				String[] args = StringUtils.split(hostAndPort, ":");
 | 
					 | 
				
			||||||
				nodes.add(new RedisNode(args[0], Integer.valueOf(args[1])));
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								return sentinels;
 | 
				
			||||||
			return nodes;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Redis connection configuration.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	@Configuration
 | 
						@Configuration
 | 
				
			||||||
	@ConditionalOnMissingClass(name = "org.apache.commons.pool2.impl.GenericObjectPool")
 | 
						@ConditionalOnMissingClass(name = "org.apache.commons.pool2.impl.GenericObjectPool")
 | 
				
			||||||
	protected static class RedisConnectionConfiguration extends
 | 
						protected static class RedisConnectionConfiguration extends
 | 
				
			||||||
			RedisHAConnectionConfiguration {
 | 
								AbstractRedisConfiguration {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		@Bean
 | 
							@Bean
 | 
				
			||||||
		@ConditionalOnMissingBean
 | 
							@ConditionalOnMissingBean
 | 
				
			||||||
		RedisConnectionFactory redisConnectionFactory() throws UnknownHostException {
 | 
							public RedisConnectionFactory redisConnectionFactory()
 | 
				
			||||||
			JedisConnectionFactory factory = new JedisConnectionFactory(
 | 
									throws UnknownHostException {
 | 
				
			||||||
					potentiallyGetSentinelConfig());
 | 
								return applyProperties(new JedisConnectionFactory(getSentinelConfig()));
 | 
				
			||||||
			applyConnectionFactoryProperties(factory, this.properties);
 | 
					 | 
				
			||||||
			return factory;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Redis pooled connection configuration.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	@Configuration
 | 
						@Configuration
 | 
				
			||||||
	@ConditionalOnClass(GenericObjectPool.class)
 | 
						@ConditionalOnClass(GenericObjectPool.class)
 | 
				
			||||||
	protected static class RedisPooledConnectionConfiguration extends
 | 
						protected static class RedisPooledConnectionConfiguration extends
 | 
				
			||||||
			RedisHAConnectionConfiguration {
 | 
								AbstractRedisConfiguration {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		@Bean
 | 
							@Bean
 | 
				
			||||||
		@ConditionalOnMissingBean
 | 
							@ConditionalOnMissingBean
 | 
				
			||||||
		RedisConnectionFactory redisConnectionFactory() throws UnknownHostException {
 | 
							public RedisConnectionFactory redisConnectionFactory()
 | 
				
			||||||
			JedisConnectionFactory factory = createJedisConnectionFactory();
 | 
									throws UnknownHostException {
 | 
				
			||||||
			applyConnectionFactoryProperties(factory, this.properties);
 | 
								return applyProperties(createJedisConnectionFactory());
 | 
				
			||||||
			return factory;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private JedisConnectionFactory createJedisConnectionFactory() {
 | 
							private JedisConnectionFactory createJedisConnectionFactory() {
 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (this.properties.getPool() != null) {
 | 
								if (this.properties.getPool() != null) {
 | 
				
			||||||
				return new JedisConnectionFactory(potentiallyGetSentinelConfig(),
 | 
									return new JedisConnectionFactory(getSentinelConfig(), jedisPoolConfig());
 | 
				
			||||||
						jedisPoolConfig());
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			else {
 | 
					 | 
				
			||||||
				return new JedisConnectionFactory(potentiallyGetSentinelConfig());
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								return new JedisConnectionFactory(getSentinelConfig());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private JedisPoolConfig jedisPoolConfig() {
 | 
							private JedisPoolConfig jedisPoolConfig() {
 | 
				
			||||||
| 
						 | 
					@ -156,12 +170,12 @@ public class RedisAutoConfiguration {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Standard Redis configuration.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	@Configuration
 | 
						@Configuration
 | 
				
			||||||
	protected static class RedisConfiguration {
 | 
						protected static class RedisConfiguration {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		@Autowired
 | 
					 | 
				
			||||||
		private RedisProperties properties;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		@Bean
 | 
							@Bean
 | 
				
			||||||
		@ConditionalOnMissingBean(name = "redisTemplate")
 | 
							@ConditionalOnMissingBean(name = "redisTemplate")
 | 
				
			||||||
		RedisOperations<Object, Object> redisTemplate(
 | 
							RedisOperations<Object, Object> redisTemplate(
 | 
				
			||||||
| 
						 | 
					@ -184,14 +198,4 @@ public class RedisAutoConfiguration {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static void applyConnectionFactoryProperties(JedisConnectionFactory factory,
 | 
					 | 
				
			||||||
			RedisProperties properties) {
 | 
					 | 
				
			||||||
		factory.setHostName(properties.getHost());
 | 
					 | 
				
			||||||
		factory.setPort(properties.getPort());
 | 
					 | 
				
			||||||
		if (properties.getPassword() != null) {
 | 
					 | 
				
			||||||
			factory.setPassword(properties.getPassword());
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		factory.setDatabase(properties.getDatabase());
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,9 +35,9 @@ public class RedisProperties {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private int port = 6379;
 | 
						private int port = 6379;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private RedisProperties.Pool pool;
 | 
						private Pool pool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private RedisProperties.Sentinel sentinel;
 | 
						private Sentinel sentinel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public String getHost() {
 | 
						public String getHost() {
 | 
				
			||||||
		return this.host;
 | 
							return this.host;
 | 
				
			||||||
| 
						 | 
					@ -63,11 +63,11 @@ public class RedisProperties {
 | 
				
			||||||
		this.password = password;
 | 
							this.password = password;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public RedisProperties.Pool getPool() {
 | 
						public Pool getPool() {
 | 
				
			||||||
		return this.pool;
 | 
							return this.pool;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public void setPool(RedisProperties.Pool pool) {
 | 
						public void setPool(Pool pool) {
 | 
				
			||||||
		this.pool = pool;
 | 
							this.pool = pool;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,15 +79,14 @@ public class RedisProperties {
 | 
				
			||||||
		this.database = database;
 | 
							this.database = database;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public Sentinel getSentinel() {
 | 
				
			||||||
 | 
							return this.sentinel;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public void setSentinel(Sentinel sentinel) {
 | 
						public void setSentinel(Sentinel sentinel) {
 | 
				
			||||||
		this.sentinel = sentinel;
 | 
							this.sentinel = sentinel;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Sentinel getSentinel() {
 | 
					 | 
				
			||||||
		return sentinel;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Pool properties.
 | 
						 * Pool properties.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
| 
						 | 
					@ -135,15 +134,16 @@ public class RedisProperties {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
     * Properties for configuring redis sentinels.
 | 
						 * Redis sentinel properties.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public static class Sentinel {
 | 
						public static class Sentinel {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private String master;
 | 
							private String master;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private String nodes;
 | 
							private String nodes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public String getMaster() {
 | 
							public String getMaster() {
 | 
				
			||||||
            return master;
 | 
								return this.master;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void setMaster(String master) {
 | 
							public void setMaster(String master) {
 | 
				
			||||||
| 
						 | 
					@ -151,7 +151,7 @@ public class RedisProperties {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public String getNodes() {
 | 
							public String getNodes() {
 | 
				
			||||||
            return nodes;
 | 
								return this.nodes;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void setNodes(String nodes) {
 | 
							public void setNodes(String nodes) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,7 +63,7 @@ public class RabbitPropertiesTests {
 | 
				
			||||||
	public void addressesDoubleValuedPreservesOrder() {
 | 
						public void addressesDoubleValuedPreservesOrder() {
 | 
				
			||||||
		this.properties.setAddresses("myhost:9999,ahost:1111/host");
 | 
							this.properties.setAddresses("myhost:9999,ahost:1111/host");
 | 
				
			||||||
		assertNull(this.properties.getHost());
 | 
							assertNull(this.properties.getHost());
 | 
				
			||||||
		assertEquals("myhost:9999,ahost:1111", properties.getAddresses());
 | 
							assertEquals("myhost:9999,ahost:1111", this.properties.getAddresses());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Test
 | 
						@Test
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue