En esta entrada mostraré como utilizar Spring Boot y Redis con el objetivo de almacenar los objetos como JSON y no como la forma de serialización de Java por defecto que tiene RedisTemplate. Los test están con Testcontainers, Junit 5 y AssertJ.
- Lo primero es la clase que nos convoca, la configuración de RedisTemplate:
@Configuration
public class RedisConfig {
@Autowired
private ConfigurableApplicationContext context;
@Bean
@Primary
public RedisTemplate redisTemplate(JedisConnectionFactory conn) {
RedisTemplate template = new RedisTemplate<>();
template.setConnectionFactory(conn);
template.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
@Bean
public JedisConnectionFactory redisConnectionFactory(@Value("${redis.host}") String host,
@Value("${redis.puerto}") int puerto) {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(host, puerto);
return new JedisConnectionFactory(config);
}
}
- La clase que usaré para la prueba es la siguiente:
public class Persona {
private int id;
private String nombre;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
}
- La clase de entrada para la aplicación:
@SpringBootApplication
public class RedisStringApplication {
public static void main(String[] args) {
SpringApplication.run(RedisStringApplication.class, args);
}
}
- Y la clase de Test:
@SpringBootTest
@ContextConfiguration(initializers = {RedisStringJsonTests.Initializer.class})
public class RedisStringJsonTests {
private static String redisHost;
private static int redisPuerto;
@Rule
public static GenericContainer cont = new GenericContainer<>("redis:5.0.3-alpine")
.withExposedPorts(6379);
@AfterAll
static void detenerRedis() {
cont.stop();
}
@BeforeAll
static void iniciarRedis() {
cont.start();
}
static class Initializer
implements ApplicationContextInitializer {
@Override
public void initialize(ConfigurableApplicationContext ctx) {
redisHost = cont.getContainerIpAddress();
redisPuerto = cont.getFirstMappedPort();
TestPropertyValues.of(
"redis.puerto=" + redisPuerto,
"redis.host=" + redisHost
).applyTo(ctx.getEnvironment());
}
}
@Autowired
private RedisTemplate redis;
@Test
public void validarRegistroJson() throws IOException {
assertThat(redis).isNotNull();
var hash = redis.opsForHash();
final Persona p = new Persona();
final var claveRedis = "redis-clave";
final var claveRegistro = "clave";
p.setId(1);
p.setNombre("nombre");
hash.put(claveRedis, claveRegistro, p);
var x = (Persona) hash.get(claveRedis, claveRegistro);
assertThat(x.getId()).isEqualTo(1);
assertThat(x.getNombre()).isEqualTo("nombre");
Jedis jedis = new Jedis(redisHost, redisPuerto);
final var recuperado = jedis.hget(claveRedis, claveRegistro);
var personaRecuperada = new ObjectMapper().readValue(recuperado, Persona.class);
assertThat(personaRecuperada).isEqualToComparingFieldByField(p);
}
}
- El Test consiste en lo siguiente:
- Utiliza testcontainers para ejecutar redis
- Define propiedades para acceder a Redis al inicializar los beans
- Utiliza RedisTemplate para guardar un objeto y luego recuperarlo
- Recuperar el valor json guardado para transformarlo en una instancia de la clase
- El test demuestra que se puede guardar y recuperar el objeto y también se realiza una nueva conexion para recuperar el String y transformarlo para compararlo con la instancia que se guardó.
- Para confirmar que se guardó como JSON la instancia al ser serializada, usando los datos que entrega testcontainers accederé al redis del contenedor para validar que se guardó como queremos (breakpoint en el código para conocer el puerto 😁):
Eso es todo, el código queda disponible en
Github 👀
No hay comentarios.:
Publicar un comentario