Merge feature/receiver-develop #1

Merged
nthfuncx merged 2 commits from feature/receiver-develop into develop 2021-09-06 13:41:56 +00:00
28 changed files with 399 additions and 117 deletions

2
.gitignore vendored
View File

@ -35,3 +35,5 @@ out/
### VS Code ### ### VS Code ###
.vscode/ .vscode/
temppassword.yml

0
gradlew vendored Executable file → Normal file
View File

23
processor/build.gradle Normal file
View File

@ -0,0 +1,23 @@
dependencies {
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'mysql:mysql-connector-java'
compileOnly 'org.projectlombok:lombok'
implementation project(':support')
// https://projectreactor.io/docs/core/release/reference/#debug-activate
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.telegram:telegrambots:5.3.0'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
testLogging {
events "passed", "skipped", "failed"
}
}

View File

@ -1,10 +1,19 @@
package com.myoa.engineering.crawl.ppomppu.processor; package com.myoa.engineering.crawl.ppomppu.processor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/** /**
* ProcessorApplication * ProcessorApplication
* @author Shin Woo-jin (woo-jin.shin@linecorp.com) * @author Shin Woo-jin (woo-jin.shin@linecorp.com)
* @since 2021-08-20 * @since 2021-08-20
* *
*/ */
@SpringBootApplication
public class ProcessorApplication { public class ProcessorApplication {
public static void main(String[] args) {
SpringApplication.run(ProcessorApplication.class, args);
}
} }

View File

@ -0,0 +1,30 @@
package com.myoa.engineering.crawl.ppomppu.processor.controller;
import org.springframework.web.bind.annotation.PathVariable;
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.code.PpomppuBoardName;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;
/**
* CrawlAPIController
* @author Shin Woo-jin (woo-jin.shin@linecorp.com)
* @since 2021-09-05
*
*/
@Slf4j
@RestController
@RequestMapping("/api/v1/crawl")
public class CrawlAPIController {
@PostMapping("/boards/{boardName}")
public Mono<String> crawlBoard(@PathVariable("boardName") PpomppuBoardName boardName) {
log.info("got request... {}", boardName);
return Mono.just(boardName.getBoardPath());
}
}

View File

@ -0,0 +1,6 @@
spring:
config:
activate:
on-profile: development
import:
- classpath:/development/webclient.yml

View File

@ -0,0 +1,14 @@
spring:
main:
allow-bean-definition-overriding: true
profiles:
active: development
freemarker:
enabled: false
server:
port: 20081
error:
whitelabel:
enabled: false

View File

