From 3469ba78feb79fe81cdf1d0d0d755ef2406b1228 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:23:01 +0900 Subject: [PATCH 01/64] =?UTF-8?q?fix:=20application=20local=20yml=20?= =?UTF-8?q?=EB=93=A4=EC=97=AC=EC=93=B0=EA=B8=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-local.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index cf96314f..5a1d6220 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -54,12 +54,14 @@ gachtaxi: cookieMaxAge: ${JWT_COOKIE_MAX_AGE} secureOption: ${COOKIE_SECURE_OPTION} cookiePathOption: ${COOKIE_PATH_OPTION} + redis: + emailAuthCodeExpiration: ${REDIS_EMAIL_AUTH_CODE_EXPIRATION} kafka: topics: match-room-created: ${KAFKA_TOPIC_MATCH_ROOM_CREATED} match-member-joined: ${KAFKA_TOPIC_MATCH_MEMBER_JOINED} match-room-cancelled: ${KAFKA_TOPIC_MATCH_ROOM_CANCELLED} + match-member-cancelled: ${KAFKA_TOPIC_MATCH_MEMBER_CANCELLED} partition-count: ${KAFKA_PARTITION_COUNT} replication-factor: ${KAFKA_REPLICATION_FACTOR} - redis: - emailAuthCodeExpiration: ${REDIS_EMAIL_AUTH_CODE_EXPIRATION} + From 021e85c3f57006194ea1891f13f66ec73c789d05 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:23:15 +0900 Subject: [PATCH 02/64] =?UTF-8?q?feat:=20EnableJpaAuditing=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/gachtaxi/GachtaxiApplication.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/gachtaxi/GachtaxiApplication.java b/src/main/java/com/gachtaxi/GachtaxiApplication.java index 6b14e6e2..26a66dec 100644 --- a/src/main/java/com/gachtaxi/GachtaxiApplication.java +++ b/src/main/java/com/gachtaxi/GachtaxiApplication.java @@ -3,9 +3,11 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.mongodb.config.EnableMongoAuditing; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; @SpringBootApplication @EnableMongoAuditing +@EnableJpaAuditing public class GachtaxiApplication { public static void main(String[] args) { From 959419d0ae61938e24fb56eaece6b63212ecea2d Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:23:56 +0900 Subject: [PATCH 03/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EC=B7=A8?= =?UTF-8?q?=EC=86=8C=20=EA=B4=80=EB=A0=A8=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20?= =?UTF-8?q?=ED=86=A0=ED=94=BD=20DTO=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kafka_topic/MatchMemberCancelledEvent.java | 16 ++++++++++++++++ .../dto/kafka_topic/MatchRoomCancelledEvent.java | 10 ++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberCancelledEvent.java create mode 100644 src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCancelledEvent.java diff --git a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberCancelledEvent.java b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberCancelledEvent.java new file mode 100644 index 00000000..fd93e073 --- /dev/null +++ b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberCancelledEvent.java @@ -0,0 +1,16 @@ +package com.gachtaxi.domain.matching.event.dto.kafka_topic; + +import com.fasterxml.jackson.annotation.JsonFormat; +import java.time.LocalDateTime; +import lombok.Builder; + +@Builder +public record MatchMemberCancelledEvent( + Long roomId, + Long memberId, + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + LocalDateTime canceledAt +) { + +} diff --git a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCancelledEvent.java b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCancelledEvent.java new file mode 100644 index 00000000..f7ab0cb5 --- /dev/null +++ b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCancelledEvent.java @@ -0,0 +1,10 @@ +package com.gachtaxi.domain.matching.event.dto.kafka_topic; + +import lombok.Builder; + +@Builder +public record MatchRoomCancelledEvent( + Long roomId +) { + +} From 1cd28fe2a0dcc236285de4b75bca0b636c757414 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:24:43 +0900 Subject: [PATCH 04/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EC=B7=A8?= =?UTF-8?q?=EC=86=8C=20=EA=B4=80=EB=A0=A8=20enum=20=ED=95=84=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/matching/common/dto/enums/AutoMatchingStatus.java | 4 ++-- .../matching/common/entity/enums/MatchingRoomStatus.java | 2 +- .../domain/matching/common/entity/enums/PaymentStatus.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/dto/enums/AutoMatchingStatus.java b/src/main/java/com/gachtaxi/domain/matching/common/dto/enums/AutoMatchingStatus.java index c1dee135..03401cad 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/dto/enums/AutoMatchingStatus.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/dto/enums/AutoMatchingStatus.java @@ -7,7 +7,7 @@ @AllArgsConstructor public enum AutoMatchingStatus { REQUESTED("REQUESTED"), - REJECTED("REJECTED"); - + REJECTED("REJECTED"), + CANCELLED("CANCELLED"); private final String value; } diff --git a/src/main/java/com/gachtaxi/domain/matching/common/entity/enums/MatchingRoomStatus.java b/src/main/java/com/gachtaxi/domain/matching/common/entity/enums/MatchingRoomStatus.java index ddfcd386..8da75f23 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/entity/enums/MatchingRoomStatus.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/entity/enums/MatchingRoomStatus.java @@ -1,5 +1,5 @@ package com.gachtaxi.domain.matching.common.entity.enums; public enum MatchingRoomStatus { - PROCESS, COMPLETE, CANCELED, ACTIVE + PROCESS, COMPLETE, CANCELLED, ACTIVE } \ No newline at end of file diff --git a/src/main/java/com/gachtaxi/domain/matching/common/entity/enums/PaymentStatus.java b/src/main/java/com/gachtaxi/domain/matching/common/entity/enums/PaymentStatus.java index c754bfb3..bc0c4be4 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/entity/enums/PaymentStatus.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/entity/enums/PaymentStatus.java @@ -1,5 +1,5 @@ package com.gachtaxi.domain.matching.common.entity.enums; public enum PaymentStatus { - PAYED, NOT_PAYED, FAILED + PAYED, NOT_PAYED, FAILED, LEFT } From 67e59851a3133f0b7b31a1044d6e76d012ea2797 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:25:03 +0900 Subject: [PATCH 05/64] =?UTF-8?q?feat:=20Member=20entity=EC=97=90=20?= =?UTF-8?q?=EB=B0=A9=EC=9E=A5=20=ED=99=95=EC=9D=B8=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/members/entity/Members.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/main/java/com/gachtaxi/domain/members/entity/Members.java b/src/main/java/com/gachtaxi/domain/members/entity/Members.java index ed4c5ef8..1aedd0d1 100644 --- a/src/main/java/com/gachtaxi/domain/members/entity/Members.java +++ b/src/main/java/com/gachtaxi/domain/members/entity/Members.java @@ -1,11 +1,13 @@ package com.gachtaxi.domain.members.entity; +import com.gachtaxi.domain.matching.common.entity.MatchingRoom; import com.gachtaxi.domain.members.dto.request.UserSignUpRequestDto; import com.gachtaxi.domain.members.entity.enums.Gender; import com.gachtaxi.domain.members.entity.enums.Role; import com.gachtaxi.domain.members.entity.enums.UserStatus; import com.gachtaxi.global.common.entity.BaseEntity; import jakarta.persistence.*; +import java.util.Objects; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -110,4 +112,26 @@ public static Members ofKakaoId(Long kakaoId){ .role(Role.MEMBER) .build(); } + + public boolean isRoomMaster(MatchingRoom matchingRoom){ + return this.equals(matchingRoom.getRoomMaster()); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Members members = (Members) o; + return Objects.equals(studentNumber, members.studentNumber) && Objects.equals( + kakaoId, members.kakaoId); + } + + @Override + public int hashCode() { + return Objects.hash(studentNumber, kakaoId); + } } From ad3fabaff545de0ea234f477b37205a65aa044dc Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:25:24 +0900 Subject: [PATCH 06/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EC=B7=A8?= =?UTF-8?q?=EC=86=8C=20=EC=97=94=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AutoMatchingController.java | 26 ++++++++++++++----- .../common/controller/ResponseMessage.java | 3 ++- .../request/AutoMatchingCancelledRequest.java | 7 +++++ 3 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/gachtaxi/domain/matching/common/dto/request/AutoMatchingCancelledRequest.java diff --git a/src/main/java/com/gachtaxi/domain/matching/common/controller/AutoMatchingController.java b/src/main/java/com/gachtaxi/domain/matching/common/controller/AutoMatchingController.java index cd32b3cd..601f5b6e 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/controller/AutoMatchingController.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/controller/AutoMatchingController.java @@ -1,10 +1,13 @@ package com.gachtaxi.domain.matching.common.controller; +import com.gachtaxi.domain.matching.common.dto.request.AutoMatchingCancelledRequest; import com.gachtaxi.domain.matching.common.dto.request.AutoMatchingPostRequest; import com.gachtaxi.domain.matching.common.dto.response.AutoMatchingPostResponse; import com.gachtaxi.domain.matching.common.service.AutoMatchingService; +import com.gachtaxi.global.auth.jwt.annotation.CurrentMemberId; import com.gachtaxi.global.common.response.ApiResponse; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; @@ -15,6 +18,7 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; +@Slf4j @RestController @RequiredArgsConstructor @RequestMapping("/api/matching/auto") @@ -23,20 +27,15 @@ public class AutoMatchingController { private final AutoMatchingService autoMatchingService; @GetMapping(value = "/subscribe", produces = MediaType.TEXT_EVENT_STREAM_VALUE) - public SseEmitter subscribeSse(@RequestParam Long memberId) { - // TODO: 인가 로직 완성되면 해당 멤버의 아이디를 가져오도록 변경 -// Long memberId = 1L; - + public SseEmitter subscribeSse(@CurrentMemberId Long memberId) { return this.autoMatchingService.handleSubscribe(memberId); } @PostMapping("/request") public ApiResponse requestMatching( - @RequestParam Long memberId, + @CurrentMemberId Long memberId, @RequestBody AutoMatchingPostRequest autoMatchingPostRequest ) { - // TODO: 인가 로직 완성되면 해당 멤버의 아이디를 가져오도록 변경 -// Long memberId = 1L; if (!this.autoMatchingService.isSseSubscribed(memberId)) { return ApiResponse.response( HttpStatus.BAD_REQUEST, @@ -50,4 +49,17 @@ public ApiResponse requestMatching( this.autoMatchingService.handlerAutoRequestMatching(memberId, autoMatchingPostRequest) ); } + + @PostMapping("/cancel") + public ApiResponse cancelMatching( + @CurrentMemberId Long memberId, + @RequestBody AutoMatchingCancelledRequest autoMatchingCancelledRequest + ) { + log.info("memberId: {}, autoMatchingCancelledRequest: {}", memberId, autoMatchingCancelledRequest); + return ApiResponse.response( + HttpStatus.OK, + ResponseMessage.AUTO_MATCHING_REQUEST_CANCELLED.getMessage(), + this.autoMatchingService.handlerAutoCancelMatching(memberId, autoMatchingCancelledRequest) + ); + } } \ No newline at end of file diff --git a/src/main/java/com/gachtaxi/domain/matching/common/controller/ResponseMessage.java b/src/main/java/com/gachtaxi/domain/matching/common/controller/ResponseMessage.java index 63dcff16..859df93d 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/controller/ResponseMessage.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/controller/ResponseMessage.java @@ -12,7 +12,8 @@ public enum ResponseMessage { // auto matching AUTO_MATCHING_REQUEST_ACCEPTED("자동 매칭 요청 전송에 성공했습니다."), - NOT_SUBSCRIBED_SSE("SSE 구독 후 자동 매칭을 요청할 수 있습니다."); + NOT_SUBSCRIBED_SSE("SSE 구독 후 자동 매칭을 요청할 수 있습니다."), + AUTO_MATCHING_REQUEST_CANCELLED("자동 매칭 취소 요청 전송에 성공했습니다."); private final String message; } diff --git a/src/main/java/com/gachtaxi/domain/matching/common/dto/request/AutoMatchingCancelledRequest.java b/src/main/java/com/gachtaxi/domain/matching/common/dto/request/AutoMatchingCancelledRequest.java new file mode 100644 index 00000000..bd0c66fe --- /dev/null +++ b/src/main/java/com/gachtaxi/domain/matching/common/dto/request/AutoMatchingCancelledRequest.java @@ -0,0 +1,7 @@ +package com.gachtaxi.domain.matching.common.dto.request; + +public record AutoMatchingCancelledRequest( + Long roomId +) { + +} From 61af1880248f8b49c8f10a63137222474528aef6 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:25:41 +0900 Subject: [PATCH 07/64] =?UTF-8?q?feat:=20MatchingRoom=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=EC=97=90=20=EB=A7=A4=EC=B9=AD=20=EC=B7=A8=EC=86=8C=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/matching/common/entity/MatchingRoom.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoom.java b/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoom.java index 2f51ceb6..a61bd8c5 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoom.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoom.java @@ -18,6 +18,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; @Entity @Table(name = "matching_room") @@ -38,6 +39,8 @@ public class MatchingRoom extends BaseEntity { private List memberMatchingRoomChargingInfo; @ManyToOne(cascade = CascadeType.PERSIST, optional = false) + @Getter + @Setter private Members roomMaster; @Column(name = "title", nullable = false) @@ -59,4 +62,12 @@ public class MatchingRoom extends BaseEntity { public boolean isActiveMatchingRoom() { return this.matchingRoomStatus == MatchingRoomStatus.ACTIVE; } + + public void changeRoomMaster(Members members) { + this.setRoomMaster(members); + } + + public void cancelMatchingRoom() { + this.matchingRoomStatus = MatchingRoomStatus.CANCELLED; + } } From 871b065520dfe9c1d369188d6739bc98a0647559 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:25:54 +0900 Subject: [PATCH 08/64] =?UTF-8?q?feat:=20kafka=20consumer,=20producer=20?= =?UTF-8?q?=EB=A7=A4=EC=B9=AD=20=EC=B7=A8=EC=86=8C=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/kafka/KafkaConsumerConfig.java | 52 +++++++++++++++++++ .../config/kafka/KafkaProducerConfig.java | 45 ++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/src/main/java/com/gachtaxi/global/config/kafka/KafkaConsumerConfig.java b/src/main/java/com/gachtaxi/global/config/kafka/KafkaConsumerConfig.java index 4cfb0cc9..323af01a 100644 --- a/src/main/java/com/gachtaxi/global/config/kafka/KafkaConsumerConfig.java +++ b/src/main/java/com/gachtaxi/global/config/kafka/KafkaConsumerConfig.java @@ -1,6 +1,8 @@ package com.gachtaxi.global.config.kafka; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberCancelledEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberJoinedEvent; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCancelledEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; import java.util.HashMap; import java.util.Map; @@ -72,4 +74,54 @@ public ConcurrentKafkaListenerContainerFactory m factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL); return factory; } + + // MatchMemberCanceledEvent + @Bean + public ConsumerFactory matchMemberCancelledEventConsumerFactory() { + Map configs = new HashMap<>(); + configs.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); + configs.put(ConsumerConfig.GROUP_ID_CONFIG, groupId); + configs.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + + JsonDeserializer jsonDeserializer = + new JsonDeserializer<>(MatchMemberCancelledEvent.class); + jsonDeserializer.addTrustedPackages("com.gachtaxi.domain.matching.event.dto"); + + return new DefaultKafkaConsumerFactory<>(configs, new StringDeserializer(), jsonDeserializer); + } + + @Bean + public ConcurrentKafkaListenerContainerFactory matchMemberCancelledEventListenerFactory() { + ConcurrentKafkaListenerContainerFactory factory + = new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(matchMemberCancelledEventConsumerFactory()); + factory.setConcurrency(3); + factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL); + return factory; + } + + // MatchRoomCancelledEvent + @Bean + public ConsumerFactory matchRoomCancelledEventConsumerFactory() { + Map configs = new HashMap<>(); + configs.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); + configs.put(ConsumerConfig.GROUP_ID_CONFIG, groupId); + configs.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + + JsonDeserializer jsonDeserializer = + new JsonDeserializer<>(MatchRoomCancelledEvent.class); + jsonDeserializer.addTrustedPackages("com.gachtaxi.domain.matching.event.dto"); + + return new DefaultKafkaConsumerFactory<>(configs, new StringDeserializer(), jsonDeserializer); + } + + @Bean + public ConcurrentKafkaListenerContainerFactory matchRoomCancelledEventListenerFactory() { + ConcurrentKafkaListenerContainerFactory factory + = new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(matchRoomCancelledEventConsumerFactory()); + factory.setConcurrency(3); + factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL); + return factory; + } } \ No newline at end of file diff --git a/src/main/java/com/gachtaxi/global/config/kafka/KafkaProducerConfig.java b/src/main/java/com/gachtaxi/global/config/kafka/KafkaProducerConfig.java index 651f676d..f4028071 100644 --- a/src/main/java/com/gachtaxi/global/config/kafka/KafkaProducerConfig.java +++ b/src/main/java/com/gachtaxi/global/config/kafka/KafkaProducerConfig.java @@ -1,6 +1,8 @@ package com.gachtaxi.global.config.kafka; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberCancelledEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberJoinedEvent; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCancelledEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; import java.util.HashMap; import java.util.Map; @@ -51,9 +53,40 @@ public ProducerFactory matchMemberJoinedEventPro return new DefaultKafkaProducerFactory<>(configs); } + @Bean + @Qualifier("matchMemberCanceledEventProducerFactory") + public ProducerFactory matchMemberCanceledEventProducerFactory() { + Map configs = new HashMap<>(); + configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); + configs.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + configs.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class); + + configs.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true); + configs.put(ProducerConfig.ACKS_CONFIG, "all"); + configs.put(ProducerConfig.RETRIES_CONFIG, 3); + + return new DefaultKafkaProducerFactory<>(configs); + } + + @Bean + @Qualifier("matchRoomCancelledEventProducerFactory") + public ProducerFactory matchRoomCanclledEventProducerFactory() { + Map configs = new HashMap<>(); + configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); + configs.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + configs.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class); + + configs.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true); + configs.put(ProducerConfig.ACKS_CONFIG, "all"); + configs.put(ProducerConfig.RETRIES_CONFIG, 3); + + return new DefaultKafkaProducerFactory<>(configs); + } + @Bean @Qualifier("matchMemberJoinedEventKafkaTemplate") public KafkaTemplate matchMemberJoinedEventKafkaTemplate() { + return new KafkaTemplate<>(matchMemberJoinedEventProducerFactory()); } @@ -62,4 +95,16 @@ public KafkaTemplate matchMemberJoinedEventKafka public KafkaTemplate matchRoomCreatedEventKafkaTemplate() { return new KafkaTemplate<>(matchRoomCreatedEventProducerFactory()); } + + @Bean + @Qualifier("matchMemberCanceledEventKafkaTemplate") + public KafkaTemplate matchMemberCancelledEventKafkaTemplate() { + return new KafkaTemplate<>(matchMemberCanceledEventProducerFactory()); + } + + @Bean + @Qualifier("matchRoomCancelledEventKafkaTemplate") + public KafkaTemplate matchRoomCancelledEventKafkaTemplate() { + return new KafkaTemplate<>(matchRoomCanclledEventProducerFactory()); + } } \ No newline at end of file From 6b6b5c09726835d4d11d86b767a0f22b8e55755d Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:26:16 +0900 Subject: [PATCH 09/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EC=B7=A8?= =?UTF-8?q?=EC=86=8C=20=EA=B4=80=EB=A0=A8=20=EB=B9=84=EC=A6=88=EB=8B=88?= =?UTF-8?q?=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/service/MatchingRoomService.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java b/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java index 1eab6c64..69b084fb 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java @@ -5,22 +5,31 @@ import com.gachtaxi.domain.matching.common.entity.MemberMatchingRoomChargingInfo; import com.gachtaxi.domain.matching.common.entity.Route; import com.gachtaxi.domain.matching.common.entity.enums.MatchingRoomStatus; +import com.gachtaxi.domain.matching.common.entity.enums.PaymentStatus; import com.gachtaxi.domain.matching.common.entity.enums.Tags; +import com.gachtaxi.domain.matching.common.exception.MemberAlreadyJoinedException; +import com.gachtaxi.domain.matching.common.exception.MemberNotInMatchingRoomException; import com.gachtaxi.domain.matching.common.exception.NoSuchMatchingRoomException; import com.gachtaxi.domain.matching.common.exception.NotActiveMatchingRoomException; import com.gachtaxi.domain.matching.common.repository.MatchingRoomRepository; import com.gachtaxi.domain.matching.common.repository.MatchingRoomTagInfoRepository; import com.gachtaxi.domain.matching.common.repository.MemberMatchingRoomChargingInfoRepository; import com.gachtaxi.domain.matching.common.repository.RouteRepository; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberCancelledEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberJoinedEvent; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCancelledEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; +import com.gachtaxi.domain.matching.event.service.kafka.AutoMatchingProducer; import com.gachtaxi.domain.members.entity.Members; import com.gachtaxi.domain.members.service.MemberService; import jakarta.transaction.Transactional; import java.util.List; +import java.util.Optional; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +@Slf4j @Service @RequiredArgsConstructor @Transactional @@ -28,6 +37,7 @@ public class MatchingRoomService { // service private final MemberService memberService; + private final AutoMatchingProducer autoMatchingProducer; // repository private final MatchingRoomRepository matchingRoomRepository; @@ -83,6 +93,7 @@ private void saveHostMemberChargingInfo(MatchingRoom matchingRoom, Members membe .matchingRoom(matchingRoom) .members(members) .charge(matchingRoom.getTotalCharge()) + .paymentStatus(PaymentStatus.NOT_PAYED) .build(); this.memberMatchingRoomChargingInfoRepository.save(matchingRoomChargingInfo); @@ -94,6 +105,10 @@ public void joinMemberToMatchingRoom(MatchMemberJoinedEvent matchMemberJoinedEve matchMemberJoinedEvent.roomId()).orElseThrow( NoSuchMatchingRoomException::new); + if (this.memberMatchingRoomChargingInfoRepository.findByMembersAndMatchingRoom(members, matchingRoom).isPresent()) { + throw new MemberAlreadyJoinedException(); + } + if (!matchingRoom.isActiveMatchingRoom()) { throw new NotActiveMatchingRoomException(); } @@ -109,6 +124,7 @@ public void joinMemberToMatchingRoom(MatchMemberJoinedEvent matchMemberJoinedEve .matchingRoom(matchingRoom) .members(members) .charge(distributedCharge) + .paymentStatus(PaymentStatus.NOT_PAYED) .build() ); @@ -121,4 +137,48 @@ private void updateExistMembersCharge(List exist } this.memberMatchingRoomChargingInfoRepository.saveAll(existMembers); } + + public void leaveMemberFromMatchingRoom(MatchMemberCancelledEvent matchMemberCancelledEvent) { + Members members = this.memberService.findById(matchMemberCancelledEvent.memberId()); + MatchingRoom matchingRoom = this.matchingRoomRepository.findById( + matchMemberCancelledEvent.roomId()).orElseThrow( + NoSuchMatchingRoomException::new); + + MemberMatchingRoomChargingInfo memberMatchingRoomChargingInfo = this.memberMatchingRoomChargingInfoRepository.findByMembersAndMatchingRoom( + members, matchingRoom) + .orElseThrow(MemberNotInMatchingRoomException::new); + + memberMatchingRoomChargingInfo.leftMatchingRoom(); + + this.memberMatchingRoomChargingInfoRepository.save(memberMatchingRoomChargingInfo); + + if (members.isRoomMaster(matchingRoom)) { + this.findNextRoomMaster(matchingRoom, members) + .ifPresentOrElse( + nextRoomMaster -> matchingRoom.changeRoomMaster(nextRoomMaster), + () -> this.autoMatchingProducer.sendMatchRoomCancelledEvent( + MatchRoomCancelledEvent.builder().roomId(matchingRoom.getId()).build() + ) + ); + } + } + + private Optional findNextRoomMaster(MatchingRoom matchingRoom, Members members) { + List existMembers = this.memberMatchingRoomChargingInfoRepository.findByMatchingRoom( + matchingRoom); + + return existMembers.stream() + .map(MemberMatchingRoomChargingInfo::getMembers) + .filter(member -> !member.equals(members)) + .findFirst(); + } + + public void cancelMatchingRoom(MatchRoomCancelledEvent matchRoomCancelledEvent) { + MatchingRoom matchingRoom = this.matchingRoomRepository.findById( + matchRoomCancelledEvent.roomId()).orElseThrow( + NoSuchMatchingRoomException::new); + + matchingRoom.cancelMatchingRoom(); + this.matchingRoomRepository.save(matchingRoom); + } } From 05dc9dcf77f821f3ac9faf57ac229cb310627072 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:26:33 +0900 Subject: [PATCH 10/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EC=B7=A8?= =?UTF-8?q?=EC=86=8C=20=EA=B4=80=EB=A0=A8=20kafka=20consumer,=20producer?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/kafka/AutoMatchingConsumer.java | 49 +++++++++++++- .../service/kafka/AutoMatchingProducer.java | 66 +++++++++++++++++-- 2 files changed, 110 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingConsumer.java b/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingConsumer.java index 9f041594..3432bba3 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingConsumer.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingConsumer.java @@ -1,7 +1,9 @@ package com.gachtaxi.domain.matching.event.service.kafka; import com.gachtaxi.domain.matching.common.service.MatchingRoomService; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberCancelledEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberJoinedEvent; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCancelledEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; import com.gachtaxi.domain.matching.event.service.sse.SseService; import lombok.RequiredArgsConstructor; @@ -36,6 +38,7 @@ public void onMatchRoomCreated(MatchRoomCreatedEvent event, Acknowledgment ack) ack.acknowledge(); } catch (Exception e) { log.error("[KAFKA CONSUMER] Error processing MatchRoomCreatedEvent", e); + this.sseService.sendToClient(event.hostMemberId(), "MATCH_ROOM_CREATED", e.getMessage()); } } @@ -52,12 +55,56 @@ public void onMatchMemberJoined(MatchMemberJoinedEvent event, Acknowledgment ack this.matchingRoomService.joinMemberToMatchingRoom(event); - this.sseService.sendToClient(event.memberId(), "MATCH_MEMBER_JOINED", event); this.sseService.broadcast("MATCH_MEMBER_JOINED", event); ack.acknowledge(); } catch (Exception e) { log.error("[KAFKA CONSUMER] Error processing MatchMemberJoinedEvent", e); + this.sseService.sendToClient(event.memberId(), "MATCH_MEMBER_JOINED", e.getMessage()); + } + } + + /** + * 방 멤버 취소 이벤트 구독 + */ + @KafkaListener( + topics = "${gachtaxi.kafka.topics.match-member-cancelled}", + containerFactory = "matchMemberCancelledEventListenerFactory" + ) + public void onMatchMemberLeft(MatchMemberCancelledEvent event, Acknowledgment ack) { + try { + log.info("[KAFKA CONSUMER] Received MatchMemberLeftEvent: {}", event); + + this.matchingRoomService.leaveMemberFromMatchingRoom(event); + + this.sseService.broadcast("MATCH_MEMBER_LEFT", event); + + ack.acknowledge(); + } catch (Exception e) { + log.error("[KAFKA CONSUMER] Error processing MatchMemberLeftEvent", e); + this.sseService.sendToClient(event.memberId(), "MATCH_MEMBER_LEFT", e.getMessage()); + } + } + + /** + * 방 취소 이벤트 구독 + */ + @KafkaListener( + topics = "${gachtaxi.kafka.topics.match-room-cancelled}", + containerFactory = "matchRoomCancelledEventListenerFactory" + ) + public void onMatchRoomCancelled(MatchRoomCancelledEvent event, Acknowledgment ack) { + try { + log.info("[KAFKA CONSUMER] Received MatchRoomCancelledEvent: {}", event); + + this.matchingRoomService.cancelMatchingRoom(event); + + this.sseService.broadcast("MATCH_ROOM_CANCELLED", event); + + ack.acknowledge(); + } catch (Exception e) { + log.error("[KAFKA CONSUMER] Error processing MatchRoomCancelledEvent", e); + this.sseService.sendToClient(event.roomId(), "MATCH_ROOM_CANCELLED", e.getMessage()); } } } \ No newline at end of file diff --git a/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java b/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java index 406b9d37..a004b253 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java @@ -1,6 +1,8 @@ package com.gachtaxi.domain.matching.event.service.kafka; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberCancelledEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberJoinedEvent; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCancelledEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; import java.util.concurrent.CompletableFuture; import lombok.RequiredArgsConstructor; @@ -17,20 +19,29 @@ public class AutoMatchingProducer { private final KafkaTemplate matchRoomCreatedEventKafkaTemplate; private final KafkaTemplate matchMemberJoinedEventKafkaTemplate; + private final KafkaTemplate matchMemberCanceledEventKafkaTemplate; + private final KafkaTemplate matchRoomCancelledEventKafkaTemplate; - @Value("${kafka.topic.match-room-created}") + @Value("${gachtaxi.kafka.topics.match-room-created}") private String matchRoomCreatedTopic; - @Value("${kafka.topic.match-member-joined}") + @Value("${gachtaxi.kafka.topics.match-member-joined}") private String matchMemberJoinedTopic; + @Value("${gachtaxi.kafka.topics.match-member-cancelled}") + private String matchMemberCanceledTopic; + + @Value("${gachtaxi.kafka.topics.match-room-cancelled}") + private String matchRoomCancelledTopic; + /** * 방 생성 이벤트를 발행 */ public void sendMatchRoomCreatedEvent(MatchRoomCreatedEvent matchRoomCreatedEvent) { String key = matchRoomCreatedEvent.title(); - CompletableFuture future = this.matchRoomCreatedEventKafkaTemplate.send(matchRoomCreatedTopic, key, matchRoomCreatedEvent); + CompletableFuture future = this.matchRoomCreatedEventKafkaTemplate.send( + matchRoomCreatedTopic, key, matchRoomCreatedEvent); future.thenAccept(result -> { if (result instanceof RecordMetadata metadata) { @@ -52,7 +63,8 @@ public void sendMatchRoomCreatedEvent(MatchRoomCreatedEvent matchRoomCreatedEven public void sendMatchMemberJoinedEvent(MatchMemberJoinedEvent matchMemberJoinedEvent) { String key = String.valueOf(matchMemberJoinedEvent.roomId()); - CompletableFuture future = this.matchMemberJoinedEventKafkaTemplate.send(matchMemberJoinedTopic, key, matchMemberJoinedEvent); + CompletableFuture future = this.matchMemberJoinedEventKafkaTemplate.send( + matchMemberJoinedTopic, key, matchMemberJoinedEvent); future.thenAccept(result -> { if (result instanceof RecordMetadata metadata) { @@ -67,4 +79,50 @@ public void sendMatchMemberJoinedEvent(MatchMemberJoinedEvent matchMemberJoinedE return null; }); } + + /** + * 방 멤버 취소 이벤트를 발행 + */ + public void sendMatchMemberLeftEvent(MatchMemberCancelledEvent matchMemberCancelledEvent) { + String key = String.valueOf(matchMemberCancelledEvent.roomId()); + + CompletableFuture future = this.matchMemberCanceledEventKafkaTemplate.send( + matchMemberCanceledTopic, key, matchMemberCancelledEvent); + + future.thenAccept(result -> { + if (result instanceof RecordMetadata metadata) { + log.info("[KAFKA PRODUCER] Success sending MatchMemberLeftEvent: " + + "topic={}, partition={}, offset={}, key={}", + metadata.topic(), metadata.partition(), metadata.offset(), key + ); + } + } + ).exceptionally(ex -> { + log.error("[KAFKA PRODUCER] Failed to send MatchMemberLeftEvent key={}", key, ex); + return null; + }); + } + + /** + * 방 취소 이벤트를 발행 + */ + public void sendMatchRoomCancelledEvent(MatchRoomCancelledEvent matchRoomCancelledEvent) { + String key = String.valueOf(matchRoomCancelledEvent.roomId()); + + CompletableFuture future = this.matchRoomCancelledEventKafkaTemplate.send( + matchRoomCancelledTopic, key, matchRoomCancelledEvent); + + future.thenAccept(result -> { + if (result instanceof RecordMetadata metadata) { + log.info("[KAFKA PRODUCER] Success sending MatchRoomCancelledEvent: " + + "topic={}, partition={}, offset={}, key={}", + metadata.topic(), metadata.partition(), metadata.offset(), key + ); + } + } + ).exceptionally(ex -> { + log.error("[KAFKA PRODUCER] Failed to send MatchRoomCancelledEvent key={}", key, ex); + return null; + }); + } } \ No newline at end of file From 51de6b43cb3da7be0b9bba301a9086c7e246f560 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:26:46 +0900 Subject: [PATCH 11/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EC=B7=A8?= =?UTF-8?q?=EC=86=8C=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EB=B0=9C=ED=96=89=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/service/AutoMatchingService.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/service/AutoMatchingService.java b/src/main/java/com/gachtaxi/domain/matching/common/service/AutoMatchingService.java index 2428f12f..2c6e9575 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/service/AutoMatchingService.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/service/AutoMatchingService.java @@ -3,9 +3,11 @@ import com.gachtaxi.domain.matching.algorithm.dto.FindRoomResult; import com.gachtaxi.domain.matching.algorithm.service.MatchingAlgorithmService; import com.gachtaxi.domain.matching.common.dto.enums.AutoMatchingStatus; +import com.gachtaxi.domain.matching.common.dto.request.AutoMatchingCancelledRequest; import com.gachtaxi.domain.matching.common.dto.request.AutoMatchingPostRequest; import com.gachtaxi.domain.matching.common.dto.response.AutoMatchingPostResponse; import com.gachtaxi.domain.matching.common.entity.enums.Tags; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberCancelledEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberJoinedEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; import com.gachtaxi.domain.matching.event.service.kafka.AutoMatchingProducer; @@ -15,9 +17,11 @@ import java.util.Optional; import java.util.UUID; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; +@Slf4j @Service @RequiredArgsConstructor public class AutoMatchingService { @@ -84,4 +88,17 @@ private void sendMatchMemberJoinedEvent(Long memberId, FindRoomResult roomResult this.autoMatchingProducer.sendMatchMemberJoinedEvent(joinedEvent); } + + public AutoMatchingPostResponse handlerAutoCancelMatching(Long memberId, + AutoMatchingCancelledRequest autoMatchingCancelledRequest) { + + MatchMemberCancelledEvent matchMemberCancelledEvent = MatchMemberCancelledEvent.builder() + .roomId(autoMatchingCancelledRequest.roomId()) + .memberId(memberId) + .build(); + + this.autoMatchingProducer.sendMatchMemberLeftEvent(matchMemberCancelledEvent); + + return AutoMatchingPostResponse.of(AutoMatchingStatus.CANCELLED); + } } From 00bb278f0656011814be6fcaca5574e1b041fea5 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:27:15 +0900 Subject: [PATCH 12/64] =?UTF-8?q?feat:=20MemberNotInMatchingRoom=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../matching/common/exception/ErrorMessage.java | 4 +++- .../exception/MemberNotInMatchingRoomException.java | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/gachtaxi/domain/matching/common/exception/MemberNotInMatchingRoomException.java diff --git a/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java b/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java index f7569666..89f8344b 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java @@ -8,7 +8,9 @@ public enum ErrorMessage { NO_SUCH_MATCHING_ROOM("해당 매칭 방이 존재하지 않습니다."), - NOT_ACTIVE_MATCHING_ROOM("열린 매칭 방이 아닙니다."); + NOT_ACTIVE_MATCHING_ROOM("열린 매칭 방이 아닙니다."), + MEMBER_NOT_IN_MATCHING_ROOM("해당 매칭 방에 참가한 멤버가 아닙니다."), + MEMBER_ALREADY_JOINED_MATCHING_ROOM("해당 맴버는 이미 매칭 방에 참가한 멤버입니다"); private final String message; } diff --git a/src/main/java/com/gachtaxi/domain/matching/common/exception/MemberNotInMatchingRoomException.java b/src/main/java/com/gachtaxi/domain/matching/common/exception/MemberNotInMatchingRoomException.java new file mode 100644 index 00000000..f8f52374 --- /dev/null +++ b/src/main/java/com/gachtaxi/domain/matching/common/exception/MemberNotInMatchingRoomException.java @@ -0,0 +1,11 @@ +package com.gachtaxi.domain.matching.common.exception; + +import com.gachtaxi.global.common.exception.BaseException; +import org.springframework.http.HttpStatus; + +public class MemberNotInMatchingRoomException extends BaseException { + + public MemberNotInMatchingRoomException() { + super(HttpStatus.BAD_REQUEST, ErrorMessage.MEMBER_NOT_IN_MATCHING_ROOM.getMessage()); + } +} From c34a82c95214988c2c6b45a6cfd8764e8e181af4 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:27:29 +0900 Subject: [PATCH 13/64] =?UTF-8?q?feat:=20MemberAlreadyJoined=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/MemberAlreadyJoinedException.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/com/gachtaxi/domain/matching/common/exception/MemberAlreadyJoinedException.java diff --git a/src/main/java/com/gachtaxi/domain/matching/common/exception/MemberAlreadyJoinedException.java b/src/main/java/com/gachtaxi/domain/matching/common/exception/MemberAlreadyJoinedException.java new file mode 100644 index 00000000..6e83315c --- /dev/null +++ b/src/main/java/com/gachtaxi/domain/matching/common/exception/MemberAlreadyJoinedException.java @@ -0,0 +1,11 @@ +package com.gachtaxi.domain.matching.common.exception; + +import com.gachtaxi.global.common.exception.BaseException; +import org.springframework.http.HttpStatus; + +public class MemberAlreadyJoinedException extends BaseException { + + public MemberAlreadyJoinedException() { + super(HttpStatus.CONFLICT, ErrorMessage.MEMBER_ALREADY_JOINED_MATCHING_ROOM.getMessage()); + } +} From c454d929573681af53ba2555a0b2ef4a43edcb45 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:27:59 +0900 Subject: [PATCH 14/64] =?UTF-8?q?feat:=20Member=20ChargingInfo=EC=97=90=20?= =?UTF-8?q?=EB=A7=A4=EC=B9=AD=20=EC=B7=A8=EC=86=8C=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/entity/MemberMatchingRoomChargingInfo.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/entity/MemberMatchingRoomChargingInfo.java b/src/main/java/com/gachtaxi/domain/matching/common/entity/MemberMatchingRoomChargingInfo.java index aa4e11b3..0f676f0f 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/entity/MemberMatchingRoomChargingInfo.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/entity/MemberMatchingRoomChargingInfo.java @@ -14,6 +14,7 @@ import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; +import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -30,6 +31,7 @@ public class MemberMatchingRoomChargingInfo extends BaseEntity { @ManyToOne(fetch = FetchType.LAZY) + @Getter private Members members; @ManyToOne(fetch = FetchType.LAZY) @@ -40,5 +42,9 @@ public class MemberMatchingRoomChargingInfo extends BaseEntity { private Integer charge; @Enumerated(EnumType.STRING) - private PaymentStatus paymentStatus = PaymentStatus.NOT_PAYED; + private PaymentStatus paymentStatus; + + public void leftMatchingRoom() { + this.paymentStatus = PaymentStatus.LEFT; + } } From d5c389dc6c8267b8a9cb70bafde76e2696e44cd0 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:28:25 +0900 Subject: [PATCH 15/64] =?UTF-8?q?feat:=20MemberMatchingRoomChargingInfoRep?= =?UTF-8?q?ository.findByMembersAndMatchinRoom=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/MemberMatchingRoomChargingInfoRepository.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/repository/MemberMatchingRoomChargingInfoRepository.java b/src/main/java/com/gachtaxi/domain/matching/common/repository/MemberMatchingRoomChargingInfoRepository.java index d447c308..8f8746e1 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/repository/MemberMatchingRoomChargingInfoRepository.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/repository/MemberMatchingRoomChargingInfoRepository.java @@ -2,7 +2,9 @@ import com.gachtaxi.domain.matching.common.entity.MatchingRoom; import com.gachtaxi.domain.matching.common.entity.MemberMatchingRoomChargingInfo; +import com.gachtaxi.domain.members.entity.Members; import java.util.List; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -10,4 +12,5 @@ public interface MemberMatchingRoomChargingInfoRepository extends JpaRepository { List findByMatchingRoom(MatchingRoom matchingRoom); + Optional findByMembersAndMatchingRoom(Members members, MatchingRoom matchingRoom); } From 541fc949a1b49087da1c9fbe94c5f7d04a60288f Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:41:16 +0900 Subject: [PATCH 16/64] =?UTF-8?q?docs:=20.gitigonre=EC=97=90=20docker=20co?= =?UTF-8?q?mpose=20yml=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 3420b922..9c5d913e 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,5 @@ out/ .vscode/ src/main/resources/.env + +docker-compose.yml \ No newline at end of file From e4be0191fe6fc250c85f7b3ff0b8b3eb19e0f210 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:42:22 +0900 Subject: [PATCH 17/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EC=B7=A8?= =?UTF-8?q?=EC=86=8C=20=EC=9A=94=EC=B2=AD=20=EC=8B=9C=20sse=20=EA=B5=AC?= =?UTF-8?q?=EB=8F=85=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/controller/AutoMatchingController.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/controller/AutoMatchingController.java b/src/main/java/com/gachtaxi/domain/matching/common/controller/AutoMatchingController.java index 601f5b6e..4d8931d0 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/controller/AutoMatchingController.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/controller/AutoMatchingController.java @@ -55,7 +55,13 @@ public ApiResponse cancelMatching( @CurrentMemberId Long memberId, @RequestBody AutoMatchingCancelledRequest autoMatchingCancelledRequest ) { - log.info("memberId: {}, autoMatchingCancelledRequest: {}", memberId, autoMatchingCancelledRequest); + if (!this.autoMatchingService.isSseSubscribed(memberId)) { + return ApiResponse.response( + HttpStatus.BAD_REQUEST, + ResponseMessage.NOT_SUBSCRIBED_SSE.getMessage() + ); + } + return ApiResponse.response( HttpStatus.OK, ResponseMessage.AUTO_MATCHING_REQUEST_CANCELLED.getMessage(), From 115a3ffc9e096418749d60de649a654fe1df6331 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:50:32 +0900 Subject: [PATCH 18/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C=20topic=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event/dto/kafka_topic/MatchRoomCompletedEvent.java | 7 +++++++ .../gachtaxi/global/config/kafka/KafkaTopicsConfig.java | 3 +++ src/main/resources/application-local.yml | 1 + 3 files changed, 11 insertions(+) create mode 100644 src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCompletedEvent.java diff --git a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCompletedEvent.java b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCompletedEvent.java new file mode 100644 index 00000000..d0321295 --- /dev/null +++ b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCompletedEvent.java @@ -0,0 +1,7 @@ +package com.gachtaxi.domain.matching.event.dto.kafka_topic; + +public record MatchRoomCompletedEvent( + Long roomId +) { + +} diff --git a/src/main/java/com/gachtaxi/global/config/kafka/KafkaTopicsConfig.java b/src/main/java/com/gachtaxi/global/config/kafka/KafkaTopicsConfig.java index 4ecda46e..80a1517f 100644 --- a/src/main/java/com/gachtaxi/global/config/kafka/KafkaTopicsConfig.java +++ b/src/main/java/com/gachtaxi/global/config/kafka/KafkaTopicsConfig.java @@ -17,6 +17,9 @@ public class KafkaTopicsConfig { @Value("${gachtaxi.kafka.topics.match-room-cancelled}") private String matchRoomCancelledTopic; + @Value("${gachtaxi.kafka.topics.match-room-completed}") + private String matchRoomCompletedTopic; + @Value("${gachtaxi.kafka.partition-count}") private short partitionCount; diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 5a1d6220..871b6138 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -62,6 +62,7 @@ gachtaxi: match-member-joined: ${KAFKA_TOPIC_MATCH_MEMBER_JOINED} match-room-cancelled: ${KAFKA_TOPIC_MATCH_ROOM_CANCELLED} match-member-cancelled: ${KAFKA_TOPIC_MATCH_MEMBER_CANCELLED} + match-room-completed: ${KAFKA_TOPIC_MATCH_ROOM_COMPLETED} partition-count: ${KAFKA_PARTITION_COUNT} replication-factor: ${KAFKA_REPLICATION_FACTOR} From 69c357395fb574291a9b36f27be6cb926fed5858 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:50:41 +0900 Subject: [PATCH 19/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C=20producer=20config=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/kafka/KafkaProducerConfig.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/main/java/com/gachtaxi/global/config/kafka/KafkaProducerConfig.java b/src/main/java/com/gachtaxi/global/config/kafka/KafkaProducerConfig.java index f4028071..b2a6fcd7 100644 --- a/src/main/java/com/gachtaxi/global/config/kafka/KafkaProducerConfig.java +++ b/src/main/java/com/gachtaxi/global/config/kafka/KafkaProducerConfig.java @@ -3,6 +3,7 @@ import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberCancelledEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberJoinedEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCancelledEvent; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCompletedEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; import java.util.HashMap; import java.util.Map; @@ -83,6 +84,21 @@ public ProducerFactory matchRoomCanclledEventPr return new DefaultKafkaProducerFactory<>(configs); } + @Bean + @Qualifier("matchRoomCompletedEventProducerFactory") + public ProducerFactory matchRoomCompletedEventProducerFactory() { + Map configs = new HashMap<>(); + configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); + configs.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + configs.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class); + + configs.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true); + configs.put(ProducerConfig.ACKS_CONFIG, "all"); + configs.put(ProducerConfig.RETRIES_CONFIG, 3); + + return new DefaultKafkaProducerFactory<>(configs); + } + @Bean @Qualifier("matchMemberJoinedEventKafkaTemplate") public KafkaTemplate matchMemberJoinedEventKafkaTemplate() { @@ -107,4 +123,10 @@ public KafkaTemplate matchMemberCancelledEven public KafkaTemplate matchRoomCancelledEventKafkaTemplate() { return new KafkaTemplate<>(matchRoomCanclledEventProducerFactory()); } + + @Bean + @Qualifier("matchRoomCompletedEventKafkaTemplate") + public KafkaTemplate matchRoomCompletedEventKafkaTemplate() { + return new KafkaTemplate<>(matchRoomCompletedEventProducerFactory()); + } } \ No newline at end of file From e13ae216f3c56eaa79dfd2a9d2aa53203d92b791 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 18:50:51 +0900 Subject: [PATCH 20/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C=20consumer=20config=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/kafka/KafkaConsumerConfig.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/main/java/com/gachtaxi/global/config/kafka/KafkaConsumerConfig.java b/src/main/java/com/gachtaxi/global/config/kafka/KafkaConsumerConfig.java index 323af01a..25a925ea 100644 --- a/src/main/java/com/gachtaxi/global/config/kafka/KafkaConsumerConfig.java +++ b/src/main/java/com/gachtaxi/global/config/kafka/KafkaConsumerConfig.java @@ -3,6 +3,7 @@ import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberCancelledEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberJoinedEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCancelledEvent; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCompletedEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; import java.util.HashMap; import java.util.Map; @@ -124,4 +125,29 @@ public ConcurrentKafkaListenerContainerFactory factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL); return factory; } + + // MatchRoomCompleted + @Bean + public ConsumerFactory matchRoomCompletedEventConsumerFactory() { + Map configs = new HashMap<>(); + configs.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); + configs.put(ConsumerConfig.GROUP_ID_CONFIG, groupId); + configs.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + + JsonDeserializer jsonDeserializer = + new JsonDeserializer<>(MatchRoomCompletedEvent.class); + jsonDeserializer.addTrustedPackages("com.gachtaxi.domain.matching.event.dto"); + + return new DefaultKafkaConsumerFactory<>(configs, new StringDeserializer(), jsonDeserializer); + } + + @Bean + public ConcurrentKafkaListenerContainerFactory matchRoomCompletedEventListenerFactory() { + ConcurrentKafkaListenerContainerFactory factory + = new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(matchRoomCompletedEventConsumerFactory()); + factory.setConcurrency(3); + factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL); + return factory; + } } \ No newline at end of file From 4bf3e156a9dc831cc347f5126313bcee6955ffeb Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 19:01:44 +0900 Subject: [PATCH 21/64] =?UTF-8?q?feat:=20MatchRoom=20=EC=99=84=EB=A3=8C=20?= =?UTF-8?q?=EC=9D=B4=EB=B2=A4=ED=8A=B8=20DTO=EC=97=90=20builder=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event/dto/kafka_topic/MatchRoomCompletedEvent.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCompletedEvent.java b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCompletedEvent.java index d0321295..50ead675 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCompletedEvent.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCompletedEvent.java @@ -1,5 +1,8 @@ package com.gachtaxi.domain.matching.event.dto.kafka_topic; +import lombok.Builder; + +@Builder public record MatchRoomCompletedEvent( Long roomId ) { From f534c13173d535ded079853ab37c1ea5e42f3ee7 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 19:01:59 +0900 Subject: [PATCH 22/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EB=B0=A9=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=EC=97=90=EC=84=9C=20PROCESS=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/matching/common/entity/enums/MatchingRoomStatus.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/entity/enums/MatchingRoomStatus.java b/src/main/java/com/gachtaxi/domain/matching/common/entity/enums/MatchingRoomStatus.java index 8da75f23..601abd7b 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/entity/enums/MatchingRoomStatus.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/entity/enums/MatchingRoomStatus.java @@ -1,5 +1,5 @@ package com.gachtaxi.domain.matching.common.entity.enums; public enum MatchingRoomStatus { - PROCESS, COMPLETE, CANCELLED, ACTIVE + COMPLETE, CANCELLED, ACTIVE } \ No newline at end of file From 005163edfb80504156c6df3c27a5f62eb1da799a Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 19:02:09 +0900 Subject: [PATCH 23/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EB=B0=A9=20?= =?UTF-8?q?=EC=97=94=ED=8B=B0=ED=8B=B0=EC=97=90=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gachtaxi/domain/matching/common/entity/MatchingRoom.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoom.java b/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoom.java index a61bd8c5..60baa356 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoom.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoom.java @@ -70,4 +70,8 @@ public void changeRoomMaster(Members members) { public void cancelMatchingRoom() { this.matchingRoomStatus = MatchingRoomStatus.CANCELLED; } + + public void completeMatchingRoom() { + this.matchingRoomStatus = MatchingRoomStatus.COMPLETE; + } } From 4ef71d27bf1bb9a19c680358efef6c906c713cf4 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 19:02:28 +0900 Subject: [PATCH 24/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EB=B0=A9=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EB=B0=9C?= =?UTF-8?q?=ED=96=89=20producer=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/kafka/AutoMatchingProducer.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java b/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java index a004b253..11fba310 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java @@ -3,6 +3,7 @@ import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberCancelledEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberJoinedEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCancelledEvent; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCompletedEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; import java.util.concurrent.CompletableFuture; import lombok.RequiredArgsConstructor; @@ -21,6 +22,7 @@ public class AutoMatchingProducer { private final KafkaTemplate matchMemberJoinedEventKafkaTemplate; private final KafkaTemplate matchMemberCanceledEventKafkaTemplate; private final KafkaTemplate matchRoomCancelledEventKafkaTemplate; + private final KafkaTemplate matchRoomCompletedEventKafkaTemplate; @Value("${gachtaxi.kafka.topics.match-room-created}") private String matchRoomCreatedTopic; @@ -34,6 +36,9 @@ public class AutoMatchingProducer { @Value("${gachtaxi.kafka.topics.match-room-cancelled}") private String matchRoomCancelledTopic; + @Value("${gachtaxi.kafka.topics.match-room-completed}") + private String matchRoomCompletedTopic; + /** * 방 생성 이벤트를 발행 */ @@ -125,4 +130,27 @@ public void sendMatchRoomCancelledEvent(MatchRoomCancelledEvent matchRoomCancell return null; }); } + + /** + * 매칭 성공 이벤트를 발행 + */ + public void sendMatchRoomCompletedEvent(MatchRoomCompletedEvent matchRoomCompletedEvent) { + String key = String.valueOf(matchRoomCompletedEvent.roomId()); + + CompletableFuture future = this.matchRoomCompletedEventKafkaTemplate.send( + matchRoomCancelledTopic, key, matchRoomCompletedEvent); + + future.thenAccept(result -> { + if (result instanceof RecordMetadata metadata) { + log.info("[KAFKA PRODUCER] Success sending MatchRoomCompleted: " + + "topic={}, partition={}, offset={}, key={}", + metadata.topic(), metadata.partition(), metadata.offset(), key + ); + } + } + ).exceptionally(ex -> { + log.error("[KAFKA PRODUCER] Failed to send MatchRoomCompleted key={}", key, ex); + return null; + }); + } } \ No newline at end of file From c98f16112f32e313f0bd087c73b3d33fa31f8bcd Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 19:02:39 +0900 Subject: [PATCH 25/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EB=B0=A9=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=20=EB=B9=84=EC=A6=88=EB=8B=88=EC=8A=A4=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/service/MatchingRoomService.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java b/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java index 69b084fb..1eb09157 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java @@ -18,6 +18,7 @@ import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberCancelledEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberJoinedEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCancelledEvent; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCompletedEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; import com.gachtaxi.domain.matching.event.service.kafka.AutoMatchingProducer; import com.gachtaxi.domain.members.entity.Members; @@ -129,6 +130,12 @@ public void joinMemberToMatchingRoom(MatchMemberJoinedEvent matchMemberJoinedEve ); this.updateExistMembersCharge(existMembers, distributedCharge); + + if (existMembers.size() == matchingRoom.getCapacity() - 1) { + this.autoMatchingProducer.sendMatchRoomCompletedEvent( + MatchRoomCompletedEvent.builder().roomId(matchingRoom.getId()).build() + ); + } } private void updateExistMembersCharge(List existMembers, int charge) { @@ -181,4 +188,13 @@ public void cancelMatchingRoom(MatchRoomCancelledEvent matchRoomCancelledEvent) matchingRoom.cancelMatchingRoom(); this.matchingRoomRepository.save(matchingRoom); } + + public void completeMatchingRoom(MatchRoomCompletedEvent matchRoomCompletedEvent) { + MatchingRoom matchingRoom = this.matchingRoomRepository.findById( + matchRoomCompletedEvent.roomId() + ).orElseThrow(NoSuchMatchingRoomException::new); + + matchingRoom.completeMatchingRoom(); + this.matchingRoomRepository.save(matchingRoom); + } } From 3de9118b7e556afdef5f9ee835baced06b1ac6d8 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 19:02:52 +0900 Subject: [PATCH 26/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EB=B0=A9=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EA=B5=AC?= =?UTF-8?q?=EB=8F=85=20consumer=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/kafka/AutoMatchingConsumer.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingConsumer.java b/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingConsumer.java index 3432bba3..8e7e4366 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingConsumer.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingConsumer.java @@ -4,6 +4,7 @@ import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberCancelledEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberJoinedEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCancelledEvent; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCompletedEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; import com.gachtaxi.domain.matching.event.service.sse.SseService; import lombok.RequiredArgsConstructor; @@ -107,4 +108,26 @@ public void onMatchRoomCancelled(MatchRoomCancelledEvent event, Acknowledgment a this.sseService.sendToClient(event.roomId(), "MATCH_ROOM_CANCELLED", e.getMessage()); } } + + /** + * 방 완료 이벤트 구독 + */ + @KafkaListener( + topics = "${gachtaxi.kafka.topics.match-room-completed}", + containerFactory = "matchRoomCompletedEventListenerFactory" + ) + public void onMatchingRoomCompleted(MatchRoomCompletedEvent event, Acknowledgment ack) { + try { + log.info("[KAFKA CONSUMER] Received MatchingRoomCompletedEvent: {}", event); + + this.matchingRoomService.completeMatchingRoom(event); + + this.sseService.broadcast("MATCH_ROOM_COMPLETED", event); + + ack.acknowledge(); + } catch (Exception e) { + log.error("[KAFKA CONSUMER] Error processing MatchingRoomCompletedEvent", e); + this.sseService.sendToClient(event.roomId(), "MATCH_ROOM_COMPLETED", e.getMessage()); + } + } } \ No newline at end of file From d6b4817dfc0309d8505780dafd1ee8ca52425f16 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 19:33:44 +0900 Subject: [PATCH 27/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=ED=86=A0=ED=94=BD=20DTO=EC=97=90=20=EC=A0=95?= =?UTF-8?q?=EC=A0=81=20=ED=8E=99=ED=84=B0=EB=A6=AC=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MatchMemberCancelledEvent.java | 9 ++++++- .../kafka_topic/MatchMemberJoinedEvent.java | 3 ++- .../kafka_topic/MatchRoomCancelledEvent.java | 6 ++++- .../kafka_topic/MatchRoomCompletedEvent.java | 6 ++++- .../kafka_topic/MatchRoomCreatedEvent.java | 27 +++++++++++++++++-- 5 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberCancelledEvent.java b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberCancelledEvent.java index fd93e073..bded5d51 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberCancelledEvent.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberCancelledEvent.java @@ -2,9 +2,10 @@ import com.fasterxml.jackson.annotation.JsonFormat; import java.time.LocalDateTime; +import lombok.AccessLevel; import lombok.Builder; -@Builder +@Builder(access = AccessLevel.PRIVATE) public record MatchMemberCancelledEvent( Long roomId, Long memberId, @@ -13,4 +14,10 @@ public record MatchMemberCancelledEvent( LocalDateTime canceledAt ) { + public static MatchMemberCancelledEvent of(Long roomId, Long memberId) { + return MatchMemberCancelledEvent.builder(). + roomId(roomId) + .memberId(memberId) + .build(); + } } diff --git a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberJoinedEvent.java b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberJoinedEvent.java index a1a313b8..989ae7da 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberJoinedEvent.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberJoinedEvent.java @@ -2,9 +2,10 @@ import com.fasterxml.jackson.annotation.JsonFormat; import java.time.LocalDateTime; +import lombok.AccessLevel; import lombok.Builder; -@Builder +@Builder(access = AccessLevel.PRIVATE) public record MatchMemberJoinedEvent( Long roomId, Long memberId, diff --git a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCancelledEvent.java b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCancelledEvent.java index f7ab0cb5..f0bbbe2c 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCancelledEvent.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCancelledEvent.java @@ -1,10 +1,14 @@ package com.gachtaxi.domain.matching.event.dto.kafka_topic; +import lombok.AccessLevel; import lombok.Builder; -@Builder +@Builder(access = AccessLevel.PRIVATE) public record MatchRoomCancelledEvent( Long roomId ) { + public static MatchRoomCancelledEvent of(Long roomId) { + return MatchRoomCancelledEvent.builder().roomId(roomId).build(); + } } diff --git a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCompletedEvent.java b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCompletedEvent.java index 50ead675..4022476b 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCompletedEvent.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCompletedEvent.java @@ -1,10 +1,14 @@ package com.gachtaxi.domain.matching.event.dto.kafka_topic; +import lombok.AccessLevel; import lombok.Builder; -@Builder +@Builder(access = AccessLevel.PRIVATE) public record MatchRoomCompletedEvent( Long roomId ) { + public static MatchRoomCompletedEvent of(Long roomId) { + return MatchRoomCompletedEvent.builder().roomId(roomId).build(); + } } diff --git a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCreatedEvent.java b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCreatedEvent.java index e1ca21c8..62b0e195 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCreatedEvent.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCreatedEvent.java @@ -1,14 +1,18 @@ package com.gachtaxi.domain.matching.event.dto.kafka_topic; import com.fasterxml.jackson.annotation.JsonFormat; +import com.gachtaxi.domain.matching.common.dto.request.AutoMatchingPostRequest; import com.gachtaxi.domain.matching.common.entity.enums.Tags; import java.time.LocalDateTime; import java.util.List; +import java.util.UUID; +import lombok.AccessLevel; import lombok.Builder; +import org.springframework.beans.factory.annotation.Value; -@Builder +@Builder(access = AccessLevel.PRIVATE) public record MatchRoomCreatedEvent( - Long hostMemberId, + Long roomMasterId, Integer maxCapacity, String title, String description, @@ -23,4 +27,23 @@ public record MatchRoomCreatedEvent( LocalDateTime createdAt ) { + public static MatchRoomCreatedEvent of( + Long roomMasterId, + AutoMatchingPostRequest autoMatchingPostRequest, + int maxCapacity, + String description + ) { + return MatchRoomCreatedEvent.builder() + .roomMasterId(roomMasterId) + .startPoint(autoMatchingPostRequest.startPoint()) + .startName(autoMatchingPostRequest.startName()) + .destinationPoint(autoMatchingPostRequest.destinationPoint()) + .destinationName(autoMatchingPostRequest.destinationName()) + .maxCapacity(maxCapacity) + .title(UUID.randomUUID().toString()) + .description(description) + .expectedTotalCharge(autoMatchingPostRequest.expectedTotalCharge()) + .criteria(autoMatchingPostRequest.getCriteria()) + .build(); + } } From 440d91aa22f5e0a482efe31ec3703a2591eb9c3e Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 19:34:42 +0900 Subject: [PATCH 28/64] =?UTF-8?q?refactor:=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EC=9D=B4=EB=B2=A4=ED=8A=B8=20DTO=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EC=A0=95=EC=A0=81=20=ED=8E=99=ED=84=B0=EB=A6=AC=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=EB=A1=9C=20=EC=83=9D=EC=84=B1=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/service/AutoMatchingService.java | 38 +++++-------------- .../common/service/MatchingRoomService.java | 4 +- src/main/resources/application-local.yml | 3 ++ 3 files changed, 14 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/service/AutoMatchingService.java b/src/main/java/com/gachtaxi/domain/matching/common/service/AutoMatchingService.java index 2c6e9575..92b4cb9f 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/service/AutoMatchingService.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/service/AutoMatchingService.java @@ -18,6 +18,7 @@ import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; @@ -26,8 +27,11 @@ @RequiredArgsConstructor public class AutoMatchingService { - private static final int AUTO_MAX_CAPACITY = 4; - private static final String AUTO_DESCRIPTION = "AUTO_MATCHING"; + @Value("${gachtaxi.matching.auto-matching-max-capacity}") + private int autoMaxCapacity; + + @Value("${gachtaxi.matching.auto-matcnig-description}") + private String autoDescription; private final SseService sseService; private final AutoMatchingProducer autoMatchingProducer; @@ -61,43 +65,19 @@ public AutoMatchingPostResponse handlerAutoRequestMatching( private void sendMatchRoomCreatedEvent(Long memberId, AutoMatchingPostRequest autoMatchingPostRequest) { - MatchRoomCreatedEvent createdEvent = MatchRoomCreatedEvent.builder() - .hostMemberId(memberId) - .startPoint(autoMatchingPostRequest.startPoint()) - .startName(autoMatchingPostRequest.startName()) - .destinationPoint(autoMatchingPostRequest.destinationPoint()) - .destinationName(autoMatchingPostRequest.destinationName()) - .maxCapacity(AUTO_MAX_CAPACITY) - .title(UUID.randomUUID().toString()) - .description(AUTO_DESCRIPTION) - .expectedTotalCharge(autoMatchingPostRequest.expectedTotalCharge()) - .criteria(autoMatchingPostRequest.getCriteria()) - .build(); - - this.autoMatchingProducer.sendMatchRoomCreatedEvent(createdEvent); + this.autoMatchingProducer.sendMatchRoomCreatedEvent(MatchRoomCreatedEvent.of(memberId, autoMatchingPostRequest, autoMaxCapacity, autoDescription)); } private void sendMatchMemberJoinedEvent(Long memberId, FindRoomResult roomResult) { Long roomId = roomResult.roomId(); - MatchMemberJoinedEvent joinedEvent = MatchMemberJoinedEvent.builder() - .roomId(roomId) - .memberId(memberId) - .joinedAt(LocalDateTime.now()) - .build(); - - this.autoMatchingProducer.sendMatchMemberJoinedEvent(joinedEvent); + this.autoMatchingProducer.sendMatchMemberJoinedEvent(MatchMemberJoinedEvent.of(roomId, memberId)); } public AutoMatchingPostResponse handlerAutoCancelMatching(Long memberId, AutoMatchingCancelledRequest autoMatchingCancelledRequest) { - MatchMemberCancelledEvent matchMemberCancelledEvent = MatchMemberCancelledEvent.builder() - .roomId(autoMatchingCancelledRequest.roomId()) - .memberId(memberId) - .build(); - - this.autoMatchingProducer.sendMatchMemberLeftEvent(matchMemberCancelledEvent); + this.autoMatchingProducer.sendMatchMemberLeftEvent(MatchMemberCancelledEvent.of(autoMatchingCancelledRequest.roomId(), memberId)); return AutoMatchingPostResponse.of(AutoMatchingStatus.CANCELLED); } diff --git a/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java b/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java index 1eb09157..4045b638 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java @@ -133,7 +133,7 @@ public void joinMemberToMatchingRoom(MatchMemberJoinedEvent matchMemberJoinedEve if (existMembers.size() == matchingRoom.getCapacity() - 1) { this.autoMatchingProducer.sendMatchRoomCompletedEvent( - MatchRoomCompletedEvent.builder().roomId(matchingRoom.getId()).build() + MatchRoomCompletedEvent.of(matchingRoom.getId()) ); } } @@ -164,7 +164,7 @@ public void leaveMemberFromMatchingRoom(MatchMemberCancelledEvent matchMemberCan .ifPresentOrElse( nextRoomMaster -> matchingRoom.changeRoomMaster(nextRoomMaster), () -> this.autoMatchingProducer.sendMatchRoomCancelledEvent( - MatchRoomCancelledEvent.builder().roomId(matchingRoom.getId()).build() + MatchRoomCancelledEvent.of(matchingRoom.getId()) ) ); } diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 871b6138..e1b7d7e7 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -65,4 +65,7 @@ gachtaxi: match-room-completed: ${KAFKA_TOPIC_MATCH_ROOM_COMPLETED} partition-count: ${KAFKA_PARTITION_COUNT} replication-factor: ${KAFKA_REPLICATION_FACTOR} + matching: + auto-matching-max-capacity: ${AUTO_MATCHING_MAX_CAPACITY} + auto-matcnig-description: ${AUTO_MATCHING_DESCRIPTION} From 5acae17333aa9464d17ec8ad950d11e245817e12 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 19:35:19 +0900 Subject: [PATCH 29/64] =?UTF-8?q?refacrtor:=20=EC=97=94=ED=8B=B0=ED=8B=B0?= =?UTF-8?q?=EC=99=80=EC=9D=98=20=ED=86=B5=EC=9D=BC=EC=84=B1=EC=9D=84=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4=20hostId=20->=20roomMasterId=20=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/matching/common/service/MatchingRoomService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java b/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java index 4045b638..131e3d44 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java @@ -47,7 +47,7 @@ public class MatchingRoomService { private final MemberMatchingRoomChargingInfoRepository memberMatchingRoomChargingInfoRepository; public MatchingRoom save(MatchRoomCreatedEvent matchRoomCreatedEvent) { - Members members = this.memberService.findById(matchRoomCreatedEvent.hostMemberId()); + Members members = this.memberService.findById(matchRoomCreatedEvent.roomMasterId()); Route route = this.saveRoute(matchRoomCreatedEvent); From 6df1e8cca6d91700eb8a386f84a10af11c190e75 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 19:45:20 +0900 Subject: [PATCH 30/64] =?UTF-8?q?refactor:=20=EC=97=94=ED=8B=B0=ED=8B=B0?= =?UTF-8?q?=EB=93=A4=EC=97=90=20=EC=A0=95=EC=A0=81=20=ED=8E=99=ED=84=B0?= =?UTF-8?q?=EB=A6=AC=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../matching/common/entity/MatchingRoom.java | 15 ++++++++++++++- .../common/entity/MatchingRoomTagInfo.java | 9 ++++++++- .../entity/MemberMatchingRoomChargingInfo.java | 11 ++++++++++- .../domain/matching/common/entity/Route.java | 12 +++++++++++- 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoom.java b/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoom.java index 60baa356..b804eaef 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoom.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoom.java @@ -1,6 +1,7 @@ package com.gachtaxi.domain.matching.common.entity; import com.gachtaxi.domain.matching.common.entity.enums.MatchingRoomStatus; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; import com.gachtaxi.domain.members.entity.Members; import com.gachtaxi.global.common.entity.BaseEntity; import jakarta.persistence.CascadeType; @@ -22,7 +23,7 @@ @Entity @Table(name = "matching_room") -@Builder +@Builder(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor(access = AccessLevel.PRIVATE) public class MatchingRoom extends BaseEntity { @@ -74,4 +75,16 @@ public void cancelMatchingRoom() { public void completeMatchingRoom() { this.matchingRoomStatus = MatchingRoomStatus.COMPLETE; } + + public static MatchingRoom activeFrom(MatchRoomCreatedEvent matchRoomCreatedEvent, Members members, Route route) { + return MatchingRoom.builder() + .capacity(matchRoomCreatedEvent.maxCapacity()) + .roomMaster(members) + .title(matchRoomCreatedEvent.title()) + .description(matchRoomCreatedEvent.description()) + .route(route) + .totalCharge(matchRoomCreatedEvent.expectedTotalCharge()) + .matchingRoomStatus(MatchingRoomStatus.ACTIVE) + .build(); + } } diff --git a/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoomTagInfo.java b/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoomTagInfo.java index bd21d37e..944c1cd1 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoomTagInfo.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoomTagInfo.java @@ -16,7 +16,7 @@ @Table(name = "matching_room_tag_info") @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor(access = AccessLevel.PRIVATE) -@Builder +@Builder(access = AccessLevel.PRIVATE) public class MatchingRoomTagInfo extends BaseEntity { @ManyToOne @@ -24,4 +24,11 @@ public class MatchingRoomTagInfo extends BaseEntity { @Enumerated(EnumType.STRING) private Tags tags; + + public static MatchingRoomTagInfo of(MatchingRoom matchingRoom, Tags tag) { + return MatchingRoomTagInfo.builder() + .matchingRoom(matchingRoom) + .tags(tag) + .build(); + } } diff --git a/src/main/java/com/gachtaxi/domain/matching/common/entity/MemberMatchingRoomChargingInfo.java b/src/main/java/com/gachtaxi/domain/matching/common/entity/MemberMatchingRoomChargingInfo.java index 0f676f0f..8e353341 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/entity/MemberMatchingRoomChargingInfo.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/entity/MemberMatchingRoomChargingInfo.java @@ -27,7 +27,7 @@ ) @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor(access = AccessLevel.PRIVATE) -@Builder +@Builder(access = AccessLevel.PRIVATE) public class MemberMatchingRoomChargingInfo extends BaseEntity { @ManyToOne(fetch = FetchType.LAZY) @@ -47,4 +47,13 @@ public class MemberMatchingRoomChargingInfo extends BaseEntity { public void leftMatchingRoom() { this.paymentStatus = PaymentStatus.LEFT; } + + public static MemberMatchingRoomChargingInfo notPayedOf(MatchingRoom matchingRoom, Members members) { + return MemberMatchingRoomChargingInfo.builder() + .matchingRoom(matchingRoom) + .members(members) + .charge(matchingRoom.getTotalCharge()) + .paymentStatus(PaymentStatus.NOT_PAYED) + .build(); + } } diff --git a/src/main/java/com/gachtaxi/domain/matching/common/entity/Route.java b/src/main/java/com/gachtaxi/domain/matching/common/entity/Route.java index bb148948..412d724d 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/entity/Route.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/entity/Route.java @@ -1,5 +1,6 @@ package com.gachtaxi.domain.matching.common.entity; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; import com.gachtaxi.global.common.entity.BaseEntity; import jakarta.persistence.Entity; import jakarta.persistence.Table; @@ -10,7 +11,7 @@ @Entity @Table(name = "route") -@Builder +@Builder(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor(access = AccessLevel.PRIVATE) public class Route extends BaseEntity { @@ -20,4 +21,13 @@ public class Route extends BaseEntity { private String endLocationCoordinate; private String endLocationName; + + public static Route from(MatchRoomCreatedEvent matchRoomCreatedEvent) { + return Route.builder() + .startLocationCoordinate(matchRoomCreatedEvent.startPoint()) + .startLocationName(matchRoomCreatedEvent.startName()) + .endLocationCoordinate(matchRoomCreatedEvent.destinationPoint()) + .endLocationName(matchRoomCreatedEvent.destinationName()) + .build(); + } } From 6424e86e13477c3fbe8433176470c59b69015b48 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 19:45:33 +0900 Subject: [PATCH 31/64] =?UTF-8?q?refactor:=20=EC=97=94=ED=8B=B0=ED=8B=B0?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=EC=9D=84=20=EC=A0=95=EC=A0=81=20=ED=8E=99?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=A1=9C=20?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/service/MatchingRoomService.java | 58 +++++-------------- 1 file changed, 13 insertions(+), 45 deletions(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java b/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java index 131e3d44..aef17ef1 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java @@ -51,15 +51,7 @@ public MatchingRoom save(MatchRoomCreatedEvent matchRoomCreatedEvent) { Route route = this.saveRoute(matchRoomCreatedEvent); - MatchingRoom matchingRoom = MatchingRoom.builder() - .capacity(matchRoomCreatedEvent.maxCapacity()) - .roomMaster(members) - .title(matchRoomCreatedEvent.title()) - .description(matchRoomCreatedEvent.description()) - .route(route) - .totalCharge(matchRoomCreatedEvent.expectedTotalCharge()) - .matchingRoomStatus(MatchingRoomStatus.ACTIVE) - .build(); + MatchingRoom matchingRoom = MatchingRoom.activeFrom(matchRoomCreatedEvent, members, route); this.saveMatchingRoomTagInfo(matchingRoom, matchRoomCreatedEvent.criteria()); this.saveHostMemberChargingInfo(matchingRoom, members); @@ -68,36 +60,17 @@ public MatchingRoom save(MatchRoomCreatedEvent matchRoomCreatedEvent) { } private Route saveRoute(MatchRoomCreatedEvent matchRoomCreatedEvent) { - Route route = Route.builder() - .startLocationCoordinate(matchRoomCreatedEvent.startPoint()) - .startLocationName(matchRoomCreatedEvent.startName()) - .endLocationCoordinate(matchRoomCreatedEvent.destinationPoint()) - .endLocationName(matchRoomCreatedEvent.destinationName()) - .build(); - - return this.routeRepository.save(route); + return this.routeRepository.save(Route.from(matchRoomCreatedEvent)); } private void saveMatchingRoomTagInfo(MatchingRoom matchingRoom, List tags) { - for (Tags tag : tags) { - MatchingRoomTagInfo matchingRoomTagInfo = MatchingRoomTagInfo.builder() - .matchingRoom(matchingRoom) - .tags(tag) - .build(); - - this.matchingRoomTagInfoRepository.save(matchingRoomTagInfo); - } + tags.forEach(tag -> { + this.matchingRoomTagInfoRepository.save(MatchingRoomTagInfo.of(matchingRoom, tag)); + }); } private void saveHostMemberChargingInfo(MatchingRoom matchingRoom, Members members) { - MemberMatchingRoomChargingInfo matchingRoomChargingInfo = MemberMatchingRoomChargingInfo.builder() - .matchingRoom(matchingRoom) - .members(members) - .charge(matchingRoom.getTotalCharge()) - .paymentStatus(PaymentStatus.NOT_PAYED) - .build(); - - this.memberMatchingRoomChargingInfoRepository.save(matchingRoomChargingInfo); + this.memberMatchingRoomChargingInfoRepository.save(MemberMatchingRoomChargingInfo.notPayedOf(matchingRoom, members)); } public void joinMemberToMatchingRoom(MatchMemberJoinedEvent matchMemberJoinedEvent) { @@ -121,12 +94,7 @@ public void joinMemberToMatchingRoom(MatchMemberJoinedEvent matchMemberJoinedEve int distributedCharge = matchingRoom.getTotalCharge() / (existMembers.size() + 1); this.memberMatchingRoomChargingInfoRepository.save( - MemberMatchingRoomChargingInfo.builder() - .matchingRoom(matchingRoom) - .members(members) - .charge(distributedCharge) - .paymentStatus(PaymentStatus.NOT_PAYED) - .build() + MemberMatchingRoomChargingInfo.notPayedOf(matchingRoom, members) ); this.updateExistMembersCharge(existMembers, distributedCharge); @@ -181,18 +149,18 @@ private Optional findNextRoomMaster(MatchingRoom matchingRoom, Members } public void cancelMatchingRoom(MatchRoomCancelledEvent matchRoomCancelledEvent) { - MatchingRoom matchingRoom = this.matchingRoomRepository.findById( - matchRoomCancelledEvent.roomId()).orElseThrow( - NoSuchMatchingRoomException::new); + MatchingRoom matchingRoom = getMatchingRoomById(matchRoomCancelledEvent.roomId()); matchingRoom.cancelMatchingRoom(); this.matchingRoomRepository.save(matchingRoom); } + private MatchingRoom getMatchingRoomById(Long roomId) { + return this.matchingRoomRepository.findById(roomId).orElseThrow(NoSuchMatchingRoomException::new); + } + public void completeMatchingRoom(MatchRoomCompletedEvent matchRoomCompletedEvent) { - MatchingRoom matchingRoom = this.matchingRoomRepository.findById( - matchRoomCompletedEvent.roomId() - ).orElseThrow(NoSuchMatchingRoomException::new); + MatchingRoom matchingRoom = this.getMatchingRoomById(matchRoomCompletedEvent.roomId()); matchingRoom.completeMatchingRoom(); this.matchingRoomRepository.save(matchingRoom); From cd4c568e73fe45c693316ac9471077120ec3449b Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 19:46:31 +0900 Subject: [PATCH 32/64] =?UTF-8?q?refactor:=20consumer=EC=9D=98=20hostMembe?= =?UTF-8?q?rId=20->=20roomMasterId=20=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../matching/event/service/kafka/AutoMatchingConsumer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingConsumer.java b/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingConsumer.java index 8e7e4366..df87696b 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingConsumer.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingConsumer.java @@ -34,12 +34,12 @@ public void onMatchRoomCreated(MatchRoomCreatedEvent event, Acknowledgment ack) this.matchingRoomService.save(event); - this.sseService.sendToClient(event.hostMemberId(), "MATCH_ROOM_CREATED", event); + this.sseService.sendToClient(event.roomMasterId(), "MATCH_ROOM_CREATED", event); ack.acknowledge(); } catch (Exception e) { log.error("[KAFKA CONSUMER] Error processing MatchRoomCreatedEvent", e); - this.sseService.sendToClient(event.hostMemberId(), "MATCH_ROOM_CREATED", e.getMessage()); + this.sseService.sendToClient(event.roomMasterId(), "MATCH_ROOM_CREATED", e.getMessage()); } } From f3e97b42f8ea6080f5f012627616e15931cc27ab Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 19:46:51 +0900 Subject: [PATCH 33/64] =?UTF-8?q?fix:=20=EB=A7=A4=EC=B9=AD=20=EC=84=B1?= =?UTF-8?q?=EA=B3=B5=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=A7=A4=EC=B9=AD=20=EC=B7=A8=EC=86=8C=20=EC=9D=B4=EB=B2=A4?= =?UTF-8?q?=ED=8A=B8=EB=A5=BC=20=EB=B0=9C=ED=96=89=ED=95=98=EB=8D=98=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../matching/event/service/kafka/AutoMatchingProducer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java b/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java index 11fba310..f4a11be7 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java @@ -138,7 +138,7 @@ public void sendMatchRoomCompletedEvent(MatchRoomCompletedEvent matchRoomComplet String key = String.valueOf(matchRoomCompletedEvent.roomId()); CompletableFuture future = this.matchRoomCompletedEventKafkaTemplate.send( - matchRoomCancelledTopic, key, matchRoomCompletedEvent); + matchRoomCompletedTopic, key, matchRoomCompletedEvent); future.thenAccept(result -> { if (result instanceof RecordMetadata metadata) { From a2d7000c5e5b39862709eb70397d5550c27173a3 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 19:50:35 +0900 Subject: [PATCH 34/64] =?UTF-8?q?refactor:=20=EC=98=88=EC=99=B8=EB=93=A4?= =?UTF-8?q?=EC=97=90=20=EC=A0=95=EC=A0=81=20=EB=B3=80=EC=88=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/exception/MemberAlreadyJoinedException.java | 6 ++++-- .../common/exception/MemberNotInMatchingRoomException.java | 6 ++++-- .../common/exception/NoSuchMatchingRoomException.java | 6 ++++-- .../common/exception/NotActiveMatchingRoomException.java | 6 ++++-- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/exception/MemberAlreadyJoinedException.java b/src/main/java/com/gachtaxi/domain/matching/common/exception/MemberAlreadyJoinedException.java index 6e83315c..ad935d43 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/exception/MemberAlreadyJoinedException.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/exception/MemberAlreadyJoinedException.java @@ -1,11 +1,13 @@ package com.gachtaxi.domain.matching.common.exception; +import static com.gachtaxi.domain.matching.common.exception.ErrorMessage.MEMBER_ALREADY_JOINED_MATCHING_ROOM; +import static org.springframework.http.HttpStatus.CONFLICT; + import com.gachtaxi.global.common.exception.BaseException; -import org.springframework.http.HttpStatus; public class MemberAlreadyJoinedException extends BaseException { public MemberAlreadyJoinedException() { - super(HttpStatus.CONFLICT, ErrorMessage.MEMBER_ALREADY_JOINED_MATCHING_ROOM.getMessage()); + super(CONFLICT, MEMBER_ALREADY_JOINED_MATCHING_ROOM.getMessage()); } } diff --git a/src/main/java/com/gachtaxi/domain/matching/common/exception/MemberNotInMatchingRoomException.java b/src/main/java/com/gachtaxi/domain/matching/common/exception/MemberNotInMatchingRoomException.java index f8f52374..457aac99 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/exception/MemberNotInMatchingRoomException.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/exception/MemberNotInMatchingRoomException.java @@ -1,11 +1,13 @@ package com.gachtaxi.domain.matching.common.exception; +import static com.gachtaxi.domain.matching.common.exception.ErrorMessage.*; +import static org.springframework.http.HttpStatus.BAD_REQUEST; + import com.gachtaxi.global.common.exception.BaseException; -import org.springframework.http.HttpStatus; public class MemberNotInMatchingRoomException extends BaseException { public MemberNotInMatchingRoomException() { - super(HttpStatus.BAD_REQUEST, ErrorMessage.MEMBER_NOT_IN_MATCHING_ROOM.getMessage()); + super(BAD_REQUEST, MEMBER_NOT_IN_MATCHING_ROOM.getMessage()); } } diff --git a/src/main/java/com/gachtaxi/domain/matching/common/exception/NoSuchMatchingRoomException.java b/src/main/java/com/gachtaxi/domain/matching/common/exception/NoSuchMatchingRoomException.java index 997d6d41..931e7fb6 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/exception/NoSuchMatchingRoomException.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/exception/NoSuchMatchingRoomException.java @@ -1,11 +1,13 @@ package com.gachtaxi.domain.matching.common.exception; +import static com.gachtaxi.domain.matching.common.exception.ErrorMessage.NO_SUCH_MATCHING_ROOM; +import static org.springframework.http.HttpStatus.NOT_FOUND; + import com.gachtaxi.global.common.exception.BaseException; -import org.springframework.http.HttpStatus; public class NoSuchMatchingRoomException extends BaseException { public NoSuchMatchingRoomException() { - super(HttpStatus.NOT_FOUND, ErrorMessage.NO_SUCH_MATCHING_ROOM.getMessage()); + super(NOT_FOUND, NO_SUCH_MATCHING_ROOM.getMessage()); } } diff --git a/src/main/java/com/gachtaxi/domain/matching/common/exception/NotActiveMatchingRoomException.java b/src/main/java/com/gachtaxi/domain/matching/common/exception/NotActiveMatchingRoomException.java index 88ded883..46917062 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/exception/NotActiveMatchingRoomException.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/exception/NotActiveMatchingRoomException.java @@ -1,11 +1,13 @@ package com.gachtaxi.domain.matching.common.exception; +import static com.gachtaxi.domain.matching.common.exception.ErrorMessage.NOT_ACTIVE_MATCHING_ROOM; +import static org.springframework.http.HttpStatus.BAD_REQUEST; + import com.gachtaxi.global.common.exception.BaseException; -import org.springframework.http.HttpStatus; public class NotActiveMatchingRoomException extends BaseException { public NotActiveMatchingRoomException() { - super(HttpStatus.BAD_REQUEST, ErrorMessage.NOT_ACTIVE_MATCHING_ROOM.getMessage()); + super(BAD_REQUEST, lNOT_ACTIVE_MATCHING_ROOM.getMessage()); } } From 93ee46b63822a7a36d65a084d7a32b8a54cc4fcd Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 19:50:48 +0900 Subject: [PATCH 35/64] =?UTF-8?q?refactor:=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/exception/NotActiveMatchingRoomException.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/exception/NotActiveMatchingRoomException.java b/src/main/java/com/gachtaxi/domain/matching/common/exception/NotActiveMatchingRoomException.java index 46917062..58197e5a 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/exception/NotActiveMatchingRoomException.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/exception/NotActiveMatchingRoomException.java @@ -8,6 +8,6 @@ public class NotActiveMatchingRoomException extends BaseException { public NotActiveMatchingRoomException() { - super(BAD_REQUEST, lNOT_ACTIVE_MATCHING_ROOM.getMessage()); + super(BAD_REQUEST, NOT_ACTIVE_MATCHING_ROOM.getMessage()); } } From e9faac61b5db6b5d1d8f000c33d6908632f79c53 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 19:55:45 +0900 Subject: [PATCH 36/64] =?UTF-8?q?refactor:=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EB=B0=A9=20=EC=83=9D=EC=84=B1=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?createMatcingRoom=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EB=A6=AC=ED=84=B4=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20void=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../matching/common/service/MatchingRoomService.java | 7 +++---- .../matching/event/service/kafka/AutoMatchingConsumer.java | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java b/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java index aef17ef1..bf046c92 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java @@ -46,7 +46,7 @@ public class MatchingRoomService { private final RouteRepository routeRepository; private final MemberMatchingRoomChargingInfoRepository memberMatchingRoomChargingInfoRepository; - public MatchingRoom save(MatchRoomCreatedEvent matchRoomCreatedEvent) { + public void createMatchingRoom(MatchRoomCreatedEvent matchRoomCreatedEvent) { Members members = this.memberService.findById(matchRoomCreatedEvent.roomMasterId()); Route route = this.saveRoute(matchRoomCreatedEvent); @@ -56,7 +56,7 @@ public MatchingRoom save(MatchRoomCreatedEvent matchRoomCreatedEvent) { this.saveMatchingRoomTagInfo(matchingRoom, matchRoomCreatedEvent.criteria()); this.saveHostMemberChargingInfo(matchingRoom, members); - return this.matchingRoomRepository.save(matchingRoom); + this.matchingRoomRepository.save(matchingRoom); } private Route saveRoute(MatchRoomCreatedEvent matchRoomCreatedEvent) { @@ -90,8 +90,7 @@ public void joinMemberToMatchingRoom(MatchMemberJoinedEvent matchMemberJoinedEve List existMembers = this.memberMatchingRoomChargingInfoRepository.findByMatchingRoom( matchingRoom); - // TODO: 딱 떨어지지 않는 금액은 어떻게 해야할지? - int distributedCharge = matchingRoom.getTotalCharge() / (existMembers.size() + 1); + int distributedCharge = (int) Math.ceil((double) matchingRoom.getTotalCharge() / (existMembers.size() + 1)); this.memberMatchingRoomChargingInfoRepository.save( MemberMatchingRoomChargingInfo.notPayedOf(matchingRoom, members) diff --git a/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingConsumer.java b/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingConsumer.java index df87696b..62b71401 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingConsumer.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingConsumer.java @@ -32,7 +32,7 @@ public void onMatchRoomCreated(MatchRoomCreatedEvent event, Acknowledgment ack) try { log.info("[KAFKA CONSUMER] Received MatchRoomCreatedEvent: {}", event); - this.matchingRoomService.save(event); + this.matchingRoomService.createMatchingRoom(event); this.sseService.sendToClient(event.roomMasterId(), "MATCH_ROOM_CREATED", event); From 242b7e216f908d145060e027bc7b53f2bc69d69f Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 23:18:15 +0900 Subject: [PATCH 37/64] =?UTF-8?q?feat:=20MemberAlreadyLeftMatchingRoom=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../matching/common/exception/ErrorMessage.java | 3 ++- .../MemberAlreadyLeftMatchingRoomException.java | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/gachtaxi/domain/matching/common/exception/MemberAlreadyLeftMatchingRoomException.java diff --git a/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java b/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java index 89f8344b..0c2ae0e3 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java @@ -10,7 +10,8 @@ public enum ErrorMessage { NO_SUCH_MATCHING_ROOM("해당 매칭 방이 존재하지 않습니다."), NOT_ACTIVE_MATCHING_ROOM("열린 매칭 방이 아닙니다."), MEMBER_NOT_IN_MATCHING_ROOM("해당 매칭 방에 참가한 멤버가 아닙니다."), - MEMBER_ALREADY_JOINED_MATCHING_ROOM("해당 맴버는 이미 매칭 방에 참가한 멤버입니다"); + MEMBER_ALREADY_JOINED_MATCHING_ROOM("해당 맴버는 이미 매칭 방에 참가한 멤버입니다"), + MEMBER_ALREADY_LEFT_MATCHING_ROOM("해당 멤버는 이미 매칭 방에서 나간 멤버입니다."); private final String message; } diff --git a/src/main/java/com/gachtaxi/domain/matching/common/exception/MemberAlreadyLeftMatchingRoomException.java b/src/main/java/com/gachtaxi/domain/matching/common/exception/MemberAlreadyLeftMatchingRoomException.java new file mode 100644 index 00000000..344789ea --- /dev/null +++ b/src/main/java/com/gachtaxi/domain/matching/common/exception/MemberAlreadyLeftMatchingRoomException.java @@ -0,0 +1,13 @@ +package com.gachtaxi.domain.matching.common.exception; + +import static com.gachtaxi.domain.matching.common.exception.ErrorMessage.MEMBER_ALREADY_LEFT_MATCHING_ROOM; +import static org.springframework.http.HttpStatus.CONFLICT; + +import com.gachtaxi.global.common.exception.BaseException; + +public class MemberAlreadyLeftMatchingRoomException extends BaseException { + + public MemberAlreadyLeftMatchingRoomException() { + super(CONFLICT, MEMBER_ALREADY_LEFT_MATCHING_ROOM.getMessage()); + } +} From f9aeea4c702df81344ffa1f0e533da8967969d9b Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 23:18:36 +0900 Subject: [PATCH 38/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EB=B0=A9?= =?UTF-8?q?=EC=9D=B4=20=EB=8B=A4=20=EC=B0=BC=EB=8A=94=EC=A7=80=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=20=EC=B1=85=EC=9E=84=20MatchingRoom=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=EB=A1=9C=20=EC=9D=B4=EC=A0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/matching/common/entity/MatchingRoom.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoom.java b/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoom.java index b804eaef..efc74aa7 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoom.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/entity/MatchingRoom.java @@ -60,7 +60,7 @@ public class MatchingRoom extends BaseEntity { @Enumerated(EnumType.STRING) private MatchingRoomStatus matchingRoomStatus; - public boolean isActiveMatchingRoom() { + public boolean isActive() { return this.matchingRoomStatus == MatchingRoomStatus.ACTIVE; } @@ -76,7 +76,11 @@ public void completeMatchingRoom() { this.matchingRoomStatus = MatchingRoomStatus.COMPLETE; } - public static MatchingRoom activeFrom(MatchRoomCreatedEvent matchRoomCreatedEvent, Members members, Route route) { + public boolean isFull(int size) { + return size == totalCharge; + } + + public static MatchingRoom activeOf(MatchRoomCreatedEvent matchRoomCreatedEvent, Members members, Route route) { return MatchingRoom.builder() .capacity(matchRoomCreatedEvent.maxCapacity()) .roomMaster(members) From 56dc901ef53258d7495d4d97d0f6b82f6f602731 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 23:19:06 +0900 Subject: [PATCH 39/64] =?UTF-8?q?feat:=20=EB=A9=A4=EB=B2=84=EA=B0=80=20?= =?UTF-8?q?=EB=A7=A4=EC=B9=AD=20=EB=B0=A9=EC=97=90=20=EB=93=A4=EC=96=B4?= =?UTF-8?q?=EC=98=A8=20=EC=A0=81=20=EC=9E=88=EB=8A=94=EC=A7=80=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=20=EC=97=AC=EB=B6=80=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/entity/MemberMatchingRoomChargingInfo.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/entity/MemberMatchingRoomChargingInfo.java b/src/main/java/com/gachtaxi/domain/matching/common/entity/MemberMatchingRoomChargingInfo.java index 8e353341..ec1a7e59 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/entity/MemberMatchingRoomChargingInfo.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/entity/MemberMatchingRoomChargingInfo.java @@ -48,6 +48,15 @@ public void leftMatchingRoom() { this.paymentStatus = PaymentStatus.LEFT; } + public boolean isAlreadyLeft() { + return this.paymentStatus == PaymentStatus.LEFT; + } + + public MemberMatchingRoomChargingInfo joinMatchingRoom() { + this.paymentStatus = PaymentStatus.NOT_PAYED; + return this; + } + public static MemberMatchingRoomChargingInfo notPayedOf(MatchingRoom matchingRoom, Members members) { return MemberMatchingRoomChargingInfo.builder() .matchingRoom(matchingRoom) From 2b31cdb56516a5737a6f98a03123fe40b9140f10 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 23:19:41 +0900 Subject: [PATCH 40/64] =?UTF-8?q?refactor:=20=EB=A9=A4=EB=B2=84=EA=B0=80?= =?UTF-8?q?=20=EC=B0=B8=EC=97=AC=ED=95=9C=20=EB=A7=A4=EC=B9=AD=EB=B0=A9?= =?UTF-8?q?=EC=9D=84=20=EC=A1=B0=ED=9A=8C=ED=95=A0=EB=95=8C=20PaymentStatu?= =?UTF-8?q?s=EB=8F=84=20=ED=99=95=EC=9D=B8=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/MemberMatchingRoomChargingInfoRepository.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/repository/MemberMatchingRoomChargingInfoRepository.java b/src/main/java/com/gachtaxi/domain/matching/common/repository/MemberMatchingRoomChargingInfoRepository.java index 8f8746e1..982cf175 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/repository/MemberMatchingRoomChargingInfoRepository.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/repository/MemberMatchingRoomChargingInfoRepository.java @@ -2,6 +2,7 @@ import com.gachtaxi.domain.matching.common.entity.MatchingRoom; import com.gachtaxi.domain.matching.common.entity.MemberMatchingRoomChargingInfo; +import com.gachtaxi.domain.matching.common.entity.enums.PaymentStatus; import com.gachtaxi.domain.members.entity.Members; import java.util.List; import java.util.Optional; @@ -11,6 +12,6 @@ @Repository public interface MemberMatchingRoomChargingInfoRepository extends JpaRepository { - List findByMatchingRoom(MatchingRoom matchingRoom); + List findByMatchingRoomAAndPaymentStatus(MatchingRoom matchingRoom, PaymentStatus paymentStatus); Optional findByMembersAndMatchingRoom(Members members, MatchingRoom matchingRoom); } From 8e212b735d0141fa7f166192bd2cce6469ab5f53 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 23:19:59 +0900 Subject: [PATCH 41/64] =?UTF-8?q?refactor:=20MatchingRoomService=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=A0=95=EB=A6=AC=20=EB=B0=8F=20=EB=A6=AC?= =?UTF-8?q?=ED=8E=99=ED=84=B0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/service/MatchingRoomService.java | 81 +++++++++++-------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java b/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java index bf046c92..fc877e5c 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java @@ -4,10 +4,9 @@ import com.gachtaxi.domain.matching.common.entity.MatchingRoomTagInfo; import com.gachtaxi.domain.matching.common.entity.MemberMatchingRoomChargingInfo; import com.gachtaxi.domain.matching.common.entity.Route; -import com.gachtaxi.domain.matching.common.entity.enums.MatchingRoomStatus; import com.gachtaxi.domain.matching.common.entity.enums.PaymentStatus; import com.gachtaxi.domain.matching.common.entity.enums.Tags; -import com.gachtaxi.domain.matching.common.exception.MemberAlreadyJoinedException; +import com.gachtaxi.domain.matching.common.exception.MemberAlreadyLeftMatchingRoomException; import com.gachtaxi.domain.matching.common.exception.MemberNotInMatchingRoomException; import com.gachtaxi.domain.matching.common.exception.NoSuchMatchingRoomException; import com.gachtaxi.domain.matching.common.exception.NotActiveMatchingRoomException; @@ -51,10 +50,10 @@ public void createMatchingRoom(MatchRoomCreatedEvent matchRoomCreatedEvent) { Route route = this.saveRoute(matchRoomCreatedEvent); - MatchingRoom matchingRoom = MatchingRoom.activeFrom(matchRoomCreatedEvent, members, route); + MatchingRoom matchingRoom = MatchingRoom.activeOf(matchRoomCreatedEvent, members, route); this.saveMatchingRoomTagInfo(matchingRoom, matchRoomCreatedEvent.criteria()); - this.saveHostMemberChargingInfo(matchingRoom, members); + this.saveRoomMasterChargingInfo(matchingRoom, members); this.matchingRoomRepository.save(matchingRoom); } @@ -64,47 +63,51 @@ private Route saveRoute(MatchRoomCreatedEvent matchRoomCreatedEvent) { } private void saveMatchingRoomTagInfo(MatchingRoom matchingRoom, List tags) { - tags.forEach(tag -> { - this.matchingRoomTagInfoRepository.save(MatchingRoomTagInfo.of(matchingRoom, tag)); - }); + tags.forEach(tag -> this.matchingRoomTagInfoRepository.save(MatchingRoomTagInfo.of(matchingRoom, tag))); } - private void saveHostMemberChargingInfo(MatchingRoom matchingRoom, Members members) { + private void saveRoomMasterChargingInfo(MatchingRoom matchingRoom, Members members) { this.memberMatchingRoomChargingInfoRepository.save(MemberMatchingRoomChargingInfo.notPayedOf(matchingRoom, members)); } public void joinMemberToMatchingRoom(MatchMemberJoinedEvent matchMemberJoinedEvent) { Members members = this.memberService.findById(matchMemberJoinedEvent.memberId()); - MatchingRoom matchingRoom = this.matchingRoomRepository.findById( - matchMemberJoinedEvent.roomId()).orElseThrow( - NoSuchMatchingRoomException::new); + MatchingRoom matchingRoom = this.matchingRoomRepository.findById(matchMemberJoinedEvent.roomId()).orElseThrow(NoSuchMatchingRoomException::new); - if (this.memberMatchingRoomChargingInfoRepository.findByMembersAndMatchingRoom(members, matchingRoom).isPresent()) { - throw new MemberAlreadyJoinedException(); + if (!matchingRoom.isActive()) { + throw new NotActiveMatchingRoomException(); } - if (!matchingRoom.isActiveMatchingRoom()) { - throw new NotActiveMatchingRoomException(); + MemberMatchingRoomChargingInfo requestedMembersInfo = null; + + Optional joinedInPast = this.alreadyJoinedInPast(members, matchingRoom); + + if (joinedInPast.isPresent()) { + requestedMembersInfo = joinedInPast.get().joinMatchingRoom(); + } else { + requestedMembersInfo = MemberMatchingRoomChargingInfo.notPayedOf(matchingRoom, members); } + this.memberMatchingRoomChargingInfoRepository.save(requestedMembersInfo); - List existMembers = this.memberMatchingRoomChargingInfoRepository.findByMatchingRoom( - matchingRoom); + List existMembers = this.memberMatchingRoomChargingInfoRepository.findByMatchingRoomAAndPaymentStatus(matchingRoom, PaymentStatus.NOT_PAYED); int distributedCharge = (int) Math.ceil((double) matchingRoom.getTotalCharge() / (existMembers.size() + 1)); - this.memberMatchingRoomChargingInfoRepository.save( - MemberMatchingRoomChargingInfo.notPayedOf(matchingRoom, members) - ); - this.updateExistMembersCharge(existMembers, distributedCharge); - if (existMembers.size() == matchingRoom.getCapacity() - 1) { + int nowMemberCount = existMembers.size() + 1; + + if (matchingRoom.isFull(nowMemberCount)) { this.autoMatchingProducer.sendMatchRoomCompletedEvent( MatchRoomCompletedEvent.of(matchingRoom.getId()) ); } } + private Optional alreadyJoinedInPast(Members members, MatchingRoom matchingRoom) { + return this.memberMatchingRoomChargingInfoRepository.findByMembersAndMatchingRoom(members, matchingRoom); + } + private void updateExistMembersCharge(List existMembers, int charge) { for (MemberMatchingRoomChargingInfo memberMatchingRoomChargingInfo : existMembers) { memberMatchingRoomChargingInfo.setCharge(charge); @@ -114,14 +117,16 @@ private void updateExistMembersCharge(List exist public void leaveMemberFromMatchingRoom(MatchMemberCancelledEvent matchMemberCancelledEvent) { Members members = this.memberService.findById(matchMemberCancelledEvent.memberId()); - MatchingRoom matchingRoom = this.matchingRoomRepository.findById( - matchMemberCancelledEvent.roomId()).orElseThrow( - NoSuchMatchingRoomException::new); + MatchingRoom matchingRoom = this.matchingRoomRepository.findById(matchMemberCancelledEvent.roomId()).orElseThrow(NoSuchMatchingRoomException::new); - MemberMatchingRoomChargingInfo memberMatchingRoomChargingInfo = this.memberMatchingRoomChargingInfoRepository.findByMembersAndMatchingRoom( - members, matchingRoom) + MemberMatchingRoomChargingInfo memberMatchingRoomChargingInfo = + this.memberMatchingRoomChargingInfoRepository.findByMembersAndMatchingRoom(members, matchingRoom) .orElseThrow(MemberNotInMatchingRoomException::new); + if (memberMatchingRoomChargingInfo.isAlreadyLeft()) { + throw new MemberAlreadyLeftMatchingRoomException(); + } + memberMatchingRoomChargingInfo.leftMatchingRoom(); this.memberMatchingRoomChargingInfoRepository.save(memberMatchingRoomChargingInfo); @@ -138,8 +143,8 @@ public void leaveMemberFromMatchingRoom(MatchMemberCancelledEvent matchMemberCan } private Optional findNextRoomMaster(MatchingRoom matchingRoom, Members members) { - List existMembers = this.memberMatchingRoomChargingInfoRepository.findByMatchingRoom( - matchingRoom); + List existMembers = + this.memberMatchingRoomChargingInfoRepository.findByMatchingRoomAAndPaymentStatus(matchingRoom, PaymentStatus.NOT_PAYED); return existMembers.stream() .map(MemberMatchingRoomChargingInfo::getMembers) @@ -148,20 +153,28 @@ private Optional findNextRoomMaster(MatchingRoom matchingRoom, Members } public void cancelMatchingRoom(MatchRoomCancelledEvent matchRoomCancelledEvent) { - MatchingRoom matchingRoom = getMatchingRoomById(matchRoomCancelledEvent.roomId()); + MatchingRoom matchingRoom = this.getMatchingRoomById(matchRoomCancelledEvent.roomId()); + + if (!matchingRoom.isActive()) { + throw new NotActiveMatchingRoomException(); + } matchingRoom.cancelMatchingRoom(); this.matchingRoomRepository.save(matchingRoom); } - private MatchingRoom getMatchingRoomById(Long roomId) { - return this.matchingRoomRepository.findById(roomId).orElseThrow(NoSuchMatchingRoomException::new); - } - public void completeMatchingRoom(MatchRoomCompletedEvent matchRoomCompletedEvent) { MatchingRoom matchingRoom = this.getMatchingRoomById(matchRoomCompletedEvent.roomId()); + if (!matchingRoom.isActive()) { + throw new NotActiveMatchingRoomException(); + } + matchingRoom.completeMatchingRoom(); this.matchingRoomRepository.save(matchingRoom); } + + private MatchingRoom getMatchingRoomById(Long roomId) { + return this.matchingRoomRepository.findById(roomId).orElseThrow(NoSuchMatchingRoomException::new); + } } From 25b6d01cbe34184b1393d43cd291ff4541e24439 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 23:36:28 +0900 Subject: [PATCH 42/64] =?UTF-8?q?feat:=20=EC=BB=A8=ED=8A=B8=EB=A1=A4?= =?UTF-8?q?=EB=9F=AC=EA=B0=80=20current=20member=20id=EB=A5=BC=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=EB=A1=9C=ED=95=98=EC=A7=80=EB=A7=8C=20=ED=8C=8C?= =?UTF-8?q?=EB=9D=BC=EB=AF=B8=ED=84=B0=EB=A1=9C=20=EB=B0=9B=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EC=95=98=EC=9D=84=20=EB=95=8C=20=EB=8D=98=EC=A7=88=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ControllerNotHasCurrentMemberIdException.java | 13 +++++++++++++ .../matching/common/exception/ErrorMessage.java | 3 ++- 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/gachtaxi/domain/matching/common/exception/ControllerNotHasCurrentMemberIdException.java diff --git a/src/main/java/com/gachtaxi/domain/matching/common/exception/ControllerNotHasCurrentMemberIdException.java b/src/main/java/com/gachtaxi/domain/matching/common/exception/ControllerNotHasCurrentMemberIdException.java new file mode 100644 index 00000000..3e24768f --- /dev/null +++ b/src/main/java/com/gachtaxi/domain/matching/common/exception/ControllerNotHasCurrentMemberIdException.java @@ -0,0 +1,13 @@ +package com.gachtaxi.domain.matching.common.exception; + +import static com.gachtaxi.domain.matching.common.exception.ErrorMessage.CONTROLLER_NOT_HAS_CURRENT_MEMBER_ID; +import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; + +import com.gachtaxi.global.common.exception.BaseException; + +public class ControllerNotHasCurrentMemberIdException extends BaseException { + + public ControllerNotHasCurrentMemberIdException() { + super(INTERNAL_SERVER_ERROR, CONTROLLER_NOT_HAS_CURRENT_MEMBER_ID.getMessage()); + } +} diff --git a/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java b/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java index 0c2ae0e3..018b51ae 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java @@ -11,7 +11,8 @@ public enum ErrorMessage { NOT_ACTIVE_MATCHING_ROOM("열린 매칭 방이 아닙니다."), MEMBER_NOT_IN_MATCHING_ROOM("해당 매칭 방에 참가한 멤버가 아닙니다."), MEMBER_ALREADY_JOINED_MATCHING_ROOM("해당 맴버는 이미 매칭 방에 참가한 멤버입니다"), - MEMBER_ALREADY_LEFT_MATCHING_ROOM("해당 멤버는 이미 매칭 방에서 나간 멤버입니다."); + MEMBER_ALREADY_LEFT_MATCHING_ROOM("해당 멤버는 이미 매칭 방에서 나간 멤버입니다."), + CONTROLLER_NOT_HAS_CURRENT_MEMBER_ID("해당 컨트롤러는 인가된 멤버 ID가 필요합니다."); private final String message; } From c79b747ead9523fa5c85487d764ac8cb97b9c63a Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 23:36:45 +0900 Subject: [PATCH 43/64] =?UTF-8?q?feat:=20SSE=20=EA=B5=AC=EB=8F=85=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?AOP=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../matching/aop/SseSubscribeRequired.java | 12 +++++ .../matching/aop/SseSubscribeRequiredAop.java | 45 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 src/main/java/com/gachtaxi/domain/matching/aop/SseSubscribeRequired.java create mode 100644 src/main/java/com/gachtaxi/domain/matching/aop/SseSubscribeRequiredAop.java diff --git a/src/main/java/com/gachtaxi/domain/matching/aop/SseSubscribeRequired.java b/src/main/java/com/gachtaxi/domain/matching/aop/SseSubscribeRequired.java new file mode 100644 index 00000000..28970452 --- /dev/null +++ b/src/main/java/com/gachtaxi/domain/matching/aop/SseSubscribeRequired.java @@ -0,0 +1,12 @@ +package com.gachtaxi.domain.matching.aop; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface SseSubscribeRequired { + +} diff --git a/src/main/java/com/gachtaxi/domain/matching/aop/SseSubscribeRequiredAop.java b/src/main/java/com/gachtaxi/domain/matching/aop/SseSubscribeRequiredAop.java new file mode 100644 index 00000000..677a4f52 --- /dev/null +++ b/src/main/java/com/gachtaxi/domain/matching/aop/SseSubscribeRequiredAop.java @@ -0,0 +1,45 @@ +package com.gachtaxi.domain.matching.aop; + +import com.gachtaxi.domain.matching.common.controller.ResponseMessage; +import com.gachtaxi.domain.matching.common.exception.ControllerNotHasCurrentMemberIdException; +import com.gachtaxi.domain.matching.common.service.AutoMatchingService; +import com.gachtaxi.global.auth.jwt.annotation.CurrentMemberId; +import com.gachtaxi.global.common.response.ApiResponse; +import lombok.RequiredArgsConstructor; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; + +@Aspect +@Component +@RequiredArgsConstructor +public class SseSubscribeRequiredAop { + + private final AutoMatchingService autoMatchingService; + + @Around("@annotation(com.gachtaxi.domain.matching.aop.SseSubscribeRequired)") + public Object checkSseSubscribe(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{ + Long memberId = null; + for (Object arg : proceedingJoinPoint.getArgs()) { + Class argClass = arg.getClass(); + if (arg instanceof Long && argClass.isAnnotationPresent(CurrentMemberId.class)) { + memberId = (Long) arg; + break; + } + } + if (memberId == null) { + throw new ControllerNotHasCurrentMemberIdException(); + } + + if (!this.autoMatchingService.isSseSubscribed(memberId)) { + return ApiResponse.response( + HttpStatus.BAD_REQUEST, + ResponseMessage.NOT_SUBSCRIBED_SSE.getMessage() + ); + } + + return proceedingJoinPoint.proceed(); + } +} From 4c2ce2c6ad9dcf26b131deb876421044357c233c Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 23:37:03 +0900 Subject: [PATCH 44/64] =?UTF-8?q?refactor:=20SSE=20=EA=B5=AC=EB=8F=85=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8=20=EC=96=B4=EB=85=B8?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=BB=A8=ED=8A=B8=EB=A1=A4?= =?UTF-8?q?=EB=9F=AC=EC=97=90=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AutoMatchingController.java | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/controller/AutoMatchingController.java b/src/main/java/com/gachtaxi/domain/matching/common/controller/AutoMatchingController.java index 4d8931d0..95c2296e 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/controller/AutoMatchingController.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/controller/AutoMatchingController.java @@ -1,5 +1,6 @@ package com.gachtaxi.domain.matching.common.controller; +import com.gachtaxi.domain.matching.aop.SseSubscribeRequired; import com.gachtaxi.domain.matching.common.dto.request.AutoMatchingCancelledRequest; import com.gachtaxi.domain.matching.common.dto.request.AutoMatchingPostRequest; import com.gachtaxi.domain.matching.common.dto.response.AutoMatchingPostResponse; @@ -32,17 +33,11 @@ public SseEmitter subscribeSse(@CurrentMemberId Long memberId) { } @PostMapping("/request") + @SseSubscribeRequired public ApiResponse requestMatching( @CurrentMemberId Long memberId, @RequestBody AutoMatchingPostRequest autoMatchingPostRequest ) { - if (!this.autoMatchingService.isSseSubscribed(memberId)) { - return ApiResponse.response( - HttpStatus.BAD_REQUEST, - ResponseMessage.NOT_SUBSCRIBED_SSE.getMessage() - ); - } - return ApiResponse.response( HttpStatus.OK, ResponseMessage.AUTO_MATCHING_REQUEST_ACCEPTED.getMessage(), @@ -51,17 +46,11 @@ public ApiResponse requestMatching( } @PostMapping("/cancel") + @SseSubscribeRequired public ApiResponse cancelMatching( @CurrentMemberId Long memberId, @RequestBody AutoMatchingCancelledRequest autoMatchingCancelledRequest ) { - if (!this.autoMatchingService.isSseSubscribed(memberId)) { - return ApiResponse.response( - HttpStatus.BAD_REQUEST, - ResponseMessage.NOT_SUBSCRIBED_SSE.getMessage() - ); - } - return ApiResponse.response( HttpStatus.OK, ResponseMessage.AUTO_MATCHING_REQUEST_CANCELLED.getMessage(), From a1e1171c99d725ddb447e8f76c22c1e8e0907008 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 23:48:17 +0900 Subject: [PATCH 45/64] =?UTF-8?q?feat:=20=EC=9E=90=EB=8F=99=20=EB=A7=A4?= =?UTF-8?q?=EC=B9=AD=20=EC=B7=A8=EC=86=8C,=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EB=B0=A9=20=EB=A7=A4=EC=B9=AD=20=EC=99=84=EB=A3=8C=20Topic=20?= =?UTF-8?q?=EA=B0=9D=EC=B2=B4=20bean=20=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/config/kafka/KafkaTopicsConfig.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/com/gachtaxi/global/config/kafka/KafkaTopicsConfig.java b/src/main/java/com/gachtaxi/global/config/kafka/KafkaTopicsConfig.java index 80a1517f..1b73120f 100644 --- a/src/main/java/com/gachtaxi/global/config/kafka/KafkaTopicsConfig.java +++ b/src/main/java/com/gachtaxi/global/config/kafka/KafkaTopicsConfig.java @@ -20,6 +20,9 @@ public class KafkaTopicsConfig { @Value("${gachtaxi.kafka.topics.match-room-completed}") private String matchRoomCompletedTopic; + @Value("${gachtaxi.kafka.topics.match-member-cancelled}") + private String matchMemberCancelledTopic; + @Value("${gachtaxi.kafka.partition-count}") private short partitionCount; @@ -40,4 +43,14 @@ public NewTopic matchMemberJoinedTopic() { public NewTopic matchRoomCancelledTopic() { return new NewTopic(matchRoomCancelledTopic, partitionCount, replicationFactor); } + + @Bean + public NewTopic matchMemberCancelledTopic() { + return new NewTopic(matchMemberCancelledTopic, partitionCount, replicationFactor); + } + + @Bean + public NewTopic matchRoomCompletedTopic() { + return new NewTopic(matchRoomCompletedTopic, partitionCount, replicationFactor); + } } \ No newline at end of file From 8f3c4c8ee31f67962a8f83ff1017b4f4a7c13298 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 23:48:44 +0900 Subject: [PATCH 46/64] =?UTF-8?q?refactor:=20kafka=20template,=20kafka=20p?= =?UTF-8?q?roducer=20factory=20config=20=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/kafka/KafkaProducerConfig.java | 81 +++---------------- .../config/kafka/KafkaTemplateConfig.java | 56 +++++++++++++ 2 files changed, 65 insertions(+), 72 deletions(-) create mode 100644 src/main/java/com/gachtaxi/global/config/kafka/KafkaTemplateConfig.java diff --git a/src/main/java/com/gachtaxi/global/config/kafka/KafkaProducerConfig.java b/src/main/java/com/gachtaxi/global/config/kafka/KafkaProducerConfig.java index b2a6fcd7..1e50fbb7 100644 --- a/src/main/java/com/gachtaxi/global/config/kafka/KafkaProducerConfig.java +++ b/src/main/java/com/gachtaxi/global/config/kafka/KafkaProducerConfig.java @@ -27,66 +27,34 @@ public class KafkaProducerConfig { @Bean @Qualifier("matchRoomCreatedEventProducerFactory") public ProducerFactory matchRoomCreatedEventProducerFactory() { - Map configs = new HashMap<>(); - configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); - configs.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); - configs.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class); - - configs.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true); - configs.put(ProducerConfig.ACKS_CONFIG, "all"); - configs.put(ProducerConfig.RETRIES_CONFIG, 3); - - return new DefaultKafkaProducerFactory<>(configs); + return new DefaultKafkaProducerFactory<>(this.getProducerOptions()); } @Bean @Qualifier("matchMemberJoinedEventProducerFactory") public ProducerFactory matchMemberJoinedEventProducerFactory() { - Map configs = new HashMap<>(); - configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); - configs.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); - configs.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class); - - configs.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true); - configs.put(ProducerConfig.ACKS_CONFIG, "all"); - configs.put(ProducerConfig.RETRIES_CONFIG, 3); - - return new DefaultKafkaProducerFactory<>(configs); + return new DefaultKafkaProducerFactory<>(this.getProducerOptions()); } @Bean @Qualifier("matchMemberCanceledEventProducerFactory") public ProducerFactory matchMemberCanceledEventProducerFactory() { - Map configs = new HashMap<>(); - configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); - configs.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); - configs.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class); - - configs.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true); - configs.put(ProducerConfig.ACKS_CONFIG, "all"); - configs.put(ProducerConfig.RETRIES_CONFIG, 3); - - return new DefaultKafkaProducerFactory<>(configs); + return new DefaultKafkaProducerFactory<>(this.getProducerOptions()); } @Bean @Qualifier("matchRoomCancelledEventProducerFactory") public ProducerFactory matchRoomCanclledEventProducerFactory() { - Map configs = new HashMap<>(); - configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); - configs.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); - configs.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class); - - configs.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true); - configs.put(ProducerConfig.ACKS_CONFIG, "all"); - configs.put(ProducerConfig.RETRIES_CONFIG, 3); - - return new DefaultKafkaProducerFactory<>(configs); + return new DefaultKafkaProducerFactory<>(getProducerOptions()); } @Bean @Qualifier("matchRoomCompletedEventProducerFactory") public ProducerFactory matchRoomCompletedEventProducerFactory() { + return new DefaultKafkaProducerFactory<>(this.getProducerOptions()); + } + + private Map getProducerOptions() { Map configs = new HashMap<>(); configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); configs.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); @@ -96,37 +64,6 @@ public ProducerFactory matchRoomCompletedEventP configs.put(ProducerConfig.ACKS_CONFIG, "all"); configs.put(ProducerConfig.RETRIES_CONFIG, 3); - return new DefaultKafkaProducerFactory<>(configs); - } - - @Bean - @Qualifier("matchMemberJoinedEventKafkaTemplate") - public KafkaTemplate matchMemberJoinedEventKafkaTemplate() { - - return new KafkaTemplate<>(matchMemberJoinedEventProducerFactory()); - } - - @Bean - @Qualifier("matchRoomCreatedEventKafkaTemplate") - public KafkaTemplate matchRoomCreatedEventKafkaTemplate() { - return new KafkaTemplate<>(matchRoomCreatedEventProducerFactory()); - } - - @Bean - @Qualifier("matchMemberCanceledEventKafkaTemplate") - public KafkaTemplate matchMemberCancelledEventKafkaTemplate() { - return new KafkaTemplate<>(matchMemberCanceledEventProducerFactory()); - } - - @Bean - @Qualifier("matchRoomCancelledEventKafkaTemplate") - public KafkaTemplate matchRoomCancelledEventKafkaTemplate() { - return new KafkaTemplate<>(matchRoomCanclledEventProducerFactory()); - } - - @Bean - @Qualifier("matchRoomCompletedEventKafkaTemplate") - public KafkaTemplate matchRoomCompletedEventKafkaTemplate() { - return new KafkaTemplate<>(matchRoomCompletedEventProducerFactory()); + return configs; } } \ No newline at end of file diff --git a/src/main/java/com/gachtaxi/global/config/kafka/KafkaTemplateConfig.java b/src/main/java/com/gachtaxi/global/config/kafka/KafkaTemplateConfig.java new file mode 100644 index 00000000..2a774a99 --- /dev/null +++ b/src/main/java/com/gachtaxi/global/config/kafka/KafkaTemplateConfig.java @@ -0,0 +1,56 @@ +package com.gachtaxi.global.config.kafka; + +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberCancelledEvent; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberJoinedEvent; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCancelledEvent; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCompletedEvent; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.core.ProducerFactory; + +@Configuration +public class KafkaTemplateConfig { + + @Bean + @Qualifier("matchMemberJoinedEventKafkaTemplate") + public KafkaTemplate matchMemberJoinedEventKafkaTemplate( + ProducerFactory matchMemberJoinedEventProducerFactory + ) { + return new KafkaTemplate<>(matchMemberJoinedEventProducerFactory); + } + + @Bean + @Qualifier("matchRoomCreatedEventKafkaTemplate") + public KafkaTemplate matchRoomCreatedEventKafkaTemplate( + ProducerFactory matchRoomCreatedEventProducerFactory + ) { + return new KafkaTemplate<>(matchRoomCreatedEventProducerFactory); + } + + @Bean + @Qualifier("matchMemberCanceledEventKafkaTemplate") + public KafkaTemplate matchMemberCancelledEventKafkaTemplate( + ProducerFactory matchMemberCanceledEventProducerFactory + ) { + return new KafkaTemplate<>(matchMemberCanceledEventProducerFactory); + } + + @Bean + @Qualifier("matchRoomCancelledEventKafkaTemplate") + public KafkaTemplate matchRoomCancelledEventKafkaTemplate( + ProducerFactory matchRoomCancelledEventProducerFactory + ) { + return new KafkaTemplate<>(matchRoomCancelledEventProducerFactory); + } + + @Bean + @Qualifier("matchRoomCompletedEventKafkaTemplate") + public KafkaTemplate matchRoomCompletedEventKafkaTemplate( + ProducerFactory matchRoomCompletedEventProducerFactory + ) { + return new KafkaTemplate<>(matchRoomCompletedEventProducerFactory); + } +} From 3c36c2c42c5336b478069d647834de060ac63cf5 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 13 Jan 2025 23:48:51 +0900 Subject: [PATCH 47/64] =?UTF-8?q?refactor:=20=EA=B0=9C=ED=96=89=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event/dto/kafka_topic/MatchMemberCancelledEvent.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberCancelledEvent.java b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberCancelledEvent.java index bded5d51..b96020f0 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberCancelledEvent.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberCancelledEvent.java @@ -15,8 +15,8 @@ public record MatchMemberCancelledEvent( ) { public static MatchMemberCancelledEvent of(Long roomId, Long memberId) { - return MatchMemberCancelledEvent.builder(). - roomId(roomId) + return MatchMemberCancelledEvent.builder() + .roomId(roomId) .memberId(memberId) .build(); } From a3f8abbe41c39ec6de156f031103be260b28d6f5 Mon Sep 17 00:00:00 2001 From: senna Date: Tue, 14 Jan 2025 03:08:19 +0900 Subject: [PATCH 48/64] =?UTF-8?q?refactor:=20producer,=20kafka=20template,?= =?UTF-8?q?=20topic=20=EB=8F=99=EC=A0=81=EC=9C=BC=EB=A1=9C=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=B4=20=EA=B8=B0=EC=A1=B4=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/kafka/AutoMatchingProducer.java | 156 ------------------ ...g.java => DefaultKafkaProducerConfig.java} | 65 +++++--- .../config/kafka/KafkaTemplateConfig.java | 56 ------- .../config/kafka/KafkaTopicsConfig.java | 56 ------- 4 files changed, 39 insertions(+), 294 deletions(-) delete mode 100644 src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java rename src/main/java/com/gachtaxi/global/config/kafka/{KafkaProducerConfig.java => DefaultKafkaProducerConfig.java} (55%) delete mode 100644 src/main/java/com/gachtaxi/global/config/kafka/KafkaTemplateConfig.java delete mode 100644 src/main/java/com/gachtaxi/global/config/kafka/KafkaTopicsConfig.java diff --git a/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java b/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java deleted file mode 100644 index f4a11be7..00000000 --- a/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java +++ /dev/null @@ -1,156 +0,0 @@ -package com.gachtaxi.domain.matching.event.service.kafka; - -import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberCancelledEvent; -import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberJoinedEvent; -import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCancelledEvent; -import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCompletedEvent; -import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; -import java.util.concurrent.CompletableFuture; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.apache.kafka.clients.producer.RecordMetadata; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.stereotype.Service; - -@Slf4j -@Service -@RequiredArgsConstructor -public class AutoMatchingProducer { - - private final KafkaTemplate matchRoomCreatedEventKafkaTemplate; - private final KafkaTemplate matchMemberJoinedEventKafkaTemplate; - private final KafkaTemplate matchMemberCanceledEventKafkaTemplate; - private final KafkaTemplate matchRoomCancelledEventKafkaTemplate; - private final KafkaTemplate matchRoomCompletedEventKafkaTemplate; - - @Value("${gachtaxi.kafka.topics.match-room-created}") - private String matchRoomCreatedTopic; - - @Value("${gachtaxi.kafka.topics.match-member-joined}") - private String matchMemberJoinedTopic; - - @Value("${gachtaxi.kafka.topics.match-member-cancelled}") - private String matchMemberCanceledTopic; - - @Value("${gachtaxi.kafka.topics.match-room-cancelled}") - private String matchRoomCancelledTopic; - - @Value("${gachtaxi.kafka.topics.match-room-completed}") - private String matchRoomCompletedTopic; - - /** - * 방 생성 이벤트를 발행 - */ - public void sendMatchRoomCreatedEvent(MatchRoomCreatedEvent matchRoomCreatedEvent) { - String key = matchRoomCreatedEvent.title(); - - CompletableFuture future = this.matchRoomCreatedEventKafkaTemplate.send( - matchRoomCreatedTopic, key, matchRoomCreatedEvent); - - future.thenAccept(result -> { - if (result instanceof RecordMetadata metadata) { - log.info("[KAFKA PRODUCER] Success sending MatchRoomCreatedEvent: " - + "topic={}, partition={}, offset={}, key={}", - metadata.topic(), metadata.partition(), metadata.offset(), key - ); - } - } - ).exceptionally(ex -> { - log.error("[KAFKA PRODUCER] Failed to send MatchRoomCreatedEvent key={}", key, ex); - return null; - }); - } - - /** - * 방 멤버 참가 이벤트를 발행 - */ - public void sendMatchMemberJoinedEvent(MatchMemberJoinedEvent matchMemberJoinedEvent) { - String key = String.valueOf(matchMemberJoinedEvent.roomId()); - - CompletableFuture future = this.matchMemberJoinedEventKafkaTemplate.send( - matchMemberJoinedTopic, key, matchMemberJoinedEvent); - - future.thenAccept(result -> { - if (result instanceof RecordMetadata metadata) { - log.info("[KAFKA PRODUCER] Success sending MatchMemberJoinedEvent: " - + "topic={}, partition={}, offset={}, key={}", - metadata.topic(), metadata.partition(), metadata.offset(), key - ); - } - } - ).exceptionally(ex -> { - log.error("[KAFKA PRODUCER] Failed to send MatchMemberJoinedEvent key={}", key, ex); - return null; - }); - } - - /** - * 방 멤버 취소 이벤트를 발행 - */ - public void sendMatchMemberLeftEvent(MatchMemberCancelledEvent matchMemberCancelledEvent) { - String key = String.valueOf(matchMemberCancelledEvent.roomId()); - - CompletableFuture future = this.matchMemberCanceledEventKafkaTemplate.send( - matchMemberCanceledTopic, key, matchMemberCancelledEvent); - - future.thenAccept(result -> { - if (result instanceof RecordMetadata metadata) { - log.info("[KAFKA PRODUCER] Success sending MatchMemberLeftEvent: " - + "topic={}, partition={}, offset={}, key={}", - metadata.topic(), metadata.partition(), metadata.offset(), key - ); - } - } - ).exceptionally(ex -> { - log.error("[KAFKA PRODUCER] Failed to send MatchMemberLeftEvent key={}", key, ex); - return null; - }); - } - - /** - * 방 취소 이벤트를 발행 - */ - public void sendMatchRoomCancelledEvent(MatchRoomCancelledEvent matchRoomCancelledEvent) { - String key = String.valueOf(matchRoomCancelledEvent.roomId()); - - CompletableFuture future = this.matchRoomCancelledEventKafkaTemplate.send( - matchRoomCancelledTopic, key, matchRoomCancelledEvent); - - future.thenAccept(result -> { - if (result instanceof RecordMetadata metadata) { - log.info("[KAFKA PRODUCER] Success sending MatchRoomCancelledEvent: " - + "topic={}, partition={}, offset={}, key={}", - metadata.topic(), metadata.partition(), metadata.offset(), key - ); - } - } - ).exceptionally(ex -> { - log.error("[KAFKA PRODUCER] Failed to send MatchRoomCancelledEvent key={}", key, ex); - return null; - }); - } - - /** - * 매칭 성공 이벤트를 발행 - */ - public void sendMatchRoomCompletedEvent(MatchRoomCompletedEvent matchRoomCompletedEvent) { - String key = String.valueOf(matchRoomCompletedEvent.roomId()); - - CompletableFuture future = this.matchRoomCompletedEventKafkaTemplate.send( - matchRoomCompletedTopic, key, matchRoomCompletedEvent); - - future.thenAccept(result -> { - if (result instanceof RecordMetadata metadata) { - log.info("[KAFKA PRODUCER] Success sending MatchRoomCompleted: " - + "topic={}, partition={}, offset={}, key={}", - metadata.topic(), metadata.partition(), metadata.offset(), key - ); - } - } - ).exceptionally(ex -> { - log.error("[KAFKA PRODUCER] Failed to send MatchRoomCompleted key={}", key, ex); - return null; - }); - } -} \ No newline at end of file diff --git a/src/main/java/com/gachtaxi/global/config/kafka/KafkaProducerConfig.java b/src/main/java/com/gachtaxi/global/config/kafka/DefaultKafkaProducerConfig.java similarity index 55% rename from src/main/java/com/gachtaxi/global/config/kafka/KafkaProducerConfig.java rename to src/main/java/com/gachtaxi/global/config/kafka/DefaultKafkaProducerConfig.java index 1e50fbb7..fab7b235 100644 --- a/src/main/java/com/gachtaxi/global/config/kafka/KafkaProducerConfig.java +++ b/src/main/java/com/gachtaxi/global/config/kafka/DefaultKafkaProducerConfig.java @@ -13,6 +13,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; import org.springframework.kafka.core.DefaultKafkaProducerFactory; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.core.ProducerFactory; @@ -21,39 +22,51 @@ @Configuration public class KafkaProducerConfig { - @Value("${spring.kafka.bootstrap-servers}") - private String bootstrapServers; - + @Primary @Bean - @Qualifier("matchRoomCreatedEventProducerFactory") - public ProducerFactory matchRoomCreatedEventProducerFactory() { + public ProducerFactory producerFactory() { return new DefaultKafkaProducerFactory<>(this.getProducerOptions()); } + @Primary @Bean - @Qualifier("matchMemberJoinedEventProducerFactory") - public ProducerFactory matchMemberJoinedEventProducerFactory() { - return new DefaultKafkaProducerFactory<>(this.getProducerOptions()); - } - - @Bean - @Qualifier("matchMemberCanceledEventProducerFactory") - public ProducerFactory matchMemberCanceledEventProducerFactory() { - return new DefaultKafkaProducerFactory<>(this.getProducerOptions()); - } - - @Bean - @Qualifier("matchRoomCancelledEventProducerFactory") - public ProducerFactory matchRoomCanclledEventProducerFactory() { - return new DefaultKafkaProducerFactory<>(getProducerOptions()); - } - - @Bean - @Qualifier("matchRoomCompletedEventProducerFactory") - public ProducerFactory matchRoomCompletedEventProducerFactory() { - return new DefaultKafkaProducerFactory<>(this.getProducerOptions()); + public KafkaTemplate kafkaTemplate() { + return new KafkaTemplate<>(producerFactory()); } + @Value("${spring.kafka.bootstrap-servers}") + private String bootstrapServers; +// +// @Bean +// @Qualifier("matchRoomCreatedEventProducerFactory") +// public ProducerFactory matchRoomCreatedEventProducerFactory() { +// return new DefaultKafkaProducerFactory<>(this.getProducerOptions()); +// } +// +// @Bean +// @Qualifier("matchMemberJoinedEventProducerFactory") +// public ProducerFactory matchMemberJoinedEventProducerFactory() { +// return new DefaultKafkaProducerFactory<>(this.getProducerOptions()); +// } +// +// @Bean +// @Qualifier("matchMemberCanceledEventProducerFactory") +// public ProducerFactory matchMemberCanceledEventProducerFactory() { +// return new DefaultKafkaProducerFactory<>(this.getProducerOptions()); +// } +// +// @Bean +// @Qualifier("matchRoomCancelledEventProducerFactory") +// public ProducerFactory matchRoomCanclledEventProducerFactory() { +// return new DefaultKafkaProducerFactory<>(getProducerOptions()); +// } +// +// @Bean +// @Qualifier("matchRoomCompletedEventProducerFactory") +// public ProducerFactory matchRoomCompletedEventProducerFactory() { +// return new DefaultKafkaProducerFactory<>(this.getProducerOptions()); +// } +// private Map getProducerOptions() { Map configs = new HashMap<>(); configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); diff --git a/src/main/java/com/gachtaxi/global/config/kafka/KafkaTemplateConfig.java b/src/main/java/com/gachtaxi/global/config/kafka/KafkaTemplateConfig.java deleted file mode 100644 index 2a774a99..00000000 --- a/src/main/java/com/gachtaxi/global/config/kafka/KafkaTemplateConfig.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.gachtaxi.global.config.kafka; - -import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberCancelledEvent; -import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberJoinedEvent; -import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCancelledEvent; -import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCompletedEvent; -import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.kafka.core.ProducerFactory; - -@Configuration -public class KafkaTemplateConfig { - - @Bean - @Qualifier("matchMemberJoinedEventKafkaTemplate") - public KafkaTemplate matchMemberJoinedEventKafkaTemplate( - ProducerFactory matchMemberJoinedEventProducerFactory - ) { - return new KafkaTemplate<>(matchMemberJoinedEventProducerFactory); - } - - @Bean - @Qualifier("matchRoomCreatedEventKafkaTemplate") - public KafkaTemplate matchRoomCreatedEventKafkaTemplate( - ProducerFactory matchRoomCreatedEventProducerFactory - ) { - return new KafkaTemplate<>(matchRoomCreatedEventProducerFactory); - } - - @Bean - @Qualifier("matchMemberCanceledEventKafkaTemplate") - public KafkaTemplate matchMemberCancelledEventKafkaTemplate( - ProducerFactory matchMemberCanceledEventProducerFactory - ) { - return new KafkaTemplate<>(matchMemberCanceledEventProducerFactory); - } - - @Bean - @Qualifier("matchRoomCancelledEventKafkaTemplate") - public KafkaTemplate matchRoomCancelledEventKafkaTemplate( - ProducerFactory matchRoomCancelledEventProducerFactory - ) { - return new KafkaTemplate<>(matchRoomCancelledEventProducerFactory); - } - - @Bean - @Qualifier("matchRoomCompletedEventKafkaTemplate") - public KafkaTemplate matchRoomCompletedEventKafkaTemplate( - ProducerFactory matchRoomCompletedEventProducerFactory - ) { - return new KafkaTemplate<>(matchRoomCompletedEventProducerFactory); - } -} diff --git a/src/main/java/com/gachtaxi/global/config/kafka/KafkaTopicsConfig.java b/src/main/java/com/gachtaxi/global/config/kafka/KafkaTopicsConfig.java deleted file mode 100644 index 1b73120f..00000000 --- a/src/main/java/com/gachtaxi/global/config/kafka/KafkaTopicsConfig.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.gachtaxi.global.config.kafka; - -import org.apache.kafka.clients.admin.NewTopic; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class KafkaTopicsConfig { - - @Value("${gachtaxi.kafka.topics.match-room-created}") - private String matchRoomCreatedTopic; - - @Value("${gachtaxi.kafka.topics.match-member-joined}") - private String matchMemberJoinedTopic; - - @Value("${gachtaxi.kafka.topics.match-room-cancelled}") - private String matchRoomCancelledTopic; - - @Value("${gachtaxi.kafka.topics.match-room-completed}") - private String matchRoomCompletedTopic; - - @Value("${gachtaxi.kafka.topics.match-member-cancelled}") - private String matchMemberCancelledTopic; - - @Value("${gachtaxi.kafka.partition-count}") - private short partitionCount; - - @Value("${gachtaxi.kafka.replication-factor}") - private short replicationFactor; - - @Bean - public NewTopic matchRoomCreatedTopic() { - return new NewTopic(matchRoomCreatedTopic, partitionCount, replicationFactor); - } - - @Bean - public NewTopic matchMemberJoinedTopic() { - return new NewTopic(matchMemberJoinedTopic, partitionCount, replicationFactor); - } - - @Bean - public NewTopic matchRoomCancelledTopic() { - return new NewTopic(matchRoomCancelledTopic, partitionCount, replicationFactor); - } - - @Bean - public NewTopic matchMemberCancelledTopic() { - return new NewTopic(matchMemberCancelledTopic, partitionCount, replicationFactor); - } - - @Bean - public NewTopic matchRoomCompletedTopic() { - return new NewTopic(matchRoomCompletedTopic, partitionCount, replicationFactor); - } -} \ No newline at end of file From b0af0fea0171153698f9dfba1e645ff121562021 Mon Sep 17 00:00:00 2001 From: senna Date: Tue, 14 Jan 2025 03:08:39 +0900 Subject: [PATCH 49/64] =?UTF-8?q?feat:=20NotDefienedKafkaTemplateException?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../matching/common/exception/ErrorMessage.java | 3 ++- .../exception/NotDefinedKafkaTemplateException.java | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/gachtaxi/domain/matching/common/exception/NotDefinedKafkaTemplateException.java diff --git a/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java b/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java index 018b51ae..e3bd4705 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java @@ -12,7 +12,8 @@ public enum ErrorMessage { MEMBER_NOT_IN_MATCHING_ROOM("해당 매칭 방에 참가한 멤버가 아닙니다."), MEMBER_ALREADY_JOINED_MATCHING_ROOM("해당 맴버는 이미 매칭 방에 참가한 멤버입니다"), MEMBER_ALREADY_LEFT_MATCHING_ROOM("해당 멤버는 이미 매칭 방에서 나간 멤버입니다."), - CONTROLLER_NOT_HAS_CURRENT_MEMBER_ID("해당 컨트롤러는 인가된 멤버 ID가 필요합니다."); + CONTROLLER_NOT_HAS_CURRENT_MEMBER_ID("해당 컨트롤러는 인가된 멤버 ID가 필요합니다."), + NOT_DEFINED_KAFKA_TEMPLATE("해당 이벤트와 맞는 KafkaTemplate이 정의되지 않았습니다."); private final String message; } diff --git a/src/main/java/com/gachtaxi/domain/matching/common/exception/NotDefinedKafkaTemplateException.java b/src/main/java/com/gachtaxi/domain/matching/common/exception/NotDefinedKafkaTemplateException.java new file mode 100644 index 00000000..2bb75035 --- /dev/null +++ b/src/main/java/com/gachtaxi/domain/matching/common/exception/NotDefinedKafkaTemplateException.java @@ -0,0 +1,13 @@ +package com.gachtaxi.domain.matching.common.exception; + +import static com.gachtaxi.domain.matching.common.exception.ErrorMessage.NOT_DEFINED_KAFKA_TEMPLATE; +import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; + +import com.gachtaxi.global.common.exception.BaseException; + +public class NotDefinedKafkaTemplateException extends BaseException { + + public NotDefinedKafkaTemplateException() { + super(INTERNAL_SERVER_ERROR, NOT_DEFINED_KAFKA_TEMPLATE.getMessage()); + } +} From 952d355d0a0258538956671c628c6844be502f3e Mon Sep 17 00:00:00 2001 From: senna Date: Tue, 14 Jan 2025 03:09:02 +0900 Subject: [PATCH 50/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EC=9D=B4?= =?UTF-8?q?=EB=B2=A4=ED=8A=B8=EA=B0=80=20=EA=B5=AC=ED=98=84=ED=95=B4?= =?UTF-8?q?=EC=95=BC=ED=95=98=EB=8A=94=20=EC=9D=B8=ED=84=B0=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../matching/event/dto/kafka_topic/MatchingEvent.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchingEvent.java diff --git a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchingEvent.java b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchingEvent.java new file mode 100644 index 00000000..a2b0ae4a --- /dev/null +++ b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchingEvent.java @@ -0,0 +1,7 @@ +package com.gachtaxi.domain.matching.event.dto.kafka_topic; + +public interface MatchingEvent { + + Object getKey(); + String getTopic(); +} From d3a3b29da2f5c262e6dd3458085fd87947d3bc1a Mon Sep 17 00:00:00 2001 From: senna Date: Tue, 14 Jan 2025 03:09:29 +0900 Subject: [PATCH 51/64] =?UTF-8?q?feat:=20=EA=B8=B0=EC=A1=B4=20=EB=A7=A4?= =?UTF-8?q?=EC=B9=AD=20=EA=B4=80=EB=A0=A8=20=EC=9D=B4=EB=B2=A4=ED=8A=B8?= =?UTF-8?q?=EB=93=A4=EC=9D=B4=20MatchingEvent=EB=A5=BC=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MatchMemberCancelledEvent.java | 20 ++++++++++++--- .../kafka_topic/MatchMemberJoinedEvent.java | 25 ++++++++++++++++--- .../kafka_topic/MatchRoomCancelledEvent.java | 24 +++++++++++++++--- .../kafka_topic/MatchRoomCompletedEvent.java | 24 +++++++++++++++--- .../kafka_topic/MatchRoomCreatedEvent.java | 20 ++++++++++++--- 5 files changed, 95 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberCancelledEvent.java b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberCancelledEvent.java index b96020f0..32922887 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberCancelledEvent.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberCancelledEvent.java @@ -4,6 +4,7 @@ import java.time.LocalDateTime; import lombok.AccessLevel; import lombok.Builder; +import org.springframework.beans.factory.annotation.Value; @Builder(access = AccessLevel.PRIVATE) public record MatchMemberCancelledEvent( @@ -11,13 +12,26 @@ public record MatchMemberCancelledEvent( Long memberId, @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - LocalDateTime canceledAt -) { + LocalDateTime canceledAt, - public static MatchMemberCancelledEvent of(Long roomId, Long memberId) { + String topic +) implements MatchingEvent{ + + @Override + public Object getKey() { + return String.valueOf(this.roomId); + } + + @Override + public String getTopic() { + return this.topic; + } + + public static MatchMemberCancelledEvent of(Long roomId, Long memberId, String topic) { return MatchMemberCancelledEvent.builder() .roomId(roomId) .memberId(memberId) + .topic(topic) .build(); } } diff --git a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberJoinedEvent.java b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberJoinedEvent.java index 989ae7da..22d1f395 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberJoinedEvent.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchMemberJoinedEvent.java @@ -4,6 +4,7 @@ import java.time.LocalDateTime; import lombok.AccessLevel; import lombok.Builder; +import org.springframework.beans.factory.annotation.Value; @Builder(access = AccessLevel.PRIVATE) public record MatchMemberJoinedEvent( @@ -11,10 +12,26 @@ public record MatchMemberJoinedEvent( Long memberId, @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - LocalDateTime joinedAt -) { + LocalDateTime joinedAt, - public static MatchMemberJoinedEvent of(Long roomId, Long memberId) { - return new MatchMemberJoinedEvent(roomId, memberId, LocalDateTime.now()); + String topic +) implements MatchingEvent{ + + @Override + public Object getKey() { + return String.valueOf(this.roomId); + } + + @Override + public String getTopic() { + return this.topic; + } + + public static MatchMemberJoinedEvent of(Long roomId, Long memberId, String topic) { + return MatchMemberJoinedEvent.builder() + .roomId(roomId) + .memberId(memberId) + .topic(topic) + .build(); } } diff --git a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCancelledEvent.java b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCancelledEvent.java index f0bbbe2c..b6870b74 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCancelledEvent.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCancelledEvent.java @@ -2,13 +2,29 @@ import lombok.AccessLevel; import lombok.Builder; +import org.springframework.beans.factory.annotation.Value; @Builder(access = AccessLevel.PRIVATE) public record MatchRoomCancelledEvent( - Long roomId -) { + Long roomId, - public static MatchRoomCancelledEvent of(Long roomId) { - return MatchRoomCancelledEvent.builder().roomId(roomId).build(); + String topic +) implements MatchingEvent{ + + @Override + public Object getKey() { + return String.valueOf(this.roomId); + } + + @Override + public String getTopic() { + return this.topic; + } + + public static MatchRoomCancelledEvent of(Long roomId, String topic) { + return MatchRoomCancelledEvent.builder() + .roomId(roomId) + .topic(topic) + .build(); } } diff --git a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCompletedEvent.java b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCompletedEvent.java index 4022476b..80669452 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCompletedEvent.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCompletedEvent.java @@ -2,13 +2,29 @@ import lombok.AccessLevel; import lombok.Builder; +import org.springframework.beans.factory.annotation.Value; @Builder(access = AccessLevel.PRIVATE) public record MatchRoomCompletedEvent( - Long roomId -) { + Long roomId, - public static MatchRoomCompletedEvent of(Long roomId) { - return MatchRoomCompletedEvent.builder().roomId(roomId).build(); + String topic +) implements MatchingEvent{ + + @Override + public Object getKey() { + return String.valueOf(this.roomId); + } + + @Override + public String getTopic() { + return this.topic; + } + + public static MatchRoomCompletedEvent of(Long roomId, String topic) { + return MatchRoomCompletedEvent.builder() + .roomId(roomId) + .topic(topic) + .build(); } } diff --git a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCreatedEvent.java b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCreatedEvent.java index 62b0e195..89333de7 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCreatedEvent.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/dto/kafka_topic/MatchRoomCreatedEvent.java @@ -24,14 +24,27 @@ public record MatchRoomCreatedEvent( Integer expectedTotalCharge, @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - LocalDateTime createdAt -) { + LocalDateTime createdAt, + + String topic +) implements MatchingEvent{ + + @Override + public Object getKey() { + return null; + } + + @Override + public String getTopic() { + return this.topic; + } public static MatchRoomCreatedEvent of( Long roomMasterId, AutoMatchingPostRequest autoMatchingPostRequest, int maxCapacity, - String description + String description, + String topic ) { return MatchRoomCreatedEvent.builder() .roomMasterId(roomMasterId) @@ -44,6 +57,7 @@ public static MatchRoomCreatedEvent of( .description(description) .expectedTotalCharge(autoMatchingPostRequest.expectedTotalCharge()) .criteria(autoMatchingPostRequest.getCriteria()) + .topic(topic) .build(); } } From 12cf905ac6a9378efcb55a0c68ac706dfebffc23 Mon Sep 17 00:00:00 2001 From: senna Date: Tue, 14 Jan 2025 03:09:54 +0900 Subject: [PATCH 52/64] =?UTF-8?q?feat:=20Kafka=20=EB=B9=88=EB=93=A4?= =?UTF-8?q?=EC=9D=84=20=EB=8F=99=EC=A0=81=EC=9C=BC=EB=A1=9C=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=9C=20suffix=20?= =?UTF-8?q?=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/auth/jwt/util/kafka/KafkaBeanSuffix.java | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/main/java/com/gachtaxi/global/auth/jwt/util/kafka/KafkaBeanSuffix.java diff --git a/src/main/java/com/gachtaxi/global/auth/jwt/util/kafka/KafkaBeanSuffix.java b/src/main/java/com/gachtaxi/global/auth/jwt/util/kafka/KafkaBeanSuffix.java new file mode 100644 index 00000000..b008743b --- /dev/null +++ b/src/main/java/com/gachtaxi/global/auth/jwt/util/kafka/KafkaBeanSuffix.java @@ -0,0 +1,8 @@ +package com.gachtaxi.global.auth.jwt.util.kafka; + +public abstract class KafkaBeanSuffix { + + public static final String PRODUCER_FACTORY_SUFFIX = "ProducerFactory"; + public static final String NEW_TOPIC_SUFFIX = "Topic"; + public static final String KAFKA_TEMPLATE_SUFFIX = "KafkaTemplate"; +} From b20683f7b5e853bdf0145b9248f5d72a698cbb64 Mon Sep 17 00:00:00 2001 From: senna Date: Tue, 14 Jan 2025 03:10:08 +0900 Subject: [PATCH 53/64] =?UTF-8?q?feat:=20kafka=20=EB=B9=88=EB=93=A4?= =?UTF-8?q?=EC=9D=84=20=EB=8F=99=EC=A0=81=EC=9C=BC=EB=A1=9C=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=ED=95=98=EA=B8=B0=EC=9C=84=ED=95=9C=20=EC=9C=A0?= =?UTF-8?q?=ED=8B=B8=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/auth/jwt/util/KafkaBeanUtils.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/main/java/com/gachtaxi/global/auth/jwt/util/KafkaBeanUtils.java diff --git a/src/main/java/com/gachtaxi/global/auth/jwt/util/KafkaBeanUtils.java b/src/main/java/com/gachtaxi/global/auth/jwt/util/KafkaBeanUtils.java new file mode 100644 index 00000000..dee64965 --- /dev/null +++ b/src/main/java/com/gachtaxi/global/auth/jwt/util/KafkaBeanUtils.java @@ -0,0 +1,25 @@ +package com.gachtaxi.global.auth.jwt.util; + +import java.util.StringTokenizer; + +public abstract class KafkaBeanUtils { + + public static String getBeanName(String topic, String suffix) { + StringTokenizer stringTokenizer = new StringTokenizer(topic, "-_"); + + StringBuilder beanNameBuilder = new StringBuilder(); + beanNameBuilder.append(stringTokenizer.nextToken()); + + while (stringTokenizer.hasMoreTokens()) { + beanNameBuilder.append(getFirstUpperString(stringTokenizer.nextToken())); + } + + beanNameBuilder.append(suffix); + + return beanNameBuilder.toString(); + } + + public static String getFirstUpperString(String str) { + return str.substring(0, 1).toUpperCase() + str.substring(1); + } +} From 342227eaa45d9f9bf105362e380805e3b4bf3557 Mon Sep 17 00:00:00 2001 From: senna Date: Tue, 14 Jan 2025 03:10:27 +0900 Subject: [PATCH 54/64] =?UTF-8?q?feat:=20=EA=B8=B0=EB=B3=B8=20kafka=20prod?= =?UTF-8?q?ucer,=20kafka=20template=EC=9D=84=20=EC=83=9D=EC=84=B1=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kafka/DefaultKafkaProducerConfig.java | 62 ++++--------------- 1 file changed, 11 insertions(+), 51 deletions(-) diff --git a/src/main/java/com/gachtaxi/global/config/kafka/DefaultKafkaProducerConfig.java b/src/main/java/com/gachtaxi/global/config/kafka/DefaultKafkaProducerConfig.java index fab7b235..d2a79cbc 100644 --- a/src/main/java/com/gachtaxi/global/config/kafka/DefaultKafkaProducerConfig.java +++ b/src/main/java/com/gachtaxi/global/config/kafka/DefaultKafkaProducerConfig.java @@ -1,15 +1,9 @@ package com.gachtaxi.global.config.kafka; -import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberCancelledEvent; -import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberJoinedEvent; -import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCancelledEvent; -import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCompletedEvent; -import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; import java.util.HashMap; import java.util.Map; import org.apache.kafka.clients.producer.ProducerConfig; import org.apache.kafka.common.serialization.StringSerializer; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -20,54 +14,14 @@ import org.springframework.kafka.support.serializer.JsonSerializer; @Configuration -public class KafkaProducerConfig { +public class DefaultKafkaProducerConfig { - @Primary - @Bean - public ProducerFactory producerFactory() { - return new DefaultKafkaProducerFactory<>(this.getProducerOptions()); - } + @Value("${spring.kafka.bootstrap-servers}") + private String bootstrapServers; @Primary @Bean - public KafkaTemplate kafkaTemplate() { - return new KafkaTemplate<>(producerFactory()); - } - - @Value("${spring.kafka.bootstrap-servers}") - private String bootstrapServers; -// -// @Bean -// @Qualifier("matchRoomCreatedEventProducerFactory") -// public ProducerFactory matchRoomCreatedEventProducerFactory() { -// return new DefaultKafkaProducerFactory<>(this.getProducerOptions()); -// } -// -// @Bean -// @Qualifier("matchMemberJoinedEventProducerFactory") -// public ProducerFactory matchMemberJoinedEventProducerFactory() { -// return new DefaultKafkaProducerFactory<>(this.getProducerOptions()); -// } -// -// @Bean -// @Qualifier("matchMemberCanceledEventProducerFactory") -// public ProducerFactory matchMemberCanceledEventProducerFactory() { -// return new DefaultKafkaProducerFactory<>(this.getProducerOptions()); -// } -// -// @Bean -// @Qualifier("matchRoomCancelledEventProducerFactory") -// public ProducerFactory matchRoomCanclledEventProducerFactory() { -// return new DefaultKafkaProducerFactory<>(getProducerOptions()); -// } -// -// @Bean -// @Qualifier("matchRoomCompletedEventProducerFactory") -// public ProducerFactory matchRoomCompletedEventProducerFactory() { -// return new DefaultKafkaProducerFactory<>(this.getProducerOptions()); -// } -// - private Map getProducerOptions() { + public ProducerFactory producerFactory() { Map configs = new HashMap<>(); configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); configs.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); @@ -77,6 +31,12 @@ private Map getProducerOptions() { configs.put(ProducerConfig.ACKS_CONFIG, "all"); configs.put(ProducerConfig.RETRIES_CONFIG, 3); - return configs; + return new DefaultKafkaProducerFactory<>(configs); + } + + @Primary + @Bean + public KafkaTemplate kafkaTemplate() { + return new KafkaTemplate<>(producerFactory()); } } \ No newline at end of file From 6886e2dd539be0d13364564045b124e797441e6f Mon Sep 17 00:00:00 2001 From: senna Date: Tue, 14 Jan 2025 03:11:00 +0900 Subject: [PATCH 55/64] =?UTF-8?q?fix:=20MemberMatchingRoomChargingInfoRepo?= =?UTF-8?q?sitory=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/MemberMatchingRoomChargingInfoRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/repository/MemberMatchingRoomChargingInfoRepository.java b/src/main/java/com/gachtaxi/domain/matching/common/repository/MemberMatchingRoomChargingInfoRepository.java index 982cf175..2a76f9f1 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/repository/MemberMatchingRoomChargingInfoRepository.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/repository/MemberMatchingRoomChargingInfoRepository.java @@ -12,6 +12,6 @@ @Repository public interface MemberMatchingRoomChargingInfoRepository extends JpaRepository { - List findByMatchingRoomAAndPaymentStatus(MatchingRoom matchingRoom, PaymentStatus paymentStatus); + List findByMatchingRoomAndPaymentStatus(MatchingRoom matchingRoom, PaymentStatus paymentStatus); Optional findByMembersAndMatchingRoom(Members members, MatchingRoom matchingRoom); } From 6b999ac75d7aaa4041e983af2b99445500b2ec93 Mon Sep 17 00:00:00 2001 From: senna Date: Tue, 14 Jan 2025 03:11:27 +0900 Subject: [PATCH 56/64] =?UTF-8?q?feat:=20=EB=8F=99=EC=A0=81=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20kafka=20template,=20producer,=20topic=EC=9D=84=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=ED=95=98=EB=8A=94=20registrar=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/kafka/KafkaBeanRegistrar.java | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 src/main/java/com/gachtaxi/global/config/kafka/KafkaBeanRegistrar.java diff --git a/src/main/java/com/gachtaxi/global/config/kafka/KafkaBeanRegistrar.java b/src/main/java/com/gachtaxi/global/config/kafka/KafkaBeanRegistrar.java new file mode 100644 index 00000000..aba24d70 --- /dev/null +++ b/src/main/java/com/gachtaxi/global/config/kafka/KafkaBeanRegistrar.java @@ -0,0 +1,106 @@ +package com.gachtaxi.global.config.kafka; + +import static com.gachtaxi.global.auth.jwt.util.kafka.KafkaBeanSuffix.KAFKA_TEMPLATE_SUFFIX; +import static com.gachtaxi.global.auth.jwt.util.kafka.KafkaBeanSuffix.NEW_TOPIC_SUFFIX; +import static com.gachtaxi.global.auth.jwt.util.kafka.KafkaBeanSuffix.PRODUCER_FACTORY_SUFFIX; + +import com.gachtaxi.global.auth.jwt.util.KafkaBeanUtils; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.clients.admin.NewTopic; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.common.serialization.StringSerializer; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; +import org.springframework.boot.context.properties.bind.Bindable; +import org.springframework.boot.context.properties.bind.Binder; +import org.springframework.context.EnvironmentAware; +import org.springframework.core.env.Environment; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.support.serializer.JsonSerializer; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class KafkaBeanRegistrar implements BeanDefinitionRegistryPostProcessor, EnvironmentAware { + + private Environment environment; + + @Override + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) + throws BeansException { + Map topics = Binder.get(environment) + .bind("gachtaxi.kafka.topics", Bindable.mapOf(String.class, String.class)) + .orElse(Collections.emptyMap()); + + log.info(topics.toString()); + + for (String topic : topics.values()) { + this.registerProducerFactoryAndKafkaTemplate(topic, registry); + this.registerNewTopic(topic, registry); + } + } + + private void registerKafkaTemplate(String topic, String producerFactoryBeanName, BeanDefinitionRegistry registry) { + String kafkaTemplateBeanName = KafkaBeanUtils.getBeanName(topic, KAFKA_TEMPLATE_SUFFIX); + AbstractBeanDefinition kafkaTemplateBeanDefinition = + BeanDefinitionBuilder.genericBeanDefinition(KafkaTemplate.class) + .addConstructorArgReference(producerFactoryBeanName) + .getBeanDefinition(); + + registry.registerBeanDefinition(kafkaTemplateBeanName, kafkaTemplateBeanDefinition); + } + + private void registerNewTopic(String topic, BeanDefinitionRegistry registry) { + short partitionCount = Short.valueOf(this.environment.getProperty("gachtaxi.kafka.partition-count")); + short replicationFactor = Short.valueOf(this.environment.getProperty("gachtaxi.kafka.replication-factor")); + + String topicBeanName = KafkaBeanUtils.getBeanName(topic, NEW_TOPIC_SUFFIX); + AbstractBeanDefinition newTopicBeanDefinition = + BeanDefinitionBuilder.genericBeanDefinition(NewTopic.class) + .addConstructorArgValue(topic) + .addConstructorArgValue(partitionCount) + .addConstructorArgValue(replicationFactor) + .getBeanDefinition(); + + registry.registerBeanDefinition(topicBeanName, newTopicBeanDefinition); + } + + private void registerProducerFactoryAndKafkaTemplate(String topic, BeanDefinitionRegistry registry) { + String producerBeanName = KafkaBeanUtils.getBeanName(topic, PRODUCER_FACTORY_SUFFIX); + AbstractBeanDefinition producerBeanDefinition = + BeanDefinitionBuilder.genericBeanDefinition(DefaultKafkaProducerFactory.class) + .addConstructorArgValue(this.getProducerOptions()) + .getBeanDefinition(); + + registry.registerBeanDefinition(producerBeanName, producerBeanDefinition); + + this.registerKafkaTemplate(topic, producerBeanName, registry); + } + + private Map getProducerOptions() { + String bootstrapServers = this.environment.getProperty("spring.kafka.bootstrap-servers"); + + Map configs = new HashMap<>(); + configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); + configs.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + configs.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class); + + configs.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true); + configs.put(ProducerConfig.ACKS_CONFIG, "all"); + configs.put(ProducerConfig.RETRIES_CONFIG, 3); + + return configs; + } + + @Override + public void setEnvironment(Environment environment) { + this.environment = environment; + } +} From 2d7f2ae03bca0a4dcd08c50e103ba234933f8f8b Mon Sep 17 00:00:00 2001 From: senna Date: Tue, 14 Jan 2025 03:11:36 +0900 Subject: [PATCH 57/64] =?UTF-8?q?feat:=20=EB=A7=A4=EC=B9=AD=20=EC=9D=B4?= =?UTF-8?q?=EB=B2=A4=ED=8A=B8=EB=A5=BC=20=EC=83=9D=EC=84=B1=ED=95=B4?= =?UTF-8?q?=EC=A3=BC=EB=8A=94=20=ED=8C=A9=ED=86=A0=EB=A6=AC=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../matching/event/MatchingEventFactory.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/main/java/com/gachtaxi/domain/matching/event/MatchingEventFactory.java diff --git a/src/main/java/com/gachtaxi/domain/matching/event/MatchingEventFactory.java b/src/main/java/com/gachtaxi/domain/matching/event/MatchingEventFactory.java new file mode 100644 index 00000000..3df46e84 --- /dev/null +++ b/src/main/java/com/gachtaxi/domain/matching/event/MatchingEventFactory.java @@ -0,0 +1,55 @@ +package com.gachtaxi.domain.matching.event; + +import com.gachtaxi.domain.matching.common.dto.request.AutoMatchingPostRequest; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberCancelledEvent; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberJoinedEvent; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCancelledEvent; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCompletedEvent; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class MatchingEventFactory { + + @Value("${gachtaxi.kafka.topics.match-member-cancelled}") + private String matchMemberCancelledTopic; + + @Value("${gachtaxi.kafka.topics.match-member-joined}") + private String matchMemberJoinedTopic; + + @Value("${gachtaxi.kafka.topics.match-room-cancelled}") + private String matchRoomCancelledTopic; + + @Value("${gachtaxi.kafka.topics.match-room-completed}") + private String matchRoomCompletedTopic; + + @Value("${gachtaxi.kafka.topics.match-room-created}") + private String matchRoomCreatedTopic; + + @Value("${gachtaxi.matching.auto-matching-max-capacity}") + private int autoMaxCapacity; + + @Value("${gachtaxi.matching.auto-matcnig-description}") + private String autoDescription; + + public MatchMemberCancelledEvent createMatchMemberCancelledEvent(Long roomId, Long memberId) { + return MatchMemberCancelledEvent.of(roomId, memberId, this.matchMemberCancelledTopic); + } + + public MatchMemberJoinedEvent createMatchMemberJoinedEvent(Long roomId, Long memberId) { + return MatchMemberJoinedEvent.of(roomId, memberId, this.matchMemberJoinedTopic); + } + + public MatchRoomCancelledEvent createMatchRoomCancelledEvent(Long roomId) { + return MatchRoomCancelledEvent.of(roomId, this.matchRoomCancelledTopic); + } + + public MatchRoomCompletedEvent createMatchRoomCompletedEvent(Long roomId) { + return MatchRoomCompletedEvent.of(roomId, this.matchRoomCompletedTopic); + } + + public MatchRoomCreatedEvent createMatchRoomCreatedEvent(Long memberId, AutoMatchingPostRequest autoMatchingPostRequest) { + return MatchRoomCreatedEvent.of(memberId, autoMatchingPostRequest, this.autoMaxCapacity, this.autoDescription, this.matchRoomCreatedTopic); + } +} From e09ad24962f1484d547d0888ea329597c04c703c Mon Sep 17 00:00:00 2001 From: senna Date: Tue, 14 Jan 2025 03:12:03 +0900 Subject: [PATCH 58/64] =?UTF-8?q?refactor:=20=EB=8F=99=EC=A0=81=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=A0=95=EC=9D=98=EB=90=9C=20=EB=B9=88=EC=9D=84=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EA=B8=B0?= =?UTF-8?q?=EC=A1=B4=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/service/AutoMatchingService.java | 23 +++------ .../common/service/MatchingRoomService.java | 16 +++--- .../service/kafka/AutoMatchingProducer.java | 49 +++++++++++++++++++ 3 files changed, 63 insertions(+), 25 deletions(-) create mode 100644 src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java diff --git a/src/main/java/com/gachtaxi/domain/matching/common/service/AutoMatchingService.java b/src/main/java/com/gachtaxi/domain/matching/common/service/AutoMatchingService.java index 92b4cb9f..d9faebb3 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/service/AutoMatchingService.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/service/AutoMatchingService.java @@ -7,18 +7,13 @@ import com.gachtaxi.domain.matching.common.dto.request.AutoMatchingPostRequest; import com.gachtaxi.domain.matching.common.dto.response.AutoMatchingPostResponse; import com.gachtaxi.domain.matching.common.entity.enums.Tags; -import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberCancelledEvent; -import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberJoinedEvent; -import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent; +import com.gachtaxi.domain.matching.event.MatchingEventFactory; import com.gachtaxi.domain.matching.event.service.kafka.AutoMatchingProducer; import com.gachtaxi.domain.matching.event.service.sse.SseService; -import java.time.LocalDateTime; import java.util.List; import java.util.Optional; -import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; @@ -27,15 +22,10 @@ @RequiredArgsConstructor public class AutoMatchingService { - @Value("${gachtaxi.matching.auto-matching-max-capacity}") - private int autoMaxCapacity; - - @Value("${gachtaxi.matching.auto-matcnig-description}") - private String autoDescription; - private final SseService sseService; - private final AutoMatchingProducer autoMatchingProducer; private final MatchingAlgorithmService matchingAlgorithmService; + private final MatchingEventFactory matchingEventFactory; + private final AutoMatchingProducer autoMatchingProducer; public SseEmitter handleSubscribe(Long userId) { return this.sseService.subscribe(userId); @@ -65,19 +55,18 @@ public AutoMatchingPostResponse handlerAutoRequestMatching( private void sendMatchRoomCreatedEvent(Long memberId, AutoMatchingPostRequest autoMatchingPostRequest) { - this.autoMatchingProducer.sendMatchRoomCreatedEvent(MatchRoomCreatedEvent.of(memberId, autoMatchingPostRequest, autoMaxCapacity, autoDescription)); + this.autoMatchingProducer.sendEvent(this.matchingEventFactory.createMatchRoomCreatedEvent(memberId, autoMatchingPostRequest)); } private void sendMatchMemberJoinedEvent(Long memberId, FindRoomResult roomResult) { Long roomId = roomResult.roomId(); - - this.autoMatchingProducer.sendMatchMemberJoinedEvent(MatchMemberJoinedEvent.of(roomId, memberId)); + this.autoMatchingProducer.sendEvent(this.matchingEventFactory.createMatchMemberJoinedEvent(roomId, memberId)); } public AutoMatchingPostResponse handlerAutoCancelMatching(Long memberId, AutoMatchingCancelledRequest autoMatchingCancelledRequest) { - this.autoMatchingProducer.sendMatchMemberLeftEvent(MatchMemberCancelledEvent.of(autoMatchingCancelledRequest.roomId(), memberId)); + this.autoMatchingProducer.sendEvent(this.matchingEventFactory.createMatchMemberCancelledEvent(autoMatchingCancelledRequest.roomId(), memberId)); return AutoMatchingPostResponse.of(AutoMatchingStatus.CANCELLED); } diff --git a/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java b/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java index fc877e5c..503af0e8 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/service/MatchingRoomService.java @@ -14,6 +14,7 @@ import com.gachtaxi.domain.matching.common.repository.MatchingRoomTagInfoRepository; import com.gachtaxi.domain.matching.common.repository.MemberMatchingRoomChargingInfoRepository; import com.gachtaxi.domain.matching.common.repository.RouteRepository; +import com.gachtaxi.domain.matching.event.MatchingEventFactory; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberCancelledEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchMemberJoinedEvent; import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCancelledEvent; @@ -45,6 +46,9 @@ public class MatchingRoomService { private final RouteRepository routeRepository; private final MemberMatchingRoomChargingInfoRepository memberMatchingRoomChargingInfoRepository; + // event factory + private final MatchingEventFactory matchingEventFactory; + public void createMatchingRoom(MatchRoomCreatedEvent matchRoomCreatedEvent) { Members members = this.memberService.findById(matchRoomCreatedEvent.roomMasterId()); @@ -89,7 +93,7 @@ public void joinMemberToMatchingRoom(MatchMemberJoinedEvent matchMemberJoinedEve } this.memberMatchingRoomChargingInfoRepository.save(requestedMembersInfo); - List existMembers = this.memberMatchingRoomChargingInfoRepository.findByMatchingRoomAAndPaymentStatus(matchingRoom, PaymentStatus.NOT_PAYED); + List existMembers = this.memberMatchingRoomChargingInfoRepository.findByMatchingRoomAndPaymentStatus(matchingRoom, PaymentStatus.NOT_PAYED); int distributedCharge = (int) Math.ceil((double) matchingRoom.getTotalCharge() / (existMembers.size() + 1)); @@ -98,9 +102,7 @@ public void joinMemberToMatchingRoom(MatchMemberJoinedEvent matchMemberJoinedEve int nowMemberCount = existMembers.size() + 1; if (matchingRoom.isFull(nowMemberCount)) { - this.autoMatchingProducer.sendMatchRoomCompletedEvent( - MatchRoomCompletedEvent.of(matchingRoom.getId()) - ); + this.autoMatchingProducer.sendEvent(this.matchingEventFactory.createMatchRoomCompletedEvent(matchingRoom.getId())); } } @@ -135,16 +137,14 @@ public void leaveMemberFromMatchingRoom(MatchMemberCancelledEvent matchMemberCan this.findNextRoomMaster(matchingRoom, members) .ifPresentOrElse( nextRoomMaster -> matchingRoom.changeRoomMaster(nextRoomMaster), - () -> this.autoMatchingProducer.sendMatchRoomCancelledEvent( - MatchRoomCancelledEvent.of(matchingRoom.getId()) - ) + () -> this.autoMatchingProducer.sendEvent(this.matchingEventFactory.createMatchRoomCancelledEvent(matchingRoom.getId())) ); } } private Optional findNextRoomMaster(MatchingRoom matchingRoom, Members members) { List existMembers = - this.memberMatchingRoomChargingInfoRepository.findByMatchingRoomAAndPaymentStatus(matchingRoom, PaymentStatus.NOT_PAYED); + this.memberMatchingRoomChargingInfoRepository.findByMatchingRoomAndPaymentStatus(matchingRoom, PaymentStatus.NOT_PAYED); return existMembers.stream() .map(MemberMatchingRoomChargingInfo::getMembers) diff --git a/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java b/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java new file mode 100644 index 00000000..037c85a6 --- /dev/null +++ b/src/main/java/com/gachtaxi/domain/matching/event/service/kafka/AutoMatchingProducer.java @@ -0,0 +1,49 @@ +package com.gachtaxi.domain.matching.event.service.kafka; + +import static com.gachtaxi.global.auth.jwt.util.kafka.KafkaBeanSuffix.KAFKA_TEMPLATE_SUFFIX; + +import com.gachtaxi.domain.matching.common.exception.NotDefinedKafkaTemplateException; +import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchingEvent; +import com.gachtaxi.global.auth.jwt.util.KafkaBeanUtils; +import java.util.concurrent.CompletableFuture; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.clients.producer.RecordMetadata; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +@Slf4j +public class AutoMatchingProducer { + + private final ApplicationContext applicationContext; + + public void sendEvent(MatchingEvent matchingEvent) { + String topic = matchingEvent.getTopic(); + Object key = matchingEvent.getKey(); + + try { + KafkaTemplate kafkaTemplate = this.applicationContext.getBean( + KafkaBeanUtils.getBeanName(topic, KAFKA_TEMPLATE_SUFFIX), KafkaTemplate.class); + CompletableFuture future = kafkaTemplate.send(matchingEvent.getTopic(), matchingEvent.getKey(), matchingEvent); + + future.thenAccept(result -> { + if (result instanceof RecordMetadata metadata) { + log.info("[KAFKA PRODUCER] Success sending MatchRoomCreatedEvent: " + + "topic={}, partition={}, offset={}, key={}", + metadata.topic(), metadata.partition(), metadata.offset(), key + ); + } + } + ).exceptionally(ex -> { + log.error("[KAFKA PRODUCER] Failed to send MatchRoomCreatedEvent key={}", key, ex); + return null; + }); + } catch (BeansException beansException) { + throw new NotDefinedKafkaTemplateException(); + } + } +} From 857ae25ab346fb99279494eab05bb55141497a61 Mon Sep 17 00:00:00 2001 From: senna Date: Tue, 14 Jan 2025 03:12:33 +0900 Subject: [PATCH 59/64] =?UTF-8?q?refactor:=20sse=20=EA=B5=AC=EB=8F=85=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=EB=A5=BC=20=ED=99=95=EC=9D=B8=ED=95=98?= =?UTF-8?q?=EB=8A=94=20AOP=20=EB=A1=9C=EC=A7=81=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=EB=A5=BC=20=EA=BA=BC=EB=82=B4=EC=98=A4=EA=B8=B0?= =?UTF-8?q?=EC=9C=84=ED=95=B4=20Method=20=EA=B0=9D=EC=B2=B4=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/matching/aop/SseSubscribeRequired.java | 2 +- .../matching/aop/SseSubscribeRequiredAop.java | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/aop/SseSubscribeRequired.java b/src/main/java/com/gachtaxi/domain/matching/aop/SseSubscribeRequired.java index 28970452..a75b4a1f 100644 --- a/src/main/java/com/gachtaxi/domain/matching/aop/SseSubscribeRequired.java +++ b/src/main/java/com/gachtaxi/domain/matching/aop/SseSubscribeRequired.java @@ -6,7 +6,7 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE, ElementType.METHOD}) +@Target(ElementType.METHOD) public @interface SseSubscribeRequired { } diff --git a/src/main/java/com/gachtaxi/domain/matching/aop/SseSubscribeRequiredAop.java b/src/main/java/com/gachtaxi/domain/matching/aop/SseSubscribeRequiredAop.java index 677a4f52..fce23e7d 100644 --- a/src/main/java/com/gachtaxi/domain/matching/aop/SseSubscribeRequiredAop.java +++ b/src/main/java/com/gachtaxi/domain/matching/aop/SseSubscribeRequiredAop.java @@ -5,10 +5,12 @@ import com.gachtaxi.domain.matching.common.service.AutoMatchingService; import com.gachtaxi.global.auth.jwt.annotation.CurrentMemberId; import com.gachtaxi.global.common.response.ApiResponse; +import java.lang.reflect.Parameter; import lombok.RequiredArgsConstructor; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; @@ -22,13 +24,18 @@ public class SseSubscribeRequiredAop { @Around("@annotation(com.gachtaxi.domain.matching.aop.SseSubscribeRequired)") public Object checkSseSubscribe(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{ Long memberId = null; - for (Object arg : proceedingJoinPoint.getArgs()) { - Class argClass = arg.getClass(); - if (arg instanceof Long && argClass.isAnnotationPresent(CurrentMemberId.class)) { - memberId = (Long) arg; + MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature(); + Parameter[] parameters = signature.getMethod().getParameters(); + + for (int i = 0; i < parameters.length; i++) { + Parameter parameter = parameters[i]; + if (parameter.getType().equals(Long.class) && parameter.isAnnotationPresent( + CurrentMemberId.class)) { + memberId = (Long) proceedingJoinPoint.getArgs()[i]; break; } } + if (memberId == null) { throw new ControllerNotHasCurrentMemberIdException(); } From c0996ead00d371b2898a130e826807291d644b87 Mon Sep 17 00:00:00 2001 From: senna Date: Tue, 14 Jan 2025 14:14:35 +0900 Subject: [PATCH 60/64] =?UTF-8?q?refactor:=20=ED=95=84=EC=9A=94=20?= =?UTF-8?q?=EC=97=86=EB=8A=94=20=EB=A1=9C=EA=B7=B8=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A0=91=EA=B7=BC=20=EC=A0=9C=EC=96=B4=EC=9E=90=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gachtaxi/global/auth/jwt/util/KafkaBeanUtils.java | 2 +- .../gachtaxi/global/config/kafka/KafkaBeanRegistrar.java | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/main/java/com/gachtaxi/global/auth/jwt/util/KafkaBeanUtils.java b/src/main/java/com/gachtaxi/global/auth/jwt/util/KafkaBeanUtils.java index dee64965..b31e8655 100644 --- a/src/main/java/com/gachtaxi/global/auth/jwt/util/KafkaBeanUtils.java +++ b/src/main/java/com/gachtaxi/global/auth/jwt/util/KafkaBeanUtils.java @@ -19,7 +19,7 @@ public static String getBeanName(String topic, String suffix) { return beanNameBuilder.toString(); } - public static String getFirstUpperString(String str) { + private static String getFirstUpperString(String str) { return str.substring(0, 1).toUpperCase() + str.substring(1); } } diff --git a/src/main/java/com/gachtaxi/global/config/kafka/KafkaBeanRegistrar.java b/src/main/java/com/gachtaxi/global/config/kafka/KafkaBeanRegistrar.java index aba24d70..a6a338c7 100644 --- a/src/main/java/com/gachtaxi/global/config/kafka/KafkaBeanRegistrar.java +++ b/src/main/java/com/gachtaxi/global/config/kafka/KafkaBeanRegistrar.java @@ -8,7 +8,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; -import lombok.extern.slf4j.Slf4j; import org.apache.kafka.clients.admin.NewTopic; import org.apache.kafka.clients.producer.ProducerConfig; import org.apache.kafka.common.serialization.StringSerializer; @@ -24,10 +23,7 @@ import org.springframework.kafka.core.DefaultKafkaProducerFactory; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.support.serializer.JsonSerializer; -import org.springframework.stereotype.Component; -@Slf4j -@Component public class KafkaBeanRegistrar implements BeanDefinitionRegistryPostProcessor, EnvironmentAware { private Environment environment; @@ -39,8 +35,6 @@ public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) .bind("gachtaxi.kafka.topics", Bindable.mapOf(String.class, String.class)) .orElse(Collections.emptyMap()); - log.info(topics.toString()); - for (String topic : topics.values()) { this.registerProducerFactoryAndKafkaTemplate(topic, registry); this.registerNewTopic(topic, registry); From d93eb15b5a9c963e10a76aead16ef04025ba7639 Mon Sep 17 00:00:00 2001 From: senna Date: Tue, 14 Jan 2025 14:35:52 +0900 Subject: [PATCH 61/64] =?UTF-8?q?chore:=20dev=20yml=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-dev.yml | 30 +++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 6be8f1a0..e1b7d7e7 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -16,6 +16,21 @@ spring: host: ${REDIS_HOST} port: ${REDIS_PORT} password: ${REDIS_PASSWORD} + kafka: + bootstrap-servers: ${KAFKA_BOOTSTRAP_SERVERS} + producer: + retries: ${KAFKA_PRODUCER_RETRIES} + acks: ${KAFKA_PRODUCER_ACKS} + properties: + enable.idempotence: ${KAFKA_PRODUCER_ENABLE_IDEMPOTENCE} + max.in.flight.requests.per.connection: ${KAFKA_PRODUCER_MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION} + consumer: + group-id: ${KAFKA_CONSUMER_GROUP_ID} + auto-offset-reset: ${KAFKA_CONSUMER_AUTO_OFFSET_RESET} + enable-auto-commit: ${KAFKA_CONSUMER_ENABLE_AUTO_COMMIT} + admin: + properties: + client.id: ${KAFKA_ADMIN_CLIENT_ID} mongodb: uri: ${MONGODB_URI} @@ -40,4 +55,17 @@ gachtaxi: secureOption: ${COOKIE_SECURE_OPTION} cookiePathOption: ${COOKIE_PATH_OPTION} redis: - emailAuthCodeExpiration: ${REDIS_EMAIL_AUTH_CODE_EXPIRATION} \ No newline at end of file + emailAuthCodeExpiration: ${REDIS_EMAIL_AUTH_CODE_EXPIRATION} + kafka: + topics: + match-room-created: ${KAFKA_TOPIC_MATCH_ROOM_CREATED} + match-member-joined: ${KAFKA_TOPIC_MATCH_MEMBER_JOINED} + match-room-cancelled: ${KAFKA_TOPIC_MATCH_ROOM_CANCELLED} + match-member-cancelled: ${KAFKA_TOPIC_MATCH_MEMBER_CANCELLED} + match-room-completed: ${KAFKA_TOPIC_MATCH_ROOM_COMPLETED} + partition-count: ${KAFKA_PARTITION_COUNT} + replication-factor: ${KAFKA_REPLICATION_FACTOR} + matching: + auto-matching-max-capacity: ${AUTO_MATCHING_MAX_CAPACITY} + auto-matcnig-description: ${AUTO_MATCHING_DESCRIPTION} + From eb591316c826eb6f2455c67cfcc40728cc179afe Mon Sep 17 00:00:00 2001 From: senna Date: Thu, 16 Jan 2025 18:59:00 +0900 Subject: [PATCH 62/64] =?UTF-8?q?fix:=20=EC=84=A4=EC=A0=95=20=EC=98=A4?= =?UTF-8?q?=ED=83=80=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20registarar?= =?UTF-8?q?=EC=97=90=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=96=B4?= =?UTF-8?q?=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gachtaxi/domain/matching/event/MatchingEventFactory.java | 2 +- .../com/gachtaxi/global/config/kafka/KafkaBeanRegistrar.java | 2 ++ src/main/resources/application-local.yml | 3 +-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/event/MatchingEventFactory.java b/src/main/java/com/gachtaxi/domain/matching/event/MatchingEventFactory.java index 3df46e84..d44bf9bb 100644 --- a/src/main/java/com/gachtaxi/domain/matching/event/MatchingEventFactory.java +++ b/src/main/java/com/gachtaxi/domain/matching/event/MatchingEventFactory.java @@ -30,7 +30,7 @@ public class MatchingEventFactory { @Value("${gachtaxi.matching.auto-matching-max-capacity}") private int autoMaxCapacity; - @Value("${gachtaxi.matching.auto-matcnig-description}") + @Value("${gachtaxi.matching.auto-matching-description}") private String autoDescription; public MatchMemberCancelledEvent createMatchMemberCancelledEvent(Long roomId, Long memberId) { diff --git a/src/main/java/com/gachtaxi/global/config/kafka/KafkaBeanRegistrar.java b/src/main/java/com/gachtaxi/global/config/kafka/KafkaBeanRegistrar.java index a6a338c7..dc2b3472 100644 --- a/src/main/java/com/gachtaxi/global/config/kafka/KafkaBeanRegistrar.java +++ b/src/main/java/com/gachtaxi/global/config/kafka/KafkaBeanRegistrar.java @@ -23,7 +23,9 @@ import org.springframework.kafka.core.DefaultKafkaProducerFactory; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.support.serializer.JsonSerializer; +import org.springframework.stereotype.Component; +@Component public class KafkaBeanRegistrar implements BeanDefinitionRegistryPostProcessor, EnvironmentAware { private Environment environment; diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 35f3af98..ecc88f5a 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -62,10 +62,9 @@ gachtaxi: match-member-joined: ${KAFKA_TOPIC_MATCH_MEMBER_JOINED} match-member-cancelled: ${KAFKA_TOPIC_MATCH_MEMBER_CANCELLED} match-room-cancelled: ${KAFKA_TOPIC_MATCH_ROOM_CANCELLED} - match-member-cancelled: ${KAFKA_TOPIC_MATCH_MEMBER_CANCELLED} match-room-completed: ${KAFKA_TOPIC_MATCH_ROOM_COMPLETED} partition-count: ${KAFKA_PARTITION_COUNT} replication-factor: ${KAFKA_REPLICATION_FACTOR} matching: auto-matching-max-capacity: ${AUTO_MATCHING_MAX_CAPACITY} - auto-matcnig-description: ${AUTO_MATCHING_DESCRIPTION} + auto-matching-description: ${AUTO_MATCHING_DESCRIPTION} From 3ad5aa05f0178fa0f3db9d87da1c11ace0cd9ee1 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 20 Jan 2025 20:32:09 +0900 Subject: [PATCH 63/64] =?UTF-8?q?fix:=20=EC=84=B8=EB=AF=B8=EC=BD=9C?= =?UTF-8?q?=EB=A1=A0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gachtaxi/domain/matching/common/exception/ErrorMessage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java b/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java index 61080aec..6f8cd58b 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/exception/ErrorMessage.java @@ -13,7 +13,7 @@ public enum ErrorMessage { MEMBER_ALREADY_JOINED_MATCHING_ROOM("해당 맴버는 이미 매칭 방에 참가한 멤버입니다"), MEMBER_ALREADY_LEFT_MATCHING_ROOM("해당 멤버는 이미 매칭 방에서 나간 멤버입니다."), CONTROLLER_NOT_HAS_CURRENT_MEMBER_ID("해당 컨트롤러는 인가된 멤버 ID가 필요합니다."), - NOT_DEFINED_KAFKA_TEMPLATE("해당 이벤트와 맞는 KafkaTemplate이 정의되지 않았습니다."); + NOT_DEFINED_KAFKA_TEMPLATE("해당 이벤트와 맞는 KafkaTemplate이 정의되지 않았습니다."), DUPLICATED_MATCHING_ROOM("이미 존재하는 매칭 방입니다."), NOT_FOUND_PAGE("페이지 번호는 0 이상이어야 합니다."); From 0ed17f0cd3f5f653cf2fcb96b5ab529784b3bdd0 Mon Sep 17 00:00:00 2001 From: senna Date: Mon, 20 Jan 2025 20:34:32 +0900 Subject: [PATCH 64/64] =?UTF-8?q?fix:=20=EB=B9=8C=EB=93=9C=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/gachtaxi/GachtaxiApplication.java | 2 -- .../service/MockMatchingAlgorithmService.java | 2 +- .../gachtaxi/domain/matching/common/entity/Route.java | 11 +---------- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/gachtaxi/GachtaxiApplication.java b/src/main/java/com/gachtaxi/GachtaxiApplication.java index b4780f0b..bb667bc3 100644 --- a/src/main/java/com/gachtaxi/GachtaxiApplication.java +++ b/src/main/java/com/gachtaxi/GachtaxiApplication.java @@ -4,12 +4,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.data.mongodb.config.EnableMongoAuditing; -import org.springframework.data.jpa.repository.config.EnableJpaAuditing; @SpringBootApplication @EnableJpaAuditing @EnableMongoAuditing -@EnableJpaAuditing public class GachtaxiApplication { public static void main(String[] args) { diff --git a/src/main/java/com/gachtaxi/domain/matching/algorithm/service/MockMatchingAlgorithmService.java b/src/main/java/com/gachtaxi/domain/matching/algorithm/service/MockMatchingAlgorithmService.java index 31ea0762..fe90a21a 100644 --- a/src/main/java/com/gachtaxi/domain/matching/algorithm/service/MockMatchingAlgorithmService.java +++ b/src/main/java/com/gachtaxi/domain/matching/algorithm/service/MockMatchingAlgorithmService.java @@ -50,7 +50,7 @@ public Optional findRoom(Long userId, double startLongitude, dou ACTIVE 상태인 방만 필터링 */ matchingRooms = matchingRooms.stream() - .filter(MatchingRoom::isActiveMatchingRoom) + .filter(MatchingRoom::isActive) .toList(); /* 태그 조건이 있는 경우에 태그정보까지 필터링 diff --git a/src/main/java/com/gachtaxi/domain/matching/common/entity/Route.java b/src/main/java/com/gachtaxi/domain/matching/common/entity/Route.java index bcf3e0c7..2b7f5260 100644 --- a/src/main/java/com/gachtaxi/domain/matching/common/entity/Route.java +++ b/src/main/java/com/gachtaxi/domain/matching/common/entity/Route.java @@ -11,7 +11,7 @@ @Entity @Table(name = "route") -@Builder(access = AccessLevel.PRIVATE) +@Builder @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor(access = AccessLevel.PRIVATE) public class Route extends BaseEntity { @@ -23,13 +23,4 @@ public class Route extends BaseEntity { private double endLongitude; private double endLatitude; private String endLocationName; - - public static Route from(MatchRoomCreatedEvent matchRoomCreatedEvent) { - return Route.builder() - .startLocationCoordinate(matchRoomCreatedEvent.startPoint()) - .startLocationName(matchRoomCreatedEvent.startName()) - .endLocationCoordinate(matchRoomCreatedEvent.destinationPoint()) - .endLocationName(matchRoomCreatedEvent.destinationName()) - .build(); - } }