에이전트와 통신 작업중

main
semin.baek 5 months ago
parent db4583594a
commit ecdb0e05af

@ -0,0 +1,135 @@
package com.bsmlab.dfx.agent.config;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Data
public class AgentConfigDto {
private String description;
private String myHostId;
private int myListenPort;
private List<KnownAgent> knownAgentList;
private StatusChecker statusChecker;
private List<DataSourceConfig> dataSourceConfig;
private List<String> sqlMapperLocations;
private DropBoxConfig dropBoxConfig;
private PostmanConfig postmanConfig;
private LoggingConfig logging;
// ============================ INNER CLASSES ============================
@Data
public static class KnownAgent {
private String hostId;
private String hostName;
private int listenPort;
private List<String> dropBoxIdList;
}
@Data
public static class StatusChecker {
private String cron;
}
@Data
public static class DataSourceConfig {
private String dataSourceId;
private String driverClassName;
private String url;
private String username;
private String password;
private int initialSize;
private int minIdle;
private int maxIdle;
private int maxTotal;
private int maximumRowForTransaction;
}
@Data
public static class DropBoxConfig {
private String receivedMessageStorageRoot;
private String processedMessageStorageRoot;
private String failureMessageStorageRoot;
private List<DropBox> dropBoxList;
private int threadPoolSize;
private int retentionDaysOfProcessedMessage;
}
@Data
public static class DropBox {
private String dropBoxId;
private TaskType taskType;
private String dataSourceId;
private String sqlId;
private String saveDirectoryRoot;
private String description;
}
@Data
public static class PostmanConfig {
private int threadPoolSize;
private List<Postman> postmanList;
}
@Data
public static class Postman {
private String postmanId;
private TaskType taskType;
private PostmanAction action;
private PostmanMessage message;
private String recipientHostId;
private String recipientDropBoxId;
private List<String> routingHostIdList;
private String description;
}
@Data
public static class PostmanAction {
private ActionType type;
private String command;
private List<String> parametersKeyList;
private String cron;
}
@Data
public static class PostmanMessage {
private MessageType messageType;
private String dataSourceId;
private String sqlId;
private String watchDirectory;
private String metaDataDataSourceId;
private String metaDataSqlId;
private String metaDropBoxId;
private String postProcessingSqlId;
}
public static enum ActionType {
TRIGGER,
SCHEDULED
}
public static enum MessageType {
TRANSFER_DB_TO_DB,
TRANSFER_FILE;
}
public static enum TaskType {
DB_READ_THEN_SEND,
FILE_READ_THEN_SEND,
RECEIVE_DB_TO_DB_SAVE,
RECEIVE_FILE
}
@Data
public static class LoggingConfig {
private String logDirectory;
private String logFileName;
private String logName;
private int maxHistory;
private String logPattern;
private String rootLogLevel;
private List<Map<String, String>> packages;
}
}

@ -0,0 +1,32 @@
package com.bsmlab.dfx.agent.listener.dto;
import lombok.*;
@ToString
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
/*
* Listen
* 1. listener
* 2. ( (DropBoxQueue) )
* 3. Ack (result : RECEIVE_SUCCESS)
* 3.1 Ack (result : RECEIVE_FAIL)
* 4. Worker ( )
* 4.1 Worker sender Ack (result : PROCESS_SUCCESS)
* 4.2 Worker sender Ack (result : PROCESS_FAIL)
*/
public class AckDto {
private ResultType result;
private String resultText;
private String messageUuid;
public static enum ResultType {
RECEIVE_SUCCESS,
RECEIVE_FAIL,
PROCESS_SUCCESS,
PROCESS_FAIL
}
}

@ -0,0 +1,18 @@
package com.bsmlab.dfx.agent.listener.dto;
import lombok.*;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class CommandDto {
private CommandType commandType;
private String messageUuid;
public static enum CommandType {
ALIVE,
INFORMATION,
}
}

@ -0,0 +1,33 @@
package com.bsmlab.dfx.agent.listener.dto;
import com.bsmlab.dfx.agent.config.AgentConfigDto;
import lombok.*;
import java.io.Serializable;
import java.util.List;
@ToString
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ReceiveMessageDto implements Serializable {
private String senderHostId;
private long senderTimestamp;
private String messageUuid;
private AgentConfigDto.MessageType messageType;
private long receivedTimestamp;
private String recipientHostId;
private String recipientDropBoxId;
private String data;
private List<String> attachFileList;// = new ArrayList<>();
private ProcessStatus processStatus;
public static enum ProcessStatus {
PROCESS_RECEIVED,
PROCESS_DONE,
PROCESS_NOT_POSSIBLE,
PROCESS_FAIL
}
}

