diff --git a/src/docs/agent-bsm-lab-postgres/conf/dfxagent-bsm-lab-postgres.json b/src/docs/agent-bsm-lab-postgres/conf/dfxagent-bsm-lab-postgres.json index b6e57f5..0c32132 100644 --- a/src/docs/agent-bsm-lab-postgres/conf/dfxagent-bsm-lab-postgres.json +++ b/src/docs/agent-bsm-lab-postgres/conf/dfxagent-bsm-lab-postgres.json @@ -6,10 +6,8 @@ "keyStorePath": "D:/projects/bsm-lab/dfx/dfxagent/src/docs/agent-bsm-lab-postgres/cert/dfxagent-bsm-lab-postgres.p12", "keyStorePassword": "qortpals1!", "keyStoreAlias": "agent-bsm-lab-postgres", - "keyStoreType": "PKCS12", "trustStorePath": "D:/projects/bsm-lab/dfx/dfxagent/src/docs/agent-bsm-lab-postgres/cert/truststore-bsm-lab-postgres.jks", "trustStorePassword": "qortpals1!", - "trustStoreType": "JKS", "knownAgentList": [ { "hostId": "agent-tuf-a15-defree-oracle", diff --git a/src/main/java/com/bsmlab/dfx/agent/DfxAgentApplication.java b/src/main/java/com/bsmlab/dfx/agent/DfxAgentApplication.java index c31c9aa..92a64c5 100644 --- a/src/main/java/com/bsmlab/dfx/agent/DfxAgentApplication.java +++ b/src/main/java/com/bsmlab/dfx/agent/DfxAgentApplication.java @@ -55,6 +55,7 @@ public class DfxAgentApplication { props.put("server.ssl.enabled", agentConfigDto.isSslEnabled()); props.put("server.ssl.key-store", agentConfigDto.getKeyStorePath()); props.put("server.ssl.key-store-password", agentConfigDto.getKeyStorePassword()); + props.put("server.ssl.key-alias", agentConfigDto.getKeyStoreAlias()); props.put("server.ssl.key-store-type", "PKCS12"); props.put("server.ssl.trust-store", agentConfigDto.getTrustStorePath()); props.put("server.ssl.trust-store-password", agentConfigDto.getTrustStorePassword()); diff --git a/src/main/java/com/bsmlab/dfx/agent/config/AgentConfigDto.java b/src/main/java/com/bsmlab/dfx/agent/config/AgentConfigDto.java index 503a34b..3a579f7 100644 --- a/src/main/java/com/bsmlab/dfx/agent/config/AgentConfigDto.java +++ b/src/main/java/com/bsmlab/dfx/agent/config/AgentConfigDto.java @@ -14,6 +14,7 @@ public class AgentConfigDto { private boolean sslEnabled; private String keyStorePath; private String keyStorePassword; + private String keyStoreAlias; private String trustStorePath; private String trustStorePassword; private List knownAgentList; diff --git a/src/main/java/com/bsmlab/dfx/agent/config/datasource/SqlExecuteService.java b/src/main/java/com/bsmlab/dfx/agent/config/datasource/SqlExecuteService.java index b4fee9c..d73f1f1 100644 --- a/src/main/java/com/bsmlab/dfx/agent/config/datasource/SqlExecuteService.java +++ b/src/main/java/com/bsmlab/dfx/agent/config/datasource/SqlExecuteService.java @@ -139,6 +139,14 @@ public class SqlExecuteService { } } + public int update(String dataSourceId, String sqlId, List> parameterList) { + int result = 0; + for(Map parameter : parameterList) { + result += this.update(dataSourceId, sqlId, parameter); + } + return result; + } + public int delete(String dataSourceId, String sqlId, Map parameter) { dynamicRoutingDataSource.setDataSource(dataSourceId); try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId)) { diff --git a/src/main/java/com/bsmlab/dfx/agent/listener/service/ListenerService.java b/src/main/java/com/bsmlab/dfx/agent/listener/service/ListenerService.java index 71ceb19..8379d19 100644 --- a/src/main/java/com/bsmlab/dfx/agent/listener/service/ListenerService.java +++ b/src/main/java/com/bsmlab/dfx/agent/listener/service/ListenerService.java @@ -10,6 +10,7 @@ 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.bsmlab.dfx.agent.task.dropbox.DropBoxService; +import com.bsmlab.dfx.agent.task.postman.PostmanSchedulerService; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.http.Part; @@ -36,6 +37,7 @@ import java.util.Iterator; public class ListenerService { private final DropBoxService dropBoxService; private final AgentConfigReader agentConfigReader; + private final PostmanSchedulerService postmanSchedulerService; /** * 메시지를 파싱한다. @@ -125,12 +127,23 @@ public class ListenerService { return ackDto; } + /** + * 상대 에이전트의 DropBox가 처리한 결과를 수신하고 수신한 AckDto에 따라서 postmanSchedulerService.makeCompleteSentMessage를 수행한다. + * @param messageJsonString + * @return + */ public AckDto receiveAck(String messageJsonString) { AckDto ackDto; try { ackDto = MessageUtils.toAckDto(messageJsonString); + if((ackDto.getResult() == AckDto.ResultType.PROCESS_SUCCESS)) { // 상대 에이전트의 DropBox 수신 및 처리 후 처리결과가 정상일 때의 AckDto + postmanSchedulerService.makeCompleteSentMessage(ackDto.getMessageUuid()); + if(agentConfigReader.isConnectedConsole()) { + MessageUtils.announceMessageAck(this.agentConfigReader, ackDto); + } + } } - catch (NullMessageException | IllegalMessageException e) { + catch (NullMessageException | IllegalMessageException | JsonProcessingException e) { ackDto = AckDto.builder().result(AckDto.ResultType.RECEIVE_FAIL).resultText(e.getLocalizedMessage()).messageUuid("").build(); } return ackDto; diff --git a/src/main/java/com/bsmlab/dfx/agent/support/MessageUtils.java b/src/main/java/com/bsmlab/dfx/agent/support/MessageUtils.java index b5f57da..f714ecb 100644 --- a/src/main/java/com/bsmlab/dfx/agent/support/MessageUtils.java +++ b/src/main/java/com/bsmlab/dfx/agent/support/MessageUtils.java @@ -335,4 +335,25 @@ public class MessageUtils { ackDto = objectMapper.readValue(response, new TypeReference() {}); return ackDto; } + + public static AckDto announceMessageAck(AgentConfigReader agentConfigReader, AckDto ackDto) throws JsonProcessingException { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + httpHeaders.set("User-Agent", agentConfigReader.getApplicationName() + ", version: " + agentConfigReader.getApplicationVersion() + "(" + agentConfigReader.getApplicationCommitId() + ")" + + ", host ID: " + agentConfigReader.getAgentConfigDto().getMyHostId() + + ", action: message-history" + ); + HttpEntity bodyEntity = new HttpEntity<>(ackDto, httpHeaders); + RestTemplate restTemplate = new RestTemplate(); + String url = (agentConfigReader.getAgentConfigDto().getStatusChecker().isConsoleSslEnabled() ? "https://" : "http://") + + agentConfigReader.getAgentConfigDto().getStatusChecker().getConsoleHostName() + ":" + + agentConfigReader.getAgentConfigDto().getStatusChecker().getConsoleListenPort() + + "/telegram"; + log.debug("announceMessageAck to console {} send a message UUID {}. result: {}", agentConfigReader.getAgentConfigDto().getStatusChecker().getConsoleHostName(), ackDto.getMessageUuid(), ackDto.getResult()); + String response = ""; + AckDto consoleAckDto = null; + response = restTemplate.postForObject(url, bodyEntity, String.class); + consoleAckDto = objectMapper.readValue(response, new TypeReference() {}); + return consoleAckDto; + } } diff --git a/src/main/java/com/bsmlab/dfx/agent/task/postman/PostmanSchedulerService.java b/src/main/java/com/bsmlab/dfx/agent/task/postman/PostmanSchedulerService.java index f76a93e..37bfa84 100644 --- a/src/main/java/com/bsmlab/dfx/agent/task/postman/PostmanSchedulerService.java +++ b/src/main/java/com/bsmlab/dfx/agent/task/postman/PostmanSchedulerService.java @@ -41,6 +41,7 @@ public class PostmanSchedulerService { private final SqlExecuteService sqlExecuteService; private Map> scheduledFutureMap = new HashMap<>(); private Map postmanMap = new HashMap<>(); + private Map sentMessageFileMap = new HashMap<>(); private void startPostman(String postmanId) { AgentConfigDto.Postman postman = this.postmanMap.get(postmanId); @@ -67,6 +68,56 @@ public class PostmanSchedulerService { this.startPostman(postman.getPostmanId()); } } + this.findAndAddSentMessageFile(new File(agentConfigReader.getAgentConfigDto().getDropBoxConfig().getSentMessageStorageRoot())); + } + + private void findAndAddSentMessageFile(File parentDirectory) { + File[] filesOnDirectory = parentDirectory.listFiles(); + if(filesOnDirectory != null) { + for(File file : filesOnDirectory) { + if(file.canRead() && !".".equals(file.getName()) && !"..".equals(file.getName())) { + if(file.isFile() && !file.getName().contains("complete")) { + this.sentMessageFileMap.put(file.getName(), file.getAbsolutePath()); + } + else if(file.isDirectory()) { + findAndAddSentMessageFile(file); + } + } + } + } + } + + /** + * AckDto 수신 후 postProcessingSqlId 처리. 이후 sent 메시지 파일 이름 변경 .complete + * @param messageUuid : AckDto로 전달받은 messageUuid. sentMessageFileMap에 포함되어 있어야 함 + */ + @SuppressWarnings("unchecked") + public void makeCompleteSentMessage(String messageUuid) { + if(this.sentMessageFileMap.containsKey(messageUuid)) { + File sentMessageFile = new File(this.sentMessageFileMap.get(messageUuid)); + if(sentMessageFile.exists()) { + try (ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(sentMessageFile))) { + ReceiveMessageDto receiveMessageDto = (ReceiveMessageDto)objectInputStream.readObject(); + ObjectMapper objectMapper = new ObjectMapper(); + List> dataMapList; + dataMapList = (List>) objectMapper.readValue(receiveMessageDto.getData(), List.class); + AgentConfigDto.Postman postman = this.postmanMap.get(receiveMessageDto.getSenderPostmanId()); + sqlExecuteService.update(postman.getMessage().getDataSourceId(), postman.getMessage().getPostProcessingSqlId(), dataMapList); + } catch (FileNotFoundException e) { + log.error("cannot find a file for sent message {}", sentMessageFile.getAbsolutePath()); + log.error("{}", e, e); + } catch (IOException e) { + log.error("cannot access a file for sent message {}", sentMessageFile.getAbsolutePath()); + log.error("{}", e, e); + } catch (ClassNotFoundException e) { + log.error("cannot translate a file for sent message {}", sentMessageFile.getAbsolutePath()); + log.error("{}", e, e); + } + File completeMessageFile = new File(sentMessageFile.getAbsolutePath() + ".complete"); + sentMessageFile.renameTo(completeMessageFile); + } + this.sentMessageFileMap.remove(messageUuid); + } } private void writeSentMessage(ReceiveMessageDto receiveMessageDto) { @@ -81,6 +132,7 @@ public class PostmanSchedulerService { String targetFilePath = targetDirectoryString + "/" + receiveMessageDto.getMessageUuid(); try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(targetFilePath)))) { objectOutputStream.writeObject(receiveMessageDto); + this.sentMessageFileMap.put(receiveMessageDto.getMessageUuid(), targetFilePath); } catch (IOException e) { throw new RuntimeException(e);