Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.alicp.jetcache.autoconfigure.RedisAutoConfiguration Maven / Gradle / Ivy
package com.alicp.jetcache.autoconfigure;
import com.alicp.jetcache.CacheBuilder;
import com.alicp.jetcache.CacheConfigException;
import com.alicp.jetcache.redis.RedisCacheBuilder;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.util.ClassUtils;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.Protocol;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.util.Pool;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Created on 2016/11/25.
*
* @author huangli
*/
@Configuration
@Conditional(RedisAutoConfiguration.RedisCondition.class)
public class RedisAutoConfiguration {
public static final String AUTO_INIT_BEAN_NAME = "redisAutoInit";
@Bean(name = AUTO_INIT_BEAN_NAME)
public RedisAutoInit redisAutoInit() {
return new RedisAutoInit();
}
public static class RedisCondition extends JetCacheCondition {
public RedisCondition() {
super("redis");
}
}
public static class RedisAutoInit extends ExternalCacheAutoInit {
public RedisAutoInit() {
super("redis");
}
@Autowired
private AutoConfigureBeans autoConfigureBeans;
@Override
protected CacheBuilder initCache(ConfigTree ct, String cacheAreaWithPrefix) {
Object jedisObj = parsePool(ct);
boolean readFromSlave = Boolean.parseBoolean(ct.getProperty("readFromSlave", "False"));
RedisCacheBuilder.RedisCacheBuilderImpl builder = RedisCacheBuilder.createRedisCacheBuilder()
.readFromSlave(readFromSlave);
if (jedisObj instanceof Pool) {
builder.jedisPool((Pool) jedisObj);
} else {
builder.jedis((UnifiedJedis) jedisObj);
}
ConfigTree slaves = ct.subTree("slaves.");
Set slaveNames = slaves.directChildrenKeys();
if (slaveNames.size() > 0) {
List slavesObjects = new ArrayList<>();
int[] slavesWeights = new int[slaveNames.size()];
int i = 0;
for (String slaveName: slaveNames) {
ConfigTree slaveConfig = slaves.subTree(slaveName + ".");
slavesObjects.add(parsePool(slaveConfig));
slavesWeights[i] = Integer.parseInt(slaveConfig.getProperty("weight","100"));
i++;
}
builder.slaveReadWeights(slavesWeights);
if (slavesObjects.get(0) instanceof Pool) {
builder.jedisSlavePools(slavesObjects.toArray(new Pool[0]));
} else {
builder.slaves(slavesObjects.toArray(new UnifiedJedis[0]));
}
}
parseGeneralConfig(builder, ct);
// eg: "jedisPool.remote.default"
autoConfigureBeans.getCustomContainer().put("jedisPool." + cacheAreaWithPrefix, jedisObj);
if (jedisObj instanceof UnifiedJedis) {
autoConfigureBeans.getCustomContainer().put("jedis." + cacheAreaWithPrefix, jedisObj);
}
return builder;
}
private Object parsePool(ConfigTree ct) {
GenericObjectPoolConfig poolConfig = parsePoolConfig(ct);
Map cluster = ct.subTree("cluster"/*there is no dot*/).getProperties();
String host = ct.getProperty("host", (String) null);
int port = Integer.parseInt(ct.getProperty("port", "0"));
int timeout = Integer.parseInt(ct.getProperty("timeout", String.valueOf(Protocol.DEFAULT_TIMEOUT)));
int connectionTimeout = Integer.parseInt(ct.getProperty("connectionTimeout", String.valueOf(timeout)));
int soTimeout = Integer.parseInt(ct.getProperty("soTimeout", String.valueOf(timeout)));
String user = ct.getProperty("user", (String) null);
String password = ct.getProperty("password", (String) null);
int database = Integer.parseInt(ct.getProperty("database", String.valueOf(Protocol.DEFAULT_DATABASE)));
String clientName = ct.getProperty("clientName", (String) null);
boolean ssl = Boolean.parseBoolean(ct.getProperty("ssl", "false"));
String sentinels = ct.getProperty("sentinels", (String) null);//ip1:port,ip2:port
if (sentinels == null) {
if (cluster == null || cluster.size() == 0) {
Objects.requireNonNull(host, "host is required");
if (port == 0) {
throw new IllegalStateException("port is required");
}
return new JedisPool(poolConfig, host, port, connectionTimeout, soTimeout, user, password,
database, clientName, ssl);
} else {
int maxAttempt = Integer.parseInt(ct.getProperty("maxAttempt", "5"));
Set hostAndPortSet = cluster.values().stream()
.map(uri -> uri.toString().split(":"))
.map(hostAndPort -> new HostAndPort(hostAndPort[0], Integer.parseInt(hostAndPort[1])))
.collect(Collectors.toSet());
return new JedisCluster(hostAndPortSet, connectionTimeout, soTimeout, maxAttempt, user, password,
clientName, poolConfig, ssl);
}
} else {
String masterName = ct.getProperty("masterName", (String) null);
Objects.requireNonNull(masterName, "masterName is required");
int sentinelConnectionTimeout = Integer.parseInt(ct.getProperty("sentinelConnectionTimeout", String.valueOf(2000)));
int sentinelSoTimeout = Integer.parseInt(ct.getProperty("sentinelSoTimeout", String.valueOf(2000)));
String sentinelUser = ct.getProperty("sentinelUser", null);
String sentinelPassword = ct.getProperty("sentinelPassword", null);
String sentinelClientName = ct.getProperty("sentinelClientName", null);
String[] strings = sentinels.split(",");
HashSet sentinelsSet = new HashSet<>();
for (String s : strings) {
if (s != null && !s.trim().equals("")) {
sentinelsSet.add(s.trim());
}
}
return new JedisSentinelPool(masterName, sentinelsSet, poolConfig, connectionTimeout, soTimeout,
user, password, database, clientName, sentinelConnectionTimeout, sentinelSoTimeout,
sentinelUser, sentinelPassword, sentinelClientName);
}
}
private GenericObjectPoolConfig parsePoolConfig(ConfigTree ct) {
try {
// Spring Boot 2.0 removed RelaxedDataBinder class. Binder class not exists in 1.X
if (ClassUtils.isPresent("org.springframework.boot.context.properties.bind.Binder",
this.getClass().getClassLoader())) {
// Spring Boot 2.0+
String prefix = ct.subTree("poolConfig").getPrefix().toLowerCase();
// invoke following code by reflect
// Binder binder = Binder.get(environment);
// return binder.bind(name, Bindable.of(GenericObjectPoolConfig.class)).get();
Class> binderClass = Class.forName("org.springframework.boot.context.properties.bind.Binder");
Class> bindableClass = Class.forName("org.springframework.boot.context.properties.bind.Bindable");
Class> bindResultClass = Class.forName("org.springframework.boot.context.properties.bind.BindResult");
Method getMethodOnBinder = binderClass.getMethod("get", Environment.class);
Method getMethodOnBindResult = bindResultClass.getMethod("get");
Method bindMethod = binderClass.getMethod("bind", String.class, bindableClass);
Method ofMethod = bindableClass.getMethod("of", Class.class);
Object binder = getMethodOnBinder.invoke(null, environment);
Object bindable = ofMethod.invoke(null, GenericObjectPoolConfig.class);
Object bindResult = bindMethod.invoke(binder, prefix, bindable);
return (GenericObjectPoolConfig) getMethodOnBindResult.invoke(bindResult);
} else {
// Spring Boot 1.X
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
Map props = ct.subTree("poolConfig.").getProperties();
// invoke following code by reflect
//RelaxedDataBinder binder = new RelaxedDataBinder(poolConfig);
//binder.bind(new MutablePropertyValues(props));
Class> relaxedDataBinderClass = Class.forName("org.springframework.boot.bind.RelaxedDataBinder");
Class> mutablePropertyValuesClass = Class.forName("org.springframework.beans.MutablePropertyValues");
Constructor> c1 = relaxedDataBinderClass.getConstructor(Object.class);
Constructor> c2 = mutablePropertyValuesClass.getConstructor(Map.class);
Method bindMethod = relaxedDataBinderClass.getMethod("bind", PropertyValues.class);
Object binder = c1.newInstance(poolConfig);
bindMethod.invoke(binder, c2.newInstance(props));
return poolConfig;
}
} catch (Throwable ex) {
throw new CacheConfigException("parse poolConfig fail", ex);
}
}
}
}