diff --git a/services/performance/src/main/java/com/ticketPing/performance/application/service/SeatService.java b/services/performance/src/main/java/com/ticketPing/performance/application/service/SeatService.java index 6dd67b47..4ce4dec3 100644 --- a/services/performance/src/main/java/com/ticketPing/performance/application/service/SeatService.java +++ b/services/performance/src/main/java/com/ticketPing/performance/application/service/SeatService.java @@ -39,6 +39,11 @@ public void preReserveSeat(UUID scheduleId, UUID seatId, UUID userId) { luaScriptService.preReserveSeat(scheduleId, seatId, userId); } + public void cancelPreReserveSeat(UUID scheduleId, UUID seatId, UUID userId) { + validatePreserve(scheduleId, seatId, userId); + cacheService.canclePreReserveSeat(scheduleId, seatId); + } + public OrderSeatResponse getOrderInfo(UUID scheduleId, UUID seatId, UUID userId) { validatePreserve(scheduleId, seatId, userId); diff --git a/services/performance/src/main/java/com/ticketPing/performance/domain/model/entity/SeatCache.java b/services/performance/src/main/java/com/ticketPing/performance/domain/model/entity/SeatCache.java index a2db16c2..41ba11e9 100644 --- a/services/performance/src/main/java/com/ticketPing/performance/domain/model/entity/SeatCache.java +++ b/services/performance/src/main/java/com/ticketPing/performance/domain/model/entity/SeatCache.java @@ -1,6 +1,7 @@ package com.ticketPing.performance.domain.model.entity; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.ticketPing.performance.domain.model.enums.SeatStatus; import lombok.*; import java.util.UUID; @@ -29,4 +30,9 @@ public static SeatCache from(Seat seat) { .cost(seat.getSeatCost().getCost()) .build(); } + + public void cancelPreReserveSeat() { + seatStatus = SeatStatus.AVAILABLE.getValue();; + userId = null; + } } diff --git a/services/performance/src/main/java/com/ticketPing/performance/infrastructure/service/CacheService.java b/services/performance/src/main/java/com/ticketPing/performance/infrastructure/service/CacheService.java index 3cb79012..19105e79 100644 --- a/services/performance/src/main/java/com/ticketPing/performance/infrastructure/service/CacheService.java +++ b/services/performance/src/main/java/com/ticketPing/performance/infrastructure/service/CacheService.java @@ -1,6 +1,5 @@ package com.ticketPing.performance.infrastructure.service; -import com.ticketPing.performance.application.dtos.SeatResponse; import com.ticketPing.performance.common.exception.SeatExceptionCase; import com.ticketPing.performance.domain.model.entity.SeatCache; import exception.ApplicationException; @@ -15,6 +14,8 @@ import java.util.Optional; import java.util.UUID; +import static caching.enums.RedisKeyPrefix.AVAILABLE_SEATS; + @Service @RequiredArgsConstructor public class CacheService { @@ -29,14 +30,10 @@ public void cacheSeats(UUID scheduleId, Map seatMap, Duration seatCache.expire(ttl); } - public void cacheAvailableSeats(UUID performanceId, long availableSeats) { - String key = "availableSeats:" + performanceId; - redissonClient.getBucket(key).set(availableSeats); - } - public Map getSeatsFromCache(UUID scheduleId) { String key = "seat:{" + scheduleId + "}"; - return redissonClient.getMap(key, JsonJacksonCodec.INSTANCE); + RMap seatCacheRMap = redissonClient.getMap(key, JsonJacksonCodec.INSTANCE); + return seatCacheRMap.readAllMap(); } public SeatCache getSeatFromCache(UUID scheduleId, UUID seatId) { @@ -46,4 +43,23 @@ public SeatCache getSeatFromCache(UUID scheduleId, UUID seatId) { return Optional.ofNullable(seatCacheMap.get(seatId.toString())) .orElseThrow(() -> new ApplicationException(SeatExceptionCase.SEAT_CACHE_NOT_FOUND)); } + + public void canclePreReserveSeat(UUID scheduleId, UUID seatId) { + String key = "seat:{" + scheduleId + "}"; + RMap seatCacheMap = redissonClient.getMap(key, JsonJacksonCodec.INSTANCE); + + SeatCache seatCache = Optional.ofNullable(seatCacheMap.get(seatId.toString())) + .orElseThrow(() -> new ApplicationException(SeatExceptionCase.SEAT_CACHE_NOT_FOUND)); + seatCache.cancelPreReserveSeat(); + + seatCacheMap.put(seatId.toString(), seatCache); + + String ttlKey = "ttl:{" + scheduleId + "}:" + seatId; + redissonClient.getBucket(ttlKey).delete(); + } + + public void cacheAvailableSeats(UUID performanceId, long availableSeats) { + String key = AVAILABLE_SEATS.getValue() + performanceId; + redissonClient.getBucket(key).set(availableSeats); + } } diff --git a/services/performance/src/main/java/com/ticketPing/performance/presentation/controller/SeatController.java b/services/performance/src/main/java/com/ticketPing/performance/presentation/controller/SeatController.java index 7d170c06..d3a5497c 100644 --- a/services/performance/src/main/java/com/ticketPing/performance/presentation/controller/SeatController.java +++ b/services/performance/src/main/java/com/ticketPing/performance/presentation/controller/SeatController.java @@ -38,7 +38,17 @@ public ResponseEntity> preReserveSeat(@RequestHeader("X_U .body(CommonResponse.success()); } - // TODO: 좌석 선점 취소 + @Operation(summary = "좌석 선점 취소") + @PostMapping("/{seatId}/cancel-reserve") + public ResponseEntity> cancelPreReserveSeat(@RequestHeader("X_USER_ID") UUID userId, + @RequestParam("performanceId") UUID performanceId, + @RequestParam("scheduleId") UUID scheduleId, + @PathVariable("seatId") UUID seatId) { + seatService.cancelPreReserveSeat(scheduleId, seatId, userId); + return ResponseEntity + .status(200) + .body(CommonResponse.success()); + } @Operation(summary = "좌석 주문 정보 조회 (order 서비스에서 호출용)") @GetMapping("/{seatId}/order-info")