@ -0,0 +1,190 @@
package com.bsmlab.dfx.agent.support;
import com.bsmlab.dfx.agent.config.AgentConfigDto;
import com.bsmlab.dfx.agent.listener.dto.AckDto;
import com.bsmlab.dfx.agent.listener.dto.CommandDto;
import com.bsmlab.dfx.agent.listener.dto.ReceiveMessageDto;
import com.bsmlab.dfx.agent.support.exception.IllegalMessageException;
import com.bsmlab.dfx.agent.support.exception.InCompleteMessageException;
import com.bsmlab.dfx.agent.support.exception.NullMessageException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@Slf4j
public class MessageUtils {
private MessageUtils() {};
@SuppressWarnings("unchecked")
public static ReceiveMessageDto toReceiveMessageDto(String messageJsonString) throws IllegalMessageException, NullMessageException, InCompleteMessageException {
ReceiveMessageDto receiveMessageDto = null;
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> map = null;
try {
map = objectMapper.readValue(messageJsonString, new TypeReference<HashMap<String, Object>>() {});
if(map == null) {
throw new NullMessageException("");
}
String senderHostId;
if(map.get("senderHostId") == null) {
throw new InCompleteMessageException("senderHostId 엘리먼트를 찾을 수 없습니다.");
}
else if(StringUtils.isBlank(String.valueOf(map.get("senderHostId")))) {
throw new InCompleteMessageException("senderHostId 값을 찾을 수 없습니다.");
}
else {
senderHostId = String.valueOf(map.get("senderHostId"));
}
long senderTimestamp = 0;
if(map.get("senderTimestamp") == null) {
throw new InCompleteMessageException("senderTimestamp 엘리먼트를 찾을 수 없습니다.");
}
else if(StringUtils.isBlank(String.valueOf(map.get("senderTimestamp")))) {
throw new InCompleteMessageException("senderTimestamp 값을 찾을 수 없습니다.");
}
else {
String senderTimeStampString = String.valueOf(map.get("senderTimestamp"));
try {
senderTimestamp = Long.parseLong(senderTimeStampString);
} catch (NumberFormatException e) {
throw new InCompleteMessageException("senderTimestamp 값의 형식이 숫자형식이 아닙니다. " + senderTimeStampString);
}
}
String messageUuid;
if(map.get("messageUuid") == null) {
throw new InCompleteMessageException("messageUuid 엘리먼트를 찾을 수 없습니다.");
}
else if(StringUtils.isBlank(String.valueOf(map.get("messageUuid")))) {
throw new InCompleteMessageException("messageUuid 값을 찾을 수 없습니다.");
}
else {
messageUuid = String.valueOf(map.get("messageUuid"));
try {
UUID.fromString(messageUuid);
}
catch (IllegalArgumentException e) {
throw new InCompleteMessageException("messageUuid 값의 형식이 숫자형식이 아닙니다. " + messageUuid);
}
}
AgentConfigDto.MessageType messageType;
if(map.get("messageType") == null) {
throw new InCompleteMessageException("messageType 엘리먼트를 찾을 수 없습니다.");
}
else if(StringUtils.isBlank(String.valueOf(map.get("messageType")))) {
throw new InCompleteMessageException("messageType 값을 찾을 수 없습니다.");
}
else {
String messageTypeString = String.valueOf(map.get("messageType"));
if(!EnumUtils.isValidEnum(AgentConfigDto.MessageType.class, messageTypeString)) {
throw new InCompleteMessageException("messageType 값이 옳바르지 않습니다. " + messageTypeString);
}
messageType = EnumUtils.getEnum(AgentConfigDto.MessageType.class, messageTypeString);
}
long receivedTimestamp = 0;
if(map.get("receivedTimestamp") == null) {
throw new InCompleteMessageException("receivedTimestamp 엘리먼트를 찾을 수 없습니다.");
}
else if(StringUtils.isBlank(String.valueOf(map.get("receivedTimestamp")))) {
throw new InCompleteMessageException("receivedTimestamp 값을 찾을 수 없습니다.");
}
else {
String receivedTimestampString = String.valueOf(map.get("receivedTimestamp"));
try {
receivedTimestamp = Long.parseLong(receivedTimestampString);
} catch (NumberFormatException e) {
throw new InCompleteMessageException("receivedTimestamp 값의 형식이 숫자형식이 아닙니다. " + receivedTimestampString);
}
}
String recipientHostId;
if(map.get("recipientHostId") == null) {
throw new InCompleteMessageException("recipientHostId 엘리먼트를 찾을 수 없습니다.");
}
else if(StringUtils.isBlank(String.valueOf(map.get("recipientHostId")))) {
throw new InCompleteMessageException("recipientHostId 값을 찾을 수 없습니다.");
}
else {
recipientHostId = String.valueOf(map.get("recipientHostId"));
}
String recipientDropBoxId;
if(map.get("recipientDropBoxId") == null) {
throw new InCompleteMessageException("recipientDropBoxId 엘리먼트를 찾을 수 없습니다.");
}
else if(StringUtils.isBlank(String.valueOf(map.get("recipientDropBoxId")))) {
throw new InCompleteMessageException("recipientDropBoxId 값을 찾을 수 없습니다.");
}
else {
recipientDropBoxId = String.valueOf(map.get("recipientDropBoxId"));
}
String dataString;
if(map.get("data") == null) {
throw new InCompleteMessageException("data 엘리먼트를 찾을 수 없습니다.");
}
else if(!(map.get("data") instanceof String)) {
throw new InCompleteMessageException("data 엘리먼트의 데이터가 문자 타입이 아닙니다.");
}
else {
dataString = String.valueOf(map.get("data"));
}
receiveMessageDto = ReceiveMessageDto.builder()
.senderHostId(senderHostId).senderTimestamp(senderTimestamp)
.messageUuid(messageUuid).messageType(messageType).receivedTimestamp(receivedTimestamp)
.recipientHostId(recipientHostId).recipientDropBoxId(recipientDropBoxId)
.data(dataString).attachFileList(new ArrayList<>()).processStatus(ReceiveMessageDto.ProcessStatus.PROCESS_RECEIVED)
.build();
}
catch(JsonProcessingException e) {
throw new IllegalMessageException(e.getMessage());
}
return receiveMessageDto;
}
public static AckDto toAckDto(String messageJsonString) throws NullMessageException, IllegalMessageException {
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> map = null;
AckDto ackDto;
try {
map = objectMapper.readValue(messageJsonString, new TypeReference<HashMap<String, Object>>() {});
if(map == null) {
throw new NullMessageException("");
}
else {
AckDto.ResultType result = EnumUtils.getEnum(AckDto.ResultType.class, String.valueOf(map.get("result")));
String resultText = String.valueOf(map.get("resultText"));
String messageUuid = String.valueOf(map.get("messageUuid"));
ackDto = AckDto.builder().result(result).resultText(resultText).messageUuid(messageUuid).build();
}
}
catch(JsonProcessingException e) {
throw new IllegalMessageException(e.getMessage());
}
return ackDto;
}
public static CommandDto toCommandDto(String messageJsonString) throws IllegalMessageException, NullMessageException {
CommandDto commandDto;
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> map = null;
try {
map = objectMapper.readValue(messageJsonString, new TypeReference<Map<String, Object>>() {});
if(map == null) {
throw new NullMessageException("command message json string is invalid");
}
else {
CommandDto.CommandType commandType = EnumUtils.getEnum(CommandDto.CommandType.class, String.valueOf(map.get("commandType")));
String messageUuid = String.valueOf(map.get("messageUuid"));
commandDto = CommandDto.builder().commandType(commandType).messageUuid(messageUuid).build();
}
} catch (JsonProcessingException e) {
throw new IllegalMessageException(e.getMessage());
}
return commandDto;
}
}

@ -0,0 +1,16 @@
package com.bsmlab.dfx.agent.support;
import jakarta.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.stream.Collectors;
public class ServletUtils {
private ServletUtils() {};
public static String getBodyString(HttpServletRequest request) throws IOException {
String bodyString = new BufferedReader(request.getReader()).lines().collect(Collectors.joining("\n"));
return bodyString;
}
}

@ -0,0 +1,19 @@
package com.bsmlab.dfx.agent.support.exception;
public class DfxException extends Exception {
protected String additionalMessage;
public DfxException(String additionalMessage) {
this.additionalMessage = additionalMessage;
}
@Override
public String getMessage() {
return "cannot find message contents. " + this.additionalMessage;
}
@Override
public String getLocalizedMessage() {
return "파싱한 메시지의 내용을 찾을 수 없습니다. " + this.additionalMessage;
}
}

@ -0,0 +1,17 @@
package com.bsmlab.dfx.agent.support.exception;
public class IllegalMessageException extends DfxException {
public IllegalMessageException(String additionalMessage) {
super(additionalMessage);
}
@Override
public String getMessage() {
return "cannot parse json message." + this.additionalMessage;
}
@Override
public String getLocalizedMessage() {
return "json 메시지를 파싱할 수 없습니다." + this.additionalMessage;
}
}

@ -0,0 +1,17 @@
package com.bsmlab.dfx.agent.support.exception;
public class InCompleteMessageException extends DfxException {
public InCompleteMessageException(String additionalMessage) {
super(additionalMessage);
}
@Override
public String getMessage() {
return "incomplete message." + this.additionalMessage;
}
@Override
public String getLocalizedMessage() {
return "메시지가 불완전합니다." + this.additionalMessage;
}
}

@ -0,0 +1,17 @@
package com.bsmlab.dfx.agent.support.exception;
public class NullMessageException extends DfxException {
public NullMessageException(String addtitionalMessage) {
super(addtitionalMessage);
}
@Override
public String getMessage() {
return "cannot find message contents." + this.additionalMessage;
}
@Override
public String getLocalizedMessage() {
return "파싱한 메시지의 내용을 찾을 수 없습니다." + this.additionalMessage;
}
}

@ -0,0 +1,46 @@
package com.bsmlab.dfx.dfxconsole.app.communicate;
import com.bsmlab.dfx.agent.listener.dto.AckDto;
import com.bsmlab.dfx.agent.support.ServletUtils;
import com.bsmlab.dfx.dfxconsole.app.communicate.service.ListenerService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import java.io.IOException;
@Controller
@Slf4j
@RequiredArgsConstructor
public class ListenerController {
private final ListenerService listenerService;
/**
* .
*
* @param request
* @return
*/
@PostMapping(value = "/listen")
public AckDto listener(HttpServletRequest request) {
AckDto ackDto = AckDto.builder().build();
return ackDto;
}
/**
* command .
*/
@PostMapping(value = "/command")
public AckDto command(HttpServletRequest request) {
AckDto ackDto = AckDto.builder().build();
try {
String bodyString = ServletUtils.getBodyString(request);
ackDto = listenerService.receiveCommand(bodyString);
} catch (IOException e) {
ackDto = AckDto.builder().result(AckDto.ResultType.RECEIVE_FAIL).resultText(e.getLocalizedMessage()).messageUuid("").build();
}
return ackDto;
}
}

@ -0,0 +1,32 @@
package com.bsmlab.dfx.dfxconsole.app.communicate.service;
import com.bsmlab.dfx.agent.listener.dto.AckDto;
import com.bsmlab.dfx.agent.listener.dto.CommandDto;
import com.bsmlab.dfx.agent.support.MessageUtils;
import com.bsmlab.dfx.agent.support.exception.IllegalMessageException;
import com.bsmlab.dfx.agent.support.exception.NullMessageException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
@RequiredArgsConstructor
public class ListenerService {
public AckDto receiveCommand(String messageJsonString) {
AckDto ackDto;
CommandDto commandDto;
try {
commandDto = MessageUtils.toCommandDto(messageJsonString);
String resultText = null;
if(CommandDto.CommandType.ALIVE == commandDto.getCommandType()) {
resultText = "ALIVE";
}
ackDto = AckDto.builder().result(AckDto.ResultType.PROCESS_SUCCESS).messageUuid(commandDto.getMessageUuid()).resultText(resultText).build();
}
catch (IllegalMessageException | NullMessageException e) {
ackDto = AckDto.builder().result(AckDto.ResultType.RECEIVE_FAIL).resultText(e.getLocalizedMessage()).messageUuid("").build();
}
return ackDto;
}
}
Loading…
Cancel
Save