diff --git a/.http/NaverMap.http b/.http/NaverMap.http index 9e7760b..2f8a54f 100644 --- a/.http/NaverMap.http +++ b/.http/NaverMap.http @@ -1,5 +1,5 @@ ### 주소 좌표값 변환 api -GET https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode?query=부산 +GET https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode?query=강남대로 396 X-NCP-APIGW-API-KEY-ID: {{naver-map-client-id}} X-NCP-APIGW-API-KEY: {{naver-map-client-secret}} diff --git a/.http/Trip.http b/.http/Trip.http index cae88b7..98841e0 100644 --- a/.http/Trip.http +++ b/.http/Trip.http @@ -3,7 +3,7 @@ GET https://api.weplanplans.site/trips Content-Type: application/json { - "endPoint" : "/trip", + "endPoint" : "/place", "tripId": 1, "visitDate": "2024-01-03", "tripEditMessage" : { @@ -18,6 +18,125 @@ Content-Type: application/json "budget": 10000 }, "tripMemberMessage": null, - "tripPlaceMessage": null + "tripPlaceMessage": { + "places": [ + { + "tripItemId": 1, + "seqNum": 1, + "transportation": "CAR", + "visitDate": "2023-12-31", + "estimatePrice": 10000, + "longitude": "127.1051573", + "latitude": "37.3718141" + }, + { + "tripItemId": 2, + "seqNum": 2, + "transportation": "CAR", + "visitDate": "2023-12-31", + "estimatePrice": 10000, + "longitude": "126.9271941", + "latitude": "37.5266691" + }, + { + "tripItemId": 3, + "seqNum": 3, + "transportation": "PUBLIC_TRANSPORTATION", + "visitDate": "2023-12-31", + "estimatePrice": 10000, + "longitude": "127.0283079", + "latitude": "37.4981647" + }, + { + "tripItemId": 4, + "seqNum": 4, + "transportation": "CAR", + "visitDate": "2023-12-31", + "estimatePrice": 10000, + "longitude": "127.1051573", + "latitude": "37.3718141" + }, + { + "tripItemId": 5, + "seqNum": 5, + "transportation": "CAR", + "visitDate": "2023-12-31", + "estimatePrice": 10000, + "longitude": "127.0283079", + "latitude": "37.4981647" + } + ] + } +} + +### test +POST http://localhost:8080/trips +Content-Type: application/json + +{ + "endPoint" : "/place", + "tripId": 1, + "visitDate": "2024-01-03", + "tripEditMessage" : { + "tripId": 1, + "startDate": "2024-01-03", + "endDate" : "2024-01-05", + "numberOfPeople": 2, + "tripName": "success", + "tripStatus": "BEFORE", + "area": "서울", + "subarea": "강남구", + "budget": 10000 + }, + "tripMemberMessage": null, + "tripPlaceMessage": { + "places": [ + { + "tripItemId": 1, + "seqNum": 1, + "transportation": "CAR", + "visitDate": "2023-12-31", + "estimatePrice": 10000, + "longitude": "127.1051573", + "latitude": "37.3718141" + }, + { + "tripItemId": 2, + "seqNum": 2, + "transportation": "CAR", + "visitDate": "2023-12-31", + "estimatePrice": 10000, + "longitude": "126.9271941", + "latitude": "37.5266691" + }, + { + "tripItemId": 3, + "seqNum": 3, + "transportation": "PUBLIC_TRANSPORTATION", + "visitDate": "2023-12-31", + "estimatePrice": 10000, + "longitude": "127.0283079", + "latitude": "37.4981647" + }, + { + "tripItemId": 4, + "seqNum": 4, + "transportation": "CAR", + "visitDate": "2023-12-31", + "estimatePrice": 10000, + "longitude": "127.1051573", + "latitude": "37.3718141" + }, + { + "tripItemId": 5, + "seqNum": 5, + "transportation": "CAR", + "visitDate": "2023-12-31", + "estimatePrice": 10000, + "longitude": "127.0283079", + "latitude": "37.4981647" + } + ] + } } diff --git a/src/main/java/org/tenten/tentenstomp/config/AsyncConfig.java b/src/main/java/org/tenten/tentenstomp/config/AsyncConfig.java new file mode 100644 index 0000000..52275b3 --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/config/AsyncConfig.java @@ -0,0 +1,8 @@ +package org.tenten.tentenstomp.config; + +import org.springframework.context.annotation.Configuration; + +@Configuration +public class AsyncConfig { + +} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/controller/TripController.java b/src/main/java/org/tenten/tentenstomp/domain/trip/controller/TripController.java index c9b783e..a5ea377 100644 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/controller/TripController.java +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/controller/TripController.java @@ -5,8 +5,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.TripRequestMsg; -import org.tenten.tentenstomp.domain.trip.pubsub.RedisPublisher; +import org.tenten.tentenstomp.domain.trip.dto.request.*; import org.tenten.tentenstomp.domain.trip.service.TripService; import org.tenten.tentenstomp.global.producer.KafkaProducer; @@ -46,4 +45,5 @@ public void connectMember(@DestinationVariable String tripId, @Payload MemberCon public void disconnectMember(@DestinationVariable String tripId, @Payload MemberDisconnectMsg memberDisconnectMsg) { tripService.disconnectMember(tripId, memberDisconnectMsg); } + } 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 new file mode 100644 index 0000000..ae4a0f5 --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/controller/TripItemController.java @@ -0,0 +1,31 @@ +package org.tenten.tentenstomp.domain.trip.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.messaging.handler.annotation.DestinationVariable; +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.TripItemPriceUpdateMsg; +import org.tenten.tentenstomp.domain.trip.dto.request.TripItemVisitDateUpdateMsg; +import org.tenten.tentenstomp.domain.trip.service.TripItemService; + +@RestController +@RequiredArgsConstructor +public class TripItemController { + private final TripItemService tripItemService; + + @MessageMapping("/tripItems/{tripItemId}/updatePrice") + public void updateTripItemPrice(@DestinationVariable String tripItemId, @Payload TripItemPriceUpdateMsg priceUpdateMsg) { + tripItemService.updateTripItemPrice(tripItemId, priceUpdateMsg); + } + + @MessageMapping("/tripItems/{tripItemId}/updateVisitDate") + public void updateTripItemVisitDate(@DestinationVariable String tripItemId, @Payload TripItemVisitDateUpdateMsg visitDateUpdateMsg) { + tripItemService.updateTripItemVisitDate(tripItemId, visitDateUpdateMsg); + } + + @MessageMapping("/tripItems/{tripItemId}/deleteItem") + public void deleteTripItem(@DestinationVariable String tripItemId) { + tripItemService.deleteTripItem(tripItemId); + } +} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/MemberConnectMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/MemberConnectMsg.java new file mode 100644 index 0000000..492f2c5 --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/MemberConnectMsg.java @@ -0,0 +1,6 @@ +package org.tenten.tentenstomp.domain.trip.dto.request; + +public record MemberConnectMsg( + Long memberId +) { +} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/MemberDisconnectMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/MemberDisconnectMsg.java new file mode 100644 index 0000000..38bc862 --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/MemberDisconnectMsg.java @@ -0,0 +1,6 @@ +package org.tenten.tentenstomp.domain.trip.dto.request; + +public record MemberDisconnectMsg( + Long memberId +) { +} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemAddMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemAddMsg.java new file mode 100644 index 0000000..cd5f1cf --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemAddMsg.java @@ -0,0 +1,19 @@ +package org.tenten.tentenstomp.domain.trip.dto.request; + +import org.tenten.tentenstomp.global.common.enums.Transportation; + +import java.util.List; + +public record TripItemAddMsg( + List newTripItems +) { + public record TripItemCreateRequest( + Long tourItemId, + Transportation transportation, + Long seqNum, + String visitDate, + Long price + ) { + + } +} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemOrderUpdateMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemOrderUpdateMsg.java new file mode 100644 index 0000000..6ad9a92 --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemOrderUpdateMsg.java @@ -0,0 +1,14 @@ +package org.tenten.tentenstomp.domain.trip.dto.request; + +import java.util.List; + +public record TripItemOrderUpdateMsg( + String visitDate, + List tripItemOrder + +) { + public record OrderInfo( + Long tripItemId, + Long seqNum + ){} +} 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 new file mode 100644 index 0000000..9ff3804 --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemPriceUpdateMsg.java @@ -0,0 +1,6 @@ +package org.tenten.tentenstomp.domain.trip.dto.request; + +public record TripItemPriceUpdateMsg( + Long price +) { +} 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 new file mode 100644 index 0000000..7803314 --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripItemVisitDateUpdateMsg.java @@ -0,0 +1,4 @@ +package org.tenten.tentenstomp.domain.trip.dto.request; + +public record TripItemVisitDateUpdateMsg() { +} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripMemberRequestMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripMemberRequestMsg.java deleted file mode 100644 index 482e093..0000000 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripMemberRequestMsg.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.tenten.tentenstomp.domain.trip.dto.request; - -import org.tenten.tentenstomp.domain.trip.dto.response.TripMemberResponseMsg; -import org.tenten.tentenstomp.domain.trip.dto.response.TripMemberResponseMsg.TripLikedItem.TripLikedItemPreference; - -import java.util.List; - -public record TripMemberRequestMsg( - List tripLikedItemPreferences -) { -} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripPlaceRequestMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripPlaceRequestMsg.java deleted file mode 100644 index bb46fcf..0000000 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripPlaceRequestMsg.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.tenten.tentenstomp.domain.trip.dto.request; - -import org.tenten.tentenstomp.domain.trip.dto.response.TripPlaceResponseMsg.TripPlace; - -import java.util.List; - -public record TripPlaceRequestMsg(List places) { -} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripRequestMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripRequestMsg.java deleted file mode 100644 index 05ca9fd..0000000 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripRequestMsg.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.tenten.tentenstomp.domain.trip.dto.request; - -public record TripRequestMsg( - Long tripId, - String visitDate, - String endPoint, - TripInfoRequestMsg tripInfoMessage, - TripPlaceRequestMsg tripPlaceMessage, - TripMemberRequestMsg tripMemberMessage -) { -} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripInfoRequestMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripUpdateMsg.java similarity index 85% rename from src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripInfoRequestMsg.java rename to src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripUpdateMsg.java index e5438ad..db9b139 100644 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripInfoRequestMsg.java +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/request/TripUpdateMsg.java @@ -2,8 +2,7 @@ import org.tenten.tentenstomp.global.common.enums.TripStatus; -public record TripInfoRequestMsg( - Long tripId, +public record TripUpdateMsg( String startDate, String endDate, Long numberOfPeople, diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripInfoResponseMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripInfoMsg.java similarity index 89% rename from src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripInfoResponseMsg.java rename to src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripInfoMsg.java index 2b996b3..95cb2bc 100644 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripInfoResponseMsg.java +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripInfoMsg.java @@ -2,7 +2,7 @@ import org.tenten.tentenstomp.global.common.enums.TripStatus; -public record TripInfoResponseMsg( +public record TripInfoMsg( Long tripId, String startDate, String endDate, diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripItemInfoMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripItemInfoMsg.java new file mode 100644 index 0000000..aeca812 --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripItemInfoMsg.java @@ -0,0 +1,16 @@ +package org.tenten.tentenstomp.domain.trip.dto.response; + +import org.tenten.tentenstomp.global.common.enums.Transportation; + +public record TripItemInfoMsg( + Long tripItemId, + Long tourItemId, + String name, + String thumbnailUrl, + String category, + Transportation transportation, + Long seqNum, + String visitDate, + Long price +) { +} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripItemMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripItemMsg.java new file mode 100644 index 0000000..ec150cf --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripItemMsg.java @@ -0,0 +1,8 @@ +package org.tenten.tentenstomp.domain.trip.dto.response; + +import java.util.List; + +public record TripItemMsg( + List tripItems +) { +} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripMemberInfoMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripMemberInfoMsg.java new file mode 100644 index 0000000..fb7c0e8 --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripMemberInfoMsg.java @@ -0,0 +1,8 @@ +package org.tenten.tentenstomp.domain.trip.dto.response; + +public record TripMemberInfoMsg( + Long memberId, + String name, + String thumbnailUrl +) { +} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripMemberMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripMemberMsg.java new file mode 100644 index 0000000..6d559d3 --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripMemberMsg.java @@ -0,0 +1,8 @@ +package org.tenten.tentenstomp.domain.trip.dto.response; + +import java.util.List; + +public record TripMemberMsg( + List connectedMembers +) { +} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripMemberResponseMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripMemberResponseMsg.java deleted file mode 100644 index 2ed0282..0000000 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripMemberResponseMsg.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.tenten.tentenstomp.domain.trip.dto.response; - -import org.tenten.tentenstomp.domain.member.entity.Survey; - -import java.util.List; -import java.util.Map; - -public record TripMemberResponseMsg( - List connectedMembers, // 논의후 삭제 가능, 왜냐면, ws만 쓸때는 커넥션을 맺을 때, 해제할 때 호출되는 메소드가 있었는데, 현재 구조에서는 확실치 않음, - TripFavor tripFavor, - List tripLikedItems -) { - public record ConnectMemberMessage( - Long memberId, - String name, - String thumbnailUrl - ) { - - } - - public record TripFavor( - List memberSurveyResults, - MemberFavorStatistic favorStatistic - - ) { - - public record MemberSurveyResult( - Long memberId, - Survey survey - ) { - - } - - public record MemberFavorStatistic( - Map planning, - Map activeHours, - Map accommodations, - Map foods, - Map tripStyle - ) { - - } - } - - public record TripLikedItem( - Long tripLikedItemId, - String thumbnailImageUrl, - String tourItemName, - Long tourItemId, - List tripLikedItemPreferences - ) { - public record TripLikedItemPreference( - Long memberId, - Boolean liked, - Boolean disliked - ) { - - } - - } -} diff --git a/src/main/java/org/tenten/tentenstomp/global/component/dto/response/TripPathInfo.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripPathInfoMsg.java similarity index 57% rename from src/main/java/org/tenten/tentenstomp/global/component/dto/response/TripPathInfo.java rename to src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripPathInfoMsg.java index 11ed2ad..daa826b 100644 --- a/src/main/java/org/tenten/tentenstomp/global/component/dto/response/TripPathInfo.java +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripPathInfoMsg.java @@ -1,8 +1,8 @@ -package org.tenten.tentenstomp.global.component.dto.response; +package org.tenten.tentenstomp.domain.trip.dto.response; import org.tenten.tentenstomp.global.common.enums.Transportation; -public record TripPathInfo( +public record TripPathInfoMsg( Long fromSeqNum, Long toSeqNum, String fromLongitude, @@ -11,5 +11,11 @@ public record TripPathInfo( String toLatitude, Transportation transportation, PathInfo pathInfo + ) { + public record PathInfo( + Long price, + Double totalDistance, + Long totalTime + ){} } diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripPathMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripPathMsg.java new file mode 100644 index 0000000..5aabf2e --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripPathMsg.java @@ -0,0 +1,8 @@ +package org.tenten.tentenstomp.domain.trip.dto.response; + +import java.util.List; + +public record TripPathMsg( + List paths +) { +} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripPlaceResponseMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripPlaceResponseMsg.java deleted file mode 100644 index 813f3f7..0000000 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripPlaceResponseMsg.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.tenten.tentenstomp.domain.trip.dto.response; - -import org.tenten.tentenstomp.global.common.enums.Transportation; -import org.tenten.tentenstomp.global.component.dto.response.PathInfo; - -import java.util.List; - -public record TripPlaceResponseMsg( - List places, - List paths -) { - public record TripPlace( - Long tripItemId, - Long seqNum, - Transportation transportation, - String visitDate, - Long budget, - String longitude, - String latitude - - ) { - - } - - public record TripPath( - Long fromSeqNum, - Long toSeqNum, - String fromLongitude, - String fromLatitude, - String toLongitude, - String toLatitude, - Transportation transportation, - PathInfo pathInfo - ) { - - } -} \ No newline at end of file diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripResponseMsg.java b/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripResponseMsg.java deleted file mode 100644 index f059969..0000000 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/dto/response/TripResponseMsg.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.tenten.tentenstomp.domain.trip.dto.response; - -public record TripResponseMsg( - Long tripId, - String visitDate, - String endPoint, - TripInfoResponseMsg tripInfoMessage, - TripMemberResponseMsg tripMemberMessage, - TripPlaceResponseMsg tripPlaceMessage) { -} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/entity/Trip.java b/src/main/java/org/tenten/tentenstomp/domain/trip/entity/Trip.java index f2bb478..2475d81 100644 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/entity/Trip.java +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/entity/Trip.java @@ -5,9 +5,8 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import org.tenten.tentenstomp.domain.trip.dto.request.TripRequestMsg; -import org.tenten.tentenstomp.domain.trip.dto.response.TripInfoResponseMsg; -import org.tenten.tentenstomp.domain.trip.dto.response.TripResponseMsg; +import org.tenten.tentenstomp.domain.trip.dto.request.TripUpdateMsg; +import org.tenten.tentenstomp.domain.trip.dto.response.TripInfoMsg; import org.tenten.tentenstomp.global.common.BaseTimeEntity; import org.tenten.tentenstomp.global.common.enums.TripStatus; @@ -52,25 +51,17 @@ public class Trip extends BaseTimeEntity { @OneToMany(mappedBy = "trip", fetch = LAZY, cascade = REMOVE) private final List tripLikedItems = new ArrayList<>(); - public TripResponseMsg changeTripInfo(TripRequestMsg request) { - this.startDate = LocalDate.parse(request.tripInfoMessage().startDate()); - this.endDate = LocalDate.parse(request.tripInfoMessage().endDate()); - this.numberOfPeople = request.tripInfoMessage().numberOfPeople(); - this.tripName = request.tripInfoMessage().tripName(); - this.tripStatus = request.tripInfoMessage().tripStatus(); - this.area = request.tripInfoMessage().area(); - this.subarea = request.tripInfoMessage().subarea(); - this.budget = request.tripInfoMessage().budget(); + public TripInfoMsg changeTripInfo(TripUpdateMsg request) { + this.startDate = LocalDate.parse(request.startDate()); + this.endDate = LocalDate.parse(request.endDate()); + this.numberOfPeople = request.numberOfPeople(); + this.tripName = request.tripName(); + this.tripStatus = request.tripStatus(); + this.area = request.area(); + this.subarea = request.subarea(); + this.budget = request.budget(); - return new TripResponseMsg( - request.tripId(), request.visitDate(), request.endPoint(), - new TripInfoResponseMsg( - request.tripId(), request.tripInfoMessage().startDate(), - request.tripInfoMessage().endDate(), request.tripInfoMessage().numberOfPeople(), - request.tripInfoMessage().tripName(), request.tripInfoMessage().tripStatus(), - request.tripInfoMessage().area(), request.tripInfoMessage().subarea(), - request.tripInfoMessage().budget() - ), null, null - ); + return new TripInfoMsg(this.getId(), request.startDate(), request.endDate(), this.getNumberOfPeople(), this.getTripName(), this.getTripStatus(), + this.getArea(), this.getSubarea(), this.getBudget()); } } \ No newline at end of file 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 new file mode 100644 index 0000000..32805a4 --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/domain/trip/service/TripItemService.java @@ -0,0 +1,38 @@ +package org.tenten.tentenstomp.domain.trip.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.listener.ChannelTopic; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.tenten.tentenstomp.domain.trip.dto.request.TripItemPriceUpdateMsg; +import org.tenten.tentenstomp.domain.trip.dto.request.TripItemVisitDateUpdateMsg; +import org.tenten.tentenstomp.domain.trip.repository.TripItemRepository; +import org.tenten.tentenstomp.global.publisher.RedisPublisher; +import org.tenten.tentenstomp.global.util.RedisChannelUtil; + +import static org.tenten.tentenstomp.global.common.constant.EndPointConstant.TRIP_ITEM; + +@Service +@RequiredArgsConstructor +public class TripItemService { + private final TripItemRepository tripItemRepository; + private final RedisChannelUtil redisChannelUtil; + private final RedisPublisher redisPublisher; + @Transactional + public void updateTripItemPrice(String tripItemId, TripItemPriceUpdateMsg priceUpdateMsg) { + // TODO : /sub/{tripId}/tripItems/{visitDate} + + } + @Transactional + public void updateTripItemVisitDate(String tripItemId, TripItemVisitDateUpdateMsg visitDateUpdateMsg) { + // TODO : /sub/{tripId}/tripItems/{oldVisitDate} + // TODO : /sub/{tripId}/tripItems/{newVisitDate} + // TODO : /sub/{tripId}/path/{oldVisitDate} + // TODO : /sub/{tripId}/path/{newVisitDate} + } + @Transactional + public void deleteTripItem(String tripItemId) { + // TODO : /sub/{tripId}/tripItems/{visitDate} + // TODO : /sub/{tripId}/path/{visitDate} + } +} 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 8fd9b4e..f70db55 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 @@ -2,69 +2,75 @@ import lombok.RequiredArgsConstructor; import org.springframework.data.redis.listener.ChannelTopic; -import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.tenten.tentenstomp.domain.trip.dto.request.TripRequestMsg; -import org.tenten.tentenstomp.domain.trip.dto.response.TripResponseMsg; +import org.tenten.tentenstomp.domain.trip.dto.request.*; +import org.tenten.tentenstomp.domain.trip.dto.response.TripInfoMsg; import org.tenten.tentenstomp.domain.trip.entity.Trip; -import org.tenten.tentenstomp.domain.trip.pubsub.RedisPublisher; -import org.tenten.tentenstomp.domain.trip.pubsub.RedisSubscriber; import org.tenten.tentenstomp.domain.trip.repository.TripItemRepository; +import org.tenten.tentenstomp.global.common.constant.EndPointConstant; +import org.tenten.tentenstomp.global.publisher.RedisPublisher; import org.tenten.tentenstomp.domain.trip.repository.TripRepository; +import org.tenten.tentenstomp.global.response.GlobalStompResponse; +import org.tenten.tentenstomp.global.util.RedisChannelUtil; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import static org.tenten.tentenstomp.global.common.constant.EndPointConstant.*; + @Service @RequiredArgsConstructor public class TripService { private final TripRepository tripRepository; + private final RedisChannelUtil redisChannelUtil; private final TripItemRepository tripItemRepository; private final RedisPublisher redisPublisher; - private final RedisMessageListenerContainer redisMessageListenerContainer; - private final RedisSubscriber redisSubscriber; - private final Map channelTopicMap = new HashMap<>(); - private final Map> connectedMemberMap = new HashMap<>(); -// @Transactional -// public Long save(TripCreateRequest request) { -// -// return null; -// } + private final Map> connectedMemberMap = new HashMap<>(); +// private final PathComponent pathComponent; @Transactional - public void updateTrip(String tripId, TripRequestMsg request) { + public void updateTrip(String tripId, TripUpdateMsg tripUpdateMsg) { Trip trip = tripRepository.getReferenceById(Long.parseLong(tripId)); - ChannelTopic topic = getChannelTopic(tripId, request.endPoint()); - TripResponseMsg tripResponseMsg = trip.changeTripInfo(request); + ChannelTopic topic = redisChannelUtil.getChannelTopic(tripId, TRIP_INFO); + + TripInfoMsg tripResponseMsg = trip.changeTripInfo(tripUpdateMsg); tripRepository.save(trip); - redisPublisher.publish(topic, tripResponseMsg); // 해당 여정의 토픽을 찾아야함, + redisPublisher.publish(topic, GlobalStompResponse.ok(tripResponseMsg)); // 해당 여정의 토픽을 찾아야함, } + @Transactional + public void addTripItem(String tripId, TripItemAddMsg tripItemAddMsg) { + Trip trip = tripRepository.getReferenceById(Long.parseLong(tripId)); + ChannelTopic tripItemTopic = redisChannelUtil.getChannelTopic(tripId, tripItemAddMsg.newTripItems().get(0).visitDate(), TRIP_ITEM); + ChannelTopic pathTopic = redisChannelUtil.getChannelTopic(tripId, tripItemAddMsg.newTripItems().get(0).visitDate(), PATH); - private ChannelTopic getChannelTopic(String tripId, String endPoint) { - String channelName = tripId + endPoint; - if (!channelTopicMap.containsKey(channelName)) { - ChannelTopic newTopic = new ChannelTopic(channelName); - channelTopicMap.put(channelName, newTopic); - redisMessageListenerContainer.addMessageListener(redisSubscriber, newTopic); - } - return channelTopicMap.get(channelName); - } + // TODO : /sub/{tripId}/tripItems/{visitDate} + // TODO : /sub/{tripId}/path/{visitDate} - @Transactional - public void updateMember(String tripId, TripRequestMsg request) { - ChannelTopic topic = getChannelTopic(tripId, request.endPoint()); - TripResponseMsg tripResponseMsg = new TripResponseMsg(request.tripId(), request.visitDate(), request.endPoint(), null, null, null); - redisPublisher.publish(topic, tripResponseMsg); // 해당 여정의 토픽을 찾아야함, } - @Transactional - public void updatePlace(String tripId, TripRequestMsg request) { - ChannelTopic topic = getChannelTopic(tripId, request.endPoint()); - TripResponseMsg tripResponseMsg = new TripResponseMsg(request.tripId(), request.visitDate(), request.endPoint(), null, null, null); - redisPublisher.publish(topic, tripResponseMsg); // 해당 여정의 토픽을 찾 + public void updateTripItemOrder(String tripId, TripItemOrderUpdateMsg orderUpdateMsg) { + // TODO : /sub/{tripId}/tripItems/{visitDate} + // TODO : /sub/{tripId}/path/{visitDate} + ChannelTopic tripItemTopic = redisChannelUtil.getChannelTopic(tripId, orderUpdateMsg.visitDate(), TRIP_ITEM); + ChannelTopic pathTopic = redisChannelUtil.getChannelTopic(tripId, orderUpdateMsg.visitDate(), PATH); + + + } + @Transactional(readOnly = true) + public void connectMember(String tripId, MemberConnectMsg memberConnectMsg) { + // TODO: /sub/{tripId}/connectedMember + ChannelTopic memberTopic = redisChannelUtil.getChannelTopic(tripId, MEMBER); } + @Transactional(readOnly = true) + public void disconnectMember(String tripId, MemberDisconnectMsg memberDisconnectMsg) { + // TODO: /sub/{tripId}/connectedMember + ChannelTopic memberTopic = redisChannelUtil.getChannelTopic(tripId, MEMBER); + } + + + } diff --git a/src/main/java/org/tenten/tentenstomp/global/aspect/UtilAspect.java b/src/main/java/org/tenten/tentenstomp/global/aspect/UtilAspect.java new file mode 100644 index 0000000..951c033 --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/global/aspect/UtilAspect.java @@ -0,0 +1,22 @@ +package org.tenten.tentenstomp.global.aspect; + +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +@Component +@Aspect +@Slf4j +public class UtilAspect { + + @Around("@annotation(org.tenten.tentenstomp.global.common.annotation.GetExecutionTime)") + public Object getExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable { + long startTime = System.currentTimeMillis(); + Object proceed = joinPoint.proceed(joinPoint.getArgs()); + log.info(joinPoint.getSignature().getName() + " execution time : " + ((System.currentTimeMillis() - startTime) / 1000.0)); + + return proceed; + } +} \ No newline at end of file diff --git a/src/main/java/org/tenten/tentenstomp/global/common/annotation/GetExecutionTime.java b/src/main/java/org/tenten/tentenstomp/global/common/annotation/GetExecutionTime.java new file mode 100644 index 0000000..f7a7f66 --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/global/common/annotation/GetExecutionTime.java @@ -0,0 +1,11 @@ +package org.tenten.tentenstomp.global.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 GetExecutionTime { +} diff --git a/src/main/java/org/tenten/tentenstomp/global/common/constant/EndPointConstant.java b/src/main/java/org/tenten/tentenstomp/global/common/constant/EndPointConstant.java new file mode 100644 index 0000000..c32cf2b --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/global/common/constant/EndPointConstant.java @@ -0,0 +1,8 @@ +package org.tenten.tentenstomp.global.common.constant; + +public class EndPointConstant { + public static final String TRIP_INFO = "info"; + public static final String TRIP_ITEM = "tripItems"; + public static final String PATH = "path"; + public static final String MEMBER = "connectedMember"; +} diff --git a/src/main/java/org/tenten/tentenstomp/global/component/NaverMapComponent.java b/src/main/java/org/tenten/tentenstomp/global/component/NaverMapComponent.java index 4aa45f3..354bc88 100644 --- a/src/main/java/org/tenten/tentenstomp/global/component/NaverMapComponent.java +++ b/src/main/java/org/tenten/tentenstomp/global/component/NaverMapComponent.java @@ -11,7 +11,7 @@ import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; -import org.tenten.tentenstomp.global.component.dto.response.PathInfo; +import org.tenten.tentenstomp.domain.trip.dto.response.TripPathInfoMsg; import org.tenten.tentenstomp.global.exception.GlobalException; import java.util.List; @@ -19,6 +19,7 @@ import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpStatus.CONFLICT; +import static org.tenten.tentenstomp.domain.trip.dto.response.TripPathInfoMsg.*; import static org.tenten.tentenstomp.global.common.constant.NaverMapConstant.NAVER_MAP_API_KEY_HEADER; import static org.tenten.tentenstomp.global.common.constant.NaverMapConstant.NAVER_MAP_CLIENT_ID_HEADER; @@ -34,15 +35,15 @@ public class NaverMapComponent { @Value("${naver-map.client_id}") private String clientId; public PathInfo calculatePathInfo(String fromLongitude, - String fromLatitude, - String toLongitude, - String toLatitude) { + String fromLatitude, + String toLongitude, + String toLatitude) { UriComponents uri = UriComponentsBuilder .fromUriString(BASE_URL) .queryParam("start", fromLongitude + "," + fromLatitude) .queryParam("goal",toLongitude+","+toLatitude) .build(); - log.info(uri.toUriString()); +// log.info(uri.toUriString()); HttpHeaders header = new HttpHeaders(); header.set(NAVER_MAP_CLIENT_ID_HEADER, clientId); header.set(NAVER_MAP_API_KEY_HEADER, apiKey); @@ -51,18 +52,18 @@ public PathInfo calculatePathInfo(String fromLongitude, try { Map map = objectMapper.readValue(response.getBody(), new TypeReference>() { }); - for (String key : map.keySet()) { - log.info("key : " + key); - } - log.info("code : " + map.get("code")); - log.info("msg : " + map.get("message")); +// for (String key : map.keySet()) { +// log.info("key : " + key); +// } +// log.info("code : " + map.get("code")); +// log.info("msg : " + map.get("message")); if (map.get("code").equals(0)) { Map routeMap = (Map) map.get("route"); List> traoptimalList = (List> ) routeMap.get("traoptimal"); Map traoptimal = traoptimalList.get(0); - for (String traKey : traoptimal.keySet()) { - log.info("tra key : "+traKey); - } +// for (String traKey : traoptimal.keySet()) { +// log.info("traoptimal key : "+traKey); +// } Map summary = (Map) traoptimal.get("summary"); Integer tollFare = (Integer) summary.get("tollFare"); Integer fuelPrice = (Integer) summary.get("fuelPrice"); @@ -73,7 +74,8 @@ public PathInfo calculatePathInfo(String fromLongitude, throw new GlobalException("자동차 경로를 조회할 수 없습니다.", CONFLICT); } } catch (JsonProcessingException e) { - throw new GlobalException("자동차 경로 응답 파일을 읽어오는 과정에서 오류가 발생했습니다.", CONFLICT); + log.info("자동차 경로 응답 파일을 읽어오는 과정에서 오류가 발생했습니다."); + return null; } catch (Exception e) { log.info(e.getMessage()); return null; diff --git a/src/main/java/org/tenten/tentenstomp/global/component/OdsayComponent.java b/src/main/java/org/tenten/tentenstomp/global/component/OdsayComponent.java index f5c8b5b..4c232d1 100644 --- a/src/main/java/org/tenten/tentenstomp/global/component/OdsayComponent.java +++ b/src/main/java/org/tenten/tentenstomp/global/component/OdsayComponent.java @@ -13,7 +13,8 @@ import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; -import org.tenten.tentenstomp.global.component.dto.response.PathInfo; +import org.tenten.tentenstomp.domain.trip.dto.response.TripPathInfoMsg; +import org.tenten.tentenstomp.domain.trip.dto.response.TripPathInfoMsg.PathInfo; import org.tenten.tentenstomp.global.exception.GlobalException; import java.util.List; @@ -32,9 +33,9 @@ public class OdsayComponent { private final ObjectMapper objectMapper; private final String BASE_URL = "https://api.odsay.com/v1/api/searchPubTransPathT"; public PathInfo calculatePathInfo(String fromLongitude, - String fromLatitude, - String toLongitude, - String toLatitude) { + String fromLatitude, + String toLongitude, + String toLatitude) { UriComponents uri = UriComponentsBuilder .fromUriString(BASE_URL) .queryParam("apiKey", apiKey) @@ -43,7 +44,7 @@ public PathInfo calculatePathInfo(String fromLongitude, .queryParam("EX", toLongitude) .queryParam("EY", toLatitude) .build(); - log.info(uri.toUriString()); +// log.info(uri.toUriString()); HttpHeaders header = new HttpHeaders(); HttpEntity request = new HttpEntity(header); ResponseEntity response = restTemplate.exchange(uri.toUri(), GET, request, String.class); @@ -63,7 +64,8 @@ public PathInfo calculatePathInfo(String fromLongitude, throw new GlobalException("대중교통 경로를 조회할 수 없습니다.", CONFLICT); } } catch (JsonProcessingException jsonProcessingException) { - throw new GlobalException("대중교통 경로 응답 파일을 읽어오는 과정에서 오류가 발생했습니다.", CONFLICT); + log.info("대중교통 경로 응답 파일을 읽어오는 과정에서 오류가 발생했습니다."); + return null; } catch (Exception e) { log.info(e.getMessage()); return null; diff --git a/src/main/java/org/tenten/tentenstomp/global/component/PathComponent.java b/src/main/java/org/tenten/tentenstomp/global/component/PathComponent.java index 8a9ee1d..48a6cea 100644 --- a/src/main/java/org/tenten/tentenstomp/global/component/PathComponent.java +++ b/src/main/java/org/tenten/tentenstomp/global/component/PathComponent.java @@ -1,24 +1,51 @@ package org.tenten.tentenstomp.global.component; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; -import org.tenten.tentenstomp.global.component.dto.request.TripPlaceUpdateRequest.TripPlaceInfo; -import org.tenten.tentenstomp.global.component.dto.response.PathInfo; -import org.tenten.tentenstomp.global.component.dto.response.TripPathInfo; +import org.tenten.tentenstomp.domain.trip.dto.response.TripPathInfoMsg; +import org.tenten.tentenstomp.domain.trip.dto.response.TripPathInfoMsg.PathInfo; +import org.tenten.tentenstomp.global.common.annotation.GetExecutionTime; +import org.tenten.tentenstomp.global.component.dto.request.TripPlace; +import org.tenten.tentenstomp.global.component.dto.request.PathCalculateRequest; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import static org.tenten.tentenstomp.global.common.enums.Transportation.CAR; @Component @RequiredArgsConstructor +@Slf4j public class PathComponent { private final OdsayComponent odsayComponent; private final NaverMapComponent naverMapComponent; - - public TripPathInfo calculatePathByCar(TripPlaceInfo fromPlace, TripPlaceInfo toPlace) { - PathInfo pathInfo = naverMapComponent.calculatePathInfo(fromPlace.longitude(), fromPlace.latitude(), toPlace.longitude(), toPlace.latitude()); - return new TripPathInfo(fromPlace.seqNum(), toPlace.seqNum(), fromPlace.longitude(), fromPlace.latitude(), toPlace.longitude(), toPlace.latitude(), toPlace.transportation(), pathInfo); + @Async + public TripPathInfoMsg calculatePath(TripPlace fromPlace, TripPlace toPlace) { + long startTime = System.currentTimeMillis(); + PathInfo pathInfo; + if (toPlace.transportation().equals(CAR)) { + pathInfo = naverMapComponent.calculatePathInfo(fromPlace.longitude(), fromPlace.latitude(), toPlace.longitude(), toPlace.latitude()); + } else { + pathInfo = odsayComponent.calculatePathInfo(fromPlace.longitude(), fromPlace.latitude(), toPlace.longitude(), toPlace.latitude()); + } + log.info("from "+fromPlace.seqNum()+" to "+toPlace.seqNum()+" executionTime : "+((System.currentTimeMillis() - startTime) / 1000.0)); + return new TripPathInfoMsg(fromPlace.seqNum(), toPlace.seqNum(), fromPlace.longitude(), fromPlace.latitude(), toPlace.longitude(), toPlace.latitude(), toPlace.transportation(), pathInfo); } + @GetExecutionTime + public List getTripPath(List tripPlaceList) { + List pathCalculateRequests = toPathCalculateRequest(tripPlaceList); + return pathCalculateRequests.stream().flatMap(pathCalculateRequest -> Stream.of(calculatePath(pathCalculateRequest.from(), pathCalculateRequest.to()))).toList(); + } + - public TripPathInfo calculatePathByPublicTransportation(TripPlaceInfo fromPlace, TripPlaceInfo toPlace) { - PathInfo pathInfo = odsayComponent.calculatePathInfo(fromPlace.longitude(), fromPlace.latitude(), toPlace.longitude(), toPlace.latitude()); - return new TripPathInfo(fromPlace.seqNum(), toPlace.seqNum(), fromPlace.longitude(), fromPlace.latitude(), toPlace.longitude(), toPlace.latitude(), toPlace.transportation(), pathInfo); + private List toPathCalculateRequest(List tripPlaceList) { + List pathCalculateRequests = new ArrayList<>(); + for (int i = 0; i + 1 < tripPlaceList.size(); i++) { + pathCalculateRequests.add(new PathCalculateRequest(tripPlaceList.get(i), tripPlaceList.get(i + 1))); + } + return pathCalculateRequests; } } diff --git a/src/main/java/org/tenten/tentenstomp/global/component/controller/PathController.java b/src/main/java/org/tenten/tentenstomp/global/component/controller/PathController.java deleted file mode 100644 index ad47c56..0000000 --- a/src/main/java/org/tenten/tentenstomp/global/component/controller/PathController.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.tenten.tentenstomp.global.component.controller; - -import lombok.RequiredArgsConstructor; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import org.tenten.tentenstomp.global.common.constant.ResponseConstant; -import org.tenten.tentenstomp.global.component.PathComponent; -import org.tenten.tentenstomp.global.component.dto.request.TempPathCalculateRequest; -import org.tenten.tentenstomp.global.response.GlobalDataResponse; - -import static org.tenten.tentenstomp.global.common.constant.ResponseConstant.SUCCESS; - -@RestController -@RequiredArgsConstructor -@RequestMapping("/path") -public class PathController { - private final PathComponent pathComponent; - - @GetMapping("/car") - public ResponseEntity carPathTest(@RequestBody TempPathCalculateRequest calculateRequest) { - - return ResponseEntity.ok(GlobalDataResponse.ok(SUCCESS, pathComponent.calculatePathByCar(calculateRequest.from(), calculateRequest.to()))); - } - - @GetMapping("/public") - public ResponseEntity publicPathTest(@RequestBody TempPathCalculateRequest calculateRequest) { - return ResponseEntity.ok(GlobalDataResponse.ok(SUCCESS, pathComponent.calculatePathByPublicTransportation(calculateRequest.from(), calculateRequest.to()))); - } -} diff --git a/src/main/java/org/tenten/tentenstomp/global/component/dto/request/PathCalculateRequest.java b/src/main/java/org/tenten/tentenstomp/global/component/dto/request/PathCalculateRequest.java new file mode 100644 index 0000000..3c00383 --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/global/component/dto/request/PathCalculateRequest.java @@ -0,0 +1,6 @@ +package org.tenten.tentenstomp.global.component.dto.request; + +public record PathCalculateRequest(TripPlace from, + TripPlace to) { + +} diff --git a/src/main/java/org/tenten/tentenstomp/global/component/dto/request/TempPathCalculateRequest.java b/src/main/java/org/tenten/tentenstomp/global/component/dto/request/TempPathCalculateRequest.java deleted file mode 100644 index e161d28..0000000 --- a/src/main/java/org/tenten/tentenstomp/global/component/dto/request/TempPathCalculateRequest.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.tenten.tentenstomp.global.component.dto.request; - -import org.tenten.tentenstomp.global.component.dto.request.TripPlaceUpdateRequest.TripPlaceInfo; - -public record TempPathCalculateRequest(TripPlaceInfo from, - TripPlaceInfo to) { - -} diff --git a/src/main/java/org/tenten/tentenstomp/global/component/dto/request/TripPlace.java b/src/main/java/org/tenten/tentenstomp/global/component/dto/request/TripPlace.java new file mode 100644 index 0000000..a22f361 --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/global/component/dto/request/TripPlace.java @@ -0,0 +1,11 @@ +package org.tenten.tentenstomp.global.component.dto.request; + +import org.tenten.tentenstomp.global.common.enums.Transportation; + +public record TripPlace( + Long seqNum, + Transportation transportation, + String longitude, + String latitude +) { +} diff --git a/src/main/java/org/tenten/tentenstomp/global/component/dto/response/PathInfo.java b/src/main/java/org/tenten/tentenstomp/global/component/dto/response/PathInfo.java deleted file mode 100644 index a6d0b9f..0000000 --- a/src/main/java/org/tenten/tentenstomp/global/component/dto/response/PathInfo.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.tenten.tentenstomp.global.component.dto.response; - -public record PathInfo( - Long totalTime, - Double totalDistance, - Long price -) { -} \ No newline at end of file diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/pubsub/RedisPublisher.java b/src/main/java/org/tenten/tentenstomp/global/publisher/RedisPublisher.java similarity index 67% rename from src/main/java/org/tenten/tentenstomp/domain/trip/pubsub/RedisPublisher.java rename to src/main/java/org/tenten/tentenstomp/global/publisher/RedisPublisher.java index 5d200ad..721442a 100644 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/pubsub/RedisPublisher.java +++ b/src/main/java/org/tenten/tentenstomp/global/publisher/RedisPublisher.java @@ -1,17 +1,17 @@ -package org.tenten.tentenstomp.domain.trip.pubsub; +package org.tenten.tentenstomp.global.publisher; import lombok.RequiredArgsConstructor; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.stereotype.Service; -import org.tenten.tentenstomp.domain.trip.dto.response.TripResponseMsg; +import org.tenten.tentenstomp.global.response.GlobalStompResponse; @RequiredArgsConstructor @Service public class RedisPublisher { private final RedisTemplate redisTemplate; - public void publish(ChannelTopic topic, TripResponseMsg message) { + public void publish(ChannelTopic topic, GlobalStompResponse message) { redisTemplate.convertAndSend(topic.getTopic(), message); } } diff --git a/src/main/java/org/tenten/tentenstomp/global/response/GlobalStompResponse.java b/src/main/java/org/tenten/tentenstomp/global/response/GlobalStompResponse.java new file mode 100644 index 0000000..caf9c88 --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/global/response/GlobalStompResponse.java @@ -0,0 +1,21 @@ +package org.tenten.tentenstomp.global.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.http.HttpStatus; +import org.tenten.tentenstomp.global.common.constant.ResponseConstant; + +import static org.tenten.tentenstomp.global.common.constant.ResponseConstant.SUCCESS; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class GlobalStompResponse { + private int status; + private String message; + private T data; + public static GlobalStompResponse ok(T data) { + return new GlobalStompResponse<>(HttpStatus.OK.value(), SUCCESS, data); + } +} diff --git a/src/main/java/org/tenten/tentenstomp/domain/trip/pubsub/RedisSubscriber.java b/src/main/java/org/tenten/tentenstomp/global/subscriber/RedisSubscriber.java similarity index 67% rename from src/main/java/org/tenten/tentenstomp/domain/trip/pubsub/RedisSubscriber.java rename to src/main/java/org/tenten/tentenstomp/global/subscriber/RedisSubscriber.java index a946316..a26580f 100644 --- a/src/main/java/org/tenten/tentenstomp/domain/trip/pubsub/RedisSubscriber.java +++ b/src/main/java/org/tenten/tentenstomp/global/subscriber/RedisSubscriber.java @@ -1,4 +1,4 @@ -package org.tenten.tentenstomp.domain.trip.pubsub; +package org.tenten.tentenstomp.global.subscriber; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; @@ -8,7 +8,7 @@ import org.springframework.data.redis.core.RedisTemplate; import org.springframework.messaging.simp.SimpMessageSendingOperations; import org.springframework.stereotype.Service; -import org.tenten.tentenstomp.domain.trip.dto.response.TripResponseMsg; +import org.tenten.tentenstomp.global.response.GlobalStompResponse; @Slf4j @RequiredArgsConstructor @@ -24,12 +24,11 @@ public class RedisSubscriber implements MessageListener { @Override public void onMessage(Message message, byte[] pattern) { try { - // redis에서 발행된 데이터를 받아 deserialize String publishMessage = (String) redisTemplate.getStringSerializer().deserialize(message.getBody()); - // TripEditResponse 객채로 맵핑 - TripResponseMsg tripResponseMsg = objectMapper.readValue(publishMessage, TripResponseMsg.class); - // Websocket 구독자에게 메시지 Send - messagingTemplate.convertAndSend("/sub/trips/" + tripResponseMsg.tripId() + tripResponseMsg.endPoint(), tripResponseMsg); + String endPointUrl = (String) redisTemplate.getStringSerializer().deserialize(message.getChannel()); + log.info(endPointUrl); + GlobalStompResponse dataResponse = objectMapper.readValue(publishMessage, GlobalStompResponse.class); + messagingTemplate.convertAndSend("/sub"+endPointUrl, dataResponse); } catch (Exception e) { log.error(e.getMessage()); } diff --git a/src/main/java/org/tenten/tentenstomp/global/util/RedisChannelUtil.java b/src/main/java/org/tenten/tentenstomp/global/util/RedisChannelUtil.java new file mode 100644 index 0000000..009ed7e --- /dev/null +++ b/src/main/java/org/tenten/tentenstomp/global/util/RedisChannelUtil.java @@ -0,0 +1,46 @@ +package org.tenten.tentenstomp.global.util; + +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.listener.ChannelTopic; +import org.springframework.data.redis.listener.RedisMessageListenerContainer; +import org.springframework.stereotype.Component; +import org.tenten.tentenstomp.global.subscriber.RedisSubscriber; + +import java.util.HashMap; +import java.util.Map; + +@Component +@RequiredArgsConstructor +public class RedisChannelUtil { + private final RedisMessageListenerContainer redisMessageListenerContainer; + private final RedisSubscriber redisSubscriber; + private final Map channelTopicMap = new HashMap<>(); + + public ChannelTopic getChannelTopic(String tripId, String endPoint) { + String channelName = createChannelName(tripId, endPoint); + if (!channelTopicMap.containsKey(channelName)) { + ChannelTopic newTopic = new ChannelTopic(channelName); + channelTopicMap.put(channelName, newTopic); + redisMessageListenerContainer.addMessageListener(redisSubscriber, newTopic); + } + return channelTopicMap.get(channelName); + } + + public ChannelTopic getChannelTopic(String tripId, String visitDate, String endPoint) { + String channelName = createChannelName(tripId, visitDate, endPoint); + if (!channelTopicMap.containsKey(channelName)) { + ChannelTopic newTopic = new ChannelTopic(channelName); + channelTopicMap.put(channelName, newTopic); + redisMessageListenerContainer.addMessageListener(redisSubscriber, newTopic); + } + return channelTopicMap.get(channelName); + } + + private String createChannelName(String tripId, String endPoint) { + return "/" + tripId + "/" + endPoint; + } + + private String createChannelName(String tripId, String visitDate, String endPoint) { + return "/" + tripId + "/" + endPoint + "/" + visitDate; + } +}