# Kickoff Java Project — Redis/Cache Module Redis caching module (conditional: Redis=Yes). Reference: Janus `janus-webapp/src/main/java/.../config/cache/` and `janus-core/src/main/java/.../config/cache/`. --- ## Dependencies **webapp POM:** ```xml org.springframework.bootspring-boot-starter-data-redis org.springframework.bootspring-boot-starter-cache ``` **core POM:** ```xml org.springframework.bootspring-boot-starter-cache ``` --- ## CacheConfiguration Located in webapp: `src/main/java//webapp/config/cache/CacheConfiguration.java` ```java @Configuration @EnableCaching @EnableConfigurationProperties(CacheConfigurationProperties.class) @ConditionalOnProperty(name = "humand..cache.enabled", havingValue = "true", matchIfMissing = true) public class CacheConfiguration { @Bean public RedisCacheManager cacheManager( RedisConnectionFactory connectionFactory, CacheConfigurationProperties cacheProperties) { Duration ttl = Duration.ofMinutes(cacheProperties.ttlMinutes()); RedisCacheConfiguration cacheConfig = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(ttl) .serializeKeysWith( RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer( new GenericJackson2JsonRedisSerializer())) .disableCachingNullValues(); return RedisCacheManager.builder(connectionFactory) .cacheDefaults(cacheConfig) .build(); } } ``` --- ## CacheConfigurationProperties Located in webapp: `src/main/java//webapp/config/cache/CacheConfigurationProperties.java` ```java @ConfigurationProperties("humand..cache") public record CacheConfigurationProperties(boolean enabled, int ttlMinutes) {} ``` --- ## CacheNames Located in core: `src/main/java//core/config/cache/CacheNames.java` ```java public final class CacheNames { private CacheNames() {} public static final String SAMPLE_CACHE = ":v1:SAMPLE_CACHE"; } ``` --- ## Service usage ```java @Cacheable(value = CacheNames.SAMPLE_CACHE, key = "#id") public SampleEntity findById(long id) { ... } @CacheEvict(value = CacheNames.SAMPLE_CACHE, allEntries = true) @Transactional public void update(SampleEntity entity) { ... } ``` --- ## application.yml ```yaml humand: : cache: enabled: true ttl-minutes: 15 spring: data: redis: host: ${SPRING_DATA_REDIS_HOST:localhost} port: ${SPRING_DATA_REDIS_PORT:6379} database: 0 timeout: 2s connect-timeout: 2s ``` --- ## application-test.yml Disable Redis in tests so integration tests run without a Redis instance: ```yaml humand: : cache: enabled: false spring: autoconfigure: exclude: - org.springframework.boot.data.redis.autoconfigure.DataRedisAutoConfiguration - org.springframework.boot.data.redis.autoconfigure.DataRedisRepositoriesAutoConfiguration ``` Note the SB4 package path: `org.springframework.boot.data.redis.autoconfigure` (not `org.springframework.boot.autoconfigure.data.redis`). --- ## Infrastructure (Terraform) SSM parameters (read from `/common/cache/`): | SSM Path | Env Var | |----------|---------| | `/common/cache/hostname` | `SPRING_DATA_REDIS_HOST` | | `/common/cache/port` | `SPRING_DATA_REDIS_PORT` | | `/common/cache/password` | (secret, via SSM) | Additional env vars in project module: ```hcl { name = "SPRING_DATA_REDIS_DATABASE", value = "0" } { name = "SPRING_DATA_REDIS_SSL_ENABLED", value = "true" } ```