diff --git a/oxService/src/main/java/org/xdi/service/cache/RedisConfiguration.java b/oxService/src/main/java/org/xdi/service/cache/RedisConfiguration.java index 368a7c61..bb1dee96 100644 --- a/oxService/src/main/java/org/xdi/service/cache/RedisConfiguration.java +++ b/oxService/src/main/java/org/xdi/service/cache/RedisConfiguration.java @@ -20,6 +20,10 @@ public class RedisConfiguration implements Serializable { private String password; + private Boolean useSsl = false; + + private String sslTrustStoreFilePath = ""; + public String getServers() { return servers; } @@ -52,9 +56,30 @@ public void setPassword(String password) { this.password = password; } + public Boolean getUseSsl() { + return useSsl != null ? useSsl : false; + } + + public void setUseSsl(Boolean useSsl) { + this.useSsl = useSsl; + } + + public String getSslTrustStoreFilePath() { + return sslTrustStoreFilePath; + } + + public void setSslTrustStoreFilePath(String sslTrustStoreFilePath) { + this.sslTrustStoreFilePath = sslTrustStoreFilePath; + } + @Override public String toString() { - return "RedisConfiguration{" + "servers='" + servers + '\'' + ", defaultPutExpiration=" + defaultPutExpiration + ", redisProviderType=" - + redisProviderType + '}'; + return "RedisConfiguration{" + + "servers='" + servers + '\'' + + ", defaultPutExpiration=" + defaultPutExpiration + + ", redisProviderType=" + redisProviderType + + ", useSsl=" + useSsl + + ", sslTrustStoreFilePath=" + sslTrustStoreFilePath + + '}'; } } diff --git a/oxService/src/main/java/org/xdi/service/cache/RedisProviderFactory.java b/oxService/src/main/java/org/xdi/service/cache/RedisProviderFactory.java index f992b6f7..e2245a7d 100644 --- a/oxService/src/main/java/org/xdi/service/cache/RedisProviderFactory.java +++ b/oxService/src/main/java/org/xdi/service/cache/RedisProviderFactory.java @@ -1,8 +1,19 @@ package org.xdi.service.cache; +import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.security.KeyStore; +import java.security.SecureRandom; + /** * Important : keep it weld free. It's reused by oxd ! * @@ -51,4 +62,24 @@ public static void destroySilently(AbstractRedisProvider provider) { LOG.error("Failed to destroy redis provider.", e); } } + + public static SSLSocketFactory createTrustStoreSslSocketFactory(File keystoreFile) throws Exception { + + KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); + InputStream inputStream = null; + try { + inputStream = new FileInputStream(keystoreFile); + trustStore.load(inputStream, null); + } finally { + IOUtils.closeQuietly(inputStream); + } + + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init(trustStore); + TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); + + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, trustManagers, new SecureRandom()); + return sslContext.getSocketFactory(); + } } diff --git a/oxService/src/main/java/org/xdi/service/cache/RedisShardedProvider.java b/oxService/src/main/java/org/xdi/service/cache/RedisShardedProvider.java index f07dbc81..20f07d36 100644 --- a/oxService/src/main/java/org/xdi/service/cache/RedisShardedProvider.java +++ b/oxService/src/main/java/org/xdi/service/cache/RedisShardedProvider.java @@ -6,6 +6,7 @@ import org.apache.commons.lang.SerializationUtils; import org.apache.commons.lang.StringUtils; +import org.apache.http.conn.ssl.DefaultHostnameVerifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,6 +15,12 @@ import redis.clients.jedis.ShardedJedis; import redis.clients.jedis.ShardedJedisPool; +import javax.net.ssl.SSLParameters; +import java.io.File; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + /** * Important : keep it weld free. It's reused by oxd ! * @@ -37,7 +44,7 @@ public void create() { poolConfig.setMaxTotal(1000); poolConfig.setMinIdle(2); - pool = new ShardedJedisPool(poolConfig, shards(redisConfiguration.getServers())); + pool = new ShardedJedisPool(poolConfig, shards(redisConfiguration)); testConnection(); LOG.debug("RedisShardedProvider started."); @@ -47,17 +54,32 @@ public void create() { } } - private static List shards(String servers) { - final String[] serverWithPorts = StringUtils.split(servers.trim(), ","); + private static List shards(RedisConfiguration configuration) { + final String[] serverWithPorts = StringUtils.split(configuration.getServers().trim(), ","); List shards = new ArrayList(); for (String serverWithPort : serverWithPorts) { serverWithPort = serverWithPort.trim(); - if (serverWithPort.contains(":") && !serverWithPort.contains("@") && !servers.contains("//")) { + if (serverWithPort.contains(":") && !serverWithPort.contains("@") && !configuration.getServers().contains("//")) { final String[] split = serverWithPort.trim().split(":"); String host = split[0]; int port = Integer.parseInt(split[1].trim()); - shards.add(new JedisShardInfo(host, port)); + + try { + final JedisShardInfo shardInfo; + if (configuration.getUseSsl()) { + if (StringUtils.isNotBlank(configuration.getSslTrustStoreFilePath())) { + shardInfo = new JedisShardInfo(host, port, true, RedisProviderFactory.createTrustStoreSslSocketFactory(new File(configuration.getSslTrustStoreFilePath())), new SSLParameters(), new DefaultHostnameVerifier()); + } else { + shardInfo = new JedisShardInfo(host, port, true); + } + } else { + shardInfo = new JedisShardInfo(host, port); + } + shards.add(shardInfo); + } catch (Exception e) { + LOG.error("Failed to create shard info.", e); + } } else { shards.add(new JedisShardInfo(serverWithPort)); } diff --git a/oxService/src/main/java/org/xdi/service/cache/RedisStandaloneProvider.java b/oxService/src/main/java/org/xdi/service/cache/RedisStandaloneProvider.java index 9e179235..465a9cec 100644 --- a/oxService/src/main/java/org/xdi/service/cache/RedisStandaloneProvider.java +++ b/oxService/src/main/java/org/xdi/service/cache/RedisStandaloneProvider.java @@ -5,6 +5,8 @@ import javax.annotation.PreDestroy; import org.apache.commons.lang.SerializationUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.http.conn.ssl.DefaultHostnameVerifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -13,6 +15,11 @@ import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; +import javax.annotation.PreDestroy; +import javax.net.ssl.SSLParameters; +import java.io.File; +import java.io.Serializable; + /** * Important : keep it weld free. It's reused by oxd ! * @@ -36,9 +43,18 @@ public void create() { poolConfig.setMaxTotal(1000); poolConfig.setMinIdle(2); - HostAndPort hostAndPort = RedisClusterProvider.hosts(redisConfiguration.getServers()).iterator().next(); - pool = new JedisPool(poolConfig, hostAndPort.getHost(), hostAndPort.getPort()); + + if (redisConfiguration.getUseSsl()) { + if (StringUtils.isNotBlank(redisConfiguration.getSslTrustStoreFilePath())) { + pool = new JedisPool(poolConfig, hostAndPort.getHost(), hostAndPort.getPort(), true, + RedisProviderFactory.createTrustStoreSslSocketFactory(new File(redisConfiguration.getSslTrustStoreFilePath())), new SSLParameters(), new DefaultHostnameVerifier()); + } else { + pool = new JedisPool(poolConfig, hostAndPort.getHost(), hostAndPort.getPort(), true); + } + } else { + pool = new JedisPool(poolConfig, hostAndPort.getHost(), hostAndPort.getPort()); + } testConnection(); LOG.debug("RedisStandaloneProvider started.");