Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redis 설정 #104

Merged
merged 7 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ dependencies {
// swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'

// redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'

implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
Expand Down
35 changes: 35 additions & 0 deletions src/main/java/balancetalk/global/config/RedisConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package balancetalk.global.config;

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.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
@EnableRedisRepositories
public class RedisConfig {

@Value("${spring.data.redis.port}")
private int port;

@Value("${spring.data.redis.host}")
private String host;

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

@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(redisConnectionFactory());
return redisTemplate;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package balancetalk.global.redis.application;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.Duration;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
@RequiredArgsConstructor
public class RedisService {

private final RedisTemplate<String, Object> redisTemplate;

public void setValues(String key, String data) {
ValueOperations<String, Object> values = redisTemplate.opsForValue();
values.set(key, data);
}

/*
key와 data, 만료 시간을 Redis에 저장
*/
public void setValues(String key, String data, Duration duration) {
ValueOperations<String, Object> values = redisTemplate.opsForValue();
values.set(key, data, duration);
}

@Transactional(readOnly = true)
public String getValues(String key) {
ValueOperations<String, Object> values = redisTemplate.opsForValue();
if (values.get(key) == null) {
return "false";
}
return (String) values.get(key);
}

public void deleteValues(String key) {
redisTemplate.delete(key);
}

public void expireValues(String key, int timeout) {
redisTemplate.expire(key, timeout, TimeUnit.MILLISECONDS);
}

/*
해당 키와 해시키가 존재하면, 해당 값을 가져오고 없을 경우엔 빈 문자열 반환
*/
public String getHashOps(String key, String hashKey) {
HashOperations<String, Object, Object> values = redisTemplate.opsForHash();
boolean exists = Boolean.TRUE.equals(values.hasKey(key, hashKey));
if (exists) {
return (String) redisTemplate.opsForHash().get(key, hashKey);
}
return ""; // 빈 문자열 반환
}

public void deleteHashOps(String key, String hashKey) {
HashOperations<String, Object, Object> values = redisTemplate.opsForHash();
values.delete(key, hashKey);
}

public boolean checkExistsValue(String value) {
return !value.equals("false");
}
}
5 changes: 5 additions & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,10 @@ spring:
hibernate:
format_sql: true

data:
redis:
host: 127.0.0.1
port: 6379

logging.level:
org.hibernate.SQL: debug
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package balancetalk.global.redis.application;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.time.Duration;
import static org.assertj.core.api.Assertions.*;
import static org.awaitility.Awaitility.await;

@SpringBootTest
class RedisCrudTEST {

final String KEY = "key";
final String VALUE = "value";
final Duration DURATION = Duration.ofMillis(5000);

@Autowired
private RedisService redisService;

@BeforeEach
void setUp() {
redisService.setValues(KEY, VALUE, DURATION);
}
@Test
@DisplayName("Redis 데이터 저장후 조회 - 성공")
void Save_Find_Success() {
// when
String findValue = redisService.getValues(KEY);

// then
assertThat(findValue).isEqualTo(VALUE);
}

@Test
@DisplayName("Redis에 저장된 데이터 수정 - 성공")
void Update_Success() {
// given
String updatedValue = "updatedValue";
redisService.setValues(KEY, updatedValue, DURATION);

// when
String findValue = redisService.getValues(KEY);

// then
assertThat(findValue).isEqualTo(updatedValue);
assertThat(findValue).isNotEqualTo(VALUE);
}

@Test
@DisplayName("Redis에 저장된 데이터 삭제 - 성공")
void Delete_Success() {
// when
redisService.deleteValues(KEY);

// then
assertThat(redisService.getValues(KEY)).isEqualTo("false");
}

@Test
@DisplayName("만료시간이 지간 데이터 삭제 - 성공")
void Expired_Success() {
// when
String findValue = redisService.getValues(KEY);

// then
await().pollDelay(Duration.ofMillis(6000)).untilAsserted(
() -> {
String expiredValue = redisService.getValues(KEY);
assertThat(expiredValue).isNotEqualTo(findValue);
assertThat(expiredValue).isEqualTo("false");
}
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import balancetalk.module.member.domain.Member;
import balancetalk.module.member.domain.MemberRepository;

import balancetalk.module.post.domain.BalanceOption;
import balancetalk.module.post.domain.Post;
import balancetalk.module.post.domain.PostRepository;
import balancetalk.module.vote.domain.Vote;
Expand Down