Skip to content

Commit

Permalink
refactor: Redis 모듈 재 추가 후 RedisRepository 생성
Browse files Browse the repository at this point in the history
API 모듈에서 직접 RedisTemplate을 사용할 필요 없이 db-redis 모듈의 커스텀 RedisRepository 객체를 사용하도록 만들어서 redisTemplate 직접 의존 제거
  • Loading branch information
jemin committed Jan 27, 2024
1 parent 68a1be9 commit 4fd8895
Show file tree
Hide file tree
Showing 22 changed files with 196 additions and 149 deletions.
3 changes: 2 additions & 1 deletion core/core-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ dependencies {
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"

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

// Circuit Breaker
implementation "org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j:3.0.2"
Expand All @@ -48,6 +48,7 @@ dependencies {

// Multi Module
implementation project(":storage:db-core")
implementation project(":storage:db-redis")
implementation project(":infra:notification")
implementation project(":infra:file")
implementation project(":infra:mail")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import cmc.mellyserver.auth.service.dto.request.AuthLoginRequestDto;
import cmc.mellyserver.auth.service.dto.request.AuthSignupRequestDto;
import cmc.mellyserver.auth.service.dto.response.TokenResponseDto;
import cmc.mellyserver.auth.token.FcmTokenRepository;
import cmc.mellyserver.auth.token.RefreshToken;
import cmc.mellyserver.auth.token.TokenDto;
import cmc.mellyserver.auth.token.TokenService;
Expand All @@ -33,7 +32,7 @@ public class AuthService {

private final TokenService tokenService;

private final FcmTokenRepository fcmTokenRepository;
private final NotificationTokenDao notificationTokenDao;

private final ApplicationEventPublisher publisher;

Expand All @@ -44,7 +43,7 @@ public TokenResponseDto signup(AuthSignupRequestDto authSignupRequestDto) {
User user = userWriter.save(authSignupRequestDto.toEntity());
TokenDto tokenDto = tokenService.createToken(user);

fcmTokenRepository.saveToken(user.getId().toString(), user.getFcmToken());
notificationTokenDao.save(user.getId().toString(), user.getFcmToken());
publisher.publishEvent(new SignupEvent(user.getId()));

return TokenResponseDto.of(tokenDto.accessToken(), tokenDto.refreshToken().token());
Expand All @@ -62,7 +61,7 @@ public TokenResponseDto login(AuthLoginRequestDto authLoginRequestDto) {
checkPassword(authLoginRequestDto.password(), user.getPassword());

TokenDto tokenDto = tokenService.createToken(user);
fcmTokenRepository.saveToken(user.getId().toString(), authLoginRequestDto.fcmToken());
notificationTokenDao.save(user.getId().toString(), authLoginRequestDto.fcmToken());

return TokenResponseDto.of(tokenDto.accessToken(), tokenDto.refreshToken().token());
}
Expand All @@ -85,7 +84,7 @@ public void logout(final Long userId, final String accessToken) {

tokenService.makeAccessTokenDisabled(accessToken);
tokenService.removeRefreshToken(userId);
fcmTokenRepository.deleteToken(userId.toString());
notificationTokenDao.remove(userId.toString());
}

public void withdraw(final Long userId, final String accessToken) {
Expand All @@ -95,7 +94,7 @@ public void withdraw(final Long userId, final String accessToken) {

tokenService.makeAccessTokenDisabled(accessToken);
tokenService.removeRefreshToken(userId);
fcmTokenRepository.deleteToken(userId.toString());
notificationTokenDao.remove(userId.toString());
}

public void checkDuplicatedNickname(final String nickname) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package cmc.mellyserver.auth.service;

import org.springframework.context.annotation.Configuration;

import cmc.mellyserver.dbredis.repository.RedisRepository;
import lombok.RequiredArgsConstructor;

@Configuration
@RequiredArgsConstructor
public class NotificationTokenDao {

private final RedisRepository repository;

public void save(String key, String fcmToken) {
repository.save(key, fcmToken);
}

public void remove(String key) {
repository.delete(key);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import cmc.mellyserver.auth.service.dto.request.OAuthSignupRequestDto;
import cmc.mellyserver.auth.service.dto.response.OAuthResponseDto;
import cmc.mellyserver.auth.service.dto.response.TokenResponseDto;
import cmc.mellyserver.auth.token.FcmTokenRepository;
import cmc.mellyserver.auth.token.TokenDto;
import cmc.mellyserver.auth.token.TokenService;
import cmc.mellyserver.clientauth.LoginClient;
Expand All @@ -31,14 +30,14 @@ public class OAuthService {

private final TokenService tokenService;

private final FcmTokenRepository fcmTokenRepository;
private final NotificationTokenDao notificationTokenDao;

@Transactional
public TokenResponseDto signup(OAuthSignupRequestDto oAuthSignupRequestDto) {

User user = userWriter.save(oAuthSignupRequestDto.toEntity());
TokenDto tokenDto = tokenService.createToken(user);
fcmTokenRepository.saveToken(user.getId().toString(), oAuthSignupRequestDto.fcmToken());
notificationTokenDao.save(user.getId().toString(), oAuthSignupRequestDto.fcmToken());
return TokenResponseDto.of(tokenDto.accessToken(), tokenDto.refreshToken().token());
}

Expand All @@ -54,7 +53,7 @@ public OAuthResponseDto login(OAuthLoginRequestDto oAuthLoginRequestDto) {
}

TokenDto tokenDto = tokenService.createToken(user);
fcmTokenRepository.saveToken(user.getId().toString(), oAuthLoginRequestDto.fcmToken());
notificationTokenDao.save(user.getId().toString(), oAuthLoginRequestDto.fcmToken());
return OAuthResponseDto.of(tokenDto.accessToken(), tokenDto.refreshToken().token());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package cmc.mellyserver.auth.token;

import static cmc.mellyserver.auth.token.TokenConstants.*;

import java.util.Objects;
import java.util.Optional;

import org.springframework.stereotype.Component;

import cmc.mellyserver.dbredis.repository.RedisRepository;
import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class AuthTokenDao {

private final RedisRepository repository;

public void saveRefreshToken(RefreshToken refreshToken, Long refreshTokenExpiredTime) {
repository.save(REFRESH_TOKEN_PREFIX + refreshToken.userId(), refreshToken.refreshToken(),
refreshTokenExpiredTime);
}

public void makeAccessTokenDisabled(String accessToken, long lastExpiredTime) {
repository.save(accessToken, ACCESS_TOKEN_BLACKLIST, lastExpiredTime);
}

public Optional<RefreshToken> findRefreshToken(Long userId) {

String refreshToken = repository.get(REFRESH_TOKEN_PREFIX + userId);

if (Objects.isNull(refreshToken)) {
return Optional.empty();
}

return Optional.of(new RefreshToken(refreshToken, userId));
}

public void removeRefreshToken(Long userId) {
repository.delete(REFRESH_TOKEN_PREFIX + userId);
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,29 @@ public class TokenService {

private final TokenProvider tokenProvider;

private final AuthTokenRepository tokenRepository;
private final AuthTokenDao authTokenDao;

public TokenDto createToken(User user) {
String accessToken = tokenProvider.createAccessToken(user.getId(), user.getRoleType());
RefreshTokenDto refreshToken = tokenProvider.createRefreshToken(user.getId(), user.getRoleType());
tokenRepository.saveRefreshToken(new RefreshToken(refreshToken.token(), user.getId()),
authTokenDao.saveRefreshToken(new RefreshToken(refreshToken.token(), user.getId()),
refreshToken.expiredAt());
return new TokenDto(accessToken, refreshToken);
}

public RefreshToken findRefreshToken(Long userId) {
return tokenRepository.findRefreshToken(userId).orElseThrow(() -> {
return authTokenDao.findRefreshToken(userId).orElseThrow(() -> {
throw new BusinessException(ErrorCode.RELOGIN_REQUIRED);
});
}

public void makeAccessTokenDisabled(String accessToken) {
long lastExpireTime = tokenProvider.getLastExpiredTime(accessToken);
tokenRepository.makeAccessTokenDisabled(accessToken, lastExpireTime);
authTokenDao.makeAccessTokenDisabled(accessToken, lastExpireTime);
}

public void removeRefreshToken(Long userId) {
tokenRepository.removeRefreshToken(userId);
authTokenDao.removeRefreshToken(userId);
}

public long extractUserId(String accessToken) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,36 @@
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;

import cmc.mellyserver.auth.token.FcmTokenRepository;
import cmc.mellyserver.dbcore.memory.memory.Memory;
import cmc.mellyserver.dbcore.notification.enums.NotificationType;
import cmc.mellyserver.dbcore.user.User;
import cmc.mellyserver.domain.comment.event.CommentCreatedEvent;
import cmc.mellyserver.domain.memory.MemoryReader;
import cmc.mellyserver.domain.notification.NotificationService;
import cmc.mellyserver.domain.user.UserReader;
import cmc.mellyserver.notification.AlarmService;
import cmc.mellyserver.notification.AlarmSender;
import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class NotificationEventHandler {

private final AlarmService pushService;
private final AlarmSender pushService;

private final NotificationService notificationService;

private final MemoryReader memoryReader;

private final UserReader userReader;

private final FcmTokenRepository fcmTokenRepository;

@Async("notificationTaskExecutor")
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void sendCommentCreatedPush(CommentCreatedEvent event) {

Memory memory = memoryReader.read(event.getMemoryId());
User memoryOwner = userReader.findById(memory.getId());
User commentWriter = userReader.findById(event.getWriterId());
String token = fcmTokenRepository.getToken(memoryOwner.getId().toString());
pushService.sendCommentCreatedMessage(commentWriter.getNickname(), token);
pushService.sendCommentCreatedMessage(commentWriter.getNickname(), memoryOwner.getId());
notificationService.createNotification(COMMENT_CREATED_TITLE, NotificationType.COMMENT_ENROLL,
memory.getUserId(), event.getMemoryId());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package cmc.mellyserver.config.redis;
package cmc.mellyserver.config.cache;

import static cmc.mellyserver.config.circuitbreaker.CircuitBreakerConstants.*;

Expand All @@ -20,8 +20,6 @@
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.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
Expand All @@ -31,37 +29,16 @@
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import cmc.mellyserver.config.cache.CacheNames;
import cmc.mellyserver.config.cache.CustomCacheManager;

@EnableCaching
@Configuration
public class RedisConfig {

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

@Value("${spring.redis.token.port}")
private int tokenPort;
public class CacheConfig {

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

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

@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName(tokenHost);
redisStandaloneConfiguration.setPort(tokenPort);

LettuceClientConfiguration lettuceClientConfiguration = LettuceClientConfiguration.builder()
.commandTimeout(Duration.ofMillis(200)).build();

return new LettuceConnectionFactory(redisStandaloneConfiguration, lettuceClientConfiguration);
}

@Bean(name = "redisCacheConnectionFactory")
RedisConnectionFactory redisCacheConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
Expand Down Expand Up @@ -89,23 +66,6 @@ public ObjectMapper objectMapper() {
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}

@Bean
public RedisTemplate<?, ?> redisTemplate() {

RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return redisTemplate;
}

@Bean
public RedisMessageListenerContainer RedisMessageListener() {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(redisConnectionFactory());
return container;
}

/*
캐시 TTL 시간 설정 기준
- USER 프로필 캐시는 조회에 비해 변경 가능성이 적고 TTL로 1일을 설정했습니다.
Expand Down
Loading

0 comments on commit 4fd8895

Please sign in to comment.