Skip to content

Commit

Permalink
🚧 중복 이벤트 처리 구현 중
Browse files Browse the repository at this point in the history
  • Loading branch information
nowgnas committed Jan 9, 2024
1 parent f6a8285 commit 643c349
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 3 deletions.
12 changes: 10 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,15 @@ dependencies {
implementation 'org.springframework.cloud:spring-cloud-aws-messaging:2.2.4.RELEASE'
implementation 'org.springframework.kafka:spring-kafka'
implementation 'software.amazon.awssdk:sns:2.21.37'
implementation 'io.github.lotteon-maven:blooming-blooms-utils:202401080033'
implementation 'io.github.lotteon-maven:blooming-blooms-utils:202401081357'
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop
implementation 'org.springframework.boot:spring-boot-starter-aop:2.7.17'


// redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation("it.ozimov:embedded-redis:0.7.2")
implementation 'org.redisson:redisson-spring-boot-starter:3.17.0'

testImplementation 'org.mockito:mockito-core:4.8.0'

Expand Down Expand Up @@ -80,7 +88,7 @@ jacocoTestCoverageVerification {
value = 'COVEREDRATIO'
minimum = 0.80
}
excludes = ["*.mapper*", "**.emitter.**", "**.infrastructure.**"]
excludes = ["*.mapper*", "**.emitter.**", "**.infrastructure.**"]
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@SpringBootApplication
@EnableEurekaClient
@EnableJpaAuditing
@EnableAspectJAutoProxy
public class NotificationServiceApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package kr.bb.notification.common.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DuplicateEventHandleAnnotation {
String eventId(); // Specify eventId for constructing the cache key

String userId(); // Specify userId for constructing the cache key

long ttl() default 180; // Default TTL is 3 minutes
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package kr.bb.notification.common.aop;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

@Aspect
@Slf4j
@Component
@RequiredArgsConstructor
public class DuplicateEventHandlerAop {
private final RedisTemplate<String, Object> redisTemplate;
// https://alwayspr.tistory.com/34


@Pointcut("@annotation(kr.bb.notification.common.annotation.DuplicateEventHandleAnnotation)")
public void duplicateEvent() {}

@Around("duplicateEvent()")
public Object duplicateEventHandlerAop(ProceedingJoinPoint joinPoint) throws Throwable {
String eventId = null;
Object[] args = joinPoint.getArgs();

// Check if data exists in Redis
Object cachedData = redisTemplate.opsForValue().get(eventId);

Object result = joinPoint.proceed(); // run method

if (cachedData != null) {
// Data exists in cache, return it without executing the method
return cachedData;
}

// Data doesn't exist in cache, proceed to execute the method
Object result = joinPoint.proceed();

// Save the result in Redis with the specified TTL
redisTemplate.opsForValue().set(key, result, duplicateEventHandlerAop.ttl());

return result;
}
}
43 changes: 43 additions & 0 deletions src/main/java/kr/bb/notification/config/RedisConfiguration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package kr.bb.notification.config;

import lombok.RequiredArgsConstructor;
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.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
@RequiredArgsConstructor
public class RedisConfiguration {
@Value("${spring.redis.host}")
private String host;

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

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

@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName(host);
redisStandaloneConfiguration.setPort(port);
redisStandaloneConfiguration.setPassword(password);
return new LettuceConnectionFactory(redisStandaloneConfiguration);
}

@Bean
public RedisTemplate<String, Object> redisTemplate(
RedisConnectionFactory redisConnectionFactory) {
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
Expand Up @@ -8,7 +8,6 @@
import kr.bb.notification.domain.notification.entity.MemberNotificationCommand;
import kr.bb.notification.domain.notification.entity.Notification;
import kr.bb.notification.domain.notification.entity.NotificationCommand;
import kr.bb.notification.domain.notification.repository.MemberNotificationJpaRepository;
import kr.bb.notification.domain.notification.repository.NotificationJpaRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand Down

0 comments on commit 643c349

Please sign in to comment.