diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/config/DomainConfig.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/config/DomainConfig.java new file mode 100644 index 000000000..4acd02935 --- /dev/null +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/config/DomainConfig.java @@ -0,0 +1,12 @@ +package kr.co.pennyway.api.config; + +import kr.co.pennyway.domain.common.importer.EnablePennywayDomainConfig; +import kr.co.pennyway.domain.common.importer.PennywayDomainConfigGroup; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnablePennywayDomainConfig({ + PennywayDomainConfigGroup.REDISSON +}) +public class DomainConfig { +} diff --git a/pennyway-batch/src/main/resources/application.yml b/pennyway-batch/src/main/resources/application.yml index c8a285441..7bc8d234a 100644 --- a/pennyway-batch/src/main/resources/application.yml +++ b/pennyway-batch/src/main/resources/application.yml @@ -20,6 +20,11 @@ spring: hikari: maximum-pool-size: 2 + data: + redis: + repositories: + enabled: false + --- spring: config: diff --git a/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/aop/CallTransactionFactory.java b/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/aop/CallTransactionFactory.java index da749fa4f..77c7ed50b 100644 --- a/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/aop/CallTransactionFactory.java +++ b/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/aop/CallTransactionFactory.java @@ -1,9 +1,7 @@ package kr.co.pennyway.domain.common.aop; import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; -@Component @RequiredArgsConstructor public class CallTransactionFactory { private final RedissonCallNewTransaction redissonCallNewTransaction; diff --git a/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/aop/DistributedLockAop.java b/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/aop/DistributedLockAspect.java similarity index 96% rename from pennyway-domain/src/main/java/kr/co/pennyway/domain/common/aop/DistributedLockAop.java rename to pennyway-domain/src/main/java/kr/co/pennyway/domain/common/aop/DistributedLockAspect.java index a635f7df7..a3b76c745 100644 --- a/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/aop/DistributedLockAop.java +++ b/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/aop/DistributedLockAspect.java @@ -10,7 +10,6 @@ import org.aspectj.lang.reflect.MethodSignature; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; -import org.springframework.stereotype.Component; import java.lang.reflect.Method; @@ -19,9 +18,8 @@ */ @Slf4j @Aspect -@Component @RequiredArgsConstructor -public class DistributedLockAop { +public class DistributedLockAspect { private static final String REDISSON_LOCK_PREFIX = "LOCK:"; private final RedissonClient redissonClient; diff --git a/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/aop/RedissonCallNewTransaction.java b/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/aop/RedissonCallNewTransaction.java index 0749147d3..ba28b682e 100644 --- a/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/aop/RedissonCallNewTransaction.java +++ b/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/aop/RedissonCallNewTransaction.java @@ -2,11 +2,9 @@ import lombok.RequiredArgsConstructor; import org.aspectj.lang.ProceedingJoinPoint; -import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; -@Component @RequiredArgsConstructor public class RedissonCallNewTransaction implements CallTransaction { /** diff --git a/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/aop/RedissonCallSameTransaction.java b/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/aop/RedissonCallSameTransaction.java index d8afb0bf1..af6148eea 100644 --- a/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/aop/RedissonCallSameTransaction.java +++ b/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/aop/RedissonCallSameTransaction.java @@ -2,11 +2,9 @@ import lombok.RequiredArgsConstructor; import org.aspectj.lang.ProceedingJoinPoint; -import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; -@Component @RequiredArgsConstructor public class RedissonCallSameTransaction implements CallTransaction { /** diff --git a/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/importer/EnablePennywayDomainConfig.java b/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/importer/EnablePennywayDomainConfig.java new file mode 100644 index 000000000..4867a3cf3 --- /dev/null +++ b/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/importer/EnablePennywayDomainConfig.java @@ -0,0 +1,15 @@ +package kr.co.pennyway.domain.common.importer; + +import org.springframework.context.annotation.Import; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Import(PennywayDomainConfigImportSelector.class) +public @interface EnablePennywayDomainConfig { + PennywayDomainConfigGroup[] value(); +} diff --git a/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/importer/PennywayDomainConfig.java b/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/importer/PennywayDomainConfig.java new file mode 100644 index 000000000..0c06696a0 --- /dev/null +++ b/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/importer/PennywayDomainConfig.java @@ -0,0 +1,7 @@ +package kr.co.pennyway.domain.common.importer; + +/** + * Pennyway Domain의 Configurations를 나타내는 Marker Interface + */ +public interface PennywayDomainConfig { +} diff --git a/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/importer/PennywayDomainConfigGroup.java b/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/importer/PennywayDomainConfigGroup.java new file mode 100644 index 000000000..391e6483b --- /dev/null +++ b/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/importer/PennywayDomainConfigGroup.java @@ -0,0 +1,13 @@ +package kr.co.pennyway.domain.common.importer; + +import kr.co.pennyway.domain.config.RedissonConfig; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum PennywayDomainConfigGroup { + REDISSON(RedissonConfig.class); + + private final Class configClass; +} diff --git a/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/importer/PennywayDomainConfigImportSelector.java b/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/importer/PennywayDomainConfigImportSelector.java new file mode 100644 index 000000000..01add00bf --- /dev/null +++ b/pennyway-domain/src/main/java/kr/co/pennyway/domain/common/importer/PennywayDomainConfigImportSelector.java @@ -0,0 +1,24 @@ +package kr.co.pennyway.domain.common.importer; + +import kr.co.pennyway.common.util.MapUtils; +import org.springframework.context.annotation.DeferredImportSelector; +import org.springframework.core.type.AnnotationMetadata; +import org.springframework.lang.NonNull; + +import java.util.Arrays; +import java.util.Map; + +public class PennywayDomainConfigImportSelector implements DeferredImportSelector { + @NonNull + @Override + public String[] selectImports(@NonNull AnnotationMetadata metadata) { + return Arrays.stream(getGroups(metadata)) + .map(v -> v.getConfigClass().getName()) + .toArray(String[]::new); + } + + private PennywayDomainConfigGroup[] getGroups(AnnotationMetadata metadata) { + Map attributes = metadata.getAnnotationAttributes(EnablePennywayDomainConfig.class.getName()); + return (PennywayDomainConfigGroup[]) MapUtils.getObject(attributes, "value", new PennywayDomainConfigGroup[]{}); + } +} diff --git a/pennyway-domain/src/main/java/kr/co/pennyway/domain/config/RedissonConfig.java b/pennyway-domain/src/main/java/kr/co/pennyway/domain/config/RedissonConfig.java index 1665cc554..32e995f8e 100644 --- a/pennyway-domain/src/main/java/kr/co/pennyway/domain/config/RedissonConfig.java +++ b/pennyway-domain/src/main/java/kr/co/pennyway/domain/config/RedissonConfig.java @@ -1,14 +1,17 @@ package kr.co.pennyway.domain.config; +import kr.co.pennyway.domain.common.aop.CallTransactionFactory; +import kr.co.pennyway.domain.common.aop.DistributedLockAspect; +import kr.co.pennyway.domain.common.aop.RedissonCallNewTransaction; +import kr.co.pennyway.domain.common.aop.RedissonCallSameTransaction; +import kr.co.pennyway.domain.common.importer.PennywayDomainConfig; import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -@Configuration -public class RedissonConfig { +public class RedissonConfig implements PennywayDomainConfig { private static final String REDISSON_HOST_PREFIX = "redis://"; private final String host; private final int port; @@ -32,4 +35,24 @@ public RedissonClient redissonClient() { .setPassword(password); return Redisson.create(config); } + + @Bean + public RedissonCallNewTransaction redissonCallNewTransaction() { + return new RedissonCallNewTransaction(); + } + + @Bean + public RedissonCallSameTransaction redissonCallSameTransaction() { + return new RedissonCallSameTransaction(); + } + + @Bean + public CallTransactionFactory callTransactionFactory(RedissonCallNewTransaction redissonCallNewTransaction, RedissonCallSameTransaction redissonCallSameTransaction) { + return new CallTransactionFactory(redissonCallNewTransaction, redissonCallSameTransaction); + } + + @Bean + public DistributedLockAspect distributedLockAspect(RedissonClient redissonClient, CallTransactionFactory callTransactionFactory) { + return new DistributedLockAspect(redissonClient, callTransactionFactory); + } } \ No newline at end of file diff --git a/pennyway-domain/src/main/resources/application-domain.yml b/pennyway-domain/src/main/resources/application-domain.yml index c01c48e3f..170b91654 100644 --- a/pennyway-domain/src/main/resources/application-domain.yml +++ b/pennyway-domain/src/main/resources/application-domain.yml @@ -15,6 +15,10 @@ spring: port: ${REDIS_PORT:6379} password: ${REDIS_PASSWORD:} + autoconfigure: + exclude: + - org.redisson.spring.starter.RedissonAutoConfigurationV2 + --- spring: config: diff --git a/pennyway-domain/src/test/java/kr/co/pennyway/domain/common/redisson/CouponDecreaseLockTest.java b/pennyway-domain/src/test/java/kr/co/pennyway/domain/common/redisson/CouponDecreaseLockTest.java index 1256ab26a..f637ff6dd 100644 --- a/pennyway-domain/src/test/java/kr/co/pennyway/domain/common/redisson/CouponDecreaseLockTest.java +++ b/pennyway-domain/src/test/java/kr/co/pennyway/domain/common/redisson/CouponDecreaseLockTest.java @@ -7,7 +7,6 @@ import kr.co.pennyway.domain.domains.coupon.TestCouponDecreaseService; import kr.co.pennyway.domain.domains.coupon.TestCouponRepository; import lombok.extern.slf4j.Slf4j; -import org.junit.Ignore; import org.junit.jupiter.api.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.domain.EntityScan; @@ -20,7 +19,6 @@ import static org.assertj.core.api.Assertions.assertThat; -@Ignore @Slf4j @DomainIntegrationTest @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) @@ -42,6 +40,7 @@ void setUp() { @Test @Order(1) + @Disabled void 쿠폰차감_분산락_적용_동시성_300명_테스트() throws InterruptedException { // given int threadCount = 300; @@ -68,6 +67,7 @@ void setUp() { @Test @Order(2) + @Disabled void 쿠폰차감_분산락_미적용_동시성_300명_테스트() throws InterruptedException { // given int threadCount = 300;