@ -7,6 +7,7 @@ dependencies {
implementation project(':support') implementation project(':support')
// https://projectreactor.io/docs/core/release/reference/#debug-activate // https://projectreactor.io/docs/core/release/reference/#debug-activate
implementation 'org.springframework.boot:spring-boot-starter-webflux' implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.boot:spring-boot-configuration-processor'
implementation 'org.telegram:telegrambots:5.3.0' implementation 'org.telegram:telegrambots:5.3.0'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'

View File

@ -2,6 +2,9 @@ package com.myoa.engineering.crawl.ppomppu.receiver;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import com.myoa.engineering.crawl.ppomppu.receiver.configuration.properties.TelegramBotProperties;
/** /**
* ReceiverApplication * ReceiverApplication
@ -10,6 +13,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
* *
*/ */
@SpringBootApplication @SpringBootApplication
@EnableConfigurationProperties({ TelegramBotProperties.class })
public class ReceiverApplication { public class ReceiverApplication {
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -8,8 +8,9 @@ import org.telegram.telegrambots.meta.TelegramBotsApi;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException; import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.updatesreceivers.DefaultBotSession; import org.telegram.telegrambots.updatesreceivers.DefaultBotSession;
import com.myoa.engineering.crawl.ppomppu.receiver.handler.message.MessageHandler; import com.myoa.engineering.crawl.ppomppu.receiver.configuration.properties.TelegramBotProperties;
import com.myoa.engineering.crawl.ppomppu.receiver.dispatch.MessageDispatcher; import com.myoa.engineering.crawl.ppomppu.receiver.dispatch.MessageDispatcher;
import com.myoa.engineering.crawl.ppomppu.receiver.handler.message.MessageHandler;
/** /**
* TelegramBotConfiguration * TelegramBotConfiguration
@ -20,9 +21,6 @@ import com.myoa.engineering.crawl.ppomppu.receiver.dispatch.MessageDispatcher;
@Configuration @Configuration
public class TelegramBotConfiguration { public class TelegramBotConfiguration {
private static final String BOT_TOKEN = ""; // TODO extract to property
private static final String BOT_NAME = ""; // TODO extract to property
@Bean @Bean
public TelegramBotsApi telegramBotsApi(MessageDispatcher messageDispatcher) throws TelegramApiException { public TelegramBotsApi telegramBotsApi(MessageDispatcher messageDispatcher) throws TelegramApiException {
TelegramBotsApi api = new TelegramBotsApi(DefaultBotSession.class); TelegramBotsApi api = new TelegramBotsApi(DefaultBotSession.class);
@ -31,7 +29,8 @@ public class TelegramBotConfiguration {
} }
@Bean @Bean
public MessageDispatcher messageDispatcher(List<MessageHandler> messageHandlers) { public MessageDispatcher messageDispatcher(List<MessageHandler> messageHandlers,
return new MessageDispatcher(messageHandlers, BOT_TOKEN, BOT_NAME); TelegramBotProperties botProperties) {
return new MessageDispatcher(messageHandlers, botProperties.getName(), botProperties.getToken());
} }
} }

View File

@ -0,0 +1,25 @@
package com.myoa.engineering.crawl.ppomppu.receiver.configuration.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
import lombok.Getter;
/**
* TelegramBotProperties
* @author Shin Woo-jin (woo-jin.shin@linecorp.com)
* @since 2021-09-05
*
*/
@Getter
@ConstructorBinding
@ConfigurationProperties(prefix = "telegram.bot")
public class TelegramBotProperties {
private final String name;
private final String token;
public TelegramBotProperties(final String name, final String token) {
this.name = name;
this.token = token;
}
}

View File

@ -0,0 +1,33 @@
package com.myoa.engineering.crawl.ppomppu.receiver.controller.v1;
import org.springframework.web.bind.annotation.PathVariable;
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.receiver.service.ProcessorAPIService;
import com.myoa.engineering.crawl.ppomppu.support.dto.code.PpomppuBoardName;
import reactor.core.publisher.Mono;
/**
* EventAPIController
* @author Shin Woo-jin (woo-jin.shin@linecorp.com)
* @since 2021-09-05
*
*/
@RestController
@RequestMapping("/api/v1/")
public class EventAPIController {
private final ProcessorAPIService processorAPIService;
public EventAPIController(ProcessorAPIService processorAPIService) {
this.processorAPIService = processorAPIService;
}
@PostMapping("/exploit/parsePpomppuRSS/{boardName}")
public Mono<String> parsePpomppuRSS(@PathVariable("boardName") PpomppuBoardName boardName) {
return processorAPIService.emitParseEvent(boardName);
}
}

View File

@ -14,13 +14,13 @@ import lombok.extern.slf4j.Slf4j;
public class MessageDispatcher extends TelegramLongPollingBot { public class MessageDispatcher extends TelegramLongPollingBot {
private final List<MessageHandler> messageHandlers; private final List<MessageHandler> messageHandlers;
private final String botToken;
private final String botName; private final String botName;
private final String botToken;
public MessageDispatcher(List<MessageHandler> messageHandlers, String botToken, String botName) { public MessageDispatcher(List<MessageHandler> messageHandlers, String botName, String botToken) {
this.messageHandlers = messageHandlers; this.messageHandlers = messageHandlers;
this.botToken = botToken;
this.botName = botName; this.botName = botName;
this.botToken = botToken;
} }
@Override @Override

View File

@ -25,7 +25,6 @@ public class CommonTextHandler implements TextMessageHandler {
@Override @Override
public void handle(Message message) { public void handle(Message message) {
log.info("CommonTextHandler : {}", message.getText()); log.info("CommonTextHandler : {}", message.getText());
} }
} }

View File

@ -1,22 +1,37 @@
package com.myoa.engineering.crawl.ppomppu.receiver.infrastructure.client; package com.myoa.engineering.crawl.ppomppu.receiver.infrastructure.client;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientRequestException;
import java.util.List; import com.myoa.engineering.crawl.ppomppu.support.dto.code.PpomppuBoardName;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
@Slf4j
@Component @Component
public class ProcessorAPIWebClient { public class ProcessorAPIWebClient {
@Value("${webclient.some}")
private String baseUrl;
private final WebClient webClient; private final WebClient webClient;
public ProcessorAPIWebClient(WebClient.Builder webClientBuilder) { public ProcessorAPIWebClient(WebClient.Builder webClientBuilder,
this.webClient = webClientBuilder.baseUrl("soundhoundfound-processor:20080") @Value("${webclient.base-url}") String baseUrl) {
this.webClient = webClientBuilder.baseUrl(baseUrl)
.build(); .build();
} }
public Mono<String> emitParseEvent(PpomppuBoardName boardName) {
return webClient.post()
.uri("/api/v1/crawl/boards/{boardName}", boardName)
.exchangeToMono(e -> e.bodyToMono(new ParameterizedTypeReference<String>() {}))
.publishOn(Schedulers.boundedElastic())
.onErrorResume(WebClientRequestException.class, t -> {
log.info("Exception occured, ignoring. : {}", t.getClass().getSimpleName());
return Mono.empty();
});
}
} }

View File

@ -0,0 +1,30 @@
package com.myoa.engineering.crawl.ppomppu.receiver.service;
import org.springframework.stereotype.Service;
import com.myoa.engineering.crawl.ppomppu.receiver.infrastructure.client.ProcessorAPIWebClient;
import com.myoa.engineering.crawl.ppomppu.support.dto.code.PpomppuBoardName;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;
/**
* ProcessorAPIService
* @author Shin Woo-jin (woo-jin.shin@linecorp.com)
* @since 2021-09-05
*
*/
@Slf4j
@Service
public class ProcessorAPIService {
private final ProcessorAPIWebClient processorAPIWebClient;
public ProcessorAPIService(ProcessorAPIWebClient processorAPIWebClient) {
this.processorAPIWebClient = processorAPIWebClient;
}
public Mono<String> emitParseEvent(PpomppuBoardName boardName) {
return processorAPIWebClient.emitParseEvent(boardName);
}
}

View File

@ -0,0 +1,40 @@
package com.myoa.engineering.crawl.ppomppu.receiver.shceduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.myoa.engineering.crawl.ppomppu.receiver.service.ProcessorAPIService;
import com.myoa.engineering.crawl.ppomppu.support.dto.code.PpomppuBoardName;
import lombok.extern.slf4j.Slf4j;
/**
* ParseEventEmitter
* @author Shin Woo-jin (woo-jin.shin@linecorp.com)
* @since 2021-09-05
*
*/
@Slf4j
@Component
@EnableScheduling
public class ParseEventEmitter {
private final ProcessorAPIService processorAPIService;
public ParseEventEmitter(ProcessorAPIService processorAPIService) {
this.processorAPIService = processorAPIService;
}
@Scheduled(fixedRate = 60 * 1000L)
public void emitDomesticBoard() {
log.info("[emitDomesticBoard] trigger fired!");
processorAPIService.emitParseEvent(PpomppuBoardName.PPOMPPU_DOMESTIC).block();
}
@Scheduled(fixedRate = 300 * 1000L)
public void emitOverseaBoard() {
log.info("[emitOverseaBoard] trigger fired!");
processorAPIService.emitParseEvent(PpomppuBoardName.PPOMPPU_OVERSEA).block();
}
}

View File

@ -3,4 +3,5 @@ spring:
activate: activate:
on-profile: development on-profile: development
import: import:
- classpath:/development/webclient.yml - classpath:/webclient-development.yml
- classpath:/temppassword.yml

View File

@ -6,5 +6,5 @@ spring:
freemarker: freemarker:
enabled: false enabled: false
webclient: server:
some: not-test port: 20080

View File

@ -0,0 +1,5 @@
webclient:
base-url: http://localhost:20081
units:
- unit-name: processor-api
base-url: http://localhost:20081

View File

@ -0,0 +1,5 @@
webclient:
base-url: http://ppomppu_notifier_processor:20080
units:
- unit-name: processor-api
base-url: http://ppomppu_notifier_processor:20080

17
support/build.gradle Normal file
View File

@ -0,0 +1,17 @@
dependencies {
runtimeOnly 'mysql:mysql-connector-java'
compileOnly 'org.projectlombok:lombok'
// https://projectreactor.io/docs/core/release/reference/#debug-activate
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
annotationProcessor 'org.projectlombok:lombok'
}
test {
useJUnitPlatform()
testLogging {
events "passed", "skipped", "failed"
}
}

View File

@ -0,0 +1,24 @@
package com.myoa.engineering.crawl.ppomppu.support.dto.code;
import lombok.Getter;
import lombok.NoArgsConstructor;
/**
* PpomppuBoardName
* @author Shin Woo-jin (woo-jin.shin@linecorp.com)
* @since 2021-09-05
*
*/
@Getter
@NoArgsConstructor
public enum PpomppuBoardName {
PPOMPPU_DOMESTIC("ppomppu"),
PPOMPPU_OVERSEA("ppomppu4"),
;
private String boardPath;
PpomppuBoardName(String boardPath) {
this.boardPath = boardPath;
}
}

View File

@ -1,4 +1,4 @@
package com.myoa.engineering.music.soundhoundfound.support.util; package com.myoa.engineering.crawl.ppomppu.support.util;
public final class NumberUtil { public final class NumberUtil {

View File

@ -1,4 +1,4 @@
package com.myoa.engineering.music.soundhoundfound.support.util; package com.myoa.engineering.crawl.ppomppu.support.util;
public final class ObjectUtil { public final class ObjectUtil {

View File

@ -0,0 +1,4 @@
package com.myoa.engineering.crawl.ppomppu.support.webclient;
public interface WebClientBaseScan {
}

View File

@ -1,4 +0,0 @@
package com.myoa.engineering.music.soundhoundfound.support.webclient;
public interface WebClientBaseScan {
}