diff --git a/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/configuration/H2ConsoleConfiguration.java b/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/configuration/H2ConsoleConfiguration.java index 993d7f8..3fd4bd3 100644 --- a/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/configuration/H2ConsoleConfiguration.java +++ b/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/configuration/H2ConsoleConfiguration.java @@ -11,7 +11,7 @@ import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.EventListener; @Slf4j -@Profile("datasource-development") +@Profile({"datasource-local", "datasource-development"}) @Configuration public class H2ConsoleConfiguration { diff --git a/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/controller/CrawlAPIController.java b/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/controller/CrawlAPIController.java index 1e72f78..c520aad 100644 --- a/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/controller/CrawlAPIController.java +++ b/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/controller/CrawlAPIController.java @@ -48,8 +48,8 @@ public class CrawlAPIController { Mono> articles = ppomppuRSSFeedService.getArticles(boardName) .doOnNext(e -> ppomppuArticleService.filterOnlyNewArticles(boardName, e)) - .doOnNext(e -> ppomppuArticleService.save(boardName, e)) - .doOnNext(messageSenderService::sendMessageToSlack); + .doOnNext(e -> messageSenderService.sendMessageToSlack(e)) + .doOnNext(e -> ppomppuArticleService.save(boardName, e)); return articles.then(Mono.just(APIResponse.success(result.done()))); } diff --git a/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/infrastructure/client/MessageSenderAPIClient.java b/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/infrastructure/client/MessageSenderAPIClient.java index 1fd80ae..5110c3e 100644 --- a/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/infrastructure/client/MessageSenderAPIClient.java +++ b/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/infrastructure/client/MessageSenderAPIClient.java @@ -1,24 +1,26 @@ package com.myoa.engineering.crawl.ppomppu.processor.infrastructure.client; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.client.WebClient; -import org.springframework.web.reactive.function.client.WebClientRequestException; - import com.myoa.engineering.crawl.ppomppu.processor.dto.constant.WebClientPropertiesUnitName; import com.myoa.engineering.crawl.ppomppu.support.dto.SimpleMessageDTO; import com.myoa.engineering.crawl.ppomppu.support.webclient.factory.WebClientFilterFactory; +import com.myoa.engineering.crawl.ppomppu.support.webclient.factory.WebFluxExchangeStragiesFactory; import com.myoa.engineering.crawl.ppomppu.support.webclient.properties.WebClientProperties; import com.myoa.engineering.crawl.ppomppu.support.webclient.properties.WebClientProperties.WebClientPropertiesUnit; - import lombok.extern.slf4j.Slf4j; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.reactive.function.client.WebClientRequestException; import reactor.core.publisher.Mono; import reactor.core.scheduler.Schedulers; /** * PpomppuNotifierSenderAPIClient + * * @author Shin Woo-jin (woo-jin.shin@linecorp.com) * @since 2021-11-17 - * */ @Slf4j @Component @@ -31,6 +33,8 @@ public class MessageSenderAPIClient { webClientProperties.find(WebClientPropertiesUnitName.PPOMPPU_NOTIFIER_SENDER_API.getUnitName()); this.webClient = WebClient.builder() .baseUrl(webClientPropertiesUnit.getBaseUrl()) + .exchangeStrategies(WebFluxExchangeStragiesFactory.ofDefault()) + .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .filter(WebClientFilterFactory.logRequest()) .filter(WebClientFilterFactory.logResponse()) .build(); @@ -40,11 +44,12 @@ public class MessageSenderAPIClient { return webClient.post() .uri("/api/v1/messages/sendMessage/messengers/slack") .bodyValue(dto) - .exchangeToMono(e -> e.bodyToMono(String.class)) + .exchangeToMono(e -> e.bodyToMono(new ParameterizedTypeReference() {})) .publishOn(Schedulers.boundedElastic()) .onErrorResume(WebClientRequestException.class, t -> { log.info("Exception occured, ignoring. : {}", t.getClass().getSimpleName()); return Mono.empty(); - }); + }) + .doOnNext(e -> log.info("response: {} ", e)); } } \ No newline at end of file diff --git a/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/service/MessageSenderService.java b/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/service/MessageSenderService.java index 60f1d0d..2a6d0ac 100644 --- a/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/service/MessageSenderService.java +++ b/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/service/MessageSenderService.java @@ -9,6 +9,7 @@ import com.myoa.engineering.crawl.ppomppu.processor.dto.PpomppuArticleTransforme import com.myoa.engineering.crawl.ppomppu.processor.infrastructure.client.MessageSenderAPIClient; import lombok.extern.slf4j.Slf4j; +import reactor.core.publisher.Mono; /** * MessageSenderService @@ -26,12 +27,12 @@ public class MessageSenderService { this.messageSenderAPIClient = messageSenderAPIClient; } - public void sendMessageToSlack(PpomppuArticle article) { - messageSenderAPIClient.sendMessageToSlack(PpomppuArticleTransformer.TRANSFORM_TO_MESSAGE_DTO.apply(article)); + public Mono sendMessageToSlack(PpomppuArticle article) { + return messageSenderAPIClient.sendMessageToSlack(PpomppuArticleTransformer.TRANSFORM_TO_MESSAGE_DTO.apply(article)); } - public void sendMessageToSlack(List articles) { - messageSenderAPIClient.sendMessageToSlack(PpomppuArticleTransformer.transform(articles)); + public Mono sendMessageToSlack(List articles) { + return messageSenderAPIClient.sendMessageToSlack(PpomppuArticleTransformer.transform(articles)); } } diff --git a/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/service/PpomppuArticleService.java b/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/service/PpomppuArticleService.java index 632e3c3..e810c56 100644 --- a/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/service/PpomppuArticleService.java +++ b/processor/src/main/java/com/myoa/engineering/crawl/ppomppu/processor/service/PpomppuArticleService.java @@ -38,7 +38,7 @@ public class PpomppuArticleService { } @Transactional - public void save(PpomppuBoardName boardName, List articles) { + public List save(PpomppuBoardName boardName, List articles) { Long latestArticleId = articles.stream() .map(PpomppuArticle::getArticleId) .max(Long::compareTo) @@ -54,6 +54,6 @@ public class PpomppuArticleService { latestArticleId))); // save real articles. - ppomppuArticleRepository.saveAll(articles); + return ppomppuArticleRepository.saveAll(articles); } } diff --git a/processor/src/main/resources/application-local.yml b/processor/src/main/resources/application-local.yml new file mode 100644 index 0000000..c2198e0 --- /dev/null +++ b/processor/src/main/resources/application-local.yml @@ -0,0 +1,12 @@ +spring: + config: + activate: + on-profile: local + import: + - "configserver:http://localhost:20085" + - classpath:/local/webclient.yml + +server: + port: 20081 + + # import: optional:configserver:http://localhost:11080 # can be start up even config server was not found. \ No newline at end of file diff --git a/processor/src/main/resources/application.yml b/processor/src/main/resources/application.yml index 0cc3fd9..d136cf7 100644 --- a/processor/src/main/resources/application.yml +++ b/processor/src/main/resources/application.yml @@ -4,8 +4,9 @@ spring: main: allow-bean-definition-overriding: true profiles: - active: ${SPRING_ACTIVE_PROFILE:development} + active: ${SPRING_ACTIVE_PROFILE:local} group: + local: "local,datasource-local" development: "development,datasource-development" production: "production, datasource-production" freemarker: diff --git a/processor/src/main/resources/development/webclient.yml b/processor/src/main/resources/development/webclient.yml index d600658..06ec4a9 100644 --- a/processor/src/main/resources/development/webclient.yml +++ b/processor/src/main/resources/development/webclient.yml @@ -2,4 +2,4 @@ webclient: init: true units: - unit-name: ppn-sender-api - base-url: http://localhost:20081 \ No newline at end of file + base-url: http://localhost:20082 \ No newline at end of file diff --git a/processor/src/main/resources/local/webclient.yml b/processor/src/main/resources/local/webclient.yml new file mode 100644 index 0000000..06ec4a9 --- /dev/null +++ b/processor/src/main/resources/local/webclient.yml @@ -0,0 +1,5 @@ +webclient: + init: true + units: + - unit-name: ppn-sender-api + base-url: http://localhost:20082 \ No newline at end of file diff --git a/processor/src/main/resources/logback-spring.xml b/processor/src/main/resources/logback-spring.xml index f0fcb6c..907a4f5 100644 --- a/processor/src/main/resources/logback-spring.xml +++ b/processor/src/main/resources/logback-spring.xml @@ -1,6 +1,10 @@ + + + + diff --git a/processor/src/main/resources/production/webclient.yml b/processor/src/main/resources/production/webclient.yml index 862c2b9..373ba18 100644 --- a/processor/src/main/resources/production/webclient.yml +++ b/processor/src/main/resources/production/webclient.yml @@ -2,4 +2,4 @@ webclient: init: true units: - unit-name: ppn-sender-api - base-url: http://ppn_sender:20081 \ No newline at end of file + base-url: http://ppn_sender:20082 \ No newline at end of file diff --git a/receiver/src/main/resources/application-local.yml b/receiver/src/main/resources/application-local.yml new file mode 100644 index 0000000..297ac57 --- /dev/null +++ b/receiver/src/main/resources/application-local.yml @@ -0,0 +1,7 @@ +spring: + config: + activate: + on-profile: local + import: + - classpath:/local/webclient.yml + - "configserver:http://localhost:20085" \ No newline at end of file diff --git a/receiver/src/main/resources/application.yml b/receiver/src/main/resources/application.yml index 61ebab9..a89a769 100644 --- a/receiver/src/main/resources/application.yml +++ b/receiver/src/main/resources/application.yml @@ -4,7 +4,7 @@ spring: main: allow-bean-definition-overriding: true profiles: - active: ${SPRING_ACTIVE_PROFILE:development} + active: ${SPRING_ACTIVE_PROFILE:local} freemarker: enabled: false diff --git a/receiver/src/main/resources/local/webclient.yml b/receiver/src/main/resources/local/webclient.yml new file mode 100644 index 0000000..9fbfe3a --- /dev/null +++ b/receiver/src/main/resources/local/webclient.yml @@ -0,0 +1,5 @@ +webclient: + init: true + units: + - unit-name: ppn-processor-api + base-url: http://localhost:20081 \ No newline at end of file diff --git a/receiver/src/main/resources/logback-spring.xml b/receiver/src/main/resources/logback-spring.xml index f0fcb6c..907a4f5 100644 --- a/receiver/src/main/resources/logback-spring.xml +++ b/receiver/src/main/resources/logback-spring.xml @@ -1,6 +1,10 @@ + + + + diff --git a/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/configuration/properties/SlackSecretProperties.java b/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/configuration/properties/SlackSecretProperties.java new file mode 100644 index 0000000..d47983c --- /dev/null +++ b/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/configuration/properties/SlackSecretProperties.java @@ -0,0 +1,34 @@ +package com.myoa.engineering.crawl.ppomppu.sender.configuration.properties; + +import java.util.List; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Getter +@Setter +@Component +@ConfigurationProperties("infra.slack.bot") +public class SlackSecretProperties { + + private List units; + + @Data + public static class SlackSecretPropertiesUnit { + + private String botName; + private String username; + private String iconEmoji; + private String channel; + private String token; + } + + public SlackSecretPropertiesUnit find(String botUnitName) { + return units.stream() + .filter(e -> e.getBotName().equals(botUnitName)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("not found bot unit name : " + botUnitName)); + } +} diff --git a/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/controller/MessageSenderAPIController.java b/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/controller/MessageSenderAPIController.java index a049fe1..373e5bf 100644 --- a/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/controller/MessageSenderAPIController.java +++ b/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/controller/MessageSenderAPIController.java @@ -1,13 +1,12 @@ package com.myoa.engineering.crawl.ppomppu.sender.controller; +import com.myoa.engineering.crawl.ppomppu.sender.infrastructure.client.MongeShoppingBotSlackMessageSender; +import com.myoa.engineering.crawl.ppomppu.support.dto.APIResponse; +import com.myoa.engineering.crawl.ppomppu.support.dto.SimpleMessageDTO; +import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; - -import com.myoa.engineering.crawl.ppomppu.support.dto.APIResponse; -import com.myoa.engineering.crawl.ppomppu.support.dto.SimpleMessageDTO; - -import lombok.extern.slf4j.Slf4j; import reactor.core.publisher.Mono; /** @@ -21,11 +20,17 @@ import reactor.core.publisher.Mono; @RequestMapping("/api/v1") public class MessageSenderAPIController { + private final MongeShoppingBotSlackMessageSender sender; + + public MessageSenderAPIController(MongeShoppingBotSlackMessageSender sender) { + this.sender = sender; + } + @PostMapping("/messages/sendMessage/messengers/slack") public Mono> sendMessageToSlack(SimpleMessageDTO dto) { log.info("received : {}, \nbody: {}", dto.getTitle(), dto.getBody()); - // TODO transform - return Mono.just(APIResponse.success(dto)); + return sender.sendMessage(sender.ofMessage(dto.getBody())) + .then(Mono.just(APIResponse.success(dto))); } } diff --git a/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/controller/TestAPIController.java b/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/controller/TestAPIController.java index fad3683..96fcc55 100644 --- a/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/controller/TestAPIController.java +++ b/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/controller/TestAPIController.java @@ -1,37 +1,29 @@ package com.myoa.engineering.crawl.ppomppu.sender.controller; +import com.myoa.engineering.crawl.ppomppu.sender.infrastructure.client.MongeShoppingBotSlackMessageSender; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; - -import com.myoa.engineering.crawl.ppomppu.sender.dto.SlackMessageDTO; -import com.myoa.engineering.crawl.ppomppu.sender.infrastructure.client.SlackMessageSender; - import reactor.core.publisher.Mono; /** * TestAPIController + * * @author Shin Woo-jin (woo-jin.shin@linecorp.com) * @since 2021-11-15 - * */ @RestController @RequestMapping("/api/v1") public class TestAPIController { - private final SlackMessageSender sender; + private final MongeShoppingBotSlackMessageSender sender; - public TestAPIController() { - this.sender = new SlackMessageSender("xoxb-2688454277126-2695026012277-K2Ib13lKokmTiBSnSMrc0Bp2"); + public TestAPIController(MongeShoppingBotSlackMessageSender sender) { + this.sender = sender; } @GetMapping("/test") public Mono test() { - return sender.sendMessage(SlackMessageDTO.builder() - .text("test!") - .iconEmoji("monge") - .channel("notify_shopping") - .username("shopping notifier") - .build()); + return sender.sendMessage(sender.ofMessage("testtesttest!!!")); } } diff --git a/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/dto/SlackMessageDTO.java b/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/dto/SlackMessageDTO.java index c02cb71..faf7ef5 100644 --- a/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/dto/SlackMessageDTO.java +++ b/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/dto/SlackMessageDTO.java @@ -33,4 +33,7 @@ public class SlackMessageDTO implements MessageDTO { this.iconEmoji = iconEmoji; } + public void applyText(String text) { + this.text = text; + } } diff --git a/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/infrastructure/client/MongeShoppingBotSlackMessageSender.java b/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/infrastructure/client/MongeShoppingBotSlackMessageSender.java new file mode 100644 index 0000000..8ab5b00 --- /dev/null +++ b/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/infrastructure/client/MongeShoppingBotSlackMessageSender.java @@ -0,0 +1,39 @@ +package com.myoa.engineering.crawl.ppomppu.sender.infrastructure.client; + +import com.myoa.engineering.crawl.ppomppu.sender.configuration.properties.SlackSecretProperties; +import com.myoa.engineering.crawl.ppomppu.sender.configuration.properties.SlackSecretProperties.SlackSecretPropertiesUnit; +import com.myoa.engineering.crawl.ppomppu.sender.dto.SlackMessageDTO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class MongeShoppingBotSlackMessageSender extends SlackMessageSender { + + private static final String SLACK_SECRET_UNIT_NAME = "monge_shopping_bot"; + + private final SlackSecretPropertiesUnit slackProperties; +// private final SlackMessageSender slackMessageSender; + + public MongeShoppingBotSlackMessageSender(SlackSecretProperties slackSecretProperties) { + super(slackSecretProperties.find(SLACK_SECRET_UNIT_NAME).getToken()); + this.slackProperties = slackSecretProperties.find(SLACK_SECRET_UNIT_NAME); + } + + public SlackMessageDTO ofMessageTemplate() { + return SlackMessageDTO.builder() + .channel(slackProperties.getChannel()) + .iconEmoji(slackProperties.getIconEmoji()) + .username(slackProperties.getUsername()) + .build(); + } + + public SlackMessageDTO ofMessage(String text) { + return SlackMessageDTO.builder() + .channel(slackProperties.getChannel()) + .iconEmoji(slackProperties.getIconEmoji()) + .username(slackProperties.getUsername()) + .text(text) + .build(); + } +} diff --git a/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/infrastructure/client/SlackMessageSender.java b/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/infrastructure/client/SlackMessageSender.java index 1eef297..5f349bd 100644 --- a/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/infrastructure/client/SlackMessageSender.java +++ b/sender/src/main/java/com/myoa/engineering/crawl/ppomppu/sender/infrastructure/client/SlackMessageSender.java @@ -53,34 +53,3 @@ public class SlackMessageSender implements MessageSender { } } - -/* -import requests -import json - -# woozuyeni_watchtower -SLACK_TOKEN="xoxb-2688454277126-2695026012277-K2Ib13lKokmTiBSnSMrc0Bp2" -CHANNEL = "notify_watchtower" -CHANNEL = "common" - - -POST_API = "https://slack.com/api/chat.postMessage" -HEADER = "Authorization: Bearer" - -headers = { - "Content-Type" : "application/json", - "Authorization" : f"Bearer {SLACK_TOKEN}" -} - -data = {} -data["text"] = "몽몽! :monge_big:" -data["channel"] = CHANNEL -data["username"] = "몽이봇" -data["icon_emoji"] = ":monge_big:" - -# requests.post(POST_API, data=json.dumps(data), headers=headers) - - -attachments = [{"title": "Cat", "image_url": image_url}] -image_url = "https://myoa-universe.com/assets/love1.png" - */ \ No newline at end of file diff --git a/sender/src/main/resources/application-local.yml b/sender/src/main/resources/application-local.yml new file mode 100644 index 0000000..5c6bfbb --- /dev/null +++ b/sender/src/main/resources/application-local.yml @@ -0,0 +1,10 @@ +spring: + config: + activate: + on-profile: local + import: + - "configserver:http://localhost:20085" + # import: optional:configserver:http://localhost:11080 # can be start up even config server was not found. + +server: + port: 20082 diff --git a/sender/src/main/resources/application.yml b/sender/src/main/resources/application.yml index ee15561..670365b 100644 --- a/sender/src/main/resources/application.yml +++ b/sender/src/main/resources/application.yml @@ -4,8 +4,9 @@ spring: main: allow-bean-definition-overriding: true profiles: - active: ${SPRING_ACTIVE_PROFILE:development} + active: ${SPRING_ACTIVE_PROFILE:local} group: + local: local, slackapi-local development: development, slackapi-development production: production, slackapi-production freemarker: diff --git a/sender/src/main/resources/logback-spring.xml b/sender/src/main/resources/logback-spring.xml index f0fcb6c..32276f3 100644 --- a/sender/src/main/resources/logback-spring.xml +++ b/sender/src/main/resources/logback-spring.xml @@ -1,5 +1,9 @@ + + + +