diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/controller/TripItemController.java b/src/main/java/org/tenten/tentenstomp/domain/trip/controller/TripItemController.java index 87716c7..0aea6d4 100644 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/controller/TripItemController.java +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/controller/TripItemController.java @@ -6,6 +6,7 @@ import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.messaging.handler.annotation.Payload; import org.springframework.web.bind.annotation.RestController; +import org.tenten.tentenstomp.domain.trip.dto.request.TripItemDeleteMsg; import org.tenten.tentenstomp.domain.trip.dto.request.TripItemPriceUpdateMsg; import org.tenten.tentenstomp.domain.trip.dto.request.TripItemTransportationUpdateMsg; import org.tenten.tentenstomp.domain.trip.dto.request.TripItemVisitDateUpdateMsg; @@ -33,7 +34,7 @@ public void updateTripItemTransportation(@DestinationVariable String tripItemId, } @MessageMapping("/tripItems/{tripItemId}/deleteItem") - public void deleteTripItem(@DestinationVariable String tripItemId) { - tripItemService.deleteTripItem(tripItemId); + public void deleteTripItem(@DestinationVariable String tripItemId, @Payload TripItemDeleteMsg tripItemDeleteMsg) { + tripItemService.deleteTripItem(tripItemId, tripItemDeleteMsg); } } diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemDeleteMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemDeleteMsg.java new file mode 100644 index 0000000..def5215 --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemDeleteMsg.java @@ -0,0 +1,7 @@ +package org.tenten.tentenstomp.domain.trip.dto.request; + +public record TripItemDeleteMsg( + Long tripId, + String visitDate +) { +} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemPriceUpdateMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemPriceUpdateMsg.java index 9ff3804..89ccf23 100644 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemPriceUpdateMsg.java +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemPriceUpdateMsg.java @@ -1,6 +1,8 @@ package org.tenten.tentenstomp.domain.trip.dto.request; public record TripItemPriceUpdateMsg( + Long tripId, + String visitDate, Long price ) { } diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemTransportationUpdateMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemTransportationUpdateMsg.java index f63d4ce..b50bc75 100644 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemTransportationUpdateMsg.java +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemTransportationUpdateMsg.java @@ -3,6 +3,8 @@ import org.tenten.tentenstomp.global.common.enums.Transportation; public record TripItemTransportationUpdateMsg( + Long tripId, + String visitDate, Transportation transportation ) { } diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemVisitDateUpdateMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemVisitDateUpdateMsg.java index e2e297c..f2a77ea 100644 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemVisitDateUpdateMsg.java +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemVisitDateUpdateMsg.java @@ -1,6 +1,8 @@ package org.tenten.tentenstomp.domain.trip.dto.request; public record TripItemVisitDateUpdateMsg( - String visitDate + Long tripId, + String oldVisitDate, + String newVisitDate ) { } diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/repository/MessageProxyRepository.java b/src/main/java/org/tenten/tentenstomp/domain/trip/repository/MessageProxyRepository.java new file mode 100644 index 0000000..78a34c7 --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/repository/MessageProxyRepository.java @@ -0,0 +1,86 @@ +package org.tenten.tentenstomp.domain.trip.repository; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; +import org.tenten.tentenstomp.domain.member.repository.MemberRepository; +import org.tenten.tentenstomp.domain.trip.dto.response.*; +import org.tenten.tentenstomp.domain.trip.entity.Trip; +import org.tenten.tentenstomp.global.cache.RedisCache; +import org.tenten.tentenstomp.global.common.enums.Category; +import org.tenten.tentenstomp.global.component.PathComponent; +import org.tenten.tentenstomp.global.component.dto.response.TripPathCalculationResult; + +import java.time.LocalDate; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.tenten.tentenstomp.global.common.constant.TopicConstant.*; + +@Repository +@RequiredArgsConstructor +public class MessageProxyRepository { + private final RedisCache redisCache; + private final ObjectMapper objectMapper; + private final TripRepository tripRepository; + private final MemberRepository memberRepository; + private final TripItemRepository tripItemRepository; + private final PathComponent pathComponent; + @Transactional(readOnly = true) + public TripMemberMsg getTripMemberMsg(Long tripId, Map> tripConnectedMemberMap) { + Object cached = redisCache.get(MEMBER, Long.toString(tripId)); + if (cached != null) { + return objectMapper.convertValue(cached, TripMemberMsg.class); + } + HashMap connectedMemberMap = tripConnectedMemberMap.getOrDefault(Long.toString(tripId), new HashMap<>()); + Trip trip = tripRepository.getReferenceById(tripId); + TripMemberMsg tripMemberMsg = new TripMemberMsg( + tripId, connectedMemberMap.values().stream().toList(), memberRepository.findTripMemberInfoByTripId(tripId), trip.getNumberOfPeople() + ); + redisCache.save(MEMBER, Long.toString(tripId), tripMemberMsg); + return tripMemberMsg; + } + @Transactional(readOnly = true) + public TripBudgetMsg getTripBudgetMsg(Trip trip) { + + Object cached = redisCache.get(BUDGET, Long.toString(trip.getId())); + if (cached != null) { + return objectMapper.convertValue(cached, TripBudgetMsg.class); + } + TripBudgetMsg tripBudgetMsg = new TripBudgetMsg( + trip.getId(), trip.getBudget(), trip.getTripItemPriceSum() + trip.getTransportationPriceSum() + ); + redisCache.save(BUDGET, Long.toString(trip.getId()), tripBudgetMsg); + return tripBudgetMsg; + } + @Transactional(readOnly = true) + public TripItemMsg getTripItemMsg(Long tripId, String visitDate) { + Object cached = redisCache.get(TRIP_ITEM, Long.toString(tripId), visitDate); + if (cached != null) { + return objectMapper.convertValue(cached, TripItemMsg.class); + + } + List tripInfos = tripItemRepository.getTripItemInfoByTripIdAndVisitDate(tripId, LocalDate.parse(visitDate)); + List tripItemInfoMsgs = tripInfos.stream().map(t -> new TripItemInfoMsg( + t.tripItemId(), t.tourItemId(), t.name(), t.thumbnailUrl(), Category.fromCode(t.contentTypeId()).getName(), t.transportation(), t.seqNum(), t.visitDate().toString(), t.price() + )).toList(); + TripItemMsg tripItemMsg = new TripItemMsg(tripId, visitDate, tripItemInfoMsgs); + redisCache.save(TRIP_ITEM, Long.toString(tripId), visitDate, tripItemMsg); + return tripItemMsg; + + } + @Transactional(readOnly = true) + public TripPathMsg getTripPathMsg(Long tripId, String visitDate) { + Object cached = redisCache.get(PATH, Long.toString(tripId), visitDate); + if (cached != null) { + return objectMapper.convertValue(cached, TripPathMsg.class); + } + TripPathCalculationResult tripPath = pathComponent.getTripPath(tripItemRepository.findTripPlaceByTripIdAndVisitDate(tripId, LocalDate.parse(visitDate))); + TripPathMsg tripPathMsg = new TripPathMsg(tripId, visitDate, tripPath.tripPathInfoMsgs()); + redisCache.save(PATH, Long.toString(tripId), visitDate, tripPathMsg); + return tripPathMsg; + + } +} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/service/TripItemService.java b/src/main/java/org/tenten/tentenstomp/domain/trip/service/TripItemService.java index f26b538..e19f3e8 100644 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/service/TripItemService.java +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/service/TripItemService.java @@ -3,6 +3,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.tenten.tentenstomp.domain.trip.dto.request.TripItemDeleteMsg; import org.tenten.tentenstomp.domain.trip.dto.request.TripItemPriceUpdateMsg; import org.tenten.tentenstomp.domain.trip.dto.request.TripItemTransportationUpdateMsg; import org.tenten.tentenstomp.domain.trip.dto.request.TripItemVisitDateUpdateMsg; @@ -11,20 +12,19 @@ import org.tenten.tentenstomp.domain.trip.dto.response.TripPathMsg; import org.tenten.tentenstomp.domain.trip.entity.Trip; import org.tenten.tentenstomp.domain.trip.entity.TripItem; +import org.tenten.tentenstomp.domain.trip.repository.MessageProxyRepository; import org.tenten.tentenstomp.domain.trip.repository.TripItemRepository; import org.tenten.tentenstomp.domain.trip.repository.TripRepository; import org.tenten.tentenstomp.global.component.PathComponent; import org.tenten.tentenstomp.global.component.dto.request.TripPlace; import org.tenten.tentenstomp.global.component.dto.response.TripPathCalculationResult; -import org.tenten.tentenstomp.global.exception.GlobalException; import org.tenten.tentenstomp.global.messaging.kafka.producer.KafkaProducer; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; import java.util.Map; - -import static org.springframework.http.HttpStatus.NOT_FOUND; +import java.util.Optional; @Service @RequiredArgsConstructor @@ -33,126 +33,175 @@ public class TripItemService { private final TripRepository tripRepository; private final KafkaProducer kafkaProducer; private final PathComponent pathComponent; + private final MessageProxyRepository messageProxyRepository; + @Transactional public void updateTripItemPrice(String tripItemId, TripItemPriceUpdateMsg priceUpdateMsg) { - TripItem tripItem = tripItemRepository.findTripItemForUpdate(Long.parseLong(tripItemId)).orElseThrow(() -> new GlobalException("해당 아이디로 존재하는 tripItem이 없다 " + tripItemId, NOT_FOUND)); - Long oldPrice = tripItem.getPrice(); - Long newPrice = priceUpdateMsg.price(); - Trip trip = tripItem.getTrip(); - trip.updateTripItemPriceSum(oldPrice, newPrice); - tripItem.updatePrice(newPrice); - List tripItems = trip.getTripItems(); - TripBudgetMsg tripBudgetMsg = new TripBudgetMsg(trip.getId(), trip.getBudget(), trip.getTripItemPriceSum() + trip.getTransportationPriceSum()); - TripItemMsg tripItemMsg = TripItemMsg.fromTripItemList(trip.getId(), tripItem.getVisitDate().toString(), tripItems, tripItem.getId(), priceUpdateMsg); - kafkaProducer.sendAndSaveToRedis(tripBudgetMsg, tripItemMsg); + Optional optionalTripItem = tripItemRepository.findTripItemForUpdate(Long.parseLong(tripItemId)); + if (optionalTripItem.isEmpty()) { + Trip trip = tripRepository.getReferenceById(priceUpdateMsg.tripId()); + kafkaProducer.sendWithOutCaching( + messageProxyRepository.getTripBudgetMsg(trip), + messageProxyRepository.getTripItemMsg(trip.getId(), priceUpdateMsg.visitDate()) + ); + } else { + TripItem tripItem = optionalTripItem.get(); + Long oldPrice = tripItem.getPrice(); + Long newPrice = priceUpdateMsg.price(); + Trip trip = tripItem.getTrip(); + trip.updateTripItemPriceSum(oldPrice, newPrice); + tripItem.updatePrice(newPrice); + List tripItems = trip.getTripItems(); + TripBudgetMsg tripBudgetMsg = new TripBudgetMsg(trip.getId(), trip.getBudget(), trip.getTripItemPriceSum() + trip.getTransportationPriceSum()); + TripItemMsg tripItemMsg = TripItemMsg.fromTripItemList(trip.getId(), tripItem.getVisitDate().toString(), tripItems, tripItem.getId(), priceUpdateMsg); + kafkaProducer.sendAndSaveToRedis(tripBudgetMsg, tripItemMsg); + } + } + @Transactional public void updateTripItemVisitDate(String tripItemId, TripItemVisitDateUpdateMsg visitDateUpdateMsg) { - TripItem tripItem = tripItemRepository.findTripItemForUpdate(Long.parseLong(tripItemId)).orElseThrow(() -> new GlobalException("해당 아이디로 존재하는 tripItem이 없다 " + tripItemId, NOT_FOUND)); - Trip trip = tripRepository.getReferenceById(tripItem.getTrip().getId()); - LocalDate pastDate = tripItem.getVisitDate(); - LocalDate newDate = LocalDate.parse(visitDateUpdateMsg.visitDate()); - - List pastDateTripItems = tripItemRepository.findTripItemByTripIdAndVisitDate(tripItem.getTrip().getId(), pastDate); - List newDateTripItems = tripItemRepository.findTripItemByTripIdAndVisitDate(tripItem.getTrip().getId(), newDate); - - Long oldSeqNum = tripItem.getSeqNum(); - Long newSeqNum = (long) newDateTripItems.size()+1; - List newPastDateTripItems = new ArrayList<>(); - for (TripItem pastDateTripItem : pastDateTripItems) { - if (pastDateTripItem.getId().equals(tripItem.getId())) { - continue; + Optional optionalTripItem = tripItemRepository.findTripItemForUpdate(Long.parseLong(tripItemId)); + if (optionalTripItem.isEmpty()) { + Trip trip = tripRepository.getReferenceById(visitDateUpdateMsg.tripId()); + kafkaProducer.sendWithOutCaching( + messageProxyRepository.getTripItemMsg(trip.getId(), visitDateUpdateMsg.oldVisitDate()), + messageProxyRepository.getTripItemMsg(trip.getId(), visitDateUpdateMsg.newVisitDate()), + messageProxyRepository.getTripPathMsg(trip.getId(), visitDateUpdateMsg.oldVisitDate()), + messageProxyRepository.getTripPathMsg(trip.getId(), visitDateUpdateMsg.newVisitDate()), + messageProxyRepository.getTripBudgetMsg(trip) + ); + } else { + TripItem tripItem = optionalTripItem.get(); + Trip trip = tripRepository.getReferenceById(tripItem.getTrip().getId()); + LocalDate pastDate = tripItem.getVisitDate(); + LocalDate newDate = LocalDate.parse(visitDateUpdateMsg.newVisitDate()); + + List pastDateTripItems = tripItemRepository.findTripItemByTripIdAndVisitDate(tripItem.getTrip().getId(), pastDate); + List newDateTripItems = tripItemRepository.findTripItemByTripIdAndVisitDate(tripItem.getTrip().getId(), newDate); + + Long oldSeqNum = tripItem.getSeqNum(); + Long newSeqNum = (long) newDateTripItems.size() + 1; + List newPastDateTripItems = new ArrayList<>(); + for (TripItem pastDateTripItem : pastDateTripItems) { + if (pastDateTripItem.getId().equals(tripItem.getId())) { + continue; + } + if (pastDateTripItem.getSeqNum() > oldSeqNum) { + pastDateTripItem.updateSeqNum(pastDateTripItem.getSeqNum() - 1); + } + newPastDateTripItems.add(pastDateTripItem); } - if (pastDateTripItem.getSeqNum() > oldSeqNum) { - pastDateTripItem.updateSeqNum(pastDateTripItem.getSeqNum() - 1); - } - newPastDateTripItems.add(pastDateTripItem); - } - tripItem.updateSeqNum(newSeqNum); - tripItem.updateVisitDate(LocalDate.parse(visitDateUpdateMsg.visitDate())); - newDateTripItems.add(tripItem); + tripItem.updateSeqNum(newSeqNum); + tripItem.updateVisitDate(LocalDate.parse(visitDateUpdateMsg.newVisitDate())); + newDateTripItems.add(tripItem); - TripPathCalculationResult pastDateTripPath = pathComponent.getTripPath(TripPlace.fromTripItems(newPastDateTripItems)); - TripPathCalculationResult newDateTripPath = pathComponent.getTripPath(TripPlace.fromTripItems(newDateTripItems)); + TripPathCalculationResult pastDateTripPath = pathComponent.getTripPath(TripPlace.fromTripItems(newPastDateTripItems)); + TripPathCalculationResult newDateTripPath = pathComponent.getTripPath(TripPlace.fromTripItems(newDateTripItems)); - Map tripPathPriceMap = trip.getTripPathPriceMap(); - trip.updateTransportationPriceSum(tripPathPriceMap.getOrDefault(pastDate.toString(), 0), pastDateTripPath.pathPriceSum()); - trip.updateTransportationPriceSum(tripPathPriceMap.getOrDefault(newDate.toString(), 0), newDateTripPath.pathPriceSum()); - tripPathPriceMap.put(pastDate.toString(), pastDateTripPath.pathPriceSum()); - tripPathPriceMap.put(newDate.toString(), newDateTripPath.pathPriceSum()); - tripRepository.save(trip); + Map tripPathPriceMap = trip.getTripPathPriceMap(); + trip.updateTransportationPriceSum(tripPathPriceMap.getOrDefault(pastDate.toString(), 0), pastDateTripPath.pathPriceSum()); + trip.updateTransportationPriceSum(tripPathPriceMap.getOrDefault(newDate.toString(), 0), newDateTripPath.pathPriceSum()); + tripPathPriceMap.put(pastDate.toString(), pastDateTripPath.pathPriceSum()); + tripPathPriceMap.put(newDate.toString(), newDateTripPath.pathPriceSum()); + tripRepository.save(trip); - TripItemMsg pastDateTripItemMsg = TripItemMsg.fromTripItemList(trip.getId(), pastDate.toString(), newPastDateTripItems); - TripItemMsg newDateTripItemMsg = TripItemMsg.fromTripItemList(trip.getId(), newDate.toString(), newDateTripItems); - TripPathMsg pastDateTripPathMsg = new TripPathMsg(trip.getId(), pastDate.toString(), pastDateTripPath.tripPathInfoMsgs()); - TripPathMsg newDateTripPathMsg = new TripPathMsg(trip.getId(), newDate.toString(), newDateTripPath.tripPathInfoMsgs()); - TripBudgetMsg tripBudgetMsg = new TripBudgetMsg(trip.getId(), trip.getBudget(), trip.getTripItemPriceSum() + trip.getTransportationPriceSum()); + TripItemMsg pastDateTripItemMsg = TripItemMsg.fromTripItemList(trip.getId(), pastDate.toString(), newPastDateTripItems); + TripItemMsg newDateTripItemMsg = TripItemMsg.fromTripItemList(trip.getId(), newDate.toString(), newDateTripItems); + TripPathMsg pastDateTripPathMsg = new TripPathMsg(trip.getId(), pastDate.toString(), pastDateTripPath.tripPathInfoMsgs()); + TripPathMsg newDateTripPathMsg = new TripPathMsg(trip.getId(), newDate.toString(), newDateTripPath.tripPathInfoMsgs()); + TripBudgetMsg tripBudgetMsg = new TripBudgetMsg(trip.getId(), trip.getBudget(), trip.getTripItemPriceSum() + trip.getTransportationPriceSum()); - kafkaProducer.sendAndSaveToRedis(pastDateTripItemMsg, newDateTripItemMsg, pastDateTripPathMsg, newDateTripPathMsg, tripBudgetMsg); + kafkaProducer.sendAndSaveToRedis(pastDateTripItemMsg, newDateTripItemMsg, pastDateTripPathMsg, newDateTripPathMsg, tripBudgetMsg); + } } + @Transactional - public void deleteTripItem(String tripItemId) { - TripItem tripItem = tripItemRepository.findTripItemForDelete(Long.parseLong(tripItemId)).orElseThrow(() -> new GlobalException("해당 아이디로 존재하는 tripItem이 없다 " + tripItemId, NOT_FOUND)); - Trip trip = tripRepository.getReferenceById(tripItem.getTrip().getId()); - - LocalDate visitDate = tripItem.getVisitDate(); - - List tripItems = tripItemRepository.findTripItemByTripIdAndVisitDate(tripItem.getTrip().getId(), visitDate); - Long seqNum = tripItem.getSeqNum(); - List newTripItems = new ArrayList<>(); - for (TripItem newTripItem : tripItems) { - if (newTripItem.getId().equals(tripItem.getId())) { - continue; + public void deleteTripItem(String tripItemId, TripItemDeleteMsg tripItemDeleteMsg) { + Optional optionalTripItem = tripItemRepository.findTripItemForUpdate(Long.parseLong(tripItemId)); + if (optionalTripItem.isEmpty()) { + Trip trip = tripRepository.getReferenceById(tripItemDeleteMsg.tripId()); + kafkaProducer.sendWithOutCaching( + messageProxyRepository.getTripItemMsg(trip.getId(), tripItemDeleteMsg.visitDate()), + messageProxyRepository.getTripPathMsg(trip.getId(), tripItemDeleteMsg.visitDate()), + messageProxyRepository.getTripBudgetMsg(trip) + ); + } else { + TripItem tripItem = optionalTripItem.get(); + Trip trip = tripRepository.getReferenceById(tripItem.getTrip().getId()); + + LocalDate visitDate = tripItem.getVisitDate(); + + List tripItems = tripItemRepository.findTripItemByTripIdAndVisitDate(tripItem.getTrip().getId(), visitDate); + Long seqNum = tripItem.getSeqNum(); + List newTripItems = new ArrayList<>(); + for (TripItem newTripItem : tripItems) { + if (newTripItem.getId().equals(tripItem.getId())) { + continue; + } + if (newTripItem.getSeqNum() > seqNum) { + newTripItem.updateSeqNum(newTripItem.getSeqNum() - 1); + } + newTripItems.add(newTripItem); } - if (newTripItem.getSeqNum() > seqNum) { - newTripItem.updateSeqNum(newTripItem.getSeqNum() - 1); - } - newTripItems.add(newTripItem); - } - tripItemRepository.delete(tripItem); - TripPathCalculationResult tripPath = pathComponent.getTripPath(TripPlace.fromTripItems(newTripItems)); - Map tripPathPriceMap = trip.getTripPathPriceMap(); - trip.updateTransportationPriceSum(tripPathPriceMap.getOrDefault(visitDate.toString(), 0), tripPath.pathPriceSum()); - tripPathPriceMap.put(visitDate.toString(), tripPath.pathPriceSum()); - tripRepository.save(trip); + tripItemRepository.delete(tripItem); + TripPathCalculationResult tripPath = pathComponent.getTripPath(TripPlace.fromTripItems(newTripItems)); + Map tripPathPriceMap = trip.getTripPathPriceMap(); + trip.updateTransportationPriceSum(tripPathPriceMap.getOrDefault(visitDate.toString(), 0), tripPath.pathPriceSum()); + tripPathPriceMap.put(visitDate.toString(), tripPath.pathPriceSum()); + tripRepository.save(trip); - TripItemMsg tripItemMsg = TripItemMsg.fromTripItemList(trip.getId(), visitDate.toString(), newTripItems); - TripPathMsg tripPathMsg = new TripPathMsg(trip.getId(), visitDate.toString(), tripPath.tripPathInfoMsgs()); - TripBudgetMsg tripBudgetMsg = new TripBudgetMsg(trip.getId(), trip.getBudget(), trip.getTripItemPriceSum() + trip.getTransportationPriceSum()); + TripItemMsg tripItemMsg = TripItemMsg.fromTripItemList(trip.getId(), visitDate.toString(), newTripItems); + TripPathMsg tripPathMsg = new TripPathMsg(trip.getId(), visitDate.toString(), tripPath.tripPathInfoMsgs()); + TripBudgetMsg tripBudgetMsg = new TripBudgetMsg(trip.getId(), trip.getBudget(), trip.getTripItemPriceSum() + trip.getTransportationPriceSum()); + + kafkaProducer.sendAndSaveToRedis(tripItemMsg, tripPathMsg, tripBudgetMsg); + } - kafkaProducer.sendAndSaveToRedis(tripItemMsg, tripPathMsg, tripBudgetMsg); } + @Transactional public void updateTripItemTransportation(String tripItemId, TripItemTransportationUpdateMsg tripItemTransportationUpdateMsg) { - TripItem tripItem = tripItemRepository.findTripItemForUpdate(Long.parseLong(tripItemId)).orElseThrow(() -> new GlobalException("해당 아이디로 존재하는 tripItem이 없다 " + tripItemId, NOT_FOUND)); - Trip trip = tripRepository.getReferenceById(tripItem.getTrip().getId()); - - LocalDate visitDate = tripItem.getVisitDate(); - List tripItems = tripItemRepository.findTripItemByTripIdAndVisitDate(tripItem.getTrip().getId(), visitDate); - for (TripItem newTripItem : tripItems) { - if (newTripItem.getId().equals(tripItem.getId())) { - newTripItem.updateTransportation(tripItemTransportationUpdateMsg.transportation()); + Optional optionalTripItem = tripItemRepository.findTripItemForUpdate(Long.parseLong(tripItemId)); + if (optionalTripItem.isEmpty()) { + Trip trip = tripRepository.getReferenceById(tripItemTransportationUpdateMsg.tripId()); + kafkaProducer.sendWithOutCaching( + messageProxyRepository.getTripItemMsg(trip.getId(), tripItemTransportationUpdateMsg.visitDate()), + messageProxyRepository.getTripPathMsg(trip.getId(), tripItemTransportationUpdateMsg.visitDate()), + messageProxyRepository.getTripBudgetMsg(trip) + ); + } else { + TripItem tripItem = optionalTripItem.get(); + Trip trip = tripRepository.getReferenceById(tripItem.getTrip().getId()); + + LocalDate visitDate = tripItem.getVisitDate(); + List tripItems = tripItemRepository.findTripItemByTripIdAndVisitDate(tripItem.getTrip().getId(), visitDate); + for (TripItem newTripItem : tripItems) { + if (newTripItem.getId().equals(tripItem.getId())) { + newTripItem.updateTransportation(tripItemTransportationUpdateMsg.transportation()); + } } - } - tripItem.updateTransportation(tripItemTransportationUpdateMsg.transportation()); - tripItemRepository.save(tripItem); + tripItem.updateTransportation(tripItemTransportationUpdateMsg.transportation()); + tripItemRepository.save(tripItem); - TripPathCalculationResult tripPath = pathComponent.getTripPath(TripPlace.fromTripItems(tripItems)); - Map tripPathPriceMap = trip.getTripPathPriceMap(); - trip.updateTransportationPriceSum(tripPathPriceMap.getOrDefault(visitDate.toString(), 0), tripPath.pathPriceSum()); - tripPathPriceMap.put(visitDate.toString(), tripPath.pathPriceSum()); - tripRepository.save(trip); + TripPathCalculationResult tripPath = pathComponent.getTripPath(TripPlace.fromTripItems(tripItems)); + Map tripPathPriceMap = trip.getTripPathPriceMap(); + trip.updateTransportationPriceSum(tripPathPriceMap.getOrDefault(visitDate.toString(), 0), tripPath.pathPriceSum()); + tripPathPriceMap.put(visitDate.toString(), tripPath.pathPriceSum()); + tripRepository.save(trip); - TripItemMsg tripItemMsg = TripItemMsg.fromTripItemList(trip.getId(), visitDate.toString(), tripItems); - TripPathMsg tripPathMsg = new TripPathMsg(trip.getId(), visitDate.toString(), tripPath.tripPathInfoMsgs()); - TripBudgetMsg tripBudgetMsg = new TripBudgetMsg(trip.getId(), trip.getBudget(), trip.getTripItemPriceSum() + trip.getTransportationPriceSum()); + TripItemMsg tripItemMsg = TripItemMsg.fromTripItemList(trip.getId(), visitDate.toString(), tripItems); + TripPathMsg tripPathMsg = new TripPathMsg(trip.getId(), visitDate.toString(), tripPath.tripPathInfoMsgs()); + TripBudgetMsg tripBudgetMsg = new TripBudgetMsg(trip.getId(), trip.getBudget(), trip.getTripItemPriceSum() + trip.getTransportationPriceSum()); + + kafkaProducer.sendAndSaveToRedis(tripItemMsg, tripPathMsg, tripBudgetMsg); + } - kafkaProducer.sendAndSaveToRedis(tripItemMsg, tripPathMsg, tripBudgetMsg); } diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/service/TripService.java b/src/main/java/org/tenten/tentenstomp/domain/trip/service/TripService.java index 9c7b6cc..7016522 100644 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/service/TripService.java +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/service/TripService.java @@ -1,6 +1,5 @@ package org.tenten.tentenstomp.domain.trip.service; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -12,10 +11,9 @@ import org.tenten.tentenstomp.domain.trip.dto.response.*; import org.tenten.tentenstomp.domain.trip.entity.Trip; import org.tenten.tentenstomp.domain.trip.entity.TripItem; +import org.tenten.tentenstomp.domain.trip.repository.MessageProxyRepository; import org.tenten.tentenstomp.domain.trip.repository.TripItemRepository; import org.tenten.tentenstomp.domain.trip.repository.TripRepository; -import org.tenten.tentenstomp.global.cache.RedisCache; -import org.tenten.tentenstomp.global.common.enums.Category; import org.tenten.tentenstomp.global.common.enums.TripStatus; import org.tenten.tentenstomp.global.component.PathComponent; import org.tenten.tentenstomp.global.component.dto.request.TripPlace; @@ -39,9 +37,8 @@ public class TripService { private final MemberRepository memberRepository; private final TourItemRepository tourItemRepository; private final KafkaProducer kafkaProducer; - private final RedisCache redisCache; private final PathComponent pathComponent; - private final ObjectMapper objectMapper; + private final MessageProxyRepository messageProxyRepository; private final Map> tripConnectedMemberMap = new HashMap<>(); @Transactional @@ -86,15 +83,15 @@ public void disconnectMember(String tripId, MemberDisconnectMsg memberDisconnect } - @Transactional + @Transactional(readOnly = true) public void enterMember(String tripId, MemberConnectMsg memberConnectMsg) { Trip trip = tripRepository.getReferenceById(Long.parseLong(tripId)); - kafkaProducer.send(MEMBER, getTripMemberMsg(tripId)); + kafkaProducer.send(MEMBER, messageProxyRepository.getTripMemberMsg(trip.getId(), tripConnectedMemberMap)); kafkaProducer.send(TRIP_INFO, trip.toTripInfo()); - kafkaProducer.send(TRIP_ITEM, getTripItemMsg(trip, trip.getStartDate().toString())); - kafkaProducer.send(PATH, getTripPathMsg(trip, trip.getStartDate().toString())); - kafkaProducer.send(BUDGET, getTripBudgetMsg(trip)); + kafkaProducer.send(TRIP_ITEM, messageProxyRepository.getTripItemMsg(trip.getId(), trip.getStartDate().toString())); + kafkaProducer.send(PATH, messageProxyRepository.getTripPathMsg(trip.getId(), trip.getStartDate().toString())); + kafkaProducer.send(BUDGET, messageProxyRepository.getTripBudgetMsg(trip)); } @@ -162,8 +159,8 @@ public void updateTripItemOrder(String tripId, TripItemOrderUpdateMsg orderUpdat public void getPathAndItems(String tripId, PathAndItemRequestMsg pathAndItemRequestMsg) { Trip trip = tripRepository.getReferenceById(Long.parseLong(tripId)); - kafkaProducer.send(TRIP_ITEM, getTripItemMsg(trip, pathAndItemRequestMsg.visitDate())); - kafkaProducer.send(PATH, getTripPathMsg(trip, pathAndItemRequestMsg.visitDate())); + kafkaProducer.send(TRIP_ITEM, messageProxyRepository.getTripItemMsg(trip.getId(), pathAndItemRequestMsg.visitDate())); + kafkaProducer.send(PATH, messageProxyRepository.getTripPathMsg(trip.getId(), pathAndItemRequestMsg.visitDate())); } @Transactional @@ -185,60 +182,5 @@ public void updateTripBudget(String tripId, TripBudgetUpdateMsg tripBudgetUpdate kafkaProducer.sendAndSaveToRedis(tripBudgetMsg, tripInfoMsg); } - private TripMemberMsg getTripMemberMsg(String tripId) { - Object cached = redisCache.get(MEMBER, tripId); - if (cached != null) { - return objectMapper.convertValue(cached, TripMemberMsg.class); - } - HashMap connectedMemberMap = tripConnectedMemberMap.getOrDefault(tripId, new HashMap<>()); - Trip trip = tripRepository.getReferenceById(Long.parseLong(tripId)); - TripMemberMsg tripMemberMsg = new TripMemberMsg( - Long.parseLong(tripId), connectedMemberMap.values().stream().toList(), memberRepository.findTripMemberInfoByTripId(Long.parseLong(tripId)), trip.getNumberOfPeople() - ); - redisCache.save(MEMBER, tripId, tripMemberMsg); - return tripMemberMsg; - } - - private TripBudgetMsg getTripBudgetMsg(Trip trip) { - - Object cached = redisCache.get(BUDGET, Long.toString(trip.getId())); - if (cached != null) { - return objectMapper.convertValue(cached, TripBudgetMsg.class); - } - TripBudgetMsg tripBudgetMsg = new TripBudgetMsg( - trip.getId(), trip.getBudget(), trip.getTripItemPriceSum() + trip.getTransportationPriceSum() - ); - redisCache.save(BUDGET, Long.toString(trip.getId()), tripBudgetMsg); - return tripBudgetMsg; - } - - private TripItemMsg getTripItemMsg(Trip trip, String visitDate) { - Object cached = redisCache.get(TRIP_ITEM, Long.toString(trip.getId()), visitDate); - if (cached != null) { - return objectMapper.convertValue(cached, TripItemMsg.class); - - } - List tripInfos = tripItemRepository.getTripItemInfoByTripIdAndVisitDate(trip.getId(), LocalDate.parse(visitDate)); - List tripItemInfoMsgs = tripInfos.stream().map(t -> new TripItemInfoMsg( - t.tripItemId(), t.tourItemId(), t.name(), t.thumbnailUrl(), Category.fromCode(t.contentTypeId()).getName(), t.transportation(), t.seqNum(), t.visitDate().toString(), t.price() - )).toList(); - TripItemMsg tripItemMsg = new TripItemMsg(trip.getId(), visitDate, tripItemInfoMsgs); - redisCache.save(TRIP_ITEM, Long.toString(trip.getId()), visitDate, tripItemMsg); - return tripItemMsg; - - } - - private TripPathMsg getTripPathMsg(Trip trip, String visitDate) { - Object cached = redisCache.get(PATH, Long.toString(trip.getId()), visitDate); - if (cached != null) { - return objectMapper.convertValue(cached, TripPathMsg.class); - } - TripPathCalculationResult tripPath = pathComponent.getTripPath(tripItemRepository.findTripPlaceByTripIdAndVisitDate(trip.getId(), LocalDate.parse(visitDate))); - TripPathMsg tripPathMsg = new TripPathMsg(trip.getId(), visitDate, tripPath.tripPathInfoMsgs()); - redisCache.save(PATH, Long.toString(trip.getId()), visitDate, tripPathMsg); - return tripPathMsg; - - } - } diff --git a/src/main/java/org/tenten/tentenstomp/global/messaging/kafka/producer/KafkaProducer.java b/src/main/java/org/tenten/tentenstomp/global/messaging/kafka/producer/KafkaProducer.java index 6afaf1f..ebfa5f3 100644 --- a/src/main/java/org/tenten/tentenstomp/global/messaging/kafka/producer/KafkaProducer.java +++ b/src/main/java/org/tenten/tentenstomp/global/messaging/kafka/producer/KafkaProducer.java @@ -18,6 +18,26 @@ public void send(String to, Object data) { kafkaTemplate.send(to, data); } + public void sendWithOutCaching(Object... dataArgs) { + for (Object data : dataArgs) { + if (data.getClass().equals(TripPathMsg.class)) { + send(PATH, data); + } + if (data.getClass().equals(TripItemMsg.class)) { + send(TRIP_ITEM, data); + } + if (data.getClass().equals(TripInfoMsg.class)) { + send(TRIP_INFO, data); + } + if (data.getClass().equals(TripMemberMsg.class)) { + send(MEMBER, data); + } + if (data.getClass().equals(TripBudgetMsg.class)) { + send(BUDGET, data); + } + } + } + public void sendAndSaveToRedis(Object... dataArgs) { for (Object data : dataArgs) { if (data.getClass().equals(TripPathMsg.class)) {