I am migrating my traditional Redis cache to the Spring Data Reactive Redis. After migration I would like to test if my new integration works as expected but I faced a problem with getting key/keys from particular Redis Db, namely:
My redisConfiguration
class looks like this:
import java.time.Duration; import java.util.Properties; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.PropertySource; import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; import org.springframework.data.redis.connection.RedisPassword; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.ReactiveRedisOperations; import org.springframework.data.redis.core.ReactiveRedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializationContext.RedisSerializationContextBuilder; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration @PropertySource("classpath:redis.properties") @Slf4j public class RedisConfiguration { private static final String REDIS_PROPERTIES = "redis.properties"; private final Properties redisProperties = readConfigurationFile(REDIS_PROPERTIES); @Value("${redis.host}") private String host; @Value("${redis.port}") private int port; @Value("${redis.password}") private String password; @Value("${redis.timeout}") private String timeout; @Bean(name = "reactiveRedisConnectionFactory") @Primary public ReactiveRedisConnectionFactory reactiveRedisConnectionFactory() { return new LettuceConnectionFactory(); } @Bean(name ="reactiveRedisTemplate") public ReactiveRedisOperations<String, Object> reactiveRedisTemplate( @Qualifier(value = "reactiveRedisConnectionFactory") ReactiveRedisConnectionFactory factory) { return prepareRedisTemplate(factory); } @Bean(name = "reactiveRedisUserConnectionFactory") public ReactiveRedisConnectionFactory reactiveRedisUserConnectionFactory() { RedisStandaloneConfiguration redisConfiguration = new RedisStandaloneConfiguration(); String userDb = getProperty(redisProperties, RedisDb.USER_DB); setRedisProperties(redisConfiguration, userDb); LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder() .commandTimeout(Duration.ofMillis(Long.parseLong(timeout))) .build(); logRedisConnectionDetails(redisConfiguration, clientConfiguration); return new LettuceConnectionFactory(redisConfiguration, clientConfiguration); } @Bean(name = "reactiveUserRedisTemplate") public ReactiveRedisOperations<String, Object> userRedisTemplate( @Qualifier(value = "reactiveRedisUserConnectionFactory") ReactiveRedisConnectionFactory connectionFactory) { return prepareRedisTemplate(connectionFactory); } @Bean(name = "redisRegistrationTokenConnectionFactory") public ReactiveRedisConnectionFactory reactiveRedisRegistrationTokenConnectionFactory() { RedisStandaloneConfiguration redisConfiguration = new RedisStandaloneConfiguration(); String registrationTokenDb = getProperty(redisProperties, RedisDb.REGISTRATION_TOKEN_DB); setRedisProperties(redisConfiguration, registrationTokenDb); LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder() .commandTimeout(Duration.ofMillis(Long.parseLong(timeout))) .build(); logRedisConnectionDetails(redisConfiguration, clientConfiguration); return new LettuceConnectionFactory(redisConfiguration, clientConfiguration); } @Bean(name = "reactiveRegistrationTokenRedisTemplate") public ReactiveRedisOperations<String, Object> registrationTokenRedisTemplate( @Qualifier(value = "redisRegistrationTokenConnectionFactory") ReactiveRedisConnectionFactory connectionFactory) { return prepareRedisTemplate(connectionFactory); } @Bean(name = "reactiveRedisWhitelistingConnectionFactory") public ReactiveRedisConnectionFactory redisWhitelistingConnectionFactory() { RedisStandaloneConfiguration redisConfiguration = new RedisStandaloneConfiguration(); String whitelistingDb = getProperty(redisProperties, RedisDb.WHITELISTING_DB); setRedisProperties(redisConfiguration, whitelistingDb); LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder() .commandTimeout(Duration.ofMillis(Long.parseLong(timeout))) .build(); logRedisConnectionDetails(redisConfiguration, clientConfiguration); return new LettuceConnectionFactory(redisConfiguration, clientConfiguration); } @Bean(name = "reactiveWhitelistingRedisTemplate") public ReactiveRedisOperations<String, Object> reactiveWhitelistingRedisTemplate( @Qualifier(value = "reactiveRedisWhitelistingConnectionFactory") ReactiveRedisConnectionFactory connectionFactory) { return prepareRedisTemplate(connectionFactory); } @Bean(name = "redisSerializer") public Jackson2JsonRedisSerializer<Object> redisSerializer() { return new Jackson2JsonRedisSerializer<>(Object.class); } private ReactiveRedisOperations<String, Object> prepareRedisTemplate(ReactiveRedisConnectionFactory connectionFactory) { Jackson2JsonRedisSerializer<Object> redisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); RedisSerializationContextBuilder<String, Object> serializationContext = RedisSerializationContext.newSerializationContext(new StringRedisSerializer()); RedisSerializationContext<String, Object> context = serializationContext .value(redisSerializer) .hashKey(redisSerializer) .hashValue(redisSerializer) .build(); return new ReactiveRedisTemplate<>(connectionFactory, context); } private void setRedisProperties(RedisStandaloneConfiguration redisConfiguration, String redisDb) { redisConfiguration.setHostName(host); redisConfiguration.setPort(port); redisConfiguration.setDatabase(Integer.parseInt(redisDb)); redisConfiguration.setPassword(RedisPassword.of(password)); } private void logRedisConnectionDetails( RedisStandaloneConfiguration redisConfiguration, LettuceClientConfiguration clientConfiguration) { log.info( "Connected to Redis host: {}, port: {}, database: {}, commandTimeout: {}", redisConfiguration.getHostName(), redisConfiguration.getPort(), redisConfiguration.getDatabase(), clientConfiguration.getCommandTimeout().toSeconds()); } }
My “test” class looks like:
@SpringBootApplication @Slf4j public class ApiGatewayApplication implements CommandLineRunner { private final ReactiveRedisOperations<String, Object> reactiveWhitelistingRedisTemplate; private final ReactiveRedisOperations<String, Object> reactiveUserRedisTemplate; public ApiGatewayApplication( @Qualifier(value = "reactiveWhitelistingRedisTemplate") ReactiveRedisOperations<String, Object> reactiveWhitelistingRedisTemplate, @Qualifier(value = "reactiveUserRedisTemplate") ReactiveRedisOperations<String, Object> reactiveUserRedisTemplate) { this.reactiveWhitelistingRedisTemplate = reactiveWhitelistingRedisTemplate; this.reactiveUserRedisTemplate = reactiveUserRedisTemplate; } public static void main(String[] args) { SpringApplication.run(ApiGatewayApplication.class, args); } @Override public void run(String... args) { log.info("CASE1"); log.info( String.valueOf( reactiveWhitelistingRedisTemplate .keys("*") .flatMap(reactiveWhitelistingRedisTemplate.opsForValue()::get))); log.info("CASE2"); log.info(String.valueOf(reactiveWhitelistingRedisTemplate.scan())); log.info("CASE3"); log.info(String.valueOf(reactiveUserRedisTemplate.keys("*"))); log.info("CASE4"); log.info(reactiveWhitelistingRedisTemplate.randomKey() + "RANDOM"); log.info("CASE5"); log.info(String.valueOf(reactiveWhitelistingRedisTemplate.opsForValue().get("whitelisting:zenon112"))); } }
While getting key/keys I am always receiving empty Mono/Flux as a result like:
CASE1 FluxFlatMap CASE2 FluxMap CASE3 FluxMap CASE4 MonoMapRANDOM CASE5 MonoNext
I am convinced that Redis is not empty and example key in Redis is whitelisting:ranomuser112
To be honest I am confused about what I am doing wrong and will be grateful for suggestions on how to get the particular key from reactive Redis. Cheers!
Advertisement
Answer
I overlooked the .subscribe()
method call. Without it, the reactive result was ignored. The problem has been resolved.