ToolsController 개발
- base64 인코딩, damo 암복호화, version 정보
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
package com.eactive.eai.manage.tools;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* EncryptionManager의 현재 설정 상태. encrypt/decrypt 결과가 원문 그대로인 이유
|
||||
* (encryptYN=N이면 encryptDBData가 원문을 그대로 반환)를 함께 확인하기 위한 진단 정보다.
|
||||
*/
|
||||
@Data
|
||||
public class EncryptionManagerStatusDTO {
|
||||
|
||||
String encryptYN;
|
||||
String dbEncryptSolutionName;
|
||||
boolean encryptEnabled;
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package com.eactive.eai.manage.tools;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* base64 / hex / DAMO 변환을 브라우저나 Postman 등에서 바로 테스트할 수 있는 유틸리티 API.
|
||||
*
|
||||
* POST /manage/tools/base64/encode → 문자열 → Base64
|
||||
* POST /manage/tools/base64/decode → Base64 → 문자열
|
||||
* POST /manage/tools/hex/encode → 문자열 → Hex
|
||||
* POST /manage/tools/hex/decode → Hex → 문자열
|
||||
* POST /manage/tools/damo/encrypt → 평문 → DAMO 암호문 (DamoManager 직접 호출)
|
||||
* POST /manage/tools/damo/decrypt → DAMO 암호문 → 평문 (DamoManager 직접 호출)
|
||||
*
|
||||
* POST /manage/tools/encryption-manager/encrypt → EncryptionManager.encryptDBData 확인용
|
||||
* POST /manage/tools/encryption-manager/decrypt → EncryptionManager.decryptDBData 확인용
|
||||
* GET /manage/tools/encryption-manager/status → encryptYN/dbEncryptSolutionName 등 현재 설정 확인
|
||||
*
|
||||
* GET /manage/tools/version → 배포된 게이트웨이(eapim-online.war)의 git 버전/빌드시각 확인.
|
||||
* eapim-online(WAR를 만드는 루트 프로젝트) build.gradle의
|
||||
* generateVersionInfo 태스크가 생성하는 classpath 리소스
|
||||
* version.info(git describe 결과) 기반. 재빌드 없이 기동한 로컬
|
||||
* 환경 등 파일이 없으면 success=false로 응답한다
|
||||
*
|
||||
* base64/hex 변환은 요청 body의 charset(생략 시 UTF-8)을 기준으로 문자열 ↔ 바이트를 변환한다.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/manage/tools")
|
||||
public class ToolsController {
|
||||
|
||||
private static final MediaType APPLICATION_JSON_UTF8 = new MediaType("application", "json", StandardCharsets.UTF_8);
|
||||
|
||||
@Autowired
|
||||
private ToolsService toolsService;
|
||||
|
||||
@PostMapping("/base64/encode")
|
||||
public ResponseEntity<?> base64Encode(@RequestBody ToolsTextRequestDTO request) {
|
||||
return respond(() -> toolsService.base64Encode(request.getText(), request.getCharset()));
|
||||
}
|
||||
|
||||
@PostMapping("/base64/decode")
|
||||
public ResponseEntity<?> base64Decode(@RequestBody ToolsTextRequestDTO request) {
|
||||
return respond(() -> toolsService.base64Decode(request.getText(), request.getCharset()));
|
||||
}
|
||||
|
||||
@PostMapping("/hex/encode")
|
||||
public ResponseEntity<?> hexEncode(@RequestBody ToolsTextRequestDTO request) {
|
||||
return respond(() -> toolsService.hexEncode(request.getText(), request.getCharset()));
|
||||
}
|
||||
|
||||
@PostMapping("/hex/decode")
|
||||
public ResponseEntity<?> hexDecode(@RequestBody ToolsTextRequestDTO request) {
|
||||
return respond(() -> toolsService.hexDecode(request.getText(), request.getCharset()));
|
||||
}
|
||||
|
||||
@PostMapping("/damo/encrypt")
|
||||
public ResponseEntity<?> damoEncrypt(@RequestBody ToolsTextRequestDTO request) {
|
||||
return respond(() -> toolsService.damoEncrypt(request.getText()));
|
||||
}
|
||||
|
||||
@PostMapping("/damo/decrypt")
|
||||
public ResponseEntity<?> damoDecrypt(@RequestBody ToolsTextRequestDTO request) {
|
||||
return respond(() -> toolsService.damoDecrypt(request.getText()));
|
||||
}
|
||||
|
||||
@PostMapping("/encryption-manager/encrypt")
|
||||
public ResponseEntity<?> encryptionManagerEncrypt(@RequestBody ToolsTextRequestDTO request) {
|
||||
return respond(() -> toolsService.encryptionManagerEncrypt(request.getText()));
|
||||
}
|
||||
|
||||
@PostMapping("/encryption-manager/decrypt")
|
||||
public ResponseEntity<?> encryptionManagerDecrypt(@RequestBody ToolsTextRequestDTO request) {
|
||||
return respond(() -> toolsService.encryptionManagerDecrypt(request.getText()));
|
||||
}
|
||||
|
||||
@GetMapping("/encryption-manager/status")
|
||||
public ResponseEntity<?> encryptionManagerStatus() {
|
||||
return respond(() -> toolsService.encryptionManagerStatus());
|
||||
}
|
||||
|
||||
@GetMapping("/version")
|
||||
public ResponseEntity<?> getVersionInfo() {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
VersionInfoDTO versionInfo = toolsService.getVersionInfo();
|
||||
if (versionInfo == null) {
|
||||
result.put("success", false);
|
||||
result.put("message", "version.info 파일이 없습니다. gradle의 generateVersionInfo 태스크(또는 build) 실행 후 재기동하세요.");
|
||||
} else {
|
||||
result.put("success", true);
|
||||
result.put("data", versionInfo);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
result.put("success", false);
|
||||
result.put("message", e.getMessage());
|
||||
}
|
||||
return ResponseEntity.ok().contentType(APPLICATION_JSON_UTF8).body(result);
|
||||
}
|
||||
|
||||
private ResponseEntity<?> respond(Callable<Object> action) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
result.put("success", true);
|
||||
result.put("data", action.call());
|
||||
} catch (Exception e) {
|
||||
result.put("success", false);
|
||||
result.put("message", e.getMessage());
|
||||
}
|
||||
return ResponseEntity.ok().contentType(APPLICATION_JSON_UTF8).body(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.eactive.eai.manage.tools;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.eactive.eai.agent.encryption.EncryptionManager;
|
||||
|
||||
/**
|
||||
* base64 / hex / DAMO 변환을 테스트하기 위한 서비스.
|
||||
*
|
||||
* DAMO 암복호화는 EncryptionManager와 동일하게 com.eactive.ext.djb.DamoManager를 직접 사용한다.
|
||||
* EncryptionManager.encryptDBData/decryptDBData는 encryptYN=Y로 설정된 환경에서만 동작하므로
|
||||
* (비활성 환경에서는 원문을 그대로 반환), 환경 설정과 무관하게 항상 실제 암복호화를 확인할 수 있도록
|
||||
* DamoManager를 직접 호출한다.
|
||||
*
|
||||
* encryptionManagerEncrypt/Decrypt는 위와 별개로, 실제 운영 코드가 사용하는
|
||||
* EncryptionManager.encryptDBData/decryptDBData를 그대로 호출해 현재 서버 설정(encryptYN,
|
||||
* dbEncryptSolutionName)이 반영된 실제 동작을 확인하기 위한 용도다.
|
||||
*/
|
||||
@Service
|
||||
public class ToolsService {
|
||||
|
||||
private static final String MODULE_KEY_PREFIX = "module.";
|
||||
|
||||
private Charset resolveCharset(String charset) {
|
||||
return StringUtils.isNotBlank(charset) ? Charset.forName(charset) : StandardCharsets.UTF_8;
|
||||
}
|
||||
|
||||
public String base64Encode(String text, String charset) {
|
||||
byte[] bytes = text.getBytes(resolveCharset(charset));
|
||||
return Base64.getEncoder().encodeToString(bytes);
|
||||
}
|
||||
|
||||
public String base64Decode(String base64Text, String charset) {
|
||||
byte[] bytes = Base64.getDecoder().decode(base64Text);
|
||||
return new String(bytes, resolveCharset(charset));
|
||||
}
|
||||
|
||||
public String hexEncode(String text, String charset) {
|
||||
byte[] bytes = text.getBytes(resolveCharset(charset));
|
||||
return DatatypeConverter.printHexBinary(bytes);
|
||||
}
|
||||
|
||||
public String hexDecode(String hexText, String charset) {
|
||||
byte[] bytes = DatatypeConverter.parseHexBinary(hexText.trim());
|
||||
return new String(bytes, resolveCharset(charset));
|
||||
}
|
||||
|
||||
public String damoEncrypt(String text) {
|
||||
return new com.eactive.ext.djb.DamoManager().encrypt(text);
|
||||
}
|
||||
|
||||
public String damoDecrypt(String text) {
|
||||
return new com.eactive.ext.djb.DamoManager().decrypt(text);
|
||||
}
|
||||
|
||||
public String encryptionManagerEncrypt(String text) {
|
||||
return EncryptionManager.getInstance().encryptDBData(text);
|
||||
}
|
||||
|
||||
public String encryptionManagerDecrypt(String text) {
|
||||
return EncryptionManager.getInstance().decryptDBData(text);
|
||||
}
|
||||
|
||||
public EncryptionManagerStatusDTO encryptionManagerStatus() {
|
||||
EncryptionManager manager = EncryptionManager.getInstance();
|
||||
EncryptionManagerStatusDTO status = new EncryptionManagerStatusDTO();
|
||||
status.setEncryptYN(manager.getEncryptYN());
|
||||
status.setDbEncryptSolutionName(manager.getDBEncryptSolutionName());
|
||||
status.setEncryptEnabled(manager.isEncrypt());
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* eapim-online(WAR를 생성하는 루트 프로젝트) build.gradle의 generateVersionInfo 태스크가
|
||||
* processResources 이전에 생성하는 classpath 리소스 version.info(version=git describe 결과,
|
||||
* buildTime=...)를 읽는다. WAR는 WEB-INF/classes와 WEB-INF/lib가 클래스로더를 공유하므로
|
||||
* 이 클래스(elink-online-common 모듈)에서 조회해도 정상적으로 찾을 수 있다.
|
||||
* 재빌드 없이 IDE에서 바로 기동한 로컬 환경 등 파일이 없는 경우 null을 반환한다.
|
||||
*/
|
||||
public VersionInfoDTO getVersionInfo() {
|
||||
try (InputStream in = getClass().getResourceAsStream("/version.info")) {
|
||||
if (in == null) {
|
||||
return null;
|
||||
}
|
||||
return parseVersionInfo(in);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("version.info 읽기 실패", e);
|
||||
}
|
||||
}
|
||||
|
||||
/** version.info 내용을 파싱한다. 리소스 조회와 분리해 테스트에서 직접 검증할 수 있게 한다. */
|
||||
VersionInfoDTO parseVersionInfo(InputStream in) throws IOException {
|
||||
Properties props = new Properties();
|
||||
// Properties.load(InputStream)은 ISO-8859-1로 고정 해석되어 UTF-8로 기록된
|
||||
// version.info의 한글(git tag 등)이 깨진다. Reader로 감싸 UTF-8로 디코딩해서 넘긴다.
|
||||
props.load(new InputStreamReader(in, StandardCharsets.UTF_8));
|
||||
|
||||
VersionInfoDTO dto = new VersionInfoDTO();
|
||||
dto.setVersion(props.getProperty("version"));
|
||||
dto.setBuildTime(props.getProperty("buildTime"));
|
||||
|
||||
// module.<서브모듈명>=<git describe 결과> 형태의 키를 모아 서브모듈별 버전으로 담는다.
|
||||
Map<String, String> moduleVersions = new TreeMap<>();
|
||||
for (String key : props.stringPropertyNames()) {
|
||||
if (key.startsWith(MODULE_KEY_PREFIX)) {
|
||||
moduleVersions.put(key.substring(MODULE_KEY_PREFIX.length()), props.getProperty(key));
|
||||
}
|
||||
}
|
||||
dto.setModuleVersions(moduleVersions);
|
||||
|
||||
return dto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.eactive.eai.manage.tools;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* base64/hex/damo 변환 테스트 요청 DTO.
|
||||
*
|
||||
* charset은 base64/hex 변환에서 문자열 ↔ 바이트 변환에 사용되며, 생략 시 UTF-8이 적용된다.
|
||||
* damo 암복호화는 String 기반 API(DamoManager)를 그대로 사용하므로 charset을 사용하지 않는다.
|
||||
*/
|
||||
@Data
|
||||
public class ToolsTextRequestDTO {
|
||||
|
||||
String text;
|
||||
String charset;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.eactive.eai.manage.tools;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 빌드 시점에 생성되는 version.info(classpath 리소스) 내용을 담는 DTO.
|
||||
* eapim-online(WAR 루트 프로젝트) build.gradle의 generateVersionInfo 태스크가
|
||||
* processResources 이전에 생성한다.
|
||||
*/
|
||||
@Data
|
||||
public class VersionInfoDTO {
|
||||
|
||||
/** git describe --tags --always --dirty 결과 (예: 20260722_개발배포, 또는 태그 없으면 커밋 해시). */
|
||||
String version;
|
||||
String buildTime;
|
||||
|
||||
/**
|
||||
* elink-online-common 등 git submodule 각각의 git describe 결과.
|
||||
* 키는 submodule 디렉토리명(elink-online-common 등), 값은 describe 결과.
|
||||
* 루트(eapim-online)의 describe/dirty만으로는 어느 서브모듈이 바뀌었는지 알 수 없어서 별도로 담는다.
|
||||
*/
|
||||
Map<String, String> moduleVersions;
|
||||
}
|
||||
Reference in New Issue
Block a user