package com.arms.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.ReactiveRedisTemplate; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.session.data.redis.config.annotation.web.server.EnableRedisWebSession; import org.springframework.web.reactive.config.EnableWebFlux; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; 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.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.data.redis.core.script.RedisScript; import javax.annotation.PostConstruct; @Configuration @EnableWebFlux @EnableRedisRepositories @EnableRedisWebSession(maxInactiveIntervalInSeconds = 60*60*2) public class RedisConfig { private static final Logger logger = LoggerFactory.getLogger(RedisConfig.class); @Bean public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connectionFactory) { StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(connectionFactory); return template; } @Bean public RedisTemplate redisTemplate(RedisConnectionFactory factory) { RedisTemplate redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(factory); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); redisTemplate.afterPropertiesSet(); return redisTemplate; } @Bean public ReactiveRedisTemplate reactiveRedisTemplate( ReactiveRedisConnectionFactory factory) { RedisSerializationContext serializationContext = RedisSerializationContext.newSerializationContext(new StringRedisSerializer()) .hashKey(new StringRedisSerializer()) .hashValue(new GenericJackson2JsonRedisSerializer()) .build(); return new ReactiveRedisTemplate<>(factory, serializationContext); } @Bean public RedisScript updateContentAndHistoryScript() { String luaScript = """ local contentKey = KEYS[1] local historyKey = KEYS[2] local newContent = ARGV[1] local operationJson = ARGV[2] -- Operation passed as JSON string redis.call('SET', contentKey, newContent) redis.call('RPUSH', historyKey, operationJson) -- Store the JSON string -- Trim the history list if it exceeds the max size local maxHistory = tonumber(ARGV[3]) if maxHistory and maxHistory > 0 then local currentSize = redis.call('LLEN', historyKey) if currentSize > maxHistory then redis.call('LTRIM', historyKey, currentSize - maxHistory, -1) end end return true """; DefaultRedisScript redisScript = new DefaultRedisScript<>(); redisScript.setScriptText(luaScript); redisScript.setResultType(Boolean.class); return redisScript; } }