You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
VMIS-interface/README.md

14 KiB

VMIS-interface

시군구 시스템이 도로교통공단(차세대교통안전공단) Open API와 연계하여 자동차 기본사항 조회와 자동차 등록원부(갑) 조회 기능을 제공하는 Spring Boot 애플리케이션입니다. 모든 요청/응답은 공통 래퍼 Envelope<T> 형태를 사용하며, 기본사항 조회의 경우 요청과 응답(또는 오류)을 로그 테이블에 적재합니다.

최종 업데이트: 2025-11-05 14:00


개요

  • 목적
    • 자동차 기본사항 조회
    • 자동차 등록원부(갑) 조회
    • 요청/응답 로그 적재(기본사항 조회 도메인)
  • 주요 특징
    • Envelope<T> 공통 래퍼 구조 사용
    • 환경 프로파일 분리: dev, prd
    • GPKI 연계: 운영은 실서명(RealGpkiService), 개발은 NoopGpkiService
    • MyBatis + MariaDB를 통한 로깅 및 조회 이력 관리(기본사항)
  • 추후 기능 개발 사항
    • request data[] 배열과 response data[] 배열을 별도로 처리하는 기능 추가, 현재 1건의 차량번호와 1건의 response 만 처리하도록 되어있음
    • response.getRecord().get(0); || response.getBody().getData().get(0); 으로 모두 처리함, 단건이 아닌 배열처리 기능 필요함
    • 배열에 따른 로깅기능도 같이 수정되어야함, 배열만큼 rows insert(그룹해줄수 있는 tx id 컬럼 추가) or 마스터->디테일 테이블 구조로 변경

기술 스택

  • 언어: Java 17
  • 프레임워크: Spring Boot 3.3.x (Web, Validation, JDBC)
  • 퍼시스턴스: MyBatis, MariaDB JDBC
  • HTTP 클라이언트: Apache HttpClient5
  • 문서화: springdoc-openapi (Swagger UI)
  • 로깅: Logback
  • 빌드 도구: Gradle(Wrapper 포함)
  • GPKI: JNI 라이브러리(lib/libgpkiapi_jni_1.5.jar)

진입점(Entry Points)

  • 애플리케이션 메인 클래스
    • src/main/java/com/vmis/interfaceapp/VmisInterfaceApplication.java
  • REST 컨트롤러
    • src/main/java/com/vmis/interfaceapp/controller/VehicleInterfaceController.java
    • 기본 경로: /api/v1/vehicles
      • 기본사항 조회: POST /api/v1/vehicles/basic
      • 등록원부(갑) 조회: POST /api/v1/vehicles/ledger

시스템 요구 사항

  • JDK 17 이상
  • Gradle Wrapper 사용(별도 설치 불필요)
  • MariaDB 인스턴스(개발/운영 DB)
  • (운영) GPKI 인증서/개인키 및 네이티브 라이브러리 로딩 환경

설정 파일 및 프로파일

  • 기본 설정: src/main/resources/application.yml
    • 서버 포트 기본값: 8081
    • 전역 DB 타입 변수: Globals.DbType: maria
  • 개발: src/main/resources/application-dev.yml
  • 운영: src/main/resources/application-prd.yml

프로파일 활성화 방법

  • JVM 옵션: -Dspring.profiles.active=dev 또는 prd
  • 환경변수: SPRING_PROFILES_ACTIVE=dev 또는 prd

중요: 예시 설정 파일에 포함된 계정/키 값은 샘플이거나 개발용입니다. 실제 운영 환경에서는 반드시 환경변수/비밀 관리(예: Vault, KMS)로 주입하고, 파일에는 값을 남기지 마세요.

주요 설정 키(요약)

  • Spring DataSource (spring.datasource.*)
    • url, username, password, hikari.*
  • MyBatis (mybatis.*)
    • config-location, mapper-locations, type-aliases-package
  • 로깅(logging.*)
    • config, file.path, level.*
  • 서비스 도메인(vmis.*)
    • vmis.system.*: 시스템/담당자 식별 정보
    • vmis.gpki.*: GPKI 사용 여부, 경로, 패스워드 등
    • vmis.gov.*: 외부 API 엔드포인트, 타임아웃, 서비스 경로/키

