diff --git a/.gitignore b/.gitignore index 778e131..1420ee3 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ /build/ /gradle/ /.claude/settings.local.json +/.junie/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..374e250 --- /dev/null +++ b/README.md @@ -0,0 +1,226 @@ +# VMIS-interface + +시군구 시스템이 도로교통공단(차세대교통안전공단) Open API와 연계하여 자동차 기본사항 조회와 자동차 등록원부(갑) 조회 기능을 제공하는 Spring Boot 애플리케이션입니다. 모든 요청/응답은 공통 래퍼 `Envelope` 형태를 사용하며, 기본사항 조회의 경우 요청과 응답(또는 오류)을 로그 테이블에 적재합니다. + +최종 업데이트: 2025-11-05 14:00 + +--- + +## 개요 +- 목적 + - 자동차 기본사항 조회 + - 자동차 등록원부(갑) 조회 + - 요청/응답 로그 적재(기본사항 조회 도메인) +- 주요 특징 + - `Envelope` 공통 래퍼 구조 사용 + - 환경 프로파일 분리: `dev`, `prd` + - GPKI 연계: 운영은 실서명(`RealGpkiService`), 개발은 `NoopGpkiService` + - MyBatis + MariaDB를 통한 로깅 및 조회 이력 관리(기본사항) + +--- + +## 기술 스택 +- 언어: 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` + - 서버 포트 기본값: `8080` + - 전역 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_REGION_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 +cd VMIS-interface +``` + +### 2) 빌드 +``` +# 테스트 포함 빌드 +./gradlew build + +# 테스트 제외 빌드(필요 시) +./gradlew clean build -x test +``` +Windows PowerShell에서는 `./gradlew.bat` 사용 가능합니다. + +### 3) 실행 +``` +# 개발 프로파일로 실행(기본 포트 8080) +java -jar build/libs/VMIS-interface-0.0.1-SNAPSHOT.jar -Dspring.profiles.active=dev + +# 또는 환경변수로 +$env:SPRING_PROFILES_ACTIVE = "dev" +java -jar build/libs/VMIS-interface-0.0.1-SNAPSHOT.jar +``` + +### 4) API 문서(Swagger UI) +- 실행 후: `http://localhost:8080/swagger-ui/index.html` + +--- + +## 사용 방법(엔드포인트) +- 기본 경로: `/api/v1/vehicles` + +### 1) 자동차 기본사항 조회 +- `POST /api/v1/vehicles/basic` +- 요청/응답은 `Envelope` 구조(JSON) +- 컨트롤러: `VehicleInterfaceController#basic` + +### 2) 자동차 등록원부(갑) 조회 +- `POST /api/v1/vehicles/ledger` +- 요청/응답은 `Envelope` 구조(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 사양은 `참고자료/인터페이스 정의서` 디렉토리의 문서를 참조하세요.