VMIS-interface → VIPS 통합 작업 분석, 계획 문서 작성

internalApi
박성영 1 month ago
parent e782cdac5c
commit 1486df75be

@ -0,0 +1,753 @@
# VMIS-interface → VIPS 통합 프로젝트 분석 문서
**작성일**: 2025-11-06
**작업 방식**: 방법 2 - 직접 통합 (Spring Boot 2.7 다운그레이드)
---
## 목차
1. [프로젝트 개요](#1-프로젝트-개요)
2. [VIPS 프로젝트 구조](#2-vips-프로젝트-구조)
3. [VMIS-interface 프로젝트 구조](#3-vmis-interface-프로젝트-구조)
4. [기술 스택 비교](#4-기술-스택-비교)
5. [통합 방식 선택 이유](#5-통합-방식-선택-이유)
6. [주요 차이점 및 해결 방안](#6-주요-차이점-및-해결-방안)
---
## 1. 프로젝트 개요
### VIPS (차량 점검 페널티 시스템)
- **위치**: D:\workspace\git\VIPS
- **목적**: 자동차 점검 페널티 관리 업무 시스템
- **형태**: 단일 모듈 Spring Boot 웹 애플리케이션
### VMIS-interface (차량 정보 조회 API)
- **위치**: D:\workspace\git\VMIS-interface
- **목적**: 도로교통공단 Open API 연동하여 차량 정보 조회
- **형태**: REST API 서버
### 통합 목표
VMIS-interface의 모든 설정, 로직, 데이터베이스를 VIPS 내부로 이식하여 외부 API 호출 없이 내부 모듈로 작동
---
## 2. VIPS 프로젝트 구조
### 2.1 기본 정보
```
프로젝트명: VIPS
Spring Boot: 2.7.18
Java: 1.8
빌드: Gradle
패키징: WAR
데이터베이스: MariaDB
ORM: MyBatis
```
### 2.2 디렉토리 구조
```
D:\workspace\git\VIPS\
├── src/main/java/
│ ├── egovframework/ (전자정부 프레임워크)
│ │ ├── config/ (설정 클래스)
│ │ │ ├── RestTemplateConfig.java
│ │ │ ├── DataSourceProxyConfig.java
│ │ │ ├── EgovConfigCommon.java
│ │ │ ├── EgovConfigWeb.java
│ │ │ ├── SqlLoggingInterceptor.java
│ │ │ └── SwaggerConfig.java
│ │ ├── configProperties/
│ │ │ └── RestTemplateProperties.java
│ │ ├── filter/
│ │ │ └── XssFilterConfig.java
│ │ └── util/
│ │ ├── ApiResponseEntity.java
│ │ └── ApiResponseUtil.java
│ │
│ └── go/kr/project/
│ ├── externalApi/ (외부 API 통합 모듈) ★
│ │ ├── service/
│ │ │ └── ExternalVehicleApiService.java
│ │ └── vo/
│ │ ├── Envelope.java
│ │ ├── VehicleApiResponseVO.java
│ │ ├── VehicleBasicInfoVO.java
│ │ ├── VehicleBasicRequestVO.java
│ │ ├── VehicleLedgerRequestVO.java
│ │ └── VehicleLedgerVO.java
│ ├── carInspectionPenalty/
│ ├── common/
│ ├── login/
│ ├── main/
│ ├── mypage/
│ └── system/
├── src/main/resources/
│ ├── application.yml
│ ├── application-local.yml
│ ├── application-dev.yml
│ ├── application-prd.yml
│ ├── logback-spring.xml
│ └── mybatis/
│ ├── mybatis-config.xml
│ └── mapper/
└── build.gradle
```
### 2.3 주요 설정 (application.yml)
```yaml
server:
port: 8080
mybatis:
config-location: classpath:mybatis/mybatis-config.xml
mapper-locations: classpath:mybatis/mapper/**/*_${Globals.DbType}.xml
rest-template:
timeout:
connect-timeout-millis: 10000
read-timeout-millis: 12000
connection-pool:
max-total: 100
max-per-route: 20
rate-limit:
permits-per-second: 5.0
```
### 2.4 기존 외부 API 통합 구조
**ExternalVehicleApiService.java**:
- VMIS-interface를 REST API로 호출 (http://localhost:8081)
- 배치 처리 지원
- 에러 처리 및 로깅
**RestTemplateConfig.java**:
- Apache HttpClient 4 기반
- 연결 풀 관리 (PoolingHttpClientConnectionManager)
- Rate Limiting (Guava RateLimiter)
### 2.5 주요 의존성
```gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web:2.7.18'
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.3.1'
implementation 'org.mariadb.jdbc:mariadb-java-client'
implementation 'org.apache.httpcomponents:httpclient'
implementation 'com.google.guava:guava:32.1.3-jre'
implementation 'org.egovframe.rte:org.egovframe.rte.fdl.cmmn:4.3.0'
implementation 'org.egovframe.rte:org.egovframe.rte.ptl.mvc:4.3.0'
}
```
---
## 3. VMIS-interface 프로젝트 구조
### 3.1 기본 정보
```
프로젝트명: VMIS-interface
Spring Boot: 3.3.4
Java: 17
빌드: Gradle
패키징: JAR
데이터베이스: MariaDB
ORM: MyBatis
```
### 3.2 디렉토리 구조
```
D:\workspace\git\VMIS-interface\
├── src/main/java/com/vmis/interfaceapp/
│ ├── InterfaceApplication.java (메인 클래스)
│ │
│ ├── config/ (설정 계층)
│ │ ├── MyBatisConfig.java
│ │ ├── OpenApiConfig.java
│ │ └── VmisProperties.java (핵심 설정)
│ │
│ ├── controller/ (API 진입점)
│ │ └── VehicleInterfaceController.java
│ │
│ ├── service/ (비즈니스 로직)
│ │ ├── CarBassMatterInqireService.java (기본사항 조회)
│ │ ├── CarLedgerFrmbkService.java (등록원부 조회)
│ │ ├── CarBassMatterInqireLogService.java (로그)
│ │ └── CarLedgerFrmbkLogService.java (로그)
│ │
│ ├── client/ (외부 API 호출)
│ │ └── GovernmentApiClient.java (도로교통공단 API)
│ │
│ ├── enricher/ (데이터 보강)
│ │ └── RequestEnricher.java
│ │
│ ├── model/ (도메인 모델)
│ │ ├── entity/ (DB 엔티티 - 7개)
│ │ ├── vo/ (VO - 6개)
│ │ └── dto/ (DTO - 2개)
│ │
│ ├── mapper/ (MyBatis Mapper)
│ │ ├── CarBassMatterInqireLogMapper.java
│ │ └── CarLedgerFrmbkLogMapper.java
│ │
│ └── util/ (유틸리티)
│ ├── EncryptionUtil.java (GPKI 암호화)
│ └── TransactionIdGenerator.java
├── src/main/resources/
│ ├── application.yml
│ ├── application-dev.yml
│ ├── application-prd.yml
│ ├── logback-spring.xml
│ └── mybatis/
│ ├── mybatis-config.xml
│ └── mapper/
│ ├── CarBassMatterInqireLogMapper.xml
│ └── CarLedgerFrmbkLogMapper.xml
├── lib/
│ └── libgpkiapi_jni_1.5.jar (GPKI 라이브러리)
├── ddl/vips/ (데이터베이스 스키마)
│ ├── tb_car_bass_matter_inqire.sql
│ ├── seq_car_bass_matter_inqire.sql
│ ├── tb_car_ledger_frmbk.sql
│ ├── seq_car_ledger_frmbk.sql
│ ├── tb_car_ledger_frmbk_dtl.sql
│ └── seq_car_ledger_frmbk_dtl.sql
└── build.gradle
```
### 3.3 핵심 파일 목록 (34개 Java 파일)
#### 설정 (3개)
1. `MyBatisConfig.java`
2. `OpenApiConfig.java`
3. `VmisProperties.java` ⭐ (핵심 설정)
#### 컨트롤러 (1개)
4. `VehicleInterfaceController.java`
#### 서비스 (4개)
5. `CarBassMatterInqireService.java`
6. `CarLedgerFrmbkService.java`
7. `CarBassMatterInqireLogService.java`
8. `CarLedgerFrmbkLogService.java`
#### 클라이언트 (1개)
9. `GovernmentApiClient.java` ⭐ (가장 복잡)
#### 데이터 보강 (1개)
10. `RequestEnricher.java`
#### 엔티티 (7개)
11. `CarBassMatterInqire.java`
12. `CarBassMatterInqireLog.java`
13. `CarLedgerFrmbk.java`
14. `CarLedgerFrmbkDtl.java`
15. `CarLedgerFrmbkLog.java`
16. `VehicleBasicInfo.java`
17. `VehicleLedger.java`
#### VO (6개)
18. `CarBassMatterInqireRequestVO.java`
19. `CarLedgerFrmbkRequestVO.java`
20. `Envelope.java`
21. `GovApiBasicRequest.java`
22. `GovApiBasicResponse.java`
23. `GovApiLedgerRequest.java`
24. `GovApiLedgerResponse.java`
#### DTO (2개)
25. `VehicleBasicInfoDTO.java`
26. `VehicleLedgerDTO.java`
#### Mapper (2개)
27. `CarBassMatterInqireLogMapper.java`
28. `CarLedgerFrmbkLogMapper.java`
#### 유틸리티 (2개)
29. `EncryptionUtil.java`
30. `TransactionIdGenerator.java`
#### 메인 클래스 (1개)
31. `InterfaceApplication.java`
**총 31개 핵심 파일 + 3개 추가 클래스**
### 3.4 VmisProperties 구조 (핵심)
```java
@ConfigurationProperties(prefix = "vmis")
public class VmisProperties {
private SystemProps system; // 시스템 정보
private GpkiProps gpki; // GPKI 암호화 설정
private GovProps government; // 정부 API 설정
public static class SystemProps {
private String infoSysId; // 정보시스템 ID
private String infoSysIp; // 시스템 IP
private String managerId; // 담당자 ID
private String managerName; // 담당자명
private String managerTel; // 담당자 전화번호
}
public static class GpkiProps {
private boolean enabled; // 암호화 사용 여부
private String certPath; // 인증서 경로
private String privateKeyPath; // 개인키 경로
private String privateKeyPassword; // 개인키 비밀번호
}
public static class GovProps {
private String host; // API 호스트
private String basePath; // 기본 경로
private int connectTimeout; // 연결 타임아웃
private int readTimeout; // 읽기 타임아웃
private Services services; // 서비스별 설정
public static class Services {
private ServiceConfig basic; // 기본사항 API
private ServiceConfig ledger; // 등록원부 API
public static class ServiceConfig {
private String path; // API 경로
private String apiKey; // API 키
}
}
}
}
```
### 3.5 application.yml 설정
```yaml
vmis:
system:
info-sys-id: "VMIS001"
info-sys-ip: "192.168.1.100"
manager-id: "admin"
manager-name: "관리자"
manager-tel: "02-1234-5678"
gpki:
enabled: false # 개발환경에서는 false
cert-path: "/path/to/cert.der"
private-key-path: "/path/to/private.key"
private-key-password: "${GPKI_PASSWORD}"
government:
host: "https://www.vemanet.com"
base-path: "/openapi"
connect-timeout: 10000
read-timeout: 15000
services:
basic:
path: "/carBassMatterInqire"
api-key: "${GOV_API_KEY_BASIC}"
ledger:
path: "/carLedgerFrmbk"
api-key: "${GOV_API_KEY_LEDGER}"
```
### 3.6 API 엔드포인트
#### 1. 자동차 기본사항 조회
```
POST /api/v1/vehicles/basic
Content-Type: application/json
Request:
{
"vhrno": "12가3456"
}
Response:
{
"data": [
{
"vhrno": "12가3456",
"success": true,
"message": "조회 성공",
"basicInfo": {
"vhrno": "12가3456",
"vhcleNm": "소나타",
...
}
}
]
}
```
#### 2. 자동차 등록원부 조회
```
POST /api/v1/vehicles/ledger
Content-Type: application/json
Request:
{
"vhrno": "12가3456"
}
Response:
{
"data": [
{
"vhrno": "12가3456",
"success": true,
"message": "조회 성공",
"ledgerInfo": {
"master": {...},
"details": [...]
}
}
]
}
```
### 3.7 데이터베이스 테이블 (6개)
1. **tb_car_bass_matter_inqire** (기본사항 로그)
- seq_car_bass_matter_inqire (시퀀스)
2. **tb_car_ledger_frmbk** (등록원부 마스터)
- seq_car_ledger_frmbk (시퀀스)
3. **tb_car_ledger_frmbk_dtl** (등록원부 상세)
- seq_car_ledger_frmbk_dtl (시퀀스)
### 3.8 주요 의존성
```gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web:3.3.4'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3'
implementation 'org.mariadb.jdbc:mariadb-java-client:3.3.3'
implementation 'org.apache.httpcomponents.client5:httpclient5:5.2.3'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0'
implementation 'org.projectlombok:lombok:1.18.34'
implementation files('lib/libgpkiapi_jni_1.5.jar')
}
```
---
## 4. 기술 스택 비교
| 항목 | VIPS | VMIS-interface | 비고 |
|------|------|----------------|------|
| **Spring Boot** | 2.7.18 | 3.3.4 | 메이저 버전 차이 |
| **Java** | 1.8 | 17 | 9개 버전 차이 |
| **패키지** | javax.* | jakarta.* | 네임스페이스 변경 |
| **HttpClient** | Apache 4 | Apache 5 | API 변경 |
| **MyBatis** | 2.3.1 | 3.0.3 | 호환 가능 |
| **MariaDB** | 기본 | 3.3.3 | 호환 가능 |
| **Swagger** | springdoc 1.7.0 | springdoc 2.6.0 | 버전 차이 |
| **Lombok** | 기본 | 1.18.34 | 호환 가능 |
### 4.1 주요 호환성 이슈
#### Spring Boot 2.x → 3.x 주요 변경사항
1. **패키지 변경**: `javax.*``jakarta.*`
2. **최소 Java 버전**: Java 8 → Java 17
3. **Spring Security**: 아키텍처 변경
4. **Configuration Properties**: 일부 속성명 변경
#### HttpClient 4 → 5 주요 변경사항
1. **패키지명**: `org.apache.http.*``org.apache.hc.client5.*`
2. **API 재설계**: 빌더 패턴 강화
3. **클래스명 변경**: `HttpClientBuilder``HttpClients`
---
## 5. 통합 방식 선택 이유
### 방법 2: 직접 통합 (Spring Boot 2.7 다운그레이드)
#### 선택 이유
1. **내부 시스템 자체 완결**: 외부 API 호출 없이 내부 메서드 호출로 처리
2. **트랜잭션 일관성**: 단일 애플리케이션 내 DB 트랜잭션 관리
3. **배포 단순화**: 하나의 WAR 파일로 배포
4. **성능 최적화**: 네트워크 오버헤드 제거
#### 트레이드오프
- Spring Boot 3 → 2 다운그레이드 필요
- Java 17 → Java 8 호환성 작업 필요
- 최신 기술 스택 사용 불가
---
## 6. 주요 차이점 및 해결 방안
### 6.1 Spring Boot 버전 차이
#### 문제
- Spring Boot 3.3.4 → 2.7.18 다운그레이드
#### 해결 방안
```gradle
// VMIS-interface build.gradle 수정
plugins {
id 'org.springframework.boot' version '2.7.18'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
```
### 6.2 패키지 네임스페이스 변경
#### 문제
- `jakarta.*``javax.*` 전체 변경 필요
#### 영향 범위
```
jakarta.servlet.* → javax.servlet.*
jakarta.validation.* → javax.validation.*
jakarta.persistence.* → javax.persistence.*
jakarta.annotation.* → javax.annotation.*
```
#### 해결 방안
- 전체 파일에서 `jakarta``javax` 일괄 교체
- IDE의 Find & Replace 기능 활용
### 6.3 HttpClient 버전 차이
#### 문제
- Apache HttpClient 5 → 4 다운그레이드
#### GovernmentApiClient.java 수정 필요
```java
// Before (HttpClient 5)
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
// After (HttpClient 4)
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
```
### 6.4 Java 17 → Java 8 호환성
#### 주요 체크 포인트
1. **Text Blocks**: Java 15+ 기능 사용 시 일반 문자열로 변경
2. **Records**: Java 14+ 기능 사용 시 일반 클래스로 변경
3. **Switch Expressions**: Java 14+ 기능 사용 시 전통적 switch로 변경
4. **var 키워드**: Java 10+ 기능 (사용 가능하나 명시적 타입 권장)
#### 현재 VMIS-interface 코드 검토 필요
- 대부분 전통적 Java 문법 사용 예상
- Lombok 적극 활용 중 (호환 가능)
### 6.5 MyBatis 설정 차이
#### VMIS-interface mybatis-config.xml
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="callSettersOnNulls" value="true"/>
</settings>
</configuration>
```
#### VIPS 설정과 통합
- VIPS의 기존 mybatis-config.xml에 설정 병합
- mapper 위치 추가: `mybatis/mapper/vmis/**/*_maria.xml`
### 6.6 패키지 구조 변경
#### Before (VMIS-interface)
```
com.vmis.interfaceapp.*
```
#### After (VIPS 통합)
```
go.kr.project.vmis.*
```
#### 변경 계획
```
com.vmis.interfaceapp.config → go.kr.project.vmis.config
com.vmis.interfaceapp.controller → go.kr.project.vmis.controller
com.vmis.interfaceapp.service → go.kr.project.vmis.service
com.vmis.interfaceapp.client → go.kr.project.vmis.client
com.vmis.interfaceapp.model → go.kr.project.vmis.model
com.vmis.interfaceapp.mapper → go.kr.project.vmis.mapper
com.vmis.interfaceapp.util → go.kr.project.vmis.util
```
### 6.7 설정 파일 통합
#### VmisProperties 통합 방안
**Option 1**: VIPS의 application.yml에 vmis 섹션 추가
```yaml
# VIPS application.yml
vmis:
system:
info-sys-id: "VMIS001"
...
government:
...
```
**Option 2**: application-vmis.yml 별도 파일 생성
```yaml
# application-vmis.yml
vmis:
...
```
**권장**: Option 1 (단일 설정 파일 유지)
### 6.8 GPKI 라이브러리 통합
#### 파일 위치
```
D:\workspace\git\VMIS-interface\lib\libgpkiapi_jni_1.5.jar
D:\workspace\git\VIPS\lib\libgpkiapi_jni_1.5.jar
```
#### build.gradle 수정
```gradle
dependencies {
implementation files('lib/libgpkiapi_jni_1.5.jar')
}
```
---
## 7. 마이그레이션 체크리스트
### Phase 1: 환경 준비
- [ ] 현재 브랜치 상태 확인 (이미 생성됨)
- [ ] VIPS 프로젝트 백업 (선택사항)
- [ ] GPKI 라이브러리 복사
### Phase 2: 코드 이식
- [ ] VmisProperties 이식 및 패키지 변경
- [ ] 설정 클래스 이식 (MyBatisConfig, OpenApiConfig)
- [ ] GovernmentApiClient 이식 (HttpClient 4 변경)
- [ ] 모델 클래스 이식 (entity, vo, dto)
- [ ] 서비스 클래스 이식
- [ ] 컨트롤러 이식
- [ ] Mapper 인터페이스 및 XML 이식
- [ ] 유틸리티 클래스 이식
### Phase 3: 설정 통합
- [ ] application.yml 설정 통합
- [ ] mybatis-config.xml 설정 병합
- [ ] logback-spring.xml 로그 설정 추가
- [ ] build.gradle 의존성 추가
### Phase 4: 패키지 변경
- [ ] jakarta → javax 일괄 변경
- [ ] com.vmis.interfaceapp → go.kr.project.vmis 변경
- [ ] import 문 정리
### Phase 5: 데이터베이스
- [ ] 데이터베이스 연결 테스트 (테이블은 이미 존재)
### Phase 6: 빌드 및 테스트
- [ ] Gradle 빌드 성공 확인
- [ ] 애플리케이션 구동 확인
- [ ] API 엔드포인트 테스트
- [ ] 정부 API 연동 테스트
- [ ] 로그 저장 확인
### Phase 7: 기존 코드 정리
- [ ] ExternalVehicleApiService 코드 리팩토링
- [ ] 불필요한 REST 호출 로직 제거
- [ ] 내부 메서드 호출로 변경
### Phase 8: 문서화 및 배포
- [ ] API 문서 업데이트
- [ ] 운영 가이드 작성
- [ ] 코드 리뷰
- [ ] main 브랜치 머지
---
## 8. 주요 파일 절대 경로
### VIPS
```
D:\workspace\git\VIPS\src\main\java\egovframework\config\RestTemplateConfig.java
D:\workspace\git\VIPS\src\main\java\go\kr\project\externalApi\service\ExternalVehicleApiService.java
D:\workspace\git\VIPS\src\main\resources\application.yml
D:\workspace\git\VIPS\build.gradle
```
### VMIS-interface
```
D:\workspace\git\VMIS-interface\src\main\java\com\vmis\interfaceapp\config\VmisProperties.java
D:\workspace\git\VMIS-interface\src\main\java\com\vmis\interfaceapp\client\GovernmentApiClient.java
D:\workspace\git\VMIS-interface\src\main\resources\application.yml
D:\workspace\git\VMIS-interface\lib\libgpkiapi_jni_1.5.jar
D:\workspace\git\VMIS-interface\ddl\vips\*.sql
```
---
## 9. 위험 요소 및 대응 방안
### 9.1 Spring Boot 다운그레이드 실패
**위험**: 일부 Spring Boot 3 전용 기능 사용 시 빌드 실패
**대응**: 코드 리뷰 후 대체 코드 작성
### 9.2 GPKI 암호화 라이브러리 호환성
**위험**: GPKI JNI 라이브러리가 특정 Java 버전에서만 작동
**대응**: 개발환경(gpki.enabled=false)에서 먼저 테스트
### 9.3 HttpClient 버전 차이
**위험**: API 차이로 인한 런타임 에러
**대응**: GovernmentApiClient 전면 재작성 고려
### 9.4 데이터베이스 트랜잭션
**위험**: 기존 VIPS와 새로운 VMIS 로직의 트랜잭션 충돌
**대응**: @Transactional 범위 명확히 설정
---
## 10. 예상 작업 시간
| 단계 | 예상 시간 | 비고 |
|------|----------|------|
| Phase 1: 환경 준비 | 20분 | 디렉토리 생성, 라이브러리 복사 |
| Phase 2: 코드 이식 | 3시간 | 34개 파일 이식 |
| Phase 3: 설정 통합 | 1시간 | YAML, XML 병합 |
| Phase 4: 패키지 변경 | 1시간 | 일괄 변경 |
| Phase 5: 데이터베이스 | 10분 | 연결 테스트 (테이블 기존재) |
| Phase 6: 빌드/테스트 | 2시간 | 디버깅 포함 |
| Phase 7: 기존 코드 정리 | 1시간 | 리팩토링 |
| Phase 8: 문서화 | 1시간 | 문서 작성 |
| **총 예상 시간** | **9시간 20분** | 순수 작업 시간 |
---
## 11. 다음 단계
상세한 마이그레이션 계획은 `VMIS_INTERFACE_MIGRATION_PLAN.md` 파일을 참조하세요.
**작업 진행 방법**:
브랜치는 이미 생성되어 있으므로, `VMIS_INTERFACE_MIGRATION_PLAN.md`의 Phase 1부터 시작하세요.
```bash
cd D:\workspace\git\VIPS
git status # 현재 브랜치 확인
```
---
**문서 버전**: 1.1
**최종 수정**: 2025-11-06

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save