2

I have a Redis database with an RLEC (RedisLabs Enterprise Cluster) UI which has been set up for SSL connections.

I have a java app which is able to connect to the redis database using Jedis.

This works:

Jedis jedis = new Jedis(redisInfo.getHost(), redisInfo.getPort(), useSsl);

// make the connection
jedis.connect();

// authorize with our password
jedis.auth(redisInfo.getPassword());

Env vars:

"-Djavax.net.ssl.keyStoreType=PKCS12 -Djavax.net.ssl.keyStorePassword=iloveredis -Djavax.net.ssl.keyStore=$PWD/META-INF/clientKeyStore.p12 -Djavax.net.ssl.trustStoreType=JKS -Djavax.net.ssl.trustStorePassword=iloveredis -Djavax.net.ssl.trustStore=$PWD/META-INF/clientTrustStore.jks"

I also have a Spring Boot app in which I'm trying to connect to the Redis db using JedisConnectionFactory, and I'm not able to. (Using the same app, I am able to connect to a Redis db which does not have SSL enabled).

In my pom.xml:

          <dependency>
              <groupId>org.springframework.data</groupId>
              <artifactId>spring-data-redis</artifactId>
              <version>2.1.4.RELEASE</version>
          </dependency>

          <dependency>
                 <groupId>redis.clients</groupId>
                 <artifactId>jedis</artifactId>
                 <version>2.9.0</version>
          </dependency>

In my redis configuration file:

@Configuration
@EnableRedisRepositories
public class RedisConfig {

@Bean
JedisConnectionFactory jedisConnectionFactory() {
   RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration();
   redisConfig.setHostName(redisInfo.getHost());
   redisConfig.setPort(redisInfo.getPort());
   redisConfig.setPassword(RedisPassword.of(redisInfo.getPassword()));
   boolean useSsl = env.getProperty("spring.redis.ssl", Boolean.class);
   JedisClientConfiguration jedisConfig;
   if (useSsl) {
          jedisConfig = JedisClientConfiguration
                                                                              .builder()
                                                                              .useSsl()
                                                                              .build(); 
   } else {
          jedisConfig = JedisClientConfiguration
                              .builder()
                              .build();                  
   }
    JedisConnectionFactory jcf = new JedisConnectionFactory(redisConfig, jedisConfig); 

    return jcf;
}



@Bean
public RedisTemplate<?, ?> redisTemplateJedis() {
   final RedisTemplate<byte[], byte[]> template = new RedisTemplate<>();
   template.setConnectionFactory(jedisConnectionFactory());
    template.setValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
    return template;
}

This is the error I’m getting:

org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisDataException: ERR unencrypted connection is prohibited

One other point is that for testing purposes, both the server and app are using self-signed certificates (which work with Jedis).

I do not know how to configure JedisConfigurationFactory so that I don't get this error.

ash
  • 49
  • 1
  • 1
  • 7

1 Answers1

0

Edited.

To recap, I could connect to Redis with SSL enabled with Jedis the library, but not the Spring library JedisConnectionFactory.

I was trying this in Pivotal Cloud Foundry (PCF).

I wrote to Mark Paluch, author of spring-data-redis, and he suggested I turn off auto-reconfiguration to get it to work in PCF.

I found this page on turning off auto-reconfiguration:

https://docs.cloudfoundry.org/buildpacks/java/configuring-service-connections/spring-service-bindings.html#manual

Cloud Foundry will automatically create a RedisConnectionFactory bean for you, so my JedisConnectionFactory was not getting used.

I had to turn off auto-reconfiguration. Or rather turn on manual configuration.

My JedisConnectionFactory bean (with SSL enabled) then started getting instantiated (along with the cloud service connector’s RedisConnectionFactory bean).

And I had to set my JedisConnectionFactory bean to Primary as there were now two connection factory beans.

I was also getting exceptions about unexpected end of stream.

I had to turn on usePoolingin JedisClientConfiguration.

This is where I posted to jira about the issue (now moved to github):

https://github.com/spring-projects/spring-data-redis/issues/1542

ash
  • 49
  • 1
  • 1
  • 7
  • How did you create RedisCacheManager using this template? The current constructor is `RedisCacheManager(RedisOperations redisOperations)` Then it now changed to `RedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration)` – Vasudev Jul 28 '20 at 15:30
  • @ash I am having trouble setting up `usePooling`, how do I do it ? I'm using the JedisConnectionFactor – Ikaro Sales May 27 '21 at 00:46
  • @Ikaro Sales: jedisConfig = JedisClientConfiguration .builder() .useSsl() .usePooling() .build(); JedisConnectionFactory jcf = new JedisConnectionFactory(redisConfig, jedisConfig); – ash Jun 22 '21 at 22:08
  • @Vasudev: I have not used RedisCacheManager – ash Jun 22 '21 at 22:11