diff --git a/docker-compose/docker-compose.yml b/docker-compose/docker-compose.yml index ed04a46e..413e566e 100644 --- a/docker-compose/docker-compose.yml +++ b/docker-compose/docker-compose.yml @@ -174,7 +174,8 @@ services: - ZIPKIN=${ZIPKIN} - USER_TOKEN_SECRET_KEY=${USER_TOKEN_SECRET_KEY} - WORKING_QUEUE_MAX_SIZE=${WORKING_QUEUE_MAX_SIZE} - - WORKING_QUEUE_TOKEN_TTL=${WORKING_QUEUE_TOKEN_TTL} + - INITIAL_WORKING_QUEUE_TOKEN_TTL=${INITIAL_WORKING_QUEUE_TOKEN_TTL} + - EXTENDED_WORKING_QUEUE_TOKEN_TTL=${EXTENDED_WORKING_QUEUE_TOKEN_TTL} depends_on: eureka-server: condition: service_started diff --git a/services/queue-manage/src/main/java/com/ticketPing/queue_manage/application/service/WorkingQueueService.java b/services/queue-manage/src/main/java/com/ticketPing/queue_manage/application/service/WorkingQueueService.java index 329f22ef..e412702f 100644 --- a/services/queue-manage/src/main/java/com/ticketPing/queue_manage/application/service/WorkingQueueService.java +++ b/services/queue-manage/src/main/java/com/ticketPing/queue_manage/application/service/WorkingQueueService.java @@ -5,6 +5,7 @@ import com.ticketPing.queue_manage.application.dto.GeneralQueueTokenResponse; import com.ticketPing.queue_manage.domain.command.waitingQueue.DeleteFirstWaitingQueueTokenCommand; import com.ticketPing.queue_manage.domain.command.workingQueue.DeleteWorkingQueueTokenCommand; +import com.ticketPing.queue_manage.domain.command.workingQueue.ExtendWorkingQueueTokenTTLCommand; import com.ticketPing.queue_manage.domain.command.workingQueue.FindWorkingQueueTokenCommand; import com.ticketPing.queue_manage.domain.command.workingQueue.InsertWorkingQueueTokenCommand; import com.ticketPing.queue_manage.domain.model.WaitingQueueToken; @@ -60,4 +61,13 @@ private Mono enterWorkingQueue(WaitingQueueToken deletedWaitingToken) { .doOnSuccess(isWorkingQueueTokenSaved -> log.info("작업열 토큰 저장 완료 {}", isWorkingQueueTokenSaved)); } + public Mono extendWorkingQueueTokenTTL(String userId, String performanceId) { + val command = ExtendWorkingQueueTokenTTLCommand.create(userId, performanceId); + + return workingQueueRepository.extendWorkingQueueTokenTTL(command) + .doOnSuccess(token -> log.info("작업열 토큰 TTL 연장 완료 {}", token)) + .map(GeneralQueueTokenResponse::from) + .switchIfEmpty(Mono.error(new ApplicationException(WORKING_QUEUE_TOKEN_NOT_FOUND))); + } + } \ No newline at end of file diff --git a/services/queue-manage/src/main/java/com/ticketPing/queue_manage/common/utils/ConfigHolder.java b/services/queue-manage/src/main/java/com/ticketPing/queue_manage/common/utils/ConfigHolder.java index 097b1499..44498241 100644 --- a/services/queue-manage/src/main/java/com/ticketPing/queue_manage/common/utils/ConfigHolder.java +++ b/services/queue-manage/src/main/java/com/ticketPing/queue_manage/common/utils/ConfigHolder.java @@ -11,7 +11,8 @@ public class ConfigHolder { private static String tokenValueSecretKey; private static int workingQueueMaxSize; - private static int workingQueueTokenTTL; + private static int initialWorkingQueueTokenTTL; + private static int extendedWorkingQueueTokenTTL; @Value("${token-value.secret-key}") public void setSecretKey(String secretKey) { @@ -23,9 +24,14 @@ public void setWorkingQueueMaxSize(int maxSize) { workingQueueMaxSize = maxSize; } - @Value("${working-queue.token-ttl}") - public void setWorkingQueueTokenTTL(int tokenTTL) { - workingQueueTokenTTL = tokenTTL; + @Value("${working-queue.initial-token-ttl}") + public void setInitialWorkingQueueTokenTTL(int tokenTTL) { + initialWorkingQueueTokenTTL = tokenTTL; + } + + @Value("${working-queue.extended-token-ttl}") + public void setExtendedWorkingQueueTokenTTL(int tokenTTL) { + extendedWorkingQueueTokenTTL = tokenTTL; } public static String tokenValueSecretKey() { @@ -36,8 +42,10 @@ public static int workingQueueMaxSize() { return workingQueueMaxSize; } - public static int workingQueueTokenTTL() { - return workingQueueTokenTTL; + public static int initialWorkingQueueTokenTTL() { + return initialWorkingQueueTokenTTL; } + public static int extendedWorkingQueueTokenTTL() { return extendedWorkingQueueTokenTTL; } + } \ No newline at end of file diff --git a/services/queue-manage/src/main/java/com/ticketPing/queue_manage/domain/command/waitingQueue/InsertWaitingQueueTokenCommand.java b/services/queue-manage/src/main/java/com/ticketPing/queue_manage/domain/command/waitingQueue/InsertWaitingQueueTokenCommand.java index d65bb73d..ff0cc16f 100644 --- a/services/queue-manage/src/main/java/com/ticketPing/queue_manage/domain/command/waitingQueue/InsertWaitingQueueTokenCommand.java +++ b/services/queue-manage/src/main/java/com/ticketPing/queue_manage/domain/command/waitingQueue/InsertWaitingQueueTokenCommand.java @@ -2,9 +2,9 @@ import static caching.enums.RedisKeyPrefix.WAITING_QUEUE; import static caching.enums.RedisKeyPrefix.WORKING_QUEUE; +import static com.ticketPing.queue_manage.common.utils.ConfigHolder.initialWorkingQueueTokenTTL; import static com.ticketPing.queue_manage.common.utils.TokenValueGenerator.generateTokenValue; import static com.ticketPing.queue_manage.common.utils.ConfigHolder.workingQueueMaxSize; -import static com.ticketPing.queue_manage.common.utils.ConfigHolder.workingQueueTokenTTL; import lombok.AccessLevel; import lombok.Builder; @@ -42,7 +42,7 @@ public static InsertWaitingQueueTokenCommand create(String userId, String perfor .enterTime(System.currentTimeMillis() / 1000.0) .workingQueueName(WORKING_QUEUE.getValue() + performanceId) .cacheValue("NA") - .ttlInMinutes(workingQueueTokenTTL()) + .ttlInMinutes(initialWorkingQueueTokenTTL()) .workingQueueMaxSlots(workingQueueMaxSize()) .build(); } diff --git a/services/queue-manage/src/main/java/com/ticketPing/queue_manage/domain/command/workingQueue/ExtendWorkingQueueTokenTTLCommand.java b/services/queue-manage/src/main/java/com/ticketPing/queue_manage/domain/command/workingQueue/ExtendWorkingQueueTokenTTLCommand.java new file mode 100644 index 00000000..661fa916 --- /dev/null +++ b/services/queue-manage/src/main/java/com/ticketPing/queue_manage/domain/command/workingQueue/ExtendWorkingQueueTokenTTLCommand.java @@ -0,0 +1,29 @@ +package com.ticketPing.queue_manage.domain.command.workingQueue; + +import static com.ticketPing.queue_manage.common.utils.ConfigHolder.extendedWorkingQueueTokenTTL; +import static com.ticketPing.queue_manage.common.utils.TokenValueGenerator.generateTokenValue; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder(access = AccessLevel.PRIVATE) +public class ExtendWorkingQueueTokenTTLCommand { + + private String userId; + private String performanceId; + private String tokenValue; + private String cacheValue; + private long ttlInMinutes; + + public static ExtendWorkingQueueTokenTTLCommand create(String userId, String performanceId) { + return ExtendWorkingQueueTokenTTLCommand.builder() + .userId(userId) + .performanceId(performanceId) + .tokenValue(generateTokenValue(userId, performanceId)) + .ttlInMinutes(extendedWorkingQueueTokenTTL()) + .build(); + } + +} diff --git a/services/queue-manage/src/main/java/com/ticketPing/queue_manage/domain/command/workingQueue/InsertWorkingQueueTokenCommand.java b/services/queue-manage/src/main/java/com/ticketPing/queue_manage/domain/command/workingQueue/InsertWorkingQueueTokenCommand.java index 253b8669..d5675809 100644 --- a/services/queue-manage/src/main/java/com/ticketPing/queue_manage/domain/command/workingQueue/InsertWorkingQueueTokenCommand.java +++ b/services/queue-manage/src/main/java/com/ticketPing/queue_manage/domain/command/workingQueue/InsertWorkingQueueTokenCommand.java @@ -1,7 +1,7 @@ package com.ticketPing.queue_manage.domain.command.workingQueue; import static caching.enums.RedisKeyPrefix.WORKING_QUEUE; -import static com.ticketPing.queue_manage.common.utils.ConfigHolder.workingQueueTokenTTL; +import static com.ticketPing.queue_manage.common.utils.ConfigHolder.initialWorkingQueueTokenTTL; import com.ticketPing.queue_manage.domain.model.WorkingQueueToken; import lombok.AccessLevel; @@ -28,7 +28,8 @@ public static InsertWorkingQueueTokenCommand create(WorkingQueueToken token) { .tokenValue(token.getTokenValue()) .queueName(WORKING_QUEUE.getValue() + token.getPerformanceId()) .cacheValue("NA") - .ttlInMinutes(workingQueueTokenTTL()).build(); + .ttlInMinutes(initialWorkingQueueTokenTTL()) + .build(); } } diff --git a/services/queue-manage/src/main/java/com/ticketPing/queue_manage/domain/repository/WorkingQueueRepository.java b/services/queue-manage/src/main/java/com/ticketPing/queue_manage/domain/repository/WorkingQueueRepository.java index 46a06821..16bb644f 100644 --- a/services/queue-manage/src/main/java/com/ticketPing/queue_manage/domain/repository/WorkingQueueRepository.java +++ b/services/queue-manage/src/main/java/com/ticketPing/queue_manage/domain/repository/WorkingQueueRepository.java @@ -1,6 +1,7 @@ package com.ticketPing.queue_manage.domain.repository; import com.ticketPing.queue_manage.domain.command.workingQueue.DeleteWorkingQueueTokenCommand; +import com.ticketPing.queue_manage.domain.command.workingQueue.ExtendWorkingQueueTokenTTLCommand; import com.ticketPing.queue_manage.domain.command.workingQueue.InsertWorkingQueueTokenCommand; import com.ticketPing.queue_manage.domain.command.workingQueue.FindWorkingQueueTokenCommand; import com.ticketPing.queue_manage.domain.model.WorkingQueueToken; @@ -10,4 +11,5 @@ public interface WorkingQueueRepository { Mono insertWorkingQueueToken(InsertWorkingQueueTokenCommand command); Mono findWorkingQueueToken(FindWorkingQueueTokenCommand command); Mono deleteWorkingQueueToken(DeleteWorkingQueueTokenCommand command); + Mono extendWorkingQueueTokenTTL(ExtendWorkingQueueTokenTTLCommand command); } diff --git a/services/queue-manage/src/main/java/com/ticketPing/queue_manage/infrastructure/repository/WorkingQueueRepositoryImpl.java b/services/queue-manage/src/main/java/com/ticketPing/queue_manage/infrastructure/repository/WorkingQueueRepositoryImpl.java index 4cdd1fb3..8035bf5c 100644 --- a/services/queue-manage/src/main/java/com/ticketPing/queue_manage/infrastructure/repository/WorkingQueueRepositoryImpl.java +++ b/services/queue-manage/src/main/java/com/ticketPing/queue_manage/infrastructure/repository/WorkingQueueRepositoryImpl.java @@ -3,6 +3,7 @@ import static com.ticketPing.queue_manage.common.utils.TTLConverter.toLocalDateTime; import com.ticketPing.queue_manage.domain.command.workingQueue.DeleteWorkingQueueTokenCommand; +import com.ticketPing.queue_manage.domain.command.workingQueue.ExtendWorkingQueueTokenTTLCommand; import com.ticketPing.queue_manage.domain.command.workingQueue.InsertWorkingQueueTokenCommand; import com.ticketPing.queue_manage.domain.command.workingQueue.FindWorkingQueueTokenCommand; import com.ticketPing.queue_manage.domain.model.WorkingQueueToken; @@ -73,6 +74,7 @@ private Mono handleTokenExpired(String queueName) { private Mono handleOrderCompleted(String queueName, String tokenValue) { RBucketReactive bucket = redissonRepository.getBucket(tokenValue); + return handleIfTokenExists(queueName, bucket) .defaultIfEmpty(false); } @@ -94,4 +96,20 @@ private Mono decrementQueueCounter(String queueName) { return redissonRepository.getCounter(queueName).decrementAndGet(); } + @Override + public Mono extendWorkingQueueTokenTTL(ExtendWorkingQueueTokenTTLCommand command) { + RBucketReactive bucket = redissonRepository.getBucket(command.getTokenValue()); + + return bucket.expire(command.getTtlInMinutes(), TimeUnit.MINUTES) + .then( + bucket.remainTimeToLive() + .flatMap(ttl -> WorkingQueueToken.withValidUntil( + command.getUserId(), + command.getPerformanceId(), + command.getTokenValue(), + toLocalDateTime(ttl) + )) + ); + } + } \ No newline at end of file diff --git a/services/queue-manage/src/main/java/com/ticketPing/queue_manage/presentaion/controller/WorkingQueueController.java b/services/queue-manage/src/main/java/com/ticketPing/queue_manage/presentaion/controller/WorkingQueueController.java index eaed9d74..f4d7aa4c 100644 --- a/services/queue-manage/src/main/java/com/ticketPing/queue_manage/presentaion/controller/WorkingQueueController.java +++ b/services/queue-manage/src/main/java/com/ticketPing/queue_manage/presentaion/controller/WorkingQueueController.java @@ -8,6 +8,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -32,4 +33,14 @@ public Mono>> getWorkin .map(ResponseEntity::ok); } + @Operation(summary = "작업열 토큰 TTL 연장") + @PostMapping("/extend-ttl") + public Mono>> extendWorkingQueueTokenTTL( + @Valid @RequestHeader("X_USER_ID") UUID userId, + @Valid @RequestParam("performanceId") String performanceId) { + return workingQueueService.extendWorkingQueueTokenTTL(userId.toString(), performanceId) + .map(CommonResponse::success) + .map(ResponseEntity::ok); + } + } diff --git a/services/queue-manage/src/main/resources/application.yml b/services/queue-manage/src/main/resources/application.yml index 941d8710..b4f2d109 100644 --- a/services/queue-manage/src/main/resources/application.yml +++ b/services/queue-manage/src/main/resources/application.yml @@ -17,4 +17,5 @@ token-value: working-queue: max-size: ${WORKING_QUEUE_MAX_SIZE} - token-ttl: ${WORKING_QUEUE_TOKEN_TTL} \ No newline at end of file + initial-token-ttl: ${INITIAL_WORKING_QUEUE_TOKEN_TTL} + extended-token-ttl: ${EXTENDED_WORKING_QUEUE_TOKEN_TTL} \ No newline at end of file