command line 상태 점검 기능 완료

- bsm-lab/dfxagent#1
main
semin.baek 8 months ago
parent 7426b84980
commit c268cc2cbb

@ -1,12 +0,0 @@
datasource:
dfcms:
driverClassName: org.postgresql.Driver
url: jdbc:postgresql://bsm-lab.com:5432/defree?currentSchema=DFCMS
username: defreeadmin
password: qortpals1!
mochastory:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://bsm-lab.com:3306/MOCHASTORY?allowPublicKeyRetrieval=true
username: MOCHASTORY
password: MOCHASTORY

@ -0,0 +1,147 @@
package com.bsmlab.dfx.agent;
import com.bsmlab.dfx.agent.config.AgentConfigDto;
import com.bsmlab.dfx.agent.config.AgentConfigReader;
import com.bsmlab.dfx.agent.config.datasource.DynamicRoutingDataSource;
import com.bsmlab.dfx.agent.listener.dto.AckDto;
import com.bsmlab.dfx.agent.listener.dto.CommandDto;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@Slf4j
@RequiredArgsConstructor
@Component
public class DfxAgentRunner implements ApplicationRunner {
private final AgentConfigReader agentConfigReader;
private final DynamicRoutingDataSource dynamicRoutingDataSource;
@Override
public void run(ApplicationArguments args) throws Exception {
// command line 실행 중 --check-config 가 있는 경우 settings.json 을 로드하여 DB 연결, knownAgent 연결 테스트를 진행한다.
// java -jar $AGENT_HOME/lib/dfxagent.jar --setting.check --setting.file=$AGENT_HOME/conf/settings.json &
if(args.containsOption("setting.check")) {
this.print("-----------------------");
this.print("DfxAgent 설정 및 환경 점검");
this.print("-----------------------");
this.print(" (설정 파일: " + args.getOptionValues("setting.file") + ")");
// settings.json 점검 로직
boolean isValid = true;
this.print("");
this.print("데이터베이스 설정 점검");
Map<Object, Object> dataSourceMap = dynamicRoutingDataSource.getDataSourceMap();
if(dataSourceMap != null && !dataSourceMap.isEmpty()) {
for(Object key : dataSourceMap.keySet()) {
DataSource dataSource = (DataSource) dataSourceMap.get(key);
AgentConfigDto.DataSourceConfig dataSourceConfig = null;
List<AgentConfigDto.DataSourceConfig> dataSourceConfigList = agentConfigReader.getAgentConfigDto().getDataSourceConfig();
for(AgentConfigDto.DataSourceConfig thisDataSourceConfig : dataSourceConfigList) {
if(thisDataSourceConfig.getDataSourceId().equals(key)) {
dataSourceConfig = thisDataSourceConfig;
break;
}
}
this.print("DB 점검 [" + dataSourceConfig.toString() + "]");
try(Connection connection = dataSource.getConnection()) {
connection.isValid(10);
this.print("DB 연결에 성공하였습니다.");
}
catch(SQLException e) {
this.print("DB 연결에 실패하였습니다. (" + e.getLocalizedMessage() + ")");
isValid = false;
}
catch(Exception e) {
this.print("DB 점검에 실패하였습니다. (" + e.getLocalizedMessage() + ")");
isValid = false;
}
}
}
else {
this.print("데이터베이스 설정은 포함되어 있지 않습니다.");
isValid = false;
}
this.print("");
this.print("상대 agent 설정 점검");
List<AgentConfigDto.KnownAgent> knownAgentList = agentConfigReader.getAgentConfigDto().getKnownAgentList();
if(knownAgentList != null && !knownAgentList.isEmpty()) {
for(AgentConfigDto.KnownAgent knownAgent : knownAgentList) {
try {
String messageUuid = UUID.randomUUID().toString();
CommandDto commandDto = CommandDto.builder().commandType(CommandDto.CommandType.ALIVE).messageUuid(messageUuid).build();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<CommandDto> bodyEntity = new HttpEntity<>(commandDto, httpHeaders);
RestTemplate restTemplate = new RestTemplate();
String url = "http://" + knownAgent.getHostName() + ":" + knownAgent.getListenPort() + "/command";
this.print("상대 agent " + knownAgent.getHostId() + "(" + knownAgent.getHostName() + ":" + knownAgent.getListenPort() + ") 연결 점검");
String response = restTemplate.postForObject(url, bodyEntity, String.class);
ObjectMapper objectMapper = new ObjectMapper();
AckDto ackDto = null;
ackDto = objectMapper.readValue(response, new TypeReference<AckDto>() {});
if(AckDto.ResultType.PROCESS_SUCCESS == ackDto.getResult()) {
this.print("상대 agent " + knownAgent.getHostId() + "(" + knownAgent.getHostName() + "가 정상 동작합니다.");
}
else {
this.print("상대 agent " + knownAgent.getHostId() + "(" + knownAgent.getHostName() + "가 응답하였으나 정상 동작하지 않습니다.");
isValid = false;
}
}
catch (JsonProcessingException e) {
this.print("상대 agent " + knownAgent.getHostId() + "(" + knownAgent.getHostName() + "가 응답메시지가 정상적이지 않습니다. (" + e.getLocalizedMessage() + ")");
isValid = false;
}
catch (ResourceAccessException e) {
this.print("상대 agent " + knownAgent.getHostId() + "(" + knownAgent.getHostName() + "가 응답하지 않습니다. (" + e.getLocalizedMessage() + ")");
isValid = false;
}
catch (Exception e) {
this.print("상대 agent " + knownAgent.getHostId() + "(" + knownAgent.getHostName() + "상태를 알 수 없습니다. (" + e.getLocalizedMessage() + ")");
isValid = false;
}
}
}
else {
this.print("상대 agent 설정은 포함되어 있지 않습니다.");
isValid = false;
}
this.print("");
this.print("--------------------------------------");
if(isValid) {
this.print("설정과 환경이 정상적입니다.");
this.print("점검을 종료합니다.");
System.exit(0);
}
else {
this.print("설정 또는 환경에 오류가 포함되어 있습니다.");
this.print("점검을 종료합니다.");
System.exit(2);
}
this.print("--------------------------------------");
}
}
private void print(String text) {
System.out.println(text);
}
}

@ -19,7 +19,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.io.File; import java.io.File;
@ -75,12 +74,10 @@ public class DfxAgentConfiguration {
else if ("jar".equalsIgnoreCase(uri.getScheme()) || location.toString().startsWith("jar:")) { else if ("jar".equalsIgnoreCase(uri.getScheme()) || location.toString().startsWith("jar:")) {
// JAR 내부 경로일 경우 // JAR 내부 경로일 경우
String path = location.toString(); String path = location.toString();
log.debug("path: {}", path);
if (path.startsWith("jar:")) { if (path.startsWith("jar:")) {
path = path.substring(4, path.indexOf("!") - 1); path = path.substring(4, path.indexOf("!") - 1);
path = path.substring(path.indexOf(":") + 1, path.lastIndexOf("/")); path = path.substring(path.indexOf(":") + 1, path.lastIndexOf("/"));
} }
log.debug("path: {}", path);
file = new File(path); file = new File(path);
} }
else { else {
@ -150,9 +147,12 @@ public class DfxAgentConfiguration {
else if(org.postgresql.Driver.class.getCanonicalName().equals(dataSourceConfig.getDriverClassName())) { else if(org.postgresql.Driver.class.getCanonicalName().equals(dataSourceConfig.getDriverClassName())) {
dataSource.setValidationQuery("SELECT 1"); dataSource.setValidationQuery("SELECT 1");
} }
else if(com.mysql.jdbc.Driver.class.getCanonicalName().equals(dataSourceConfig.getDriverClassName())) { else if(com.mysql.cj.jdbc.Driver.class.getCanonicalName().equals(dataSourceConfig.getDriverClassName())) {
dataSource.setValidationQuery("SELECT 1"); dataSource.setValidationQuery("SELECT 1");
} }
// else if(com.mysql.jdbc.Driver.class.getCanonicalName().equals(dataSourceConfig.getDriverClassName())) {
// dataSource.setValidationQuery("SELECT 1");
// }
else if(org.mariadb.jdbc.Driver.class.getCanonicalName().equals(dataSourceConfig.getDriverClassName())) { else if(org.mariadb.jdbc.Driver.class.getCanonicalName().equals(dataSourceConfig.getDriverClassName())) {
dataSource.setValidationQuery("SELECT 1"); dataSource.setValidationQuery("SELECT 1");
} }

@ -69,7 +69,6 @@ public class StatusCheckerSchedulerService {
this.agentConfigReader.setKnownAgentStatus(knownAgent.getHostId(), "DOWN"); this.agentConfigReader.setKnownAgentStatus(knownAgent.getHostId(), "DOWN");
log.debug("known agent {} {} alive message is not valid then set DOWN", knownAgent.getHostId(), knownAgent.getHostName()); log.debug("known agent {} {} alive message is not valid then set DOWN", knownAgent.getHostId(), knownAgent.getHostName());
} }
} }
} }
} }

@ -7,5 +7,8 @@ spring:
max-request-size: 1GB max-request-size: 1GB
logging: logging:
level: level:
root: ERROR
org.springframework.boot: ERROR
com.bsmlab.dfx.agent: DEBUG com.bsmlab.dfx.agent: DEBUG
com.bsmlab.dfx.agent.DfxAgentApplication: WARN

@ -5,5 +5,4 @@
| '--' || | / . \ / _____ \ | |__| | | |____ | |\ | | | | '--' || | / . \ / _____ \ | |__| | | |____ | |\ | | |
|_______/ |__| /__/ \__\ /__/ \__\ \______| |_______||__| \__| |__| |_______/ |__| /__/ \__\ /__/ \__\ \______| |_______||__| \__| |__|
${application.title} ${application.version} ${application.title} ${application.version}
Powered by Spring Boot ${spring-boot.version}
Loading…
Cancel
Save