Gradle - Version 관리 기능 추가

Key 관리 기능 작업중
main
icksishu@gmail.com 1 month ago
parent d3e6eca84d
commit 6225cd8e6d

@ -6,7 +6,28 @@ plugins {
} }
group = 'com.bsmlab.dfx' group = 'com.bsmlab.dfx'
version = '0.0.1-SNAPSHOT' version = '0.1'
// git commit hash -> application.yml
def gitCommitId = ''
try {
def stdout = new ByteArrayOutputStream()
providers.exec {
commandLine 'git', 'rev-parse', '--short', 'HEAD'
standardOutput = stdout;
}.result.get()
gitCommitId = stdout.toString().trim()
}
catch (Exception ignored) {
print "git commit ID is not available."
}
// gradle project properties -> application.yml
processResources {
filesMatching('**/application.yml') {
expand(project.properties + [commitId: gitCommitId, version: version])
}
}
java { java {
toolchain { toolchain {

@ -172,5 +172,21 @@ COMMENT ON COLUMN TB_DFX_AGENT_MESSAGE_HISTORY.MESSAGE_DATA_COUNT IS '메시지
COMMENT ON COLUMN TB_DFX_AGENT_MESSAGE_HISTORY.PROCESS_ACK_TS IS '처리결과 수신 시간'; COMMENT ON COLUMN TB_DFX_AGENT_MESSAGE_HISTORY.PROCESS_ACK_TS IS '처리결과 수신 시간';
CREATE TABLE TB_DFX_CRYPTO_KEY (
KEY_VALUE VARCHAR(256) NOT NULL
, HASH_VALUE VARCHAR(256) NOT NULL
, ALGORITHM_NAME VARCHAR(64) NOT NULL
, MODE_NAME VARCHAR(64) NOT NULL
, TARGET_AGENT_HOST_ID VARCHAR(256)
, APPLY_TS TIMESTAMPTZ(3)
, DATA_ENCRYPTION_YN VARCHAR(1)
);
COMMENT ON TABLE TB_DFX_CRYPTO_KEY IS '암호화키정보';
COMMENT ON COLUMN TB_DFX_CRYPTO_KEY.KEY_VALUE IS 'KEY VALUE';
COMMENT ON COLUMN TB_DFX_CRYPTO_KEY.HASH_VALUE IS 'HASH VALUE';
COMMENT ON COLUMN TB_DFX_CRYPTO_KEY.ALGORITHM_NAME IS '알고리즘';
COMMENT ON COLUMN TB_DFX_CRYPTO_KEY.MODE_NAME IS '모드';
COMMENT ON COLUMN TB_DFX_CRYPTO_KEY.TARGET_AGENT_HOST_ID IS '적용 에이전트 ID';
COMMENT ON COLUMN TB_DFX_CRYPTO_KEY.APPLY_TS IS '적용 시간';
COMMENT ON COLUMN TB_DFX_CRYPTO_KEY.DATA_ENCRYPTION_YN IS '데이터 암호화 여부';

@ -26,6 +26,13 @@ const router = createRouter({
props: { contentId: 'agent-manage-view' }, props: { contentId: 'agent-manage-view' },
meta: { isRequiredAuth: true }, meta: { isRequiredAuth: true },
}, },
{
path: '/key-manage.html',
name: 'key-manage',
component: MainView,
props: { contentId: 'key-manage-view' },
meta: { isRequiredAuth: true },
},
{ {
path: '/message-history.html', path: '/message-history.html',
name: 'message-history', name: 'message-history',

@ -0,0 +1,64 @@
<script setup>
import '@/assets/main.css'
import { useApiClient } from '@/components/apiClient'
import { onMounted, ref, reactive } from 'vue'
const apiClient = useApiClient()
async function getCryptoKeyDtoList() {
const response = await apiClient.post('/app-api/agent/getCryptoKeyDtoList')
return response.data
}
let dfxCryptoKeyDtoList = ref([])
const cryptoKeyDto = reactive({})
onMounted(async () => {
dfxCryptoKeyDtoList.value = await getCryptoKeyDtoList()
})
</script>
<template>
<main class="dfx-main container w-100">
<div class="row">
<div class="col-12 pt-2 border-bottom">
<h3 class="h3">암호화 관리</h3>
</div>
</div>
<div class="row">
<article class="col-12 pt-3">
<table class="table table-striped table-bordered align-middle">
<thead>
<tr>
<th scope="col" class="text-center"></th>
<th scope="col" class="text-center">Key</th>
<th scope="col" class="text-center">Hash</th>
<th scope="col" class="text-center">Algorithm</th>
<th scope="col" class="text-center">Mode</th>
<th scope="col" class="text-center">Target agent</th>
<th scope="col" class="text-center">Applied at</th>
<th scope="col" class="text-center">Data encryption</th>
</tr>
</thead>
<tbody class="table-group-divider">
<tr v-if="dfxCryptoKeyDtoList.length > 0" v-for="(cryptoKeyDto, index) in dfxCryptoKeyDtoList" :key="index">
<td scope="row" class="text-center"><input type="checkbox" class="form-check-input" v-model="cryptoKeyDto.selected" /></td>
<td class="text-center">{{ cryptoKeyDto.keyValue }}</td>
<td class="text-center">{{ cryptoKeyDto.hashValue }}</td>
<td class="text-center">{{ cryptoKeyDto.algorithmName }}</td>
<td class="text-center">{{ cryptoKeyDto.modeName }}</td>
<td class="text-center">{{ cryptoKeyDto.targetAgentHostId }}</td>
<td class="text-center">{{ cryptoKeyDto.applyTs }}</td>
<td class="text-center">{{ cryptoKeyDto.dataEncryptionYn }}</td>
</tr>
<tr v-else>
<td scope="row" class="text-center" colspan="7">no datas.</td>
</tr>
</tbody>
</table>
</article>
</div>
</main>
</template>
<style></style>

@ -4,6 +4,7 @@ import { userApi } from '@/components/userInfo'
import { useRouter, RouterLink } from 'vue-router' import { useRouter, RouterLink } from 'vue-router'
import DashboardView from './DashboardView.vue' import DashboardView from './DashboardView.vue'
import AgentManageView from './AgentManageView.vue' import AgentManageView from './AgentManageView.vue'
import CryptoKeyManageView from './CryptoKeyManageView.vue'
import MessageHistoryView from './MessageHistoryView.vue' import MessageHistoryView from './MessageHistoryView.vue'
import { computed } from 'vue' import { computed } from 'vue'
@ -25,6 +26,8 @@ const currentContent = computed(() => {
return DashboardView return DashboardView
} else if (props.contentId == 'agent-manage-view') { } else if (props.contentId == 'agent-manage-view') {
return AgentManageView return AgentManageView
} else if (props.contentId == 'key-manage-view') {
return CryptoKeyManageView
} else if (props.contentId == 'message-history-view') { } else if (props.contentId == 'message-history-view') {
return MessageHistoryView return MessageHistoryView
} else { } else {
@ -65,6 +68,9 @@ const currentContent = computed(() => {
<li> <li>
<RouterLink to="/agent-manage.html" class="nav-link" :class="{ active: props.contentId == 'agent-manage-view', 'link-body-emphasis': props.contentId != 'agent-manage-view' }" aria-current="page"> <i class="bi bi-cpu" style="font-size: 1.1rem; padding-right: 0.5rem"></i> Agents </RouterLink> <RouterLink to="/agent-manage.html" class="nav-link" :class="{ active: props.contentId == 'agent-manage-view', 'link-body-emphasis': props.contentId != 'agent-manage-view' }" aria-current="page"> <i class="bi bi-cpu" style="font-size: 1.1rem; padding-right: 0.5rem"></i> Agents </RouterLink>
</li> </li>
<li>
<RouterLink to="/key-manage.html" class="nav-link" :class="{ active: props.contentId == 'key-manage-view', 'link-body-emphasis': props.contentId != 'key-manage-view' }" aria-current="page"> <i class="bi bi-cpu" style="font-size: 1.1rem; padding-right: 0.5rem"></i> Crypto Keys </RouterLink>
</li>
<li> <li>
<RouterLink to="/message-history.html" class="nav-link" :class="{ active: props.contentId == 'message-history-view', 'link-body-emphasis': props.contentId != 'message-history-view' }" aria-current="page"> <i class="bi bi-card-checklist" style="font-size: 1.1rem; padding-right: 0.5rem"></i> Messages </RouterLink> <RouterLink to="/message-history.html" class="nav-link" :class="{ active: props.contentId == 'message-history-view', 'link-body-emphasis': props.contentId != 'message-history-view' }" aria-current="page"> <i class="bi bi-card-checklist" style="font-size: 1.1rem; padding-right: 0.5rem"></i> Messages </RouterLink>
</li> </li>

@ -15,5 +15,6 @@ public class CommandDto {
public static enum CommandType { public static enum CommandType {
ALIVE, ALIVE,
INFORMATION, INFORMATION,
SAVE_CONFIG,
} }
} }

@ -1,7 +1,6 @@
package com.bsmlab.dfx.dfxconsole.app.agent; package com.bsmlab.dfx.dfxconsole.app.agent;
import com.bsmlab.dfx.agent.config.AgentConfigDto; import com.bsmlab.dfx.agent.config.AgentConfigDto;
import com.bsmlab.dfx.agent.listener.dto.ReceiveMessageDto;
import com.bsmlab.dfx.dfxconsole.app.agent.service.*; import com.bsmlab.dfx.dfxconsole.app.agent.service.*;
import com.bsmlab.dfx.dfxconsole.framework.dto.SearchParameterDto; import com.bsmlab.dfx.dfxconsole.framework.dto.SearchParameterDto;
import com.bsmlab.dfx.dfxconsole.framework.support.ResponseUtils; import com.bsmlab.dfx.dfxconsole.framework.support.ResponseUtils;
@ -48,6 +47,17 @@ public class DfxAgentInfoController {
} }
} }
@PostMapping("/app-api/agent/saveAgentConfigDto")
public ResponseEntity<?> saveAgentConfigDto(@RequestBody AgentConfigDto agentConfigDto) {
try {
dfxAgentInfoService.sendAgentConfigDtoToSave(agentConfigDto);
return ResponseEntity.ok().body(agentConfigDto);
}
catch(JsonProcessingException e) {
return ResponseEntity.internalServerError().body(ResponseUtils.toExceptionResponseDto(e));
}
}
@PostMapping("/app-api/agent/getAgentMessageDtoListTotalCount") @PostMapping("/app-api/agent/getAgentMessageDtoListTotalCount")
public ResponseEntity<Integer> getAgentMessageDtoListTotalCount() { public ResponseEntity<Integer> getAgentMessageDtoListTotalCount() {
int totalCount = dfxAgentMessageHistoryService.selectDfxAgentMessageDtoListTotalCount(); int totalCount = dfxAgentMessageHistoryService.selectDfxAgentMessageDtoListTotalCount();

@ -1,20 +1,33 @@
package com.bsmlab.dfx.dfxconsole.app.agent.service; package com.bsmlab.dfx.dfxconsole.app.agent.service;
import com.bsmlab.dfx.agent.config.AgentConfigDto; import com.bsmlab.dfx.agent.config.AgentConfigDto;
import com.bsmlab.dfx.agent.listener.dto.CommandDto;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
import java.util.UUID;
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
@Service @Service
@Getter
public class DfxAgentInfoService { public class DfxAgentInfoService {
@Value("${spring.application.name}")
private String applicationName;
@Value("${spring.application.version}")
private String applicationVersion;
@Value("${spring.application.commitId}")
private String applicationCommitId;
private final DfxAgentInfoMapper dfxAgentInfoMapper; private final DfxAgentInfoMapper dfxAgentInfoMapper;
public List<DfxAgentInfoDto> getDfxAgentInfoDtoList() { public List<DfxAgentInfoDto> getDfxAgentInfoDtoList() {
@ -39,6 +52,23 @@ public class DfxAgentInfoService {
} }
} }
public void sendAgentConfigDtoToSave(AgentConfigDto agentConfigDto) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
String agentConfigDtoString = objectMapper.writeValueAsString(agentConfigDto);
String messageUuid = UUID.randomUUID().toString();
CommandDto commandDto = CommandDto.builder().commandType(CommandDto.CommandType.SAVE_CONFIG).messageUuid(messageUuid).data(agentConfigDtoString).build();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
httpHeaders.set("User-Agent", this.getApplicationName() + ", version: " + this.getApplicationVersion() + "(" + this.getApplicationCommitId() + ")"
+ ", host ID: " + agentConfigDto.getStatusChecker().getConsoleHostName()
+ ", action: " + CommandDto.CommandType.SAVE_CONFIG
);
//TODO agent에 agentConfigDto를 전송하려고 하였으나 암호화 적용하는 것이 좋을 듯 하여 암호화 적용 방법 모색중임
}
public void saveDetailForRefreshDfxAgentInfoDto(DfxAgentInfoDto dfxAgentInfoDto) throws JsonProcessingException { public void saveDetailForRefreshDfxAgentInfoDto(DfxAgentInfoDto dfxAgentInfoDto) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper(); ObjectMapper objectMapper = new ObjectMapper();
AgentConfigDto agentConfigDto = objectMapper.readValue(dfxAgentInfoDto.getSettingsData(), new TypeReference<AgentConfigDto>(){}); AgentConfigDto agentConfigDto = objectMapper.readValue(dfxAgentInfoDto.getSettingsData(), new TypeReference<AgentConfigDto>(){});

@ -0,0 +1,19 @@
package com.bsmlab.dfx.dfxconsole.app.agent.service;
import lombok.*;
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@Builder
@ToString
public class DfxCryptoKeyDto {
private String keyValue;
private String hashValue;
private String algorithmName;
private String modeName;
private String targetAgentHostId;
private long applyTs;
private String dataEncryptionYn;
}

@ -0,0 +1,15 @@
package com.bsmlab.dfx.dfxconsole.app.agent.service;
import com.bsmlab.dfx.dfxconsole.framework.dto.SearchParameterDto;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface DfxCryptoKeyMapper {
List<DfxCryptoKeyDto> selectDfxCryptoKeyList(SearchParameterDto searchParameterDto);
int selectDfxCryptoKeyListTotalCount(SearchParameterDto searchParameterDto);
DfxCryptoKeyDto selectDfxCryptoKeyByKeyValue(DfxCryptoKeyDto dfxCryptoKeyDto);
void insertDfxCryptoKey(DfxCryptoKeyDto dfxCryptoKeyDto);
int updateDfxCryptoKeyToApply(DfxCryptoKeyDto dfxCryptoKeyDto);
}

@ -1,6 +1,8 @@
spring: spring:
application: application:
name: dfxconsole name: DFXConsole
version: ${version}
commitId: ${commitId}
devtools: devtools:
restart: restart:
enabled: true enabled: true

@ -169,7 +169,7 @@
SET PROCESS_STATUS_CODE = #{processStatusCode} SET PROCESS_STATUS_CODE = #{processStatusCode}
, PROCESS_ACK_TS = NOW() , PROCESS_ACK_TS = NOW()
WHERE 1 = 1 WHERE 1 = 1
SENDER_AGENT_ID = #{senderAgentId} AND SENDER_AGENT_ID = #{senderAgentId}
AND MESSAGE_UUID = #{messageUuid} AND MESSAGE_UUID = #{messageUuid}
]]> ]]>
</update> </update>

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bsmlab.dfx.dfxconsole.app.agent.service.DfxCryptoKeyMapper">
<select id="selectDfxCryptoKeyList" resultType="com.bsmlab.dfx.dfxconsole.app.agent.service.DfxCryptoKeyDto">
<![CDATA[
SELECT A.KEY_VALUE, A.HASH_VALUE, A.ALGORITHM_NAME, A.MODE_NAME, A.TARGET_AGENT_HOST_ID
, (EXTRACT(EPOCH FROM A.APPLY_TS) * 1000)::BIGINT AS APPLY_TS
, A.DATA_ENCRYPTION_YN
FROM (
SELECT KEY_VALUE, HASH_VALUE, ALGORITHM_NAME, MODE_NAME, TARGET_AGENT_HOST_ID, APPLY_TS, DATA_ENCRYPTION_YN
FROM TB_DFX_CRYPTO_KEY
WHERE 1 = 1
ORDER BY TARGET_AGENT_HOST_ID, KEY_VALUE
LIMIT #{itemCountPerPage}
OFFSET (#{page} - 1) * #{itemCountPerPage}
) A
WHERE 1 = 1
]]>
</select>
<select id="selectDfxCryptoKeyListTotalCount" resultType="int">
<![CDATA[
SELECT COUNT(*)
FROM (
SELECT KEY_VALUE, HASH_VALUE, ALGORITHM_NAME, MODE_NAME, TARGET_AGENT_HOST_ID, APPLY_TS, DATA_ENCRYPTION_YN
FROM TB_DFX_CRYPTO_KEY
WHERE 1 = 1
) A
WHERE 1 = 1
]]>
</select>
<select id="selectDfxCryptoKeyByKeyValue" parameterType="com.bsmlab.dfx.dfxconsole.app.agent.service.DfxCryptoKeyDto" resultType="com.bsmlab.dfx.dfxconsole.app.agent.service.DfxCryptoKeyDto">
<![CDATA[
SELECT KEY_VALUE, HASH_VALUE, ALGORITHM_NAME, MODE_NAME, TARGET_AGENT_HOST_ID, (EXTRACT(EPOCH FROM APPLY_TS) * 1000)::BIGINT AS APPLY_TS, DATA_ENCRYPTION_YN
FROM TB_DFX_CRYPTO_KEY
WHERE 1 = 1
AND KEY_VALUE = #{keyValue}
]]>
</select>
<insert id="insertDfxCryptoKey" parameterType="com.bsmlab.dfx.dfxconsole.app.agent.service.DfxCryptoKeyDto">
<![CDATA[
INSERT INTO TB_DFX_AGENT_MESSAGE (
KEY_VALUE, HASH_VALUE, ALGORITHM_NAME, MODE_NAME, TARGET_AGENT_HOST_ID
, APPLY_TS
, DATA_ENCRYPTION_YN
)
VALUES (
#{keyValue}, #{hashValue}, #{algorithmName}, #{modeName}, #{targetAgentHostId}
, #{applyTs, jdbcType=TIMESTAMP_WITH_TIMEZONE, javaType=Long}
, #{dataEncryptionYn}
]]>
</insert>
<update id="updateDfxCryptoKeyToApply" parameterType="com.bsmlab.dfx.dfxconsole.app.agent.service.DfxCryptoKeyDto">
<![CDATA[
UPDATE TB_DFX_AGENT_MESSAGE
SET TARGET_AGENT_HOST_ID = #{targetAgentHostId}
, APPLY_TS = NOW()
, DATA_ENCRYPTION_YN = #{dataEncryptionYn}
WHERE 1 = 1
KEY_VALUE = #{keyValue}
]]>
</update>
</mapper>
Loading…
Cancel
Save