nednella
nednella

Reputation: 1

How can I use @ServiceConnection with Redis Testcontainers for Spring Session Redis?

My application involves using Spring Session Redis to handle authenticated sessions across the application.

Spring Session Redis is configured as-per the docs.

@Configuration
@EnableRedisHttpSession
public class SessionConfig extends AbstractHttpSessionApplicationInitializer {

    @Bean
    LettuceConnectionFactory redisConnectionFactory() {
    return new LettuceConnectionFactory();
    }

...

I'm building integration tests for the application and opted to do an abstract IT class that handles the containers. I'm using @Testcontainers along with @ServiceConnection to automatically handle container lifecycles and application connection details:

@ActiveProfiles(value="test")
@Testcontainers@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public abstract class IntegrationTest {

    @Container
    @ServiceConnection
    protected static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:latest");
    
    @Container
    @ServiceConnection("redis")
    protected static RedisContainer redis = new RedisContainer("redis:latest");

...

The container lifecycles are correctly handled for both, but the application details are correctly handled only for the postgres container.


A little more reading of the docs told me that LettuceConnectionFactory defaults to localhost:6379. That's fine for development, but becomes a problem for testing when testcontainers purposely uses randomised host ports (or when I deploy to prod).

I refactored the Redis session config file:

@Setter
@Configuration
@EnableRedisHttpSession
@ConfigurationProperties(prefix = "spring.data.redis")
public class SessionConfig extends AbstractHttpSessionApplicationInitializer {

    private String host;
    private int port;

    @Bean
    LettuceConnectionFactory redisConnectionFactory() {
    return new LettuceConnectionFactory(host, port);
    }

...

But the test suite throws a fatal exception because host is null, which is telling me @ServiceConnection isn't doing what I would hope/expect it to do.

My solution was to revert back to the pre-service connection annotation method by manually declaring property sources:


...

@DynamicPropertySource
public static void redisInit(DynamicPropertyRegistry registry) {
    redis.start();
    registry.add("spring.data.redis.host", () -> redis.getHost());
    registry.add("spring.data.redis.port", () -> redis.getFirstMappedPort());
}

...

This works, but I am entirely confused around the concept of applying @ServiceConnection to my problem here. No amount of research has presented a solution to this.

I can see that Spring has added compatibility for Redis testcontainers in the last year or so as part of @ServiceConnection (see links below) but I cannot find anything with regards to using said redis container as part of Spring Session Redis.

If it comes of any help to the reader, below is the relevant application.yml file for the test environment:

spring:
    sql:
        init:
            mode: always

cors:
    allowed-origins: '*'

logging:
    level:
        org:
            springframework:
                jpa:
                    core: TRACE

Am I missing some key information here, or is there simply no existing support for tying together Testcontainers and Spring Session Redis to perform integration tests?

Any information would be great, thank you

Upvotes: 0

Views: 61

Answers (0)

Related Questions