feat: VMIS 통합 모드 전환 기능 구현 (Strategy Pattern)
내부/외부 API 호출을 YAML 설정으로 전환할 수 있는 Strategy Pattern 구현
## 주요 변경사항
### 1. Strategy Pattern 구현
- VehicleInfoService 인터페이스 생성 (공통 추상화)
- InternalVehicleInfoServiceImpl: 내부 VMIS 모듈 직접 호출
- ExternalVehicleInfoServiceImpl: 외부 REST API 호출
- @ConditionalOnProperty로 mode에 따라 Bean 자동 선택
### 2. Bean 충돌 해결
- HttpClientConfig의 restTemplate → vmisRestTemplate으로 변경
- GovernmentApiClient에 @Qualifier("vmisRestTemplate") 추가
- 기존 RestTemplateConfig와 충돌 방지
### 3. 설정 확장
- VmisProperties에 integration, external 속성 추가
- vmis.integration.mode: internal/external 설정 지원
- vmis.external.api.url: 외부 API 서버 URL 설정
### 4. 모델 변환 유틸리티
- VehicleResponseMapper 생성
- 내부 모델(BasicResponse, LedgerResponse) → 외부 VO 변환
### 5. 모니터링 및 로깅
- VmisIntegrationConfig: 시작 시 활성 모드 출력
- 각 구현체에 [Internal Mode]/[External Mode] 로그 추가
## 사용 방법
### Internal Mode (내부 모듈 직접 호출)
```yaml
vmis:
integration:
mode: internal
```
### External Mode (외부 REST API 호출)
```yaml
vmis:
integration:
mode: external
external:
api:
url: http://localhost:8081/api/v1/vehicles
```
## 빌드 성공 확인 ✅
- Bean 충돌 해결 완료
- 전체 컴파일 성공
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
internalApi
parent
ebcd17a6f0
commit
be4c926029
@ -0,0 +1,61 @@
|
||||
package go.kr.project.common.service;
|
||||
|
||||
import go.kr.project.externalApi.vo.VehicleApiResponseVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 차량 정보 조회 서비스 인터페이스
|
||||
*
|
||||
* <p>이 인터페이스는 차량 정보를 조회하는 두 가지 구현체를 추상화합니다:</p>
|
||||
* <ul>
|
||||
* <li>InternalVehicleInfoServiceImpl: 내부 VMIS 모듈을 직접 호출 (vmis.integration.mode=internal)</li>
|
||||
* <li>ExternalVehicleInfoServiceImpl: 외부 REST API를 호출 (vmis.integration.mode=external)</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h3>설정 방법:</h3>
|
||||
* <pre>
|
||||
* # application.yml
|
||||
* vmis:
|
||||
* integration:
|
||||
* mode: internal # 또는 external
|
||||
* </pre>
|
||||
*
|
||||
* <h3>사용 예시:</h3>
|
||||
* <pre>
|
||||
* {@code
|
||||
* @Autowired
|
||||
* private VehicleInfoService vehicleInfoService;
|
||||
*
|
||||
* // 단일 차량 조회
|
||||
* VehicleApiResponseVO response = vehicleInfoService.getVehicleInfo("12가3456");
|
||||
*
|
||||
* // 여러 차량 일괄 조회
|
||||
* List<VehicleApiResponseVO> responses = vehicleInfoService.getVehiclesInfo(
|
||||
* Arrays.asList("12가3456", "34나5678")
|
||||
* );
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public interface VehicleInfoService {
|
||||
|
||||
/**
|
||||
* 단일 차량번호에 대한 정보 조회
|
||||
*
|
||||
* <p>차량 기본정보와 등록원부 정보를 함께 조회합니다.</p>
|
||||
*
|
||||
* @param vehicleNumber 차량번호
|
||||
* @return 차량 정보 응답 (기본정보 + 등록원부 정보)
|
||||
*/
|
||||
VehicleApiResponseVO getVehicleInfo(String vehicleNumber);
|
||||
|
||||
/**
|
||||
* 여러 차량번호에 대한 정보를 일괄 조회
|
||||
*
|
||||
* <p>각 차량에 대해 기본정보와 등록원부 정보를 함께 조회합니다.</p>
|
||||
*
|
||||
* @param vehicleNumbers 차량번호 리스트
|
||||
* @return 차량 정보 응답 리스트
|
||||
*/
|
||||
List<VehicleApiResponseVO> getVehiclesInfo(List<String> vehicleNumbers);
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
package go.kr.project.externalApi.service;
|
||||
|
||||
import go.kr.project.common.service.VehicleInfoService;
|
||||
import go.kr.project.externalApi.vo.VehicleApiResponseVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 외부 REST API를 호출하는 차량 정보 조회 서비스 구현체
|
||||
*
|
||||
* <p>이 구현체는 외부 VMIS-interface 서버의 REST API를 호출하여
|
||||
* 차량 정보를 조회합니다. 기존 ExternalVehicleApiService를 그대로 활용합니다.</p>
|
||||
*
|
||||
* <h3>활성화 조건:</h3>
|
||||
* <pre>
|
||||
* # application.yml
|
||||
* vmis:
|
||||
* integration:
|
||||
* mode: external
|
||||
* </pre>
|
||||
*
|
||||
* <h3>처리 흐름:</h3>
|
||||
* <ol>
|
||||
* <li>기존 ExternalVehicleApiService에 요청 위임</li>
|
||||
* <li>ExternalVehicleApiService가 외부 REST API 호출</li>
|
||||
* <li>결과를 그대로 반환</li>
|
||||
* </ol>
|
||||
*
|
||||
* <h3>외부 API 서버:</h3>
|
||||
* <ul>
|
||||
* <li>서버 URL: vmis.external.api.url 설정값 사용</li>
|
||||
* <li>기본값: http://localhost:8081/api/v1/vehicles</li>
|
||||
* <li>별도의 VMIS-interface 프로젝트가 실행 중이어야 함</li>
|
||||
* </ul>
|
||||
*
|
||||
* @see VehicleInfoService
|
||||
* @see ExternalVehicleApiService
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnProperty(name = "vmis.integration.mode", havingValue = "external", matchIfMissing = true)
|
||||
public class ExternalVehicleInfoServiceImpl implements VehicleInfoService {
|
||||
|
||||
private final ExternalVehicleApiService externalVehicleApiService;
|
||||
|
||||
@Override
|
||||
public VehicleApiResponseVO getVehicleInfo(String vehicleNumber) {
|
||||
log.info("[External Mode] 차량 정보 조회 시작 - 차량번호: {}", vehicleNumber);
|
||||
|
||||
VehicleApiResponseVO response = externalVehicleApiService.getVehicleInfo(vehicleNumber);
|
||||
|
||||
if (response.isSuccess()) {
|
||||
log.info("[External Mode] 차량번호 {} 조회 성공", vehicleNumber);
|
||||
} else {
|
||||
log.warn("[External Mode] 차량번호 {} 조회 실패 - {}", vehicleNumber, response.getMessage());
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VehicleApiResponseVO> getVehiclesInfo(List<String> vehicleNumbers) {
|
||||
log.info("[External Mode] 차량 정보 일괄 조회 시작 - 대상 차량 수: {}", vehicleNumbers.size());
|
||||
|
||||
List<VehicleApiResponseVO> responses = externalVehicleApiService.getVehiclesInfo(vehicleNumbers);
|
||||
|
||||
int successCount = 0;
|
||||
for (VehicleApiResponseVO response : responses) {
|
||||
if (response.isSuccess()) {
|
||||
successCount++;
|
||||
}
|
||||
}
|
||||
|
||||
log.info("[External Mode] 차량 정보 일괄 조회 완료 - 성공: {}, 실패: {}",
|
||||
successCount, vehicleNumbers.size() - successCount);
|
||||
|
||||
return responses;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
package go.kr.project.vmis.config;
|
||||
|
||||
import go.kr.project.common.service.VehicleInfoService;
|
||||
import go.kr.project.vmis.config.properties.VmisProperties;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* VMIS 통합 설정 및 모니터링
|
||||
*
|
||||
* <p>이 설정 클래스는 VMIS 통합 모드에 대한 정보를 제공하고,
|
||||
* 애플리케이션 시작 시 현재 활성화된 모드를 로그로 출력합니다.</p>
|
||||
*
|
||||
* <h3>주요 기능:</h3>
|
||||
* <ul>
|
||||
* <li>애플리케이션 시작 시 VMIS 통합 모드 출력</li>
|
||||
* <li>활성화된 VehicleInfoService 구현체 표시</li>
|
||||
* <li>설정 검증 및 경고 메시지 출력</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h3>지원하는 모드:</h3>
|
||||
* <ul>
|
||||
* <li>internal: 내부 VMIS 모듈 직접 호출 (InternalVehicleInfoServiceImpl)</li>
|
||||
* <li>external: 외부 REST API 호출 (ExternalVehicleInfoServiceImpl)</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class VmisIntegrationConfig {
|
||||
|
||||
private final VmisProperties vmisProperties;
|
||||
|
||||
/**
|
||||
* VMIS 통합 모드 정보 출력
|
||||
*
|
||||
* <p>애플리케이션 시작 시 현재 설정된 VMIS 통합 모드와
|
||||
* 관련 설정 정보를 로그로 출력합니다.</p>
|
||||
*
|
||||
* @param vehicleInfoService 활성화된 VehicleInfoService 구현체
|
||||
* @return CommandLineRunner
|
||||
*/
|
||||
@Bean
|
||||
public CommandLineRunner vmisIntegrationModeLogger(VehicleInfoService vehicleInfoService) {
|
||||
return args -> {
|
||||
String mode = vmisProperties.getIntegration().getMode();
|
||||
String implClass = vehicleInfoService.getClass().getSimpleName();
|
||||
|
||||
log.info("========================================");
|
||||
log.info("VMIS Integration Mode: {}", mode);
|
||||
log.info("Active Implementation: {}", implClass);
|
||||
log.info("========================================");
|
||||
|
||||
if ("internal".equalsIgnoreCase(mode)) {
|
||||
logInternalModeInfo();
|
||||
} else if ("external".equalsIgnoreCase(mode)) {
|
||||
logExternalModeInfo();
|
||||
} else {
|
||||
log.warn("알 수 없는 VMIS 통합 모드: {}. 'internal' 또는 'external'을 사용하세요.", mode);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal 모드 설정 정보 출력
|
||||
*/
|
||||
private void logInternalModeInfo() {
|
||||
log.info("[Internal Mode] 내부 VMIS 모듈을 직접 사용합니다");
|
||||
log.info(" - 정부 API 호스트: {}://{}",
|
||||
vmisProperties.getGov().getScheme(),
|
||||
vmisProperties.getGov().getHost());
|
||||
log.info(" - 기본사항 조회 경로: {}",
|
||||
vmisProperties.getGov().getServices().getBasic().getPath());
|
||||
log.info(" - 등록원부 조회 경로: {}",
|
||||
vmisProperties.getGov().getServices().getLedger().getPath());
|
||||
log.info(" - GPKI 암호화: {}",
|
||||
vmisProperties.getGpki().getEnabled());
|
||||
log.info(" - 연결 타임아웃: {}ms",
|
||||
vmisProperties.getGov().getConnectTimeoutMillis());
|
||||
log.info(" - 읽기 타임아웃: {}ms",
|
||||
vmisProperties.getGov().getReadTimeoutMillis());
|
||||
|
||||
if ("Y".equalsIgnoreCase(vmisProperties.getGpki().getEnabled())) {
|
||||
log.info(" - GPKI 인증서 서버 ID: {}",
|
||||
vmisProperties.getGpki().getCertServerId());
|
||||
log.info(" - GPKI 대상 서버 ID: {}",
|
||||
vmisProperties.getGpki().getTargetServerId());
|
||||
} else {
|
||||
log.warn(" - GPKI 암호화가 비활성화되어 있습니다. 개발 환경에서만 사용하세요.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* External 모드 설정 정보 출력
|
||||
*/
|
||||
private void logExternalModeInfo() {
|
||||
log.info("[External Mode] 외부 REST API를 사용합니다");
|
||||
log.info(" - 외부 API URL: {}",
|
||||
vmisProperties.getExternal().getApi().getUrl());
|
||||
log.info(" - 연결 타임아웃: {}ms",
|
||||
vmisProperties.getExternal().getApi().getConnectTimeoutMillis());
|
||||
log.info(" - 읽기 타임아웃: {}ms",
|
||||
vmisProperties.getExternal().getApi().getReadTimeoutMillis());
|
||||
log.warn(" - 외부 VMIS-interface 서버가 실행 중이어야 합니다.");
|
||||
log.info(" - 기본사항 조회: POST {}/basic",
|
||||
vmisProperties.getExternal().getApi().getUrl());
|
||||
log.info(" - 등록원부 조회: POST {}/ledger",
|
||||
vmisProperties.getExternal().getApi().getUrl());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,219 @@
|
||||
package go.kr.project.vmis.service;
|
||||
|
||||
import go.kr.project.common.service.VehicleInfoService;
|
||||
import go.kr.project.externalApi.vo.VehicleApiResponseVO;
|
||||
import go.kr.project.externalApi.vo.VehicleBasicInfoVO;
|
||||
import go.kr.project.externalApi.vo.VehicleLedgerVO;
|
||||
import go.kr.project.vmis.model.basic.BasicRequest;
|
||||
import go.kr.project.vmis.model.basic.BasicResponse;
|
||||
import go.kr.project.vmis.model.common.Envelope;
|
||||
import go.kr.project.vmis.model.ledger.LedgerRequest;
|
||||
import go.kr.project.vmis.model.ledger.LedgerResponse;
|
||||
import go.kr.project.vmis.util.VehicleResponseMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 내부 VMIS 모듈을 직접 호출하는 차량 정보 조회 서비스 구현체
|
||||
*
|
||||
* <p>이 구현체는 외부 REST API 호출 없이 내부 VMIS 모듈을 직접 사용하여
|
||||
* 정부 시스템과 통신합니다. 네트워크 오버헤드가 없어 성능이 향상됩니다.</p>
|
||||
*
|
||||
* <h3>활성화 조건:</h3>
|
||||
* <pre>
|
||||
* # application.yml
|
||||
* vmis:
|
||||
* integration:
|
||||
* mode: internal
|
||||
* </pre>
|
||||
*
|
||||
* <h3>처리 흐름:</h3>
|
||||
* <ol>
|
||||
* <li>차량번호를 받아 BasicRequest, LedgerRequest 생성</li>
|
||||
* <li>CarBassMatterInqireService.basic() 호출 (기본정보)</li>
|
||||
* <li>CarLedgerFrmbkService.ledger() 호출 (등록원부)</li>
|
||||
* <li>내부 모델을 외부 VO로 변환 (VehicleResponseMapper 사용)</li>
|
||||
* <li>VehicleApiResponseVO로 결과 반환</li>
|
||||
* </ol>
|
||||
*
|
||||
* @see VehicleInfoService
|
||||
* @see CarBassMatterInqireService
|
||||
* @see CarLedgerFrmbkService
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnProperty(name = "vmis.integration.mode", havingValue = "internal")
|
||||
public class InternalVehicleInfoServiceImpl implements VehicleInfoService {
|
||||
|
||||
private final CarBassMatterInqireService carBassMatterInqireService;
|
||||
private final CarLedgerFrmbkService carLedgerFrmbkService;
|
||||
|
||||
@Override
|
||||
public VehicleApiResponseVO getVehicleInfo(String vehicleNumber) {
|
||||
log.info("[Internal Mode] 차량 정보 조회 시작 - 차량번호: {}", vehicleNumber);
|
||||
|
||||
VehicleApiResponseVO response = new VehicleApiResponseVO();
|
||||
response.setVhrno(vehicleNumber);
|
||||
|
||||
try {
|
||||
// 1. 차량 기본정보 조회
|
||||
VehicleBasicInfoVO basicInfo = getBasicInfo(vehicleNumber);
|
||||
response.setBasicInfo(basicInfo);
|
||||
|
||||
// 2. 자동차 등록원부 조회
|
||||
VehicleLedgerVO ledgerInfo = getLedgerInfo(vehicleNumber);
|
||||
response.setLedgerInfo(ledgerInfo);
|
||||
|
||||
// 3. 결과 검증
|
||||
if (basicInfo != null && "00".equals(basicInfo.getCntcResultCode())) {
|
||||
response.setSuccess(true);
|
||||
response.setMessage("조회 성공");
|
||||
log.info("[Internal Mode] 차량번호 {} 조회 성공", vehicleNumber);
|
||||
} else {
|
||||
response.setSuccess(false);
|
||||
response.setMessage(basicInfo != null ? basicInfo.getCntcResultDtls() : "조회 실패");
|
||||
log.warn("[Internal Mode] 차량번호 {} 조회 실패 - {}", vehicleNumber, response.getMessage());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
response.setSuccess(false);
|
||||
response.setMessage("내부 API 호출 오류: " + e.getMessage());
|
||||
log.error("[Internal Mode] 차량번호 {} 내부 API 호출 중 오류 발생", vehicleNumber, e);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VehicleApiResponseVO> getVehiclesInfo(List<String> vehicleNumbers) {
|
||||
log.info("[Internal Mode] 차량 정보 일괄 조회 시작 - 대상 차량 수: {}", vehicleNumbers.size());
|
||||
|
||||
List<VehicleApiResponseVO> responses = new ArrayList<VehicleApiResponseVO>();
|
||||
|
||||
for (String vehicleNumber : vehicleNumbers) {
|
||||
try {
|
||||
VehicleApiResponseVO response = getVehicleInfo(vehicleNumber);
|
||||
responses.add(response);
|
||||
} catch (Exception e) {
|
||||
log.error("[Internal Mode] 차량번호 {} 조회 중 오류 발생: {}", vehicleNumber, e.getMessage(), e);
|
||||
|
||||
// 오류 발생 시에도 응답 객체 생성하여 추가
|
||||
VehicleApiResponseVO errorResponse = VehicleApiResponseVO.builder()
|
||||
.vhrno(vehicleNumber)
|
||||
.success(false)
|
||||
.message("조회 실패: " + e.getMessage())
|
||||
.build();
|
||||
responses.add(errorResponse);
|
||||
}
|
||||
}
|
||||
|
||||
log.info("[Internal Mode] 차량 정보 일괄 조회 완료 - 성공: {}, 실패: {}",
|
||||
countSuccessful(responses),
|
||||
vehicleNumbers.size() - countSuccessful(responses));
|
||||
|
||||
return responses;
|
||||
}
|
||||
|
||||
/**
|
||||
* 차량 기본정보 조회 (내부 모듈 직접 호출)
|
||||
*
|
||||
* @param vehicleNumber 차량번호
|
||||
* @return 차량 기본정보 VO
|
||||
*/
|
||||
private VehicleBasicInfoVO getBasicInfo(String vehicleNumber) {
|
||||
log.debug("[Internal Mode] 차량 기본정보 조회 - 차량번호: {}", vehicleNumber);
|
||||
|
||||
// 요청 객체 생성 - 차량번호만 설정 (나머지는 RequestEnricher가 자동 설정)
|
||||
BasicRequest request = new BasicRequest();
|
||||
request.setVhrno(vehicleNumber);
|
||||
|
||||
// Envelope로 감싸기
|
||||
Envelope<BasicRequest> requestEnvelope = new Envelope<BasicRequest>();
|
||||
requestEnvelope.setData(Collections.singletonList(request));
|
||||
|
||||
try {
|
||||
// 내부 서비스 호출
|
||||
ResponseEntity<Envelope<BasicResponse>> responseEntity =
|
||||
carBassMatterInqireService.basic(requestEnvelope);
|
||||
|
||||
if (responseEntity.getBody() != null &&
|
||||
responseEntity.getBody().getData() != null &&
|
||||
!responseEntity.getBody().getData().isEmpty()) {
|
||||
|
||||
BasicResponse basicResponse = responseEntity.getBody().getData().get(0);
|
||||
|
||||
// 내부 모델을 외부 VO로 변환
|
||||
return VehicleResponseMapper.toVehicleBasicInfoVO(basicResponse);
|
||||
}
|
||||
|
||||
log.warn("[Internal Mode] 차량 기본정보 조회 응답이 비어있음 - 차량번호: {}", vehicleNumber);
|
||||
return null;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("[Internal Mode] 차량 기본정보 조회 실패 - 차량번호: {}", vehicleNumber, e);
|
||||
throw new RuntimeException("차량 기본정보 조회 실패: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 자동차 등록원부(갑) 조회 (내부 모듈 직접 호출)
|
||||
*
|
||||
* @param vehicleNumber 차량번호
|
||||
* @return 등록원부 정보 VO
|
||||
*/
|
||||
private VehicleLedgerVO getLedgerInfo(String vehicleNumber) {
|
||||
log.debug("[Internal Mode] 자동차 등록원부 조회 - 차량번호: {}", vehicleNumber);
|
||||
|
||||
// 요청 객체 생성 - 차량번호만 설정 (나머지는 RequestEnricher가 자동 설정)
|
||||
LedgerRequest request = new LedgerRequest();
|
||||
request.setVhrno(vehicleNumber);
|
||||
|
||||
// Envelope로 감싸기
|
||||
Envelope<LedgerRequest> requestEnvelope = new Envelope<LedgerRequest>();
|
||||
requestEnvelope.setData(Collections.singletonList(request));
|
||||
|
||||
try {
|
||||
// 내부 서비스 호출
|
||||
ResponseEntity<Envelope<LedgerResponse>> responseEntity =
|
||||
carLedgerFrmbkService.ledger(requestEnvelope);
|
||||
|
||||
if (responseEntity.getBody() != null &&
|
||||
responseEntity.getBody().getData() != null &&
|
||||
!responseEntity.getBody().getData().isEmpty()) {
|
||||
|
||||
LedgerResponse ledgerResponse = responseEntity.getBody().getData().get(0);
|
||||
|
||||
// 내부 모델을 외부 VO로 변환
|
||||
return VehicleResponseMapper.toLedgerVO(ledgerResponse);
|
||||
}
|
||||
|
||||
log.warn("[Internal Mode] 자동차 등록원부 조회 응답이 비어있음 - 차량번호: {}", vehicleNumber);
|
||||
return null;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("[Internal Mode] 자동차 등록원부 조회 실패 - 차량번호: {}", vehicleNumber, e);
|
||||
throw new RuntimeException("자동차 등록원부 조회 실패: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 성공한 응답 개수 계산
|
||||
*/
|
||||
private int countSuccessful(List<VehicleApiResponseVO> responses) {
|
||||
int count = 0;
|
||||
for (VehicleApiResponseVO response : responses) {
|
||||
if (response.isSuccess()) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,165 @@
|
||||
package go.kr.project.vmis.util;
|
||||
|
||||
import go.kr.project.externalApi.vo.VehicleBasicInfoVO;
|
||||
import go.kr.project.externalApi.vo.VehicleLedgerVO;
|
||||
import go.kr.project.vmis.model.basic.BasicResponse;
|
||||
import go.kr.project.vmis.model.ledger.LedgerResponse;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 차량 응답 모델 변환 유틸리티
|
||||
*
|
||||
* <p>내부 VMIS 모델(BasicResponse, LedgerResponse)을
|
||||
* 외부 API VO(VehicleBasicInfoVO, VehicleLedgerVO)로 변환합니다.</p>
|
||||
*/
|
||||
public class VehicleResponseMapper {
|
||||
|
||||
/**
|
||||
* BasicResponse를 VehicleBasicInfoVO로 변환
|
||||
*
|
||||
* @param basicResponse 내부 기본정보 응답
|
||||
* @return 외부 API용 기본정보 VO
|
||||
*/
|
||||
public static VehicleBasicInfoVO toVehicleBasicInfoVO(BasicResponse basicResponse) {
|
||||
if (basicResponse == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
VehicleBasicInfoVO vo = new VehicleBasicInfoVO();
|
||||
vo.setCntcResultCode(basicResponse.getCntcResultCode());
|
||||
vo.setCntcResultDtls(basicResponse.getCntcResultDtls());
|
||||
|
||||
// record 변환
|
||||
if (basicResponse.getRecord() != null && !basicResponse.getRecord().isEmpty()) {
|
||||
List<VehicleBasicInfoVO.Record> records = new ArrayList<VehicleBasicInfoVO.Record>();
|
||||
for (BasicResponse.Record src : basicResponse.getRecord()) {
|
||||
VehicleBasicInfoVO.Record dest = new VehicleBasicInfoVO.Record();
|
||||
|
||||
// 주요 필드 매핑
|
||||
dest.setVhrno(src.getVhrno());
|
||||
dest.setVin(src.getVin());
|
||||
dest.setCnm(src.getCnm());
|
||||
dest.setMberNm(src.getMberNm());
|
||||
dest.setMberSeNo(src.getMberSeNo());
|
||||
dest.setMberSeCode(src.getMberSeCode());
|
||||
dest.setTelno(src.getTelno());
|
||||
dest.setPrye(src.getPrye());
|
||||
dest.setRegistDe(src.getRegistDe());
|
||||
dest.setFrstRegistDe(src.getFrstRegistDe());
|
||||
dest.setColorNm(src.getColorNm());
|
||||
dest.setDsplvl(src.getDsplvl());
|
||||
dest.setVhctyAsortNm(src.getVhctyAsortNm());
|
||||
dest.setVhctyTyNm(src.getVhctyTyNm());
|
||||
dest.setVhctySeNm(src.getVhctySeNm());
|
||||
dest.setInsptValidPdBgnde(src.getInsptValidPdBgnde());
|
||||
dest.setInsptValidPdEndde(src.getInsptValidPdEndde());
|
||||
dest.setUsgsrhldAdresFull(src.getUsgsrhldAdresFull());
|
||||
dest.setOwnerAdresFull(src.getOwnerAdresFull());
|
||||
|
||||
// 추가 필드
|
||||
dest.setErsrRegistSeCode(src.getErsrRegistSeCode());
|
||||
dest.setErsrRegistSeNm(src.getErsrRegistSeNm());
|
||||
dest.setErsrRegistDe(src.getErsrRegistDe());
|
||||
dest.setRegistDetailCode(src.getRegistDetailCode());
|
||||
dest.setUseStrnghldLegaldongCode(src.getUseStrnghldLegaldongCode());
|
||||
dest.setUseStrnghldAdstrdCode(src.getUseStrnghldAdstrdCode());
|
||||
dest.setUseStrnghldMntn(src.getUseStrnghldMntn());
|
||||
dest.setUseStrnghldLnbr(src.getUseStrnghldLnbr());
|
||||
dest.setUseStrnghldHo(src.getUseStrnghldHo());
|
||||
dest.setUseStrnghldAdresNm(src.getUseStrnghldAdresNm());
|
||||
dest.setVhcleTotWt(src.getVhcleTotWt());
|
||||
dest.setCaagEndde(src.getCaagEndde());
|
||||
dest.setVhctyAsortCode(src.getVhctyAsortCode());
|
||||
dest.setVhctyTyCode(src.getVhctyTyCode());
|
||||
dest.setVhctySeCode(src.getVhctySeCode());
|
||||
dest.setMxmmLdg(src.getMxmmLdg());
|
||||
dest.setFomNm(src.getFomNm());
|
||||
dest.setUseFuelCode(src.getUseFuelCode());
|
||||
dest.setPrposSeCode(src.getPrposSeCode());
|
||||
dest.setMtrsFomNm(src.getMtrsFomNm());
|
||||
dest.setAcqsAmount(src.getAcqsAmount());
|
||||
dest.setTkcarPscapCo(src.getTkcarPscapCo());
|
||||
dest.setSpmnno(src.getSpmnno());
|
||||
dest.setTrvlDstnc(src.getTrvlDstnc());
|
||||
|
||||
records.add(dest);
|
||||
}
|
||||
vo.setRecord(records);
|
||||
}
|
||||
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* LedgerResponse를 VehicleLedgerVO로 변환
|
||||
*
|
||||
* @param ledgerResponse 내부 등록원부 응답
|
||||
* @return 외부 API용 등록원부 VO
|
||||
*/
|
||||
public static VehicleLedgerVO toLedgerVO(LedgerResponse ledgerResponse) {
|
||||
if (ledgerResponse == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
VehicleLedgerVO vo = new VehicleLedgerVO();
|
||||
|
||||
// 연계 결과
|
||||
vo.setCntcResultCode(ledgerResponse.getCntcResultCode());
|
||||
vo.setCntcResultDtls(ledgerResponse.getCntcResultDtls());
|
||||
|
||||
// 마스터 정보 (VehicleLedgerVO에 실제 존재하는 필드만 설정)
|
||||
vo.setLedgerGroupNo(ledgerResponse.getLedgerGroupNo());
|
||||
vo.setLedgerIndvdlzNo(ledgerResponse.getLedgerIndvdlzNo());
|
||||
vo.setVhmno(ledgerResponse.getVhmno());
|
||||
vo.setVhrno(ledgerResponse.getVhrno());
|
||||
vo.setVin(ledgerResponse.getVin());
|
||||
vo.setVhctyAsortCode(ledgerResponse.getVhctyAsortCode());
|
||||
vo.setVhctyAsortNm(ledgerResponse.getVhctyAsortNm());
|
||||
vo.setCnm(ledgerResponse.getCnm());
|
||||
vo.setColorNm(ledgerResponse.getColorNm());
|
||||
vo.setPrposSeCode(ledgerResponse.getPrposSeCode());
|
||||
vo.setPrposSeNm(ledgerResponse.getPrposSeNm());
|
||||
vo.setMtrsFomNm(ledgerResponse.getMtrsFomNm());
|
||||
vo.setFomNm(ledgerResponse.getFomNm());
|
||||
vo.setAcqsAmount(ledgerResponse.getAcqsAmount());
|
||||
vo.setFrstRegistDe(ledgerResponse.getFrstRegistDe());
|
||||
vo.setCaagEndde(ledgerResponse.getCaagEndde());
|
||||
vo.setPrye(ledgerResponse.getPrye());
|
||||
vo.setYblMd(ledgerResponse.getYblMd());
|
||||
vo.setTrvlDstnc(ledgerResponse.getTrvlDstnc());
|
||||
vo.setInsptValidPdBgnde(ledgerResponse.getInsptValidPdBgnde());
|
||||
vo.setInsptValidPdEndde(ledgerResponse.getInsptValidPdEndde());
|
||||
vo.setNmplCsdyAt(ledgerResponse.getNmplCsdyAt());
|
||||
vo.setErsrRegistDe(ledgerResponse.getErsrRegistDe());
|
||||
vo.setErsrRegistSeCode(ledgerResponse.getErsrRegistSeCode());
|
||||
vo.setErsrRegistSeNm(ledgerResponse.getErsrRegistSeNm());
|
||||
vo.setAdres(ledgerResponse.getAdres());
|
||||
vo.setAdresNm(ledgerResponse.getAdresNm());
|
||||
vo.setTelno(ledgerResponse.getTelno());
|
||||
vo.setMberNm(ledgerResponse.getMberNm());
|
||||
vo.setMberSeCode(ledgerResponse.getMberSeCode());
|
||||
vo.setMberSeNo(ledgerResponse.getMberSeNo());
|
||||
|
||||
// record 변경내역 변환
|
||||
if (ledgerResponse.getRecord() != null && !ledgerResponse.getRecord().isEmpty()) {
|
||||
List<VehicleLedgerVO.Record> records = new ArrayList<VehicleLedgerVO.Record>();
|
||||
for (LedgerResponse.Record src : ledgerResponse.getRecord()) {
|
||||
VehicleLedgerVO.Record dest = new VehicleLedgerVO.Record();
|
||||
dest.setMainchk(src.getMainchk());
|
||||
dest.setChangeJobSeCode(src.getChangeJobSeCode());
|
||||
dest.setMainno(src.getMainno());
|
||||
dest.setSubno(src.getSubno());
|
||||
dest.setDtls(src.getDtls());
|
||||
dest.setChangeDe(src.getChangeDe());
|
||||
dest.setGubunNm(src.getGubunNm());
|
||||
records.add(dest);
|
||||
}
|
||||
vo.setRecord(records);
|
||||
}
|
||||
|
||||
return vo;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue