From d387e971f0565d450f3ebd9d760ab27f33f29888 Mon Sep 17 00:00:00 2001 From: DDonghyeo Date: Thu, 27 Jun 2024 00:14:57 +0900 Subject: [PATCH 01/13] =?UTF-8?q?=E2=99=BB=EF=B8=8Frefactor=20:=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20API?= =?UTF-8?q?=20=EC=A7=80=EC=97=AD=20=EB=B3=80=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/NotificationService.java | 11 ++++-- .../notiservice/utils/GpsTransfer.java | 34 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 noti-service/src/main/java/com/waither/notiservice/utils/GpsTransfer.java diff --git a/noti-service/src/main/java/com/waither/notiservice/service/NotificationService.java b/noti-service/src/main/java/com/waither/notiservice/service/NotificationService.java index 2b4bf4e0..4062b874 100644 --- a/noti-service/src/main/java/com/waither/notiservice/service/NotificationService.java +++ b/noti-service/src/main/java/com/waither/notiservice/service/NotificationService.java @@ -8,16 +8,22 @@ import com.waither.notiservice.domain.redis.NotificationRecord; import com.waither.notiservice.enums.Season; import com.waither.notiservice.global.exception.CustomException; +import com.waither.notiservice.global.response.ApiResponse; import com.waither.notiservice.global.response.ErrorCode; import com.waither.notiservice.repository.jpa.NotificationRepository; import com.waither.notiservice.repository.jpa.UserDataRepository; import com.waither.notiservice.repository.jpa.UserMedianRepository; import com.waither.notiservice.repository.redis.NotificationRecordRepository; +import com.waither.notiservice.utils.GpsTransfer; import com.waither.notiservice.utils.TemperatureUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpStatusCode; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; import java.time.LocalDateTime; import java.util.List; @@ -36,6 +42,8 @@ public class NotificationService { private final AlarmService alarmService; + + @Transactional(readOnly = true) public List getNotifications(String email) { @@ -132,8 +140,7 @@ public void updateLocation(String email, LocationDto locationDto) { Optional notiRecord = notificationRecordRepository.findByEmail(email); - //TODO : 위도 경도 -> 지역 변환 - String region = "서울특별시"; + String region = GpsTransfer.transferToRegion(locationDto); if (notiRecord.isPresent()) { NotificationRecord notificationRecord = notiRecord.get(); diff --git a/noti-service/src/main/java/com/waither/notiservice/utils/GpsTransfer.java b/noti-service/src/main/java/com/waither/notiservice/utils/GpsTransfer.java new file mode 100644 index 00000000..60bc4d09 --- /dev/null +++ b/noti-service/src/main/java/com/waither/notiservice/utils/GpsTransfer.java @@ -0,0 +1,34 @@ +package com.waither.notiservice.utils; + +import com.waither.notiservice.api.request.LocationDto; +import com.waither.notiservice.global.exception.CustomException; +import com.waither.notiservice.global.response.ApiResponse; +import com.waither.notiservice.global.response.ErrorCode; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpStatusCode; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; + +@Component +public class GpsTransfer { + + public static String transferToRegion(LocationDto locationDto) { + String WEATHER_SERVICE_URL = "localhost"; + + ParameterizedTypeReference> responseType + = new ParameterizedTypeReference>() {}; + + ApiResponse response = + WebClient.create(WEATHER_SERVICE_URL).get() + .uri(uriBuilder -> uriBuilder + .scheme("http") + .path("/weather/region") + .build()) + .retrieve() + .onStatus(HttpStatusCode::isError, clientResponse -> Mono.error(new CustomException(ErrorCode.INTERNAL_SERVER_ERROR_500))) + .bodyToMono(responseType) + .block(); + return response.getResult(); + } +} From 312b2de66db981f3c9e605ebd44c061fc1f18168 Mon Sep 17 00:00:00 2001 From: DDonghyeo Date: Thu, 27 Jun 2024 16:38:05 +0900 Subject: [PATCH 02/13] =?UTF-8?q?=E2=99=BB=EF=B8=8Frefactor=20:=20KafkaCon?= =?UTF-8?q?sumer=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/KafkaConsumerConfig.java | 18 ---- .../notiservice/service/KafkaConsumer.java | 97 ++++++++++++------- 2 files changed, 62 insertions(+), 53 deletions(-) diff --git a/noti-service/src/main/java/com/waither/notiservice/config/KafkaConsumerConfig.java b/noti-service/src/main/java/com/waither/notiservice/config/KafkaConsumerConfig.java index 35a685c1..24d01533 100644 --- a/noti-service/src/main/java/com/waither/notiservice/config/KafkaConsumerConfig.java +++ b/noti-service/src/main/java/com/waither/notiservice/config/KafkaConsumerConfig.java @@ -94,24 +94,6 @@ private ConsumerFactory userMedianConsumerFactor } - - @Bean("firebaseTokenKafkaListenerContainerFactory") - public ConcurrentKafkaListenerContainerFactory firebaseTokenConcurrentKafkaListenerContainerFactory(){ - ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); - factory.setConsumerFactory(firebaseTokenConsumerFactory()); - factory.setConcurrency(3); - factory.setBatchListener(true); - factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.BATCH); - return factory; - } - - private ConsumerFactory firebaseTokenConsumerFactory() { - Map props = dtoSettings(); - return new DefaultKafkaConsumerFactory<>(props, new StringDeserializer(), new JsonDeserializer<>(KafkaDto.TokenDto.class)); - } - - - @Bean("userSettingsKafkaListenerContainerFactory") public ConcurrentKafkaListenerContainerFactory userSettingsConcurrentKafkaListenerContainerFactory(){ ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); diff --git a/noti-service/src/main/java/com/waither/notiservice/service/KafkaConsumer.java b/noti-service/src/main/java/com/waither/notiservice/service/KafkaConsumer.java index a51b8ae5..4ddfb837 100644 --- a/noti-service/src/main/java/com/waither/notiservice/service/KafkaConsumer.java +++ b/noti-service/src/main/java/com/waither/notiservice/service/KafkaConsumer.java @@ -17,8 +17,10 @@ import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; +import java.util.Arrays; import java.util.List; import java.util.Optional; +import java.util.StringTokenizer; @Slf4j @RequiredArgsConstructor @@ -49,8 +51,6 @@ public void consumeUserMedian(KafkaDto.UserMedianDto userMedianDto) { //User Median 이미 있을 경우 UserMedian userMedian = optionalUserMedian.get(); userMedian.setLevel(userMedianDto); - userMedianRepository.save(userMedian); - } else { //User Median 없을 경우 생성 //TODO : 계절당 초기값 받아야 함 @@ -65,22 +65,6 @@ public void consumeUserMedian(KafkaDto.UserMedianDto userMedianDto) { } - /** - * Firebase Token Listener - * */ - @Transactional - @KafkaListener(topics = "firebase-token", containerFactory = "firebaseTokenKafkaListenerContainerFactory") - public void consumeFirebaseToken(KafkaDto.TokenDto tokenDto) { - - log.info("[ Kafka Listener ] Firebase Token 동기화"); - log.info("[ Kafka Listener ] Email : --> {}", tokenDto.email()); - log.info("[ Kafka Listener ] Token : --> {}", tokenDto.token()); - - //토큰 Redis 저장 - redisUtils.save(tokenDto.email(), tokenDto.token()); - } - - /** * User Settings Listener * */ @@ -96,7 +80,6 @@ public void consumeUserSettings(KafkaDto.UserSettingsDto userSettingsDto) { Optional userData = userDataRepository.findByEmail(userSettingsDto.email()); if (userData.isPresent()) { userData.get().updateValue(userSettingsDto.key(), userSettingsDto.value()); - userDataRepository.save(userData.get()); } else { log.warn("[ Kafka Listener ] User Data 초기값이 없었습니다."); UserData newUserData = UserData.builder() @@ -165,7 +148,7 @@ public void consumeWindAlarm(KafkaDto.WeatherDto weatherDto) { /** - * 강설 정보 알림 Listener
+ * 강수 정보 알림 Listener
* 기상청 기준
* 약한 비 1~3mm
* 보통 비 3~15mm
@@ -174,8 +157,8 @@ public void consumeWindAlarm(KafkaDto.WeatherDto weatherDto) { * 참고 */ @Transactional - @KafkaListener(topics = "alarm-snow", containerFactory = "weatherKafkaListenerContainerFactory") - public void consumeSnow(KafkaDto.WeatherDto weatherDto) { + @KafkaListener(topics = "alarm-rain", containerFactory = "weatherKafkaListenerContainerFactory") + public void consumeRain(KafkaDto.WeatherDto weatherDto) { int currentHour = LocalDateTime.now().getHour(); // 22:00 ~ 07:00 는 알림을 전송하지 않음 @@ -184,25 +167,24 @@ public void consumeSnow(KafkaDto.WeatherDto weatherDto) { } String title = "Waither 강수 정보 알림"; + List userData = userDataRepository.findAllBySnowAlertIsTrue(); StringBuilder sb = new StringBuilder(); - - String region = weatherDto.region(); - Double prediction = Double.valueOf(weatherDto.message()); //강수량 + //지역 + String region = weatherDto.region(); log.info("[ Kafka Listener ] 강수량 지역 --> {}", region); - log.info("[ Kafka Listener ] 걍수량 --> {}", prediction); - List userData = userDataRepository.findAllBySnowAlertIsTrue(); + String rainMessage = getRainPredictions(weatherDto.message()); - //예시 : 현재 서울특별시 지역에 2mm의 약한 비가 내릴 예정입니다. - //TODO: 언제 내리는지? 확인 필요 - sb.append("현재 ").append(region).append(" 지역에 ").append(prediction).append("mm의 ") - .append(getExpression(prediction)).append("가 내릴 예정입니다."); + if (rainMessage == null) { + //6시간 동안 강수 정보 없음 + return; + } + sb.append("현재 ").append(region).append(" 지역에 ").append(rainMessage); //알림 보낼 사용자 이메일 List userEmails = filterRegionAndRainAlarm(region, userData, currentHour); - System.out.println("[ 푸시알림 ] 강수량 알림"); alarmService.sendAlarms(userEmails, title, sb.toString()); @@ -215,6 +197,7 @@ public void consumeSnow(KafkaDto.WeatherDto weatherDto) { } + /** * 기상 특보 알림 Listener * */ @@ -249,6 +232,7 @@ public void consumeClimateAlarm(KafkaDto.WeatherDto weatherDto) { //지역 필터링 & 알림 규칙 검사 + private List filterRegionAndWindAlarm(String region, List userData, int currentHour) { return userData.stream() .filter(data -> { @@ -261,8 +245,8 @@ private List filterRegionAndWindAlarm(String region, List user .map(UserData::getEmail) .toList(); } - //지역 필터링 & 알림 규칙 검사 + private List filterRegionAndRainAlarm(String region, List userData, int currentHour) { return userData.stream() .filter(data -> { @@ -275,7 +259,6 @@ private List filterRegionAndRainAlarm(String region, List user .map(UserData::getEmail) .toList(); } - private List filterRegion(String region, List userData) { return userData.stream() .filter(data -> { @@ -286,8 +269,51 @@ private List filterRegion(String region, List userData) { .toList(); } + private String getRainPredictions(String message) { + + //1시간 뒤, 2시간 뒤, 3시간 뒤, 4시간 뒤, 5시간 뒤, 6시간 뒤 + List predictions = Arrays.stream(message.split(",")) + .map(String::trim) //공백 제거 + .map(s -> s.equals("강수없음") ? "0" : s) + .map(Double::parseDouble) + .toList(); + + List predictionStr = predictions.stream() + .map(prediction -> prediction == 0 ? "강수없음" : getRainExpression(prediction)) + .toList(); + //예시 ["강수없음", "약한 비", "약한 비", "비", "비", "비"] + + //몇 시간 뒤에 비가 얼만큼 몇 시간 동안 오는지? + int startHour = -1; + int duration = 0; + String intensity = ""; + boolean isRaining = false; + + for (int i = 0; i < predictionStr.size(); i++) { + String current = predictionStr.get(i); + if (!current.equals("강수없음")) { + if (!isRaining) { + startHour = i + 1; + intensity = current; + } + isRaining = true; + duration++; + } else if (isRaining) { + break; + } + } + + if (startHour == -1) { + return null; + } else { + String timePhrase = startHour == 1 ? "1시간 후부터" : startHour + "시간 후부터"; + String durationPhrase = duration == 1 ? "1시간 동안" : duration + "시간 동안"; + //예시 "3시간 후부터 약한 비가 4시간 동안 올 예정입니다." + return String.format("%s %s가 %s 올 예정입니다.", timePhrase, intensity, durationPhrase); + } + } //강수 표현 - private String getExpression(double prediction) { + private String getRainExpression(double prediction) { //1~3mm : 약한 비 if (prediction > 1 && prediction < 3) { return "약한 비"; @@ -302,4 +328,5 @@ private String getExpression(double prediction) { return "매우 강한 비"; } else return "비"; } + } From edcafc1247f8fe85640ee8c5c6c68504052157e0 Mon Sep 17 00:00:00 2001 From: DDonghyeo Date: Thu, 27 Jun 2024 16:38:18 +0900 Subject: [PATCH 03/13] =?UTF-8?q?=E2=99=BB=EF=B8=8Frefactor=20:=20record?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/response/NotificationResponse.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/noti-service/src/main/java/com/waither/notiservice/api/response/NotificationResponse.java b/noti-service/src/main/java/com/waither/notiservice/api/response/NotificationResponse.java index 32068234..a7466e4b 100644 --- a/noti-service/src/main/java/com/waither/notiservice/api/response/NotificationResponse.java +++ b/noti-service/src/main/java/com/waither/notiservice/api/response/NotificationResponse.java @@ -9,14 +9,11 @@ import java.time.LocalDateTime; @Builder -@Getter -@AllArgsConstructor -public class NotificationResponse { - - public String id; - public LocalDateTime time; - public String message; - +public record NotificationResponse( + String id, + LocalDateTime time, + String message +) { public static NotificationResponse of(Notification notification) { return NotificationResponse.builder() .id(notification.getId()) From a547a541725ee97b984c01eba330be1ec4046b69 Mon Sep 17 00:00:00 2001 From: DDonghyeo Date: Thu, 27 Jun 2024 18:59:43 +0900 Subject: [PATCH 04/13] =?UTF-8?q?=E2=99=BB=EF=B8=8Frefactor=20:=20?= =?UTF-8?q?=EC=9C=84=EB=8F=84=20&=20=EA=B2=BD=EB=8F=84=20Validation=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notiservice/api/request/LocationDto.java | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/noti-service/src/main/java/com/waither/notiservice/api/request/LocationDto.java b/noti-service/src/main/java/com/waither/notiservice/api/request/LocationDto.java index 16d8f080..c76526d1 100644 --- a/noti-service/src/main/java/com/waither/notiservice/api/request/LocationDto.java +++ b/noti-service/src/main/java/com/waither/notiservice/api/request/LocationDto.java @@ -3,20 +3,17 @@ import jakarta.validation.constraints.DecimalMax; import jakarta.validation.constraints.DecimalMin; import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; public record LocationDto ( - @NotBlank(message = " 위도(lat) 값은 필수입니다.") - @DecimalMax(value = "132.0", inclusive = true, message = "위도(lat)는 대한민국 내에서만 가능합니다.") - @DecimalMin(value = "124.0", inclusive = true, message = "위도(lat)는 대한민국 내에서만 가능합니다.") - double lat, + @NotBlank(message = " 위도(latitude) 값은 필수입니다.") + @DecimalMax(value = "43.0", inclusive = true, message = "대한민국 내에서만 가능합니다. (33~43)") + @DecimalMin(value = "33.0", inclusive = true, message = "대한민국 내에서만 가능합니다. (33~43)") + double latitude, - @NotBlank(message = " 경도(y) 값은 필수입니다.") - @DecimalMax(value = "43.0", inclusive = true, message = "경도(lon)는 대한민국 내에서만 가능합니다.") - @DecimalMin(value = "33.0", inclusive = true, message = "경도(lon)는 대한민국 내에서만 가능합니다.") - double lon + @NotBlank(message = " 경도(longitude) 값은 필수입니다.") + @DecimalMax(value = "132.0", inclusive = true, message = "대한민국 내에서만 가능합니다. (124~132)") + @DecimalMin(value = "124.0", inclusive = true, message = "대한민국 내에서만 가능합니다. (124~132)") + double longitude ) { From 08272784ea0eabe19d2da524394a17248b809924 Mon Sep 17 00:00:00 2001 From: DDonghyeo Date: Thu, 27 Jun 2024 19:03:29 +0900 Subject: [PATCH 05/13] =?UTF-8?q?=E2=99=BB=EF=B8=8Frefactor=20:=20Notifica?= =?UTF-8?q?tionService=20Test=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notiservice/service/NotificationServiceTest.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/noti-service/src/test/java/com/waither/notiservice/service/NotificationServiceTest.java b/noti-service/src/test/java/com/waither/notiservice/service/NotificationServiceTest.java index c1e5a509..58ddbd2a 100644 --- a/noti-service/src/test/java/com/waither/notiservice/service/NotificationServiceTest.java +++ b/noti-service/src/test/java/com/waither/notiservice/service/NotificationServiceTest.java @@ -1,5 +1,6 @@ package com.waither.notiservice.service; +import com.waither.notiservice.api.request.LocationDto; import com.waither.notiservice.api.response.NotificationResponse; import com.waither.notiservice.domain.Notification; import com.waither.notiservice.domain.UserData; @@ -42,10 +43,13 @@ public class NotificationServiceTest { @MockBean NotificationRecordRepository notificationRecordRepository; + @MockBean + AlarmService alarmService; + @BeforeEach void setUp() { //가짜 객체 주입 - notificationService = new NotificationService(notificationRepository, userMedianRepository, userDataRepository, notificationRecordRepository); + notificationService = new NotificationService(notificationRepository, userMedianRepository, userDataRepository, notificationRecordRepository, alarmService); } @Test @@ -57,6 +61,7 @@ void goOutAlarm() { String tempEmail = "serviceTest@gmail.com"; Season currentSeason = TemperatureUtils.getCurrentSeason(); + LocationDto locationDto = new LocationDto(33, 134); UserData newUser = UserData.builder() .email(tempEmail) @@ -81,7 +86,7 @@ void goOutAlarm() { Mockito.when(userMedianRepository.findByEmailAndSeason(tempEmail, currentSeason)).thenReturn(Optional.of(newUserMedian)); // (Mock) find시 Return //when - String resultMessage = notificationService.sendGoOutAlarm(tempEmail); + String resultMessage = notificationService.sendGoOutAlarm(tempEmail,locationDto); //then System.out.println("[ Notification Service Test ] result Message --> "+resultMessage); @@ -109,7 +114,7 @@ void getAlarm() { //then assertEquals(1, notifications.size()); // 예상되는 알림 개수가 맞는지 확인 NotificationResponse notification = notifications.get(0); - assertEquals("test content", notification.getMessage()); // 내용이 예상과 일치하는지 확인 + assertEquals("test content", notification.message()); // 내용이 예상과 일치하는지 확인 From 8d3b919ae815a7b9f25221ecd24ae4bb0e0199ec Mon Sep 17 00:00:00 2001 From: DDonghyeo Date: Mon, 1 Jul 2024 14:42:25 +0900 Subject: [PATCH 06/13] =?UTF-8?q?=E2=99=BB=EF=B8=8Frefactor=20:=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=20=EA=B0=80=EC=A4=91=EC=B9=98=20=EC=A1=B0?= =?UTF-8?q?=EC=A0=95=20=EC=9A=94=EC=86=8C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../waither/notiservice/utils/TemperatureUtils.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/noti-service/src/main/java/com/waither/notiservice/utils/TemperatureUtils.java b/noti-service/src/main/java/com/waither/notiservice/utils/TemperatureUtils.java index efafe93e..78fb97de 100644 --- a/noti-service/src/main/java/com/waither/notiservice/utils/TemperatureUtils.java +++ b/noti-service/src/main/java/com/waither/notiservice/utils/TemperatureUtils.java @@ -17,12 +17,13 @@ public class TemperatureUtils { public static Expressions[] winterExpressions = {WARM, GOOD, LITTLE_COLD, COLD, VERY_COLD }; public static Expressions[] springAndAutumnExpressions = {HOT, LITTLE_HOT, GOOD, LITTLE_COLD, COLD}; public static Expressions[] summerExpressions = {COOL, GOOD, LITTLE_HOT, HOT, VERY_HOT}; + public static double WEIGHT_ADJUSTMENT_FACTOR = 0.5; - public static String createUserDataMessage(UserMedian userMedian, double temperature) { - double medianBetween1And2 = userMedian.getMedianOf1And2(); - double medianBetween2And3 = userMedian.getMedianOf2And3(); - double medianBetween3And4 = userMedian.getMedianOf3And4(); - double medianBetween4And5 = userMedian.getMedianOf4And5(); + public static String createUserDataMessage(UserMedian userMedian, double temperature, double weight) { + double medianBetween1And2 = userMedian.getMedianOf1And2() + weight * WEIGHT_ADJUSTMENT_FACTOR; + double medianBetween2And3 = userMedian.getMedianOf2And3() + weight * WEIGHT_ADJUSTMENT_FACTOR; + double medianBetween3And4 = userMedian.getMedianOf3And4() + weight * WEIGHT_ADJUSTMENT_FACTOR; + double medianBetween4And5 = userMedian.getMedianOf4And5() + weight * WEIGHT_ADJUSTMENT_FACTOR; if (temperature < medianBetween1And2) { return getExpression(getCurrentSeason(), 1); From 1e2efd7a37d477e1c1c401fed8ff5237bc5510af Mon Sep 17 00:00:00 2001 From: DDonghyeo Date: Mon, 1 Jul 2024 15:36:39 +0900 Subject: [PATCH 07/13] =?UTF-8?q?=E2=99=BB=EF=B8=8Frefactor=20:=20Weather?= =?UTF-8?q?=20Service=20=ED=86=B5=EC=8B=A0=20=ED=99=98=EA=B2=BD=20?= =?UTF-8?q?=EA=B5=AC=EC=B6=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/response/MainWeatherResponse.java | 33 +++++++++++ .../notiservice/utils/GpsTransfer.java | 34 ----------- .../waither/notiservice/utils/RestClient.java | 58 +++++++++++++++++++ ...ureUtils.java => WeatherMessageUtils.java} | 57 +++++++++++++++++- 4 files changed, 147 insertions(+), 35 deletions(-) create mode 100644 noti-service/src/main/java/com/waither/notiservice/api/response/MainWeatherResponse.java delete mode 100644 noti-service/src/main/java/com/waither/notiservice/utils/GpsTransfer.java create mode 100644 noti-service/src/main/java/com/waither/notiservice/utils/RestClient.java rename noti-service/src/main/java/com/waither/notiservice/utils/{TemperatureUtils.java => WeatherMessageUtils.java} (57%) diff --git a/noti-service/src/main/java/com/waither/notiservice/api/response/MainWeatherResponse.java b/noti-service/src/main/java/com/waither/notiservice/api/response/MainWeatherResponse.java new file mode 100644 index 00000000..9c6bfc80 --- /dev/null +++ b/noti-service/src/main/java/com/waither/notiservice/api/response/MainWeatherResponse.java @@ -0,0 +1,33 @@ +package com.waither.notiservice.api.response; + +import lombok.Builder; + +import java.util.List; + +@Builder +public record MainWeatherResponse( + + //현재 강수 확률 + String pop, + //현재 온도 + String temp, + //최저 온도 + String tempMin, + //최고 온도 + String tempMax, + //현재 습도 + String humidity, + //풍향 + String windVector, + //풍 + String windDegree, + // 예상 기온 + List expectedTemp, + // 예상 강수량 + List expectedRain, + // 예상 강수 형태 + List expectedPty, + // 예상 하늘 상태 + List expectedSky +) { +} diff --git a/noti-service/src/main/java/com/waither/notiservice/utils/GpsTransfer.java b/noti-service/src/main/java/com/waither/notiservice/utils/GpsTransfer.java deleted file mode 100644 index 60bc4d09..00000000 --- a/noti-service/src/main/java/com/waither/notiservice/utils/GpsTransfer.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.waither.notiservice.utils; - -import com.waither.notiservice.api.request.LocationDto; -import com.waither.notiservice.global.exception.CustomException; -import com.waither.notiservice.global.response.ApiResponse; -import com.waither.notiservice.global.response.ErrorCode; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpStatusCode; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.client.WebClient; -import reactor.core.publisher.Mono; - -@Component -public class GpsTransfer { - - public static String transferToRegion(LocationDto locationDto) { - String WEATHER_SERVICE_URL = "localhost"; - - ParameterizedTypeReference> responseType - = new ParameterizedTypeReference>() {}; - - ApiResponse response = - WebClient.create(WEATHER_SERVICE_URL).get() - .uri(uriBuilder -> uriBuilder - .scheme("http") - .path("/weather/region") - .build()) - .retrieve() - .onStatus(HttpStatusCode::isError, clientResponse -> Mono.error(new CustomException(ErrorCode.INTERNAL_SERVER_ERROR_500))) - .bodyToMono(responseType) - .block(); - return response.getResult(); - } -} diff --git a/noti-service/src/main/java/com/waither/notiservice/utils/RestClient.java b/noti-service/src/main/java/com/waither/notiservice/utils/RestClient.java new file mode 100644 index 00000000..71b1138e --- /dev/null +++ b/noti-service/src/main/java/com/waither/notiservice/utils/RestClient.java @@ -0,0 +1,58 @@ +package com.waither.notiservice.utils; + +import com.waither.notiservice.api.request.LocationDto; +import com.waither.notiservice.api.response.MainWeatherResponse; +import com.waither.notiservice.global.exception.CustomException; +import com.waither.notiservice.global.response.ApiResponse; +import com.waither.notiservice.global.response.ErrorCode; +import lombok.NoArgsConstructor; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpStatusCode; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; + +@NoArgsConstructor +@Component +public class RestClient { + + public static String WEATHER_SERVICE_URL = "localhost"; + + public static String transferToRegion(LocationDto location) { + + ParameterizedTypeReference> responseType + = new ParameterizedTypeReference>() {}; + + ApiResponse response = + WebClient.create(WEATHER_SERVICE_URL).get() + .uri(uriBuilder -> uriBuilder + .scheme("http") + .path("/weather/region") + .queryParam("latitude", location.latitude()) + .queryParam("longitude", location.longitude()) + .port(8081) + .build()) + .retrieve() + .onStatus(HttpStatusCode::isError, clientResponse -> Mono.error(new CustomException(ErrorCode.INTERNAL_SERVER_ERROR_500))) + .bodyToMono(responseType) + .block(); + return response.getResult(); + } + + public static MainWeatherResponse getMainWeather(LocationDto location) { + ParameterizedTypeReference> responseType + = new ParameterizedTypeReference>() {}; + return WebClient.create(WEATHER_SERVICE_URL).get() + .uri(uriBuilder -> uriBuilder + .scheme("http") + .path("/weather/main") + .queryParam("latitude", location.latitude()) + .queryParam("longitude", location.longitude()) + .port(8081) + .build()) + .retrieve() + .onStatus(HttpStatusCode::isError, clientResponse -> Mono.error(new CustomException(ErrorCode.INTERNAL_SERVER_ERROR_500))) + .bodyToMono(responseType) + .block().getResult(); + } +} diff --git a/noti-service/src/main/java/com/waither/notiservice/utils/TemperatureUtils.java b/noti-service/src/main/java/com/waither/notiservice/utils/WeatherMessageUtils.java similarity index 57% rename from noti-service/src/main/java/com/waither/notiservice/utils/TemperatureUtils.java rename to noti-service/src/main/java/com/waither/notiservice/utils/WeatherMessageUtils.java index 78fb97de..3f0d1736 100644 --- a/noti-service/src/main/java/com/waither/notiservice/utils/TemperatureUtils.java +++ b/noti-service/src/main/java/com/waither/notiservice/utils/WeatherMessageUtils.java @@ -7,12 +7,13 @@ import org.springframework.stereotype.Component; import java.time.LocalDateTime; +import java.util.List; import static com.waither.notiservice.enums.Expressions.*; @RequiredArgsConstructor @Component -public class TemperatureUtils { +public class WeatherMessageUtils { public static Expressions[] winterExpressions = {WARM, GOOD, LITTLE_COLD, COLD, VERY_COLD }; public static Expressions[] springAndAutumnExpressions = {HOT, LITTLE_HOT, GOOD, LITTLE_COLD, COLD}; @@ -60,4 +61,58 @@ public static String getExpression(Season season, int level) { return springAndAutumnExpressions[level - 1].getExpression(); } } + + public static String getRainPredictions(List predictions) { + + List predictionStr = predictions.stream() + .map(prediction -> prediction == 0 ? "강수없음" : getRainExpression(prediction)) + .toList(); + //예시 ["강수없음", "약한 비", "약한 비", "비", "비", "비"] + + //몇 시간 뒤에 비가 얼만큼 몇 시간 동안 오는지? + int startHour = -1; + int duration = 0; + String intensity = ""; + boolean isRaining = false; + + for (int i = 0; i < predictionStr.size(); i++) { + String current = predictionStr.get(i); + if (!current.equals("강수없음")) { + if (!isRaining) { + startHour = i + 1; + intensity = current; + } + isRaining = true; + duration++; + } else if (isRaining) { + break; + } + } + + if (startHour == -1) { + return null; + } else { + String timePhrase = startHour == 1 ? "1시간 후부터" : startHour + "시간 후부터"; + String durationPhrase = duration == 1 ? "1시간 동안" : duration + "시간 동안"; + //예시 "3시간 후부터 약한 비가 4시간 동안 올 예정입니다." + return String.format("%s %s가 %s 올 예정입니다.", timePhrase, intensity, durationPhrase); + } + } + + //강수 표현 + public static String getRainExpression(double prediction) { + //1~3mm : 약한 비 + if (prediction > 1 && prediction < 3) { + return "약한 비"; + //3~15mm : 비 + } else if (prediction >=3 && prediction < 15) { + return "비"; + //15~30mm 강한 비 + } else if (prediction >= 15 &&prediction <= 30) { + return "강한 비"; + //30mm~ 매우 강한 비 + } else if (prediction >= 30) { + return "매우 강한 비"; + } else return "비"; + } } From 459a1d7041da0803b6305b491951fb8d51eaff97 Mon Sep 17 00:00:00 2001 From: DDonghyeo Date: Mon, 1 Jul 2024 15:37:28 +0900 Subject: [PATCH 08/13] =?UTF-8?q?=E2=99=BB=EF=B8=8Frefactor=20:=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=EC=A0=84=EC=86=A1=20=EB=A1=9C=EC=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/NotificationService.java | 63 +++++++------------ 1 file changed, 23 insertions(+), 40 deletions(-) diff --git a/noti-service/src/main/java/com/waither/notiservice/service/NotificationService.java b/noti-service/src/main/java/com/waither/notiservice/service/NotificationService.java index 4062b874..b16e8349 100644 --- a/noti-service/src/main/java/com/waither/notiservice/service/NotificationService.java +++ b/noti-service/src/main/java/com/waither/notiservice/service/NotificationService.java @@ -1,5 +1,6 @@ package com.waither.notiservice.service; +import com.waither.notiservice.api.response.MainWeatherResponse; import com.waither.notiservice.api.response.NotificationResponse; import com.waither.notiservice.domain.Notification; import com.waither.notiservice.domain.UserData; @@ -8,22 +9,17 @@ import com.waither.notiservice.domain.redis.NotificationRecord; import com.waither.notiservice.enums.Season; import com.waither.notiservice.global.exception.CustomException; -import com.waither.notiservice.global.response.ApiResponse; import com.waither.notiservice.global.response.ErrorCode; import com.waither.notiservice.repository.jpa.NotificationRepository; import com.waither.notiservice.repository.jpa.UserDataRepository; import com.waither.notiservice.repository.jpa.UserMedianRepository; import com.waither.notiservice.repository.redis.NotificationRecordRepository; -import com.waither.notiservice.utils.GpsTransfer; -import com.waither.notiservice.utils.TemperatureUtils; +import com.waither.notiservice.utils.RestClient; +import com.waither.notiservice.utils.WeatherMessageUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpStatusCode; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.reactive.function.client.WebClient; -import reactor.core.publisher.Mono; import java.time.LocalDateTime; import java.util.List; @@ -38,12 +34,9 @@ public class NotificationService { private final UserMedianRepository userMedianRepository; private final UserDataRepository userDataRepository; private final NotificationRecordRepository notificationRecordRepository; - private final AlarmService alarmService; - - @Transactional(readOnly = true) public List getNotifications(String email) { @@ -64,68 +57,58 @@ public void deleteNotification(String email, String notificationId) { } @Transactional - public String sendGoOutAlarm(String email) { + public String sendGoOutAlarm(String email, LocationDto location) { UserData userData = userDataRepository.findByEmail(email).orElseThrow( () -> new CustomException(ErrorCode.NO_USER_DATA_REGISTERED)); - Season currentSeason = TemperatureUtils.getCurrentSeason(); + Season currentSeason = WeatherMessageUtils.getCurrentSeason(); LocalDateTime now = LocalDateTime.now(); String title = now.getMonth() + "월 " + now.getDayOfMonth() + "일 날씨 정보입니다."; StringBuilder sb = new StringBuilder(); + //메인 날씨 정보 + MainWeatherResponse mainWeather = RestClient.getMainWeather(location); + /** * 1. 기본 메세지 시작 형식 */ - //TODO : 날씨 정보 가져오기 & 날씨별 멘트 정리 String nickName = userData.getNickName(); sb.append(nickName).append("님, 오늘은 "); - /** * 2. 당일 온도 정리 - Weather Service * {@link com.waither.notiservice.enums.Expressions} 참고 */ - double temperature = 10.8; + //현재 온도라고 함 -> 평균 온도 구하기 알아보는 중 + double avgTemp = Double.parseDouble(mainWeather.temp()); if (userData.isUserAlert()) { //사용자 맞춤 알림이 on이라면 -> 계산 후 전용 정보 제공 UserMedian userMedian = userMedianRepository.findByEmailAndSeason(email, currentSeason).orElseThrow( () -> new CustomException(ErrorCode.NO_USER_MEDIAN_REGISTERED)); - sb.append(TemperatureUtils.createUserDataMessage(userMedian, temperature)); + sb.append(WeatherMessageUtils.createUserDataMessage(userMedian, avgTemp, userData.getWeight())); } else { //사용자 맞춤 알림이 off라면 -> 하루 평균 온도 정보 제공 - sb.append("평균 온도가 ").append(temperature).append("도입니다."); + sb.append("평균 온도가 ").append(avgTemp).append("도입니다."); } -// /** -// * 2. 미세먼지 정보 가져오기 - Weather Service -// */ -// //TODO : 미세먼지 On/Off 확인, 멘트 -// finalMessage += " 미세먼지는 없습니다."; - /** * 3. 강수 정보 가져오기 - Weather Service */ - //TODO : 강수량 확인, 멘트 - sb.append(" 오후 6시부터 8시까지 120mm의 비가 올 예정입니다."); - - /** - * 4. 꽃가루 정보 가져오기 - Weather Service - */ - //TODO : 꽃가루 확인 - sb.append(" 꽃가루는 없습니다. ") ; - - /** - * 알림 전송 - */ - //TODO : FireBase 알림 보내기 - log.info("[ Notification Service ] Final Message ---> {}", sb.toString()); + List predictions = mainWeather.expectedRain().stream() + .map(String::trim) //공백 제거 + .map(s -> s.equals("강수없음") ? "0" : s) + .map(Double::parseDouble) + .toList(); + String rainPredictionMessage = WeatherMessageUtils.getRainPredictions(predictions); + sb.append(rainPredictionMessage); //알림 보내기 + log.info("[ Notification Service ] Final Message ---> {}", sb.toString()); alarmService.sendSingleAlarm(email, title, sb.toString()); return sb.toString(); } @@ -135,12 +118,12 @@ public String sendGoOutAlarm(String email) { public void updateLocation(String email, LocationDto locationDto) { log.info("[ Notification Service ] email ---> {}", email); - log.info("[ Notification Service ] 현재 위치 위도 (lat) ---> {}", locationDto.lat()); - log.info("[ Notification Service ] 현재 위치 경도 (lon) ---> {}", locationDto.lon()); + log.info("[ Notification Service ] 현재 위치 위도 (latitude) ---> {}", locationDto.latitude()); + log.info("[ Notification Service ] 현재 위치 경도 (longitude) ---> {}", locationDto.longitude()); Optional notiRecord = notificationRecordRepository.findByEmail(email); - String region = GpsTransfer.transferToRegion(locationDto); + String region = RestClient.transferToRegion(locationDto); if (notiRecord.isPresent()) { NotificationRecord notificationRecord = notiRecord.get(); From 0f04b64afe8e5f5455cdfffb4f5e3c103efd91c0 Mon Sep 17 00:00:00 2001 From: DDonghyeo Date: Mon, 1 Jul 2024 15:43:22 +0900 Subject: [PATCH 09/13] =?UTF-8?q?=E2=99=BB=EF=B8=8Frefactor=20:=20Consumer?= =?UTF-8?q?=20Util=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notiservice/service/KafkaConsumer.java | 72 +++---------------- 1 file changed, 10 insertions(+), 62 deletions(-) diff --git a/noti-service/src/main/java/com/waither/notiservice/service/KafkaConsumer.java b/noti-service/src/main/java/com/waither/notiservice/service/KafkaConsumer.java index 4ddfb837..7ab790aa 100644 --- a/noti-service/src/main/java/com/waither/notiservice/service/KafkaConsumer.java +++ b/noti-service/src/main/java/com/waither/notiservice/service/KafkaConsumer.java @@ -9,7 +9,7 @@ import com.waither.notiservice.repository.jpa.UserMedianRepository; import com.waither.notiservice.repository.redis.NotificationRecordRepository; import com.waither.notiservice.utils.RedisUtils; -import com.waither.notiservice.utils.TemperatureUtils; +import com.waither.notiservice.utils.WeatherMessageUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.kafka.annotation.KafkaListener; @@ -20,7 +20,6 @@ import java.util.Arrays; import java.util.List; import java.util.Optional; -import java.util.StringTokenizer; @Slf4j @RequiredArgsConstructor @@ -40,7 +39,7 @@ public class KafkaConsumer { @KafkaListener(topics = "${spring.kafka.template.user-median-topic}", containerFactory = "userMedianKafkaListenerContainerFactory") public void consumeUserMedian(KafkaDto.UserMedianDto userMedianDto) { - Season currentSeason = TemperatureUtils.getCurrentSeason(); + Season currentSeason = WeatherMessageUtils.getCurrentSeason(); log.info("[ Kafka Listener ] 사용자 중앙값 데이터 동기화"); log.info("[ Kafka Listener ] Season : -- {} ", currentSeason.name()); log.info("[ Kafka Listener ] Email : --> {}", userMedianDto.email()); @@ -173,8 +172,15 @@ public void consumeRain(KafkaDto.WeatherDto weatherDto) { //지역 String region = weatherDto.region(); log.info("[ Kafka Listener ] 강수량 지역 --> {}", region); + String message = weatherDto.message(); - String rainMessage = getRainPredictions(weatherDto.message()); + //1시간 뒤, 2시간 뒤, 3시간 뒤, 4시간 뒤, 5시간 뒤, 6시간 뒤 + List predictions = Arrays.stream(message.split(",")) + .map(String::trim) //공백 제거 + .map(s -> s.equals("강수없음") ? "0" : s) + .map(Double::parseDouble) + .toList(); + String rainMessage = WeatherMessageUtils.getRainPredictions(predictions); if (rainMessage == null) { //6시간 동안 강수 정보 없음 @@ -269,64 +275,6 @@ private List filterRegion(String region, List userData) { .toList(); } - private String getRainPredictions(String message) { - //1시간 뒤, 2시간 뒤, 3시간 뒤, 4시간 뒤, 5시간 뒤, 6시간 뒤 - List predictions = Arrays.stream(message.split(",")) - .map(String::trim) //공백 제거 - .map(s -> s.equals("강수없음") ? "0" : s) - .map(Double::parseDouble) - .toList(); - - List predictionStr = predictions.stream() - .map(prediction -> prediction == 0 ? "강수없음" : getRainExpression(prediction)) - .toList(); - //예시 ["강수없음", "약한 비", "약한 비", "비", "비", "비"] - - //몇 시간 뒤에 비가 얼만큼 몇 시간 동안 오는지? - int startHour = -1; - int duration = 0; - String intensity = ""; - boolean isRaining = false; - - for (int i = 0; i < predictionStr.size(); i++) { - String current = predictionStr.get(i); - if (!current.equals("강수없음")) { - if (!isRaining) { - startHour = i + 1; - intensity = current; - } - isRaining = true; - duration++; - } else if (isRaining) { - break; - } - } - - if (startHour == -1) { - return null; - } else { - String timePhrase = startHour == 1 ? "1시간 후부터" : startHour + "시간 후부터"; - String durationPhrase = duration == 1 ? "1시간 동안" : duration + "시간 동안"; - //예시 "3시간 후부터 약한 비가 4시간 동안 올 예정입니다." - return String.format("%s %s가 %s 올 예정입니다.", timePhrase, intensity, durationPhrase); - } - } - //강수 표현 - private String getRainExpression(double prediction) { - //1~3mm : 약한 비 - if (prediction > 1 && prediction < 3) { - return "약한 비"; - //3~15mm : 비 - } else if (prediction >=3 && prediction < 15) { - return "비"; - //15~30mm 강한 비 - } else if (prediction >= 15 &&prediction <= 30) { - return "강한 비"; - //30mm~ 매우 강한 비 - } else if (prediction >= 30) { - return "매우 강한 비"; - } else return "비"; - } } From 249363489f9d830b73dd101db22a066752c4b6b5 Mon Sep 17 00:00:00 2001 From: DDonghyeo Date: Mon, 1 Jul 2024 15:43:33 +0900 Subject: [PATCH 10/13] =?UTF-8?q?=E2=99=BB=EF=B8=8Frefactor=20:=20Location?= =?UTF-8?q?Dto=20Builder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/waither/notiservice/api/request/LocationDto.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/noti-service/src/main/java/com/waither/notiservice/api/request/LocationDto.java b/noti-service/src/main/java/com/waither/notiservice/api/request/LocationDto.java index c76526d1..a59a2f82 100644 --- a/noti-service/src/main/java/com/waither/notiservice/api/request/LocationDto.java +++ b/noti-service/src/main/java/com/waither/notiservice/api/request/LocationDto.java @@ -3,7 +3,9 @@ import jakarta.validation.constraints.DecimalMax; import jakarta.validation.constraints.DecimalMin; import jakarta.validation.constraints.NotBlank; +import lombok.Builder; +@Builder public record LocationDto ( @NotBlank(message = " 위도(latitude) 값은 필수입니다.") @DecimalMax(value = "43.0", inclusive = true, message = "대한민국 내에서만 가능합니다. (33~43)") From c467db525e325b874b417fb6c43a3c0086008157 Mon Sep 17 00:00:00 2001 From: DDonghyeo Date: Mon, 1 Jul 2024 15:44:03 +0900 Subject: [PATCH 11/13] =?UTF-8?q?=E2=99=BB=EF=B8=8Frefactor=20:=20?= =?UTF-8?q?=EC=99=B8=EC=B6=9C=20=EC=95=8C=EB=A6=BC=20=EC=A0=84=EC=86=A1=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/waither/notiservice/api/NotificationController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/noti-service/src/main/java/com/waither/notiservice/api/NotificationController.java b/noti-service/src/main/java/com/waither/notiservice/api/NotificationController.java index cb343d52..7524a629 100644 --- a/noti-service/src/main/java/com/waither/notiservice/api/NotificationController.java +++ b/noti-service/src/main/java/com/waither/notiservice/api/NotificationController.java @@ -33,8 +33,8 @@ public ApiResponse deleteNotification(@AuthUser String email, @RequestParam(" @Operation(summary = "Send Go Out Alarm", description = "외출 알림 전송하기") @PostMapping("/goOut") - public ApiResponse sendGoOutAlarm(@AuthUser String email) { - notificationService.sendGoOutAlarm(email); + public ApiResponse sendGoOutAlarm(@AuthUser String email, @RequestBody @Valid LocationDto location) { + notificationService.sendGoOutAlarm(email, location); return ApiResponse.onSuccess(HttpStatus.OK); } From 6ee953b9d23fd23b68ae84ab0f6ea0a7cf00d122 Mon Sep 17 00:00:00 2001 From: DDonghyeo Date: Mon, 1 Jul 2024 16:04:36 +0900 Subject: [PATCH 12/13] =?UTF-8?q?=E2=99=BB=EF=B8=8Frefactor=20:=20Firebase?= =?UTF-8?q?=20=EC=9E=84=EC=8B=9C=20=EB=B9=84=ED=99=9C=EC=84=B1=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notiservice/config/FirebaseConfig.java | 64 +++++++++---------- .../notiservice/service/AlarmService.java | 4 +- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/noti-service/src/main/java/com/waither/notiservice/config/FirebaseConfig.java b/noti-service/src/main/java/com/waither/notiservice/config/FirebaseConfig.java index 5055a2bf..8907a8bf 100644 --- a/noti-service/src/main/java/com/waither/notiservice/config/FirebaseConfig.java +++ b/noti-service/src/main/java/com/waither/notiservice/config/FirebaseConfig.java @@ -1,32 +1,32 @@ -package com.waither.notiservice.config; - -import com.google.auth.oauth2.GoogleCredentials; -import com.google.firebase.FirebaseApp; -import com.google.firebase.FirebaseOptions; -import jakarta.annotation.PostConstruct; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; - -import java.io.FileInputStream; -import java.io.IOException; - -@Configuration -@RequiredArgsConstructor -public class FirebaseConfig { - - @Value("${firebase.key.path}") - private String keyPath; - - @PostConstruct - public void initializeApp() throws IOException { - FileInputStream serviceAccount = - new FileInputStream(keyPath); - - FirebaseOptions options = FirebaseOptions.builder() - .setCredentials(GoogleCredentials.fromStream(serviceAccount)) - .build(); - - FirebaseApp.initializeApp(options); - } -} +//package com.waither.notiservice.config; +// +//import com.google.auth.oauth2.GoogleCredentials; +//import com.google.firebase.FirebaseApp; +//import com.google.firebase.FirebaseOptions; +//import jakarta.annotation.PostConstruct; +//import lombok.RequiredArgsConstructor; +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.context.annotation.Configuration; +// +//import java.io.FileInputStream; +//import java.io.IOException; +// +//@Configuration +//@RequiredArgsConstructor +//public class FirebaseConfig { +// +// @Value("${firebase.key.path}") +// private String keyPath; +// +// @PostConstruct +// public void initializeApp() throws IOException { +// FileInputStream serviceAccount = +// new FileInputStream(keyPath); +// +// FirebaseOptions options = FirebaseOptions.builder() +// .setCredentials(GoogleCredentials.fromStream(serviceAccount)) +// .build(); +// +// FirebaseApp.initializeApp(options); +// } +//} diff --git a/noti-service/src/main/java/com/waither/notiservice/service/AlarmService.java b/noti-service/src/main/java/com/waither/notiservice/service/AlarmService.java index 8797476a..819b5246 100644 --- a/noti-service/src/main/java/com/waither/notiservice/service/AlarmService.java +++ b/noti-service/src/main/java/com/waither/notiservice/service/AlarmService.java @@ -28,7 +28,7 @@ public void updateToken(String email, TokenDto tokenDto) { public void sendSingleAlarm(String email, String title, String message) { String token = String.valueOf(redisUtils.get(email)); - fireBaseUtils.sendSingleMessage(token, title, message); +// fireBaseUtils.sendSingleMessage(token, title, message); notificationRepository.save(Notification.builder() .email(email) .title(title) @@ -44,7 +44,7 @@ public void sendAlarms(List userEmails, String title, String message) { log.info("[ 푸시알림 ] Email ---> {}", userEmails); log.info("[ 푸시알림 ] message ---> {}", message); - fireBaseUtils.sendAllMessages(tokens,title, message); +// fireBaseUtils.sendAllMessages(tokens,title, message); List notifications = userEmails.stream() .map(email -> Notification.builder() From 97efcd393a9954c3ae669799d2f340f7c33e7dd1 Mon Sep 17 00:00:00 2001 From: DDonghyeo Date: Mon, 1 Jul 2024 16:08:03 +0900 Subject: [PATCH 13/13] =?UTF-8?q?=E2=99=BB=EF=B8=8Frefactor=20:=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BC=80=EC=9D=B4=EC=8A=A4=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/KafkaConsumerTest.java | 5 ++-- .../service/NotificationServiceTest.java | 6 ++--- .../notiservice/utils/RestClientTest.java | 25 +++++++++++++++++++ 3 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 noti-service/src/test/java/com/waither/notiservice/utils/RestClientTest.java diff --git a/noti-service/src/test/java/com/waither/notiservice/service/KafkaConsumerTest.java b/noti-service/src/test/java/com/waither/notiservice/service/KafkaConsumerTest.java index f6bd0023..56fe0439 100644 --- a/noti-service/src/test/java/com/waither/notiservice/service/KafkaConsumerTest.java +++ b/noti-service/src/test/java/com/waither/notiservice/service/KafkaConsumerTest.java @@ -7,7 +7,7 @@ import com.waither.notiservice.repository.jpa.UserDataRepository; import com.waither.notiservice.repository.jpa.UserMedianRepository; import com.waither.notiservice.utils.RedisUtils; -import com.waither.notiservice.utils.TemperatureUtils; +import com.waither.notiservice.utils.WeatherMessageUtils; import org.apache.kafka.clients.producer.ProducerConfig; import org.apache.kafka.common.serialization.StringSerializer; import org.junit.jupiter.api.*; @@ -24,7 +24,6 @@ import org.springframework.transaction.annotation.Transactional; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.CompletableFuture; @@ -76,7 +75,7 @@ void userMedianTest() throws InterruptedException { //Given ProducerFactory pf = new DefaultKafkaProducerFactory<>(jsonProps); KafkaTemplate template = new KafkaTemplate<>(pf); - Season currentSeason = TemperatureUtils.getCurrentSeason(); + Season currentSeason = WeatherMessageUtils.getCurrentSeason(); String tempEmail = "kafkaTest@gmail.com"; //when diff --git a/noti-service/src/test/java/com/waither/notiservice/service/NotificationServiceTest.java b/noti-service/src/test/java/com/waither/notiservice/service/NotificationServiceTest.java index 58ddbd2a..df9335f2 100644 --- a/noti-service/src/test/java/com/waither/notiservice/service/NotificationServiceTest.java +++ b/noti-service/src/test/java/com/waither/notiservice/service/NotificationServiceTest.java @@ -10,7 +10,7 @@ import com.waither.notiservice.repository.jpa.UserDataRepository; import com.waither.notiservice.repository.jpa.UserMedianRepository; import com.waither.notiservice.repository.redis.NotificationRecordRepository; -import com.waither.notiservice.utils.TemperatureUtils; +import com.waither.notiservice.utils.WeatherMessageUtils; import org.junit.jupiter.api.*; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mockito; @@ -60,7 +60,7 @@ void goOutAlarm() { System.out.println("DB Mock 데이터 생성.. userid : 0"); String tempEmail = "serviceTest@gmail.com"; - Season currentSeason = TemperatureUtils.getCurrentSeason(); + Season currentSeason = WeatherMessageUtils.getCurrentSeason(); LocationDto locationDto = new LocationDto(33, 134); UserData newUser = UserData.builder() @@ -81,7 +81,7 @@ void goOutAlarm() { .medianOf2And3(15.0) .medianOf3And4(20.0) .medianOf4And5(25.0) - .season(TemperatureUtils.getCurrentSeason()) //현재 계절로 저장 + .season(WeatherMessageUtils.getCurrentSeason()) //현재 계절로 저장 .build(); Mockito.when(userMedianRepository.findByEmailAndSeason(tempEmail, currentSeason)).thenReturn(Optional.of(newUserMedian)); // (Mock) find시 Return diff --git a/noti-service/src/test/java/com/waither/notiservice/utils/RestClientTest.java b/noti-service/src/test/java/com/waither/notiservice/utils/RestClientTest.java new file mode 100644 index 00000000..15338d64 --- /dev/null +++ b/noti-service/src/test/java/com/waither/notiservice/utils/RestClientTest.java @@ -0,0 +1,25 @@ +package com.waither.notiservice.utils; + +import com.waither.notiservice.api.request.LocationDto; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.FactoryBasedNavigableListAssert.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +class RestClientTest { + + @Test + void transferToRegion() { + + LocationDto location = LocationDto.builder() + .longitude(36) + .latitude(127) + .build(); + + String region = RestClient.transferToRegion(location); + + assert(region).equals("서울특별시"); + } +} \ No newline at end of file