권장 환경변수 매핑(예)

  • SPRING_PROFILES_ACTIVE=dev
  • DB_URL, DB_USERNAME, DB_PASSWORD
  • VMIS_SYSTEM_INFO_SYS_ID, VMIS_SYSTEM_INFO_SYS_IP, VMIS_SYSTEM_SIGUNGU_CODE
  • VMIS_GPKI_ENABLED, VMIS_GPKI_ENV_PRIVATE_KEY_PASSWD, VMIS_GPKI_SIG_PRIVATE_KEY_PASSWD
  • VMIS_GOV_HOST, VMIS_GOV_SERVICES_BASIC_APIKEY, VMIS_GOV_SERVICES_LEDGER_APIKEY

프로퍼티 바인딩 클래스: com.vmis.interfaceapp.config.properties.VmisProperties


설치 및 실행

1) 소스 가져오기

git clone <repo-url>
cd VMIS-interface

2) 빌드

# 테스트 포함 빌드
./gradlew build

# 테스트 제외 빌드(필요 시)
./gradlew clean build -x test

Windows PowerShell에서는 ./gradlew.bat 사용 가능합니다.

3) 실행

방법 1: Gradle bootRun 사용 (개발 권장)

개발 환경 (포트 8081)

# Linux/Mac
./gradlew bootRun --args='--spring.profiles.active=dev'

# Windows
gradlew.bat bootRun --args='--spring.profiles.active=dev'

운영 환경 (포트 8080)

# Linux/Mac
./gradlew bootRun --args='--spring.profiles.active=prd'

# Windows
gradlew.bat bootRun --args='--spring.profiles.active=prd'

방법 2: JAR 파일 실행 (배포 권장)

개발 환경

# Linux/Mac
java -Dspring.profiles.active=dev -jar build/libs/VMIS-interface-0.0.1-SNAPSHOT.jar

# Windows PowerShell
java -Dspring.profiles.active=dev -jar build/libs/VMIS-interface-0.0.1-SNAPSHOT.jar

# 또는 환경변수 사용 (Windows PowerShell)
$env:SPRING_PROFILES_ACTIVE = "dev"
java -jar build/libs/VMIS-interface-0.0.1-SNAPSHOT.jar

운영 환경 (환경변수 포함)

# Linux/Mac
export SPRING_PROFILES_ACTIVE=prd
export VMIS_SYSTEM_INFO_SYS_ID="41-345"
export VMIS_SYSTEM_SIGUNGU_CODE="41460"
java -jar build/libs/VMIS-interface-0.0.1-SNAPSHOT.jar

# Windows PowerShell
$env:SPRING_PROFILES_ACTIVE = "prd"
$env:VMIS_SYSTEM_INFO_SYS_ID = "41-345"
$env:VMIS_SYSTEM_SIGUNGU_CODE = "41460"
java -jar build/libs/VMIS-interface-0.0.1-SNAPSHOT.jar

백그라운드 실행 (Linux 서버)

# nohup 사용 (기본 java 경로, 콘솔 출력을 app.log에 저장)
nohup java -Dspring.profiles.active=prd -jar build/libs/VMIS-interface-0.0.1-SNAPSHOT.jar > app.log 2>&1 &

# Java 경로를 직접 지정하는 방법 (Java 17 이상)
nohup /usr/bin/java -Dspring.profiles.active=prd -jar build/libs/VMIS-interface-0.0.1-SNAPSHOT.jar > app.log 2>&1 &

# 또는 사용자 지정 Java 경로 사용
nohup /opt/jdk-17/bin/java -Dspring.profiles.active=prd -jar build/libs/VMIS-interface-0.0.1-SNAPSHOT.jar > app.log 2>&1 &

# 콘솔 출력을 남기지 않을 때 (애플리케이션 자체 로그는 logback-spring.xml 설정에 따라 별도 저장됨)
# 개발 환경
nohup /usr/bin/java -Dspring.profiles.active=dev -jar build/libs/VMIS-interface-0.0.1-SNAPSHOT.jar > /dev/null 2>&1 &

# 운영 환경 (애플리케이션 로그: d:/data/VMIS-interface/logs/vmis-interface.log)
nohup /usr/bin/java -Dspring.profiles.active=prd -jar build/libs/VMIS-interface-0.0.1-SNAPSHOT.jar > /dev/null 2>&1 &

# Java 경로 확인 방법
which java
# 또는
readlink -f $(which java)

# 프로세스 확인
ps aux | grep VMIS-interface

# 종료
kill -9 <PID>

참고: /dev/null 사용 시 콘솔 출력만 버려지며, 애플리케이션 자체 로그는 logging.file.path 설정에 따라 정상적으로 기록됩니다.

  • 개발: d:/data/VMIS-interface/logs/vmis-interface.log
  • 운영: d:/data/VMIS-interface/logs/vmis-interface.log

백그라운드 실행 (Windows 서버)

PowerShell - 백그라운드 프로세스로 실행

# 개발 환경 (콘솔 출력을 app.log에 저장)
Start-Process -NoNewWindow -FilePath "java" -ArgumentList "-Dspring.profiles.active=dev","-jar","build\libs\VMIS-interface-0.0.1-SNAPSHOT.jar" -RedirectStandardOutput "app.log" -RedirectStandardError "app.log"

# 운영 환경 (콘솔 출력을 app.log에 저장)
Start-Process -NoNewWindow -FilePath "java" -ArgumentList "-Dspring.profiles.active=prd","-jar","build\libs\VMIS-interface-0.0.1-SNAPSHOT.jar" -RedirectStandardOutput "app.log" -RedirectStandardError "app.log"

# Java 경로를 직접 지정하는 방법
Start-Process -NoNewWindow -FilePath "C:\Program Files\Java\jdk-17\bin\java.exe" -ArgumentList "-Dspring.profiles.active=prd","-jar","build\libs\VMIS-interface-0.0.1-SNAPSHOT.jar" -RedirectStandardOutput "app.log" -RedirectStandardError "app.log"

# 콘솔 출력을 남기지 않을 때 (NUL로 리다이렉트)
Start-Process -NoNewWindow -FilePath "java" -ArgumentList "-Dspring.profiles.active=prd","-jar","build\libs\VMIS-interface-0.0.1-SNAPSHOT.jar" -RedirectStandardOutput "NUL" -RedirectStandardError "NUL"

CMD - javaw 사용 (콘솔 창 없이 실행)

# 개발 환경
start /B javaw -Dspring.profiles.active=dev -jar build\libs\VMIS-interface-0.0.1-SNAPSHOT.jar

# 운영 환경
start /B javaw -Dspring.profiles.active=prd -jar build\libs\VMIS-interface-0.0.1-SNAPSHOT.jar

# Java 경로를 직접 지정 (경로에 공백이 있을 경우 빈 창제목 "" 필요)
start "" /B "C:\Program Files\Java\jdk-17\bin\javaw.exe" -Dspring.profiles.active=prd -jar build\libs\VMIS-interface-0.0.1-SNAPSHOT.jar

# 또는 절대 경로 사용
start "" /B "D:\DEV\.jdks\azul-17.0.14\bin\javaw.exe" -Dspring.profiles.active=prd -jar D:\workspace\git\VMIS-interface\build\libs\VMIS-interface-0.0.1-SNAPSHOT.jar


cd /d d:
D:\VMIS-interface\azul-17.0.14\bin

java -Dspring.profiles.active=prd -jar D:\VMIS-interface\VMIS-interface-0.0.1-SNAPSHOT.jar

"D:\VMIS-interface\azul-17.0.14\bin\javaw.exe" -Dspring.profiles.active=prd -jar D:\VMIS-interface\VMIS-interface-0.0.1-SNAPSHOT.jar

start "" /B "D:\VMIS-interface\azul-17.0.14\bin\javaw.exe" -Dspring.profiles.active=prd -jar D:\VMIS-interface\VMIS-interface-0.0.1-SNAPSHOT.jar

참고: start 명령어는 첫 번째 따옴표 문자열을 창 제목으로 인식하므로, 경로를 따옴표로 묶을 때는 앞에 빈 창제목 ""을 추가해야 합니다.

프로세스 관리

# 프로세스 확인
Get-Process | Where-Object {$_.ProcessName -like "*java*"} | Select-Object Id, ProcessName, Path

# 또는 특정 포트로 확인
netstat -ano | findstr :18080

# 프로세스 종료 (PID로)
Stop-Process -Id <PID> -Force

# 또는 taskkill 사용
taskkill /F /PID <PID>

Java 경로 확인 (Windows)

# PowerShell
where.exe java

# 또는
(Get-Command java).Source

# Java 버전 확인
java -version

참고: Windows 환경에서도 콘솔 출력을 NUL로 리다이렉트하면, 애플리케이션 자체 로그는 d:/data/VMIS-interface/logs/vmis-interface.log에 정상적으로 기록됩니다.

4) API 문서(Swagger UI)

  • 개발 환경: http://localhost:8081/swagger-ui/index.html
  • 운영 환경: http://localhost:8080/swagger-ui/index.html

사용 방법(엔드포인트)

  • 기본 경로: /api/v1/vehicles

1) 자동차 기본사항 조회

  • POST /api/v1/vehicles/basic
  • 요청/응답은 Envelope<BasicRequest|BasicResponse> 구조(JSON)
  • 컨트롤러: VehicleInterfaceController#basic

2) 자동차 등록원부(갑) 조회

  • POST /api/v1/vehicles/ledger
  • 요청/응답은 Envelope<LedgerRequest|LedgerResponse> 구조(JSON)
  • 컨트롤러: VehicleInterfaceController#ledger

참고: 요청은 서비스 계층에서 RequestEnricher를 통해 공통 헤더/추적정보가 보강되며, 외부 시스템 호출은 GovernmentApiClient가 수행합니다.


실행 스크립트/명령(Gradle)

  • 테스트 실행: ./gradlew test
  • 애플리케이션 실행(bootRun): ./gradlew bootRun --args='--spring.profiles.active=dev'
  • 의존성 갱신: ./gradlew --refresh-dependencies

DB/로깅

  • 기본사항 조회 최초 요청/응답 로그 적재
    • 서비스: CarBassMatterInqireService
    • 매퍼: CarBassMatterInqireMapper, XML: resources/mybatis/mapper/CarBassMatterInqireMapper_maria.xml
    • DDL: ddl/vips/tb_car_bass_matter_inqire.sql, ddl/vips/seq_car_bass_matter_inqire.sql
  • 로그 태그 예시
    • [BASIC-REQ-LOG] 최초 요청 저장 완료
    • [BASIC-RES-LOG] 응답 저장 완료
    • [BASIC-ERR-LOG] 외부 호출 오류 저장

GPKI 연계

  • 구현: gpki/GpkiService.java, gpki/RealGpkiService.java, gpki/NoopGpkiService.java
  • 인증서/키 위치(예): src/GPKI/certs/*
  • 운영에서는 RealGpkiService 사용 및 JNI 라이브러리 로딩 필요(lib/libgpkiapi_jni_1.5.jar)
  • 유틸: util/GpkiCryptoUtil.java, util/NewGpkiUtil.java
  • 주의사항
    • 운영 키/패스워드 노출 금지, 파일 권한/경로 점검
    • 네이티브 라이브러리 로딩 경로와 JCE 정책 확인

프로젝트 구조(요약)

VMIS-interface/
├─ build.gradle, settings.gradle
├─ gradlew, gradlew.bat, gradle/wrapper/*
├─ lib/libgpkiapi_jni_1.5.jar
├─ ddl/vips/*.sql
├─ src/
│  ├─ main/java/com/vmis/interfaceapp/
│  │  ├─ VmisInterfaceApplication.java
│  │  ├─ controller/VehicleInterfaceController.java
│  │  ├─ service/* (VehicleInterfaceService, RequestEnricher, CarBassMatterInqireService)
│  │  ├─ client/* (GovernmentApi, GovernmentApiClient)
│  │  ├─ gpki/* (GpkiService, RealGpkiService, NoopGpkiService)
│  │  ├─ mapper/* (CarBassMatterInqireMapper)
│  │  ├─ model/* (common/Envelope, basic/*, ledger/*)
│  │  ├─ config/* (DatabaseConfig, HttpClientConfig, OpenApiConfig, PropertiesConfig, ...)
│  │  └─ util/* (TxIdUtil, GpkiCryptoUtil, NewGpkiUtil)
│  ├─ main/resources/
│  │  ├─ application.yml, application-dev.yml, application-prd.yml
│  │  ├─ logback-spring.xml
│  │  └─ mybatis/*
│  └─ GPKI/certs/*
├─ 참고자료/* (규격서/원시 샘플)
└─ README.md

테스트

  • JUnit 기반 테스트 의존성 포함
    • testImplementation 'org.springframework.boot:spring-boot-starter-test'
  • 현재 저장소에 도메인별 테스트 코드가 별도로 포함되어 있지 않을 수 있습니다.
  • 실행 방법: ./gradlew test
  • TODO: 통합 테스트(외부 API 목업), 서비스 단위 테스트, 매퍼 테스트 추가

환경 변수 및 보안

  • 프로파일: SPRING_PROFILES_ACTIVE(dev/prd)
  • DB/외부 API 키/패스워드는 환경변수나 보안 비밀 관리 도구로 주입하세요.
  • 저장소/로그에 민감정보를 남기지 말 것(PII 마스킹 권장)

라이선스

  • TODO: 라이선스 파일(LICENSE)을 추가하고 본 섹션을 갱신하세요.

변경 이력

  • 2025-11-05: 초기 README 작성 및 최신 설정 반영

참고

  • OpenAPI/Swagger UI는 springdoc-openapi를 사용합니다.
  • 외부 API 사양은 참고자료/인터페이스 정의서 디렉토리의 문서를 참조하세요.