diff --git a/.gitignore b/.gitignore
index 1de4b95..778e131 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,4 @@
/.gradle/
/build/
/gradle/
+/.claude/settings.local.json
diff --git a/build.gradle b/build.gradle
index b048499..82198f5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -29,9 +29,6 @@ dependencies {
// GPKI JNI local library
implementation files('lib/libgpkiapi_jni_1.5.jar')
- // Log4j 1.x for legacy util (NewGpkiUtil). Consider replacing with SLF4J in future.
- implementation 'log4j:log4j:1.2.17'
-
// Configuration metadata
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
diff --git a/src/main/java/com/vmis/interfaceapp/client/GovernmentApiClient.java b/src/main/java/com/vmis/interfaceapp/client/GovernmentApiClient.java
index 97da794..5e77dd7 100644
--- a/src/main/java/com/vmis/interfaceapp/client/GovernmentApiClient.java
+++ b/src/main/java/com/vmis/interfaceapp/client/GovernmentApiClient.java
@@ -10,13 +10,13 @@ import com.vmis.interfaceapp.model.common.Envelope;
import com.vmis.interfaceapp.model.ledger.LedgerRequest;
import com.vmis.interfaceapp.model.ledger.LedgerResponse;
import com.vmis.interfaceapp.util.TxIdUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestTemplate;
+import lombok.extern.slf4j.Slf4j;
+
import java.nio.charset.StandardCharsets;
/**
@@ -55,22 +55,10 @@ import java.nio.charset.StandardCharsets;
* @see GpkiService
* @see VmisProperties
*/
+@Slf4j
@Component
public class GovernmentApiClient {
- /**
- * SLF4J 로거 인스턴스
- *
- *
모든 API 호출, 에러, 응답에 대한 로그를 기록합니다.
- * 로그 레벨별 용도:
- *
- * - INFO: 정상적인 API 호출 및 응답
- * - WARN: HTTP 에러 코드 발생 시
- * - ERROR: 예외 발생 시 (현재 RuntimeException으로 래핑)
- *
- */
- private static final Logger log = LoggerFactory.getLogger(GovernmentApiClient.class);
-
/**
* Spring RestTemplate
*
@@ -358,18 +346,6 @@ public class GovernmentApiClient {
* VMIS_SEOUL |
* 필수 |
*
- *
- * | REGION_CODE |
- * 지역 코드 (시군구 코드) |
- * 11010 (서울 종로구) |
- * 선택 |
- *
- *
- * | DEPT_CODE |
- * 부서 코드 |
- * TRANS_001 |
- * 선택 |
- *
*
*
* 문자 인코딩:
@@ -426,16 +402,6 @@ public class GovernmentApiClient {
// 호출하는 시스템을 식별하는 필수 값
headers.add("INFO_SYS_ID", props.getSystem().getInfoSysId());
- // 10. 지역 코드 (선택 사항)
- // 시군구 코드 (예: 11010 = 서울특별시 종로구)
- // null이 아닌 경우에만 헤더에 추가
- if (props.getSystem().getRegionCode() != null) headers.add("REGION_CODE", props.getSystem().getRegionCode());
-
- // 11. 부서 코드 (선택 사항)
- // 호출하는 부서의 코드
- // null이 아닌 경우에만 헤더에 추가
- if (props.getSystem().getDepartmentCode() != null) headers.add("DEPT_CODE", props.getSystem().getDepartmentCode());
-
// 구성 완료된 헤더 반환
return headers;
}
diff --git a/src/main/java/com/vmis/interfaceapp/service/RequestEnricher.java b/src/main/java/com/vmis/interfaceapp/service/RequestEnricher.java
index f2674d1..52c9645 100644
--- a/src/main/java/com/vmis/interfaceapp/service/RequestEnricher.java
+++ b/src/main/java/com/vmis/interfaceapp/service/RequestEnricher.java
@@ -4,10 +4,10 @@ import com.vmis.interfaceapp.config.properties.VmisProperties;
import com.vmis.interfaceapp.model.basic.BasicRequest;
import com.vmis.interfaceapp.model.common.Envelope;
import com.vmis.interfaceapp.model.ledger.LedgerRequest;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
+import lombok.extern.slf4j.Slf4j;
+
/**
* Populates incoming request models with values from YAML configuration.
* Unconditionally overwrites the listed fields per requirement:
@@ -15,9 +15,9 @@ import org.springframework.stereotype.Component;
* - CNTC_INFO_CODE (service specific)
* - CHARGER_ID, CHARGER_IP, CHARGER_NM
*/
+@Slf4j
@Component
public class RequestEnricher {
- private static final Logger log = LoggerFactory.getLogger(RequestEnricher.class);
private final VmisProperties props;
diff --git a/src/main/java/com/vmis/interfaceapp/util/NewGpkiUtil.java b/src/main/java/com/vmis/interfaceapp/util/NewGpkiUtil.java
index 6dc2b00..77acd0d 100644
--- a/src/main/java/com/vmis/interfaceapp/util/NewGpkiUtil.java
+++ b/src/main/java/com/vmis/interfaceapp/util/NewGpkiUtil.java
@@ -4,16 +4,16 @@ import java.io.File;
import java.util.HashMap;
import java.util.Map;
-import org.apache.log4j.Logger;
-
import com.gpki.gpkiapi_jni;
import com.gpki.gpkiapi.GpkiApi;
import com.gpki.gpkiapi.cert.X509Certificate;
import com.gpki.gpkiapi.crypto.PrivateKey;
import com.gpki.gpkiapi.storage.Disk;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
public class NewGpkiUtil {
- private static Logger logger = Logger.getLogger(NewGpkiUtil.class);
byte[] myEnvCert, myEnvKey, mySigCert, mySigKey;
private Map targetServerCertMap = new HashMap();
@@ -35,11 +35,11 @@ public class NewGpkiUtil {
public void init() throws Exception {
GpkiApi.init(gpkiLicPath);
gpkiapi_jni gpki = this.getGPKI();
- if(logger.isDebugEnabled()){
+ if(log.isDebugEnabled()){
if(gpki.API_GetInfo()==0)
- logger.debug(gpki.sReturnString);
+ log.debug(gpki.sReturnString);
else
- logger.error(gpki.sDetailErrorString);
+ log.error(gpki.sDetailErrorString);
}
if(targetServerIdList!=null){
String certIdList[] = targetServerIdList.split(",");
@@ -51,7 +51,7 @@ public class NewGpkiUtil {
}
}
- logger.info("Loading gpki certificate : myServerId="
+ log.info("Loading gpki certificate : myServerId="
+ this.getMyServerId());
X509Certificate _myEnvCert = Disk.readCert(this
@@ -76,12 +76,12 @@ public class NewGpkiUtil {
testGpki(gpki);
}
this.finish(gpki);
- logger.info("GpkiUtil initialized");
+ log.info("GpkiUtil initialized");
}
private void load(gpkiapi_jni gpki, String certId) throws Exception {
- logger.debug("Loading gpki certificate : targetServerId="+ certId);
+ log.debug("Loading gpki certificate : targetServerId="+ certId);
X509Certificate cert = targetServerCertMap.get(certId);
if (cert != null) {
@@ -107,7 +107,7 @@ public class NewGpkiUtil {
if(certFilePath != null){
cert = Disk.readCert(certFilePath + File.separator + certId + ".cer");
}else{
- logger.debug("not certFilePath");
+ log.debug("not certFilePath");
}
}
@@ -117,13 +117,13 @@ public class NewGpkiUtil {
private gpkiapi_jni getGPKI(){
gpkiapi_jni gpki = new gpkiapi_jni();
if(gpki.API_Init(gpkiLicPath) != 0){
- logger.error(gpki.sDetailErrorString);
+ log.error(gpki.sDetailErrorString);
}
return gpki;
}
private void finish(gpkiapi_jni gpki){
if(gpki.API_Finish() != 0){
- logger.error(gpki.sDetailErrorString);
+ log.error(gpki.sDetailErrorString);
}
}
@@ -243,44 +243,44 @@ public class NewGpkiUtil {
public void testGpki(gpkiapi_jni gpki) throws Exception{
//gpki test eng
- logger.info("=======================================================");
- logger.info("================ TEST GPKI START ======================");
- logger.info("=======================================================");
+ log.info("=======================================================");
+ log.info("================ TEST GPKI START ======================");
+ log.info("=======================================================");
String original_Eng = "abc";
- logger.info("=== TEST ENG STRING: "+ original_Eng);
+ log.info("=== TEST ENG STRING: "+ original_Eng);
try {
byte[] encrypted = encrypt(original_Eng.getBytes(), myServerId);
- logger.info("=== TEST ENG ENCRYPT STRING: "+ encode(encrypted));
+ log.info("=== TEST ENG ENCRYPT STRING: "+ encode(encrypted));
String decrypted = new String(decrypt(encrypted));
- logger.info("=== TEST ENG DECRYPT STRING: "+decrypted);
+ log.info("=== TEST ENG DECRYPT STRING: "+decrypted);
if (!original_Eng.equals(decrypted)) {
throw new Exception("GpkiUtil not initialized properly(english)");
}
- logger.info("=== TEST ENG: OK");
+ log.info("=== TEST ENG: OK");
} catch (Exception e) {
- logger.warn("Gpki Test error(english)", e);
+ log.warn("Gpki Test error(english)", e);
throw e;
}
//gpki test kor
String original = "한글테스트";
- logger.info("=== TEST KOR STRING: "+ original);
+ log.info("=== TEST KOR STRING: "+ original);
try {
byte[] encrypted = encrypt(original.getBytes(), myServerId);
- logger.info("=== TEST KOR ENCRYPT STRING: "+ encode(encrypted));
+ log.info("=== TEST KOR ENCRYPT STRING: "+ encode(encrypted));
String decrypted = new String(decrypt(encrypted));
- logger.info("=== TEST KOR DECRYPT STRING: "+decrypted);
+ log.info("=== TEST KOR DECRYPT STRING: "+decrypted);
if (!original.equals(decrypted)) {
throw new Exception("GpkiUtil not initialized properly(korean)");
}
- logger.info("=== TEST KOR: OK");
+ log.info("=== TEST KOR: OK");
} catch (Exception e) {
- logger.warn("Gpki Test error(korean)", e);
+ log.warn("Gpki Test error(korean)", e);
throw e;
}finally{
- logger.info("=======================================================");
- logger.info("================ TEST GPKI END ========================");
- logger.info("=======================================================");
+ log.info("=======================================================");
+ log.info("================ TEST GPKI END ========================");
+ log.info("=======================================================");
}
}
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
index ffc2a64..d496d2f 100644
--- a/src/main/resources/application-dev.yml
+++ b/src/main/resources/application-dev.yml
@@ -1,6 +1,22 @@
server:
port: 8080
+# 로그 설정 - 개발(DEV) 환경
+logging:
+ config: classpath:logback-spring.xml
+ file:
+ path: d:/data/VMIS-interface/logs
+ name: vmis-interface
+ logback:
+ rollingpolicy:
+ max-file-size: 10MB
+ max-history: 30
+ level:
+ root: INFO
+ com.vmis.interfaceapp: DEBUG
+ org.springframework: INFO
+ org.springframework.web: DEBUG
+
# 인터페이스 및 연계 설정 - 개발(DEV) 환경
vmis:
system:
diff --git a/src/main/resources/application-prd.yml b/src/main/resources/application-prd.yml
index f068437..e5983b5 100644
--- a/src/main/resources/application-prd.yml
+++ b/src/main/resources/application-prd.yml
@@ -1,6 +1,22 @@
server:
port: 8080
+# 로그 설정 - 운영(PRD) 환경
+logging:
+ config: classpath:logback-spring.xml
+ file:
+ path: d:/data/VMIS-interface/logs
+ name: vmis-interface
+ logback:
+ rollingpolicy:
+ max-file-size: 10MB
+ max-history: 90
+ level:
+ root: WARN
+ com.vmis.interfaceapp: INFO
+ org.springframework: WARN
+ org.springframework.web: INFO
+
# 인터페이스 및 연계 설정 - 운영(PRD) 환경
# 주의: 실제 운영 키/호스트는 배포 환경 변수나 외부 설정(Secret)로 주입 권장
vmis:
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 260e017..caac1db 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -8,48 +8,16 @@ spring:
server:
port: 8080
-# 인터페이스 및 연계 설정 (공통 기본값)
-vmis:
- system:
- infoSysId: "41-345" # INFO_SYS_ID
- infoSysIp: "" # INFO_SYS_IP (예: 105.19.10.135)
- # 예시: 경기도 용인시 수지구 장애인복지과
- regionCode: "" # 시군구코드 (SIGUNGU_CODE, 예: 41460)
- departmentCode: "" # 행정부서코드 필요 시 입력
- # 담당자 기본값(미입력 시 빈 값)
- chargerId: ""
- chargerIp: ""
- chargerNm: ""
- gpki:
- enabled: "Y" # Y 또는 N (환경별 yml에서 재정의 가능)
- useSign: true
- charset: "UTF-8"
- certServerId: "SVR5640020001" # 이용기관 인증서 ID (ENV/SIG 공통 서버 ID)
- targetServerId: "SVR1611000006" # 보유기관 인증서 ID(교통안전공단)
- # 아래는 네이티브 GPKI 유틸(NewGpkiUtil) 설정값 (필요 시 사용)
- ldap: true # LDAP 사용 여부 (true: LDAP에서 대상서버 인증서 조회)
- gpkiLicPath: "C:/gpki2/gpkisecureweb/conf"
- certFilePath: "C:/gpki2/gpkisecureweb/certs" # LDAP 미사용 시 대상서버 인증서 파일 폴더
- envCertFilePathName: "C:/gpki2/gpkisecureweb/certs/SVRxxxx_env.cer"
- envPrivateKeyFilePathName: "C:/gpki2/gpkisecureweb/certs/SVRxxxx_env.key"
- envPrivateKeyPasswd: "change-me"
- sigCertFilePathName: "C:/gpki2/gpkisecureweb/certs/SVRxxxx_sig.cer"
- sigPrivateKeyFilePathName: "C:/gpki2/gpkisecureweb/certs/SVRxxxx_sig.key"
- sigPrivateKeyPasswd: "change-me"
- gov:
- scheme: "http"
- host: "localhost:18080" # 환경별 yml에서 재정의
- basePath: "/piss/api/molit"
- connectTimeoutMillis: 5000
- readTimeoutMillis: 10000
- services:
- basic: # 시군구연계 자동차기본사항조회
- path: "/SignguCarBassMatterInqireService"
- cntcInfoCode: "AC1_FD11_01"
- apiKey: "change-me"
- cvmisApikey: "change-me"
- ledger: # 시군구연계 자동차등록원부(갑)
- path: "/SignguCarLedgerFrmbkService"
- cntcInfoCode: "AC1_FD11_02"
- apiKey: "change-me"
- cvmisApikey: "change-me"
+# 로그 설정
+logging:
+ config: classpath:logback-spring.xml
+ file:
+ path: ./logs
+ name: vmis-interface
+ logback:
+ rollingpolicy:
+ max-file-size: 10MB
+ max-history: 30
+ level:
+ root: INFO
+ com.vmis.interfaceapp: DEBUG
\ No newline at end of file
diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml
new file mode 100644
index 0000000..9a137bc
--- /dev/null
+++ b/src/main/resources/logback-spring.xml
@@ -0,0 +1,147 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${LOG_PATTERN}
+ ${LOG_CHARSET}
+
+
+
+
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) [%thread] %cyan(%logger{36}) - %msg%n
+ ${LOG_CHARSET}
+
+
+
+
+
+ ${LOG_PATH}/${LOG_FILE}.log
+
+ ${LOG_PATTERN}
+ ${LOG_CHARSET}
+
+
+
+ ${LOG_PATH}/${LOG_FILE}.%d{yyyy-MM-dd}.%i.log
+
+ ${MAX_FILE_SIZE}
+
+ ${MAX_HISTORY}
+ true
+
+ 3GB
+
+
+
+
+
+ ${LOG_PATH}/${LOG_FILE}-error.log
+
+ ERROR
+ ACCEPT
+ DENY
+
+
+ ${LOG_PATTERN}
+ ${LOG_CHARSET}
+
+
+ ${LOG_PATH}/${LOG_FILE}-error.%d{yyyy-MM-dd}.%i.log
+
+ ${MAX_FILE_SIZE}
+ 90
+ true
+
+
+
+
+
+
+ 512
+ 0
+ false
+ false
+
+
+
+
+
+ 256
+ 0
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+