Merge remote-tracking branch 'origin/jenkins_with_weblogic' of C:/KJB_DEV/eapim-bundle/bundles/251128/eapim-admin-kjb_incremental_2025-11-01.bundle into jenkins_with_weblogic
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## 프로젝트 개요
|
||||
|
||||
`eapim-admin-kjb`는 광주은행(KJB) 전용 커스터마이징을 위한 eapim-admin 확장 모듈입니다. 빠른 부팅 속도를 위해 메인 eapim-admin 프로젝트에서 분리되어 독립적으로 테스트할 수 있습니다.
|
||||
|
||||
## 빌드 및 테스트 명령어
|
||||
|
||||
```bash
|
||||
# 빌드
|
||||
gradle build
|
||||
gradle clean build
|
||||
|
||||
# 테스트 실행 (환경변수 필요)
|
||||
KJB_EAPIM_TEST_ENABLED=TRUE gradle :eapim-admin-kjb:test
|
||||
|
||||
# 특정 테스트 클래스 실행
|
||||
KJB_EAPIM_TEST_ENABLED=TRUE gradle :eapim-admin-kjb:test --tests "com.eactive.ext.kjb.ums.test.UmsTest.testSms"
|
||||
KJB_EAPIM_TEST_ENABLED=TRUE gradle :eapim-admin-kjb:test --tests "com.eactive.ext.kjb.ums.test.UmsTest.testEmail"
|
||||
|
||||
# SafeDB 실제 모드로 테스트 (Linux 서버)
|
||||
KJB_EAPIM_TEST_ENABLED=TRUE gradle :eapim-admin-kjb:test -Psafedb
|
||||
```
|
||||
|
||||
**테스트 실행 조건**: `KJB_EAPIM_TEST_ENABLED=TRUE` 환경변수가 설정되어야 UMS/이메일 테스트가 실행됩니다.
|
||||
|
||||
## 모듈 의존성
|
||||
|
||||
```
|
||||
eapim-admin-kjb
|
||||
├── elink-portal-common # JPA 엔티티 (MessageRequest, MessageCode 등)
|
||||
└── kjb-safedb # 암호화 라이브러리
|
||||
```
|
||||
|
||||
의존 모듈들은 `../elink-portal-common/`, `../kjb-safedb/` 경로에 위치합니다.
|
||||
|
||||
## 아키텍처
|
||||
|
||||
### 주요 컴포넌트
|
||||
|
||||
| 컴포넌트 | 위치 | 설명 |
|
||||
|---------|------|------|
|
||||
| `KjbProperty` | `common/` | DB 테이블 `TSEAIRM24`에서 로드되는 설정 관리. `@KjbPropertyValue` 애노테이션으로 키 매핑 |
|
||||
| `KjbEaiBatchModule` | `eai/` | EAI 배치 시스템 HTTP 연동. 파일 기반 배치 전송 및 보관 기간 관리 |
|
||||
| `KjbUmsService` | `ums/` | UMS API를 통한 카카오 알림톡 발송 |
|
||||
| `KjbEmailSendModule` | `ums/` | EAI 배치를 통한 이메일 발송. 파일 생성 후 배치 호출 |
|
||||
| `KjbObpModule` | `obp/` | OBP(Open Banking Platform) API 연동 |
|
||||
|
||||
### 프로퍼티 키 목록 (`KjbProperty.java`)
|
||||
|
||||
**EAI 배치 연동**
|
||||
- `kjb.eai.batch.url` - EAI 배치 서버 URL
|
||||
- `kjb.eai.batch.connection_timeout` - 연결 타임아웃 (초, 기본값: 5)
|
||||
- `kjb.eai.batch.response_timeout` - 응답 타임아웃 (초, 기본값: 5)
|
||||
- `kjb.eai.batch.charset` - 문자셋 (기본값: euc-kr)
|
||||
|
||||
**이메일 발송 (EAI 배치 경유)**
|
||||
- `kjb.ums.eai_batch.send_dir` - 발송 파일 디렉토리
|
||||
- `kjb.ums.eai_batch.backup_dir` - 백업 디렉토리
|
||||
- `kjb.ums.eai_batch.error_dir` - 에러 디렉토리
|
||||
- `kjb.ums.eai_batch.interface_id` - 인터페이스 ID (13자리)
|
||||
- `kjb.ums.eai_batch.retention_date` - 파일 보관 기간 (일, 기본값: 60)
|
||||
|
||||
**UMS (카카오 알림톡)**
|
||||
- `kjb.ums.host` - UMS API 엔드포인트
|
||||
- `kjb.ums.api_key` - API 인증 키 (36자리 UUID 형식)
|
||||
- `kjb.ums.connection_timeout` - 연결 타임아웃 (초, 기본값: 5)
|
||||
- `kjb.ums.response_timeout` - 응답 타임아웃 (초, 기본값: 5)
|
||||
|
||||
**OBP 연동**
|
||||
- `kjb.obp.url` - OBP API URL
|
||||
- `kjb.obp.trust_system.key/value` - 신뢰 시스템 헤더
|
||||
- `kjb.obp.partner_code.key/value` - 파트너 코드 헤더
|
||||
|
||||
### 메시지 채널
|
||||
|
||||
- `KjbUmsService`: 카카오 알림톡 (`MessageCode.Channels.KAKAO_ALIMTALK`)
|
||||
- `KjbEmailSendModule`: 이메일 (`MessageCode.Channels.EMAIL`)
|
||||
|
||||
## 로컬 개발 환경 (Windows)
|
||||
|
||||
테스트 시 `OsUtil.isWindows()` 조건으로 로컬 경로가 자동 설정됩니다:
|
||||
- 발송 디렉토리: `c:\kjb-logs\sendmail\snd`
|
||||
- 백업 디렉토리: `c:\kjb-logs\sendmail\bak`
|
||||
- 에러 디렉토리: `c:\kjb-logs\sendmail\error`
|
||||
|
||||
URL이 빈 문자열로 설정되면 실제 API 호출 없이 모의 응답을 반환합니다.
|
||||
|
||||
## 기술 스택
|
||||
|
||||
- **Java 8**: Gradle toolchain 강제
|
||||
- **Spring Framework 5.3**: 의존성 주입
|
||||
- **Apache HttpClient 5.1**: HTTP 통신
|
||||
- **Gson 2.3.1**: JSON 처리
|
||||
- **Lombok 1.18.28**: 보일러플레이트 코드 생성
|
||||
- **JUnit 5**: 테스트 프레임워크
|
||||
- **Logback 1.2.10**: 로깅
|
||||
|
||||
## 패키지 구조
|
||||
|
||||
```
|
||||
com.eactive.ext.kjb
|
||||
├── common/ # 공통 (KjbProperty, 예외 클래스)
|
||||
├── eai/ # EAI 배치 연동
|
||||
├── obp/ # OBP API 연동
|
||||
│ └── common/ # OBP HTTP 클라이언트
|
||||
├── ums/ # UMS/이메일 발송
|
||||
│ └── gson/ # UMS 요청/응답 JSON 모델
|
||||
└── utils/ # 유틸리티 (JSON, 검증, OS 판별)
|
||||
```
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.eactive.ext.kjb.common;
|
||||
|
||||
public class KjbObpException extends Exception {
|
||||
private int statusCode;
|
||||
|
||||
public KjbObpException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public KjbObpException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public KjbObpException(int statusCode, String message) {
|
||||
super(message);
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
||||
public int getStatusCode() {
|
||||
return statusCode;
|
||||
}
|
||||
}
|
||||
@@ -91,6 +91,18 @@ public class KjbProperty {
|
||||
@NotEmpty
|
||||
private String obpPartnerCodeValue = "100001-01";
|
||||
|
||||
@KjbPropertyValue(key = "kjb.obp.connection_timeout", defaultValue = "5")
|
||||
@Min(1) @Max(10)
|
||||
private int obpConnectionTimeout = 5;
|
||||
|
||||
@KjbPropertyValue(key = "kjb.obp.response_timeout", defaultValue = "5")
|
||||
@Min(1) @Max(30)
|
||||
private int obpResponseTimeout = 5;
|
||||
|
||||
@KjbPropertyValue(key = "kjb.obp.timeout", defaultValue = "10")
|
||||
@Min(1) @Max(30)
|
||||
private int obpTimeout = 10;
|
||||
|
||||
|
||||
@KjbPropertyValue(key = "kjb.obp.url.commission", defaultValue = "/api/billing/billing/findBillingForCondition")
|
||||
@NotEmpty
|
||||
|
||||
@@ -1,36 +1,84 @@
|
||||
package com.eactive.ext.kjb.obp;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.eactive.ext.kjb.common.KjbObpException;
|
||||
import com.eactive.ext.kjb.common.KjbProperty;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
public class KjbObpModule {
|
||||
private static final String FAKE_PARTNER_CODE = "999999-99";
|
||||
|
||||
private static KjbObpModule _instance;
|
||||
|
||||
private final KjbProperty property;
|
||||
private final ObpClient client;
|
||||
|
||||
public static synchronized KjbObpModule getInstance(KjbProperty kjbProperty) {
|
||||
if (_instance == null) {
|
||||
_instance = new KjbObpModule(kjbProperty);
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
private KjbObpModule(KjbProperty kjbProperty) {
|
||||
if (kjbProperty == null) {
|
||||
throw new IllegalArgumentException("KjbProperty cannot be null");
|
||||
}
|
||||
this.property = kjbProperty;
|
||||
this.client = ObpClient.getInstance(kjbProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim, 숫자이외 자동 치환
|
||||
* @param bizNo
|
||||
* @return
|
||||
* 사업자등록번호로 partnerCode 조회
|
||||
* @param bizNo 사업자등록번호 (숫자 외 문자 자동 제거)
|
||||
* @return partnerCode
|
||||
* @throws KjbObpException 조회 실패 시
|
||||
*/
|
||||
public static JsonObject queryOrganization(String bizNo) {
|
||||
public String queryPartnerCode(String bizNo) throws KjbObpException {
|
||||
bizNo = ObpUtil.onlyDigit(bizNo);
|
||||
|
||||
if (StringUtils.isEmpty(bizNo)) {
|
||||
throw new IllegalArgumentException("BizNo is not empty.");
|
||||
throw new IllegalArgumentException("BizNo is empty.");
|
||||
}
|
||||
|
||||
if (bizNo.length() != 10) {
|
||||
throw new IllegalArgumentException("BizNo is not valid.");
|
||||
throw new IllegalArgumentException("BizNo must be 10 digits. (input: " + bizNo + ")");
|
||||
}
|
||||
|
||||
return null;
|
||||
// 가상모드: URL 미설정 시 가상 파트너코드 반환
|
||||
if (!client.isRealMode()) {
|
||||
log.info("[OBP] 가상모드 - 가상 partnerCode 반환: {}", FAKE_PARTNER_CODE);
|
||||
return FAKE_PARTNER_CODE;
|
||||
}
|
||||
|
||||
String path = String.format(property.getObpUrlOrganizationFmt(), bizNo);
|
||||
log.debug("[OBP] queryPartnerCode - bizNo: {}, path: {}", bizNo, path);
|
||||
|
||||
ObpResponse response = client.get(path);
|
||||
|
||||
if (response.getStatus() != 200) {
|
||||
log.warn("[OBP] queryPartnerCode failed - status: {}, body: {}", response.getStatus(), response.getBody());
|
||||
throw new KjbObpException(response.getStatus(), "OBP 조회 실패: " + response.getBody());
|
||||
}
|
||||
|
||||
ObpOrganization org = ObpOrganization.fromResponse(response);
|
||||
|
||||
if (org == null) {
|
||||
throw new KjbObpException("OBP 응답 파싱 실패");
|
||||
}
|
||||
|
||||
if (!org.hasPartnerCode()) {
|
||||
throw new KjbObpException("partnerCode가 없습니다. bizNo: " + bizNo);
|
||||
}
|
||||
|
||||
return org.getPartnerCode();
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
log.info("queryOrganization Test");
|
||||
queryOrganization("123asd123asd123");
|
||||
/**
|
||||
* ObpClient 반환 (직접 API 호출용)
|
||||
*/
|
||||
public ObpClient getClient() {
|
||||
return client;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
package com.eactive.ext.kjb.obp;
|
||||
|
||||
import com.eactive.ext.kjb.common.KjbProperty;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
||||
import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
|
||||
import org.apache.hc.client5.http.config.RequestConfig;
|
||||
import org.apache.hc.client5.http.entity.EntityBuilder;
|
||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
||||
import org.apache.hc.core5.http.ContentType;
|
||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
|
||||
@Slf4j
|
||||
public class ObpClient {
|
||||
private static ObpClient _instance;
|
||||
|
||||
private final KjbProperty property;
|
||||
private final CloseableHttpClient httpClient;
|
||||
private final RequestConfig requestConfig;
|
||||
private final boolean isRealMode;
|
||||
|
||||
public synchronized static ObpClient getInstance(KjbProperty kjbProperty) {
|
||||
if (_instance == null) {
|
||||
_instance = new ObpClient(kjbProperty);
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
|
||||
private ObpClient(KjbProperty kjbProperty) {
|
||||
if (kjbProperty == null) {
|
||||
throw new IllegalArgumentException("KjbProperty cannot be null");
|
||||
}
|
||||
|
||||
this.property = kjbProperty;
|
||||
this.isRealMode = StringUtils.isNotEmpty(kjbProperty.getObpUrl());
|
||||
|
||||
this.requestConfig = RequestConfig.custom()
|
||||
.setConnectTimeout(Timeout.ofSeconds(kjbProperty.getObpConnectionTimeout()))
|
||||
.setResponseTimeout(Timeout.ofSeconds(kjbProperty.getObpResponseTimeout()))
|
||||
.build();
|
||||
|
||||
if (isRealMode) {
|
||||
this.httpClient = HttpClients.createDefault();
|
||||
} else {
|
||||
this.httpClient = null;
|
||||
log.warn("[OBP] URL이 설정되지 않음. 실제 OBP 연동 없이 동작함");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GET 요청
|
||||
* @param path API 경로 (예: /api/customer/...)
|
||||
* @return ObpResponse
|
||||
*/
|
||||
public ObpResponse get(String path) {
|
||||
return get(path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET 요청 (추가 헤더 포함)
|
||||
* @param path API 경로
|
||||
* @param additionalHeaders 추가 헤더
|
||||
* @return ObpResponse
|
||||
*/
|
||||
public ObpResponse get(String path, Map<String, String> additionalHeaders) {
|
||||
String url = property.getObpUrl() + path;
|
||||
HttpGet httpGet = new HttpGet(url);
|
||||
applyDefaultHeaders(httpGet);
|
||||
applyAdditionalHeaders(httpGet, additionalHeaders);
|
||||
httpGet.setConfig(requestConfig);
|
||||
|
||||
return execute(httpGet);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST 요청 (JSON body)
|
||||
* @param path API 경로
|
||||
* @param jsonBody JSON 문자열
|
||||
* @return ObpResponse
|
||||
*/
|
||||
public ObpResponse post(String path, String jsonBody) {
|
||||
return post(path, jsonBody, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST 요청 (JSON body, 추가 헤더 포함)
|
||||
* @param path API 경로
|
||||
* @param jsonBody JSON 문자열
|
||||
* @param additionalHeaders 추가 헤더
|
||||
* @return ObpResponse
|
||||
*/
|
||||
public ObpResponse post(String path, String jsonBody, Map<String, String> additionalHeaders) {
|
||||
String url = property.getObpUrl() + path;
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
applyDefaultHeaders(httpPost);
|
||||
applyAdditionalHeaders(httpPost, additionalHeaders);
|
||||
httpPost.setConfig(requestConfig);
|
||||
|
||||
if (StringUtils.isNotEmpty(jsonBody)) {
|
||||
httpPost.setEntity(EntityBuilder.create()
|
||||
.setText(jsonBody)
|
||||
.setContentType(ContentType.APPLICATION_JSON)
|
||||
.build());
|
||||
}
|
||||
|
||||
return execute(httpPost);
|
||||
}
|
||||
|
||||
private void applyDefaultHeaders(HttpUriRequestBase request) {
|
||||
request.setHeader("Content-Type", "application/json; charset=utf-8");
|
||||
request.setHeader(property.getObpTrustSystemKey(), property.getObpTrustSystemValue());
|
||||
request.setHeader(property.getObpPartnerCodeKey(), property.getObpPartnerCodeValue());
|
||||
}
|
||||
|
||||
private void applyAdditionalHeaders(HttpUriRequestBase request, Map<String, String> additionalHeaders) {
|
||||
if (additionalHeaders != null) {
|
||||
additionalHeaders.forEach(request::setHeader);
|
||||
}
|
||||
}
|
||||
|
||||
private ObpResponse execute(HttpUriRequestBase request) {
|
||||
if (!isRealMode) {
|
||||
log.warn("[OBP] URL 미설정으로 실제 호출하지 않음. 요청: {} {}", request.getMethod(), request.getRequestUri());
|
||||
ObpResponse mockResponse = new ObpResponse();
|
||||
mockResponse.setStatus(200);
|
||||
mockResponse.setBody("{}");
|
||||
return mockResponse;
|
||||
}
|
||||
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
|
||||
try {
|
||||
log.debug("[OBP] 요청: {} {}", request.getMethod(), request.getRequestUri());
|
||||
|
||||
Future<ObpResponse> future = executor.submit(() ->
|
||||
httpClient.execute(request, response -> {
|
||||
ObpResponse obpResponse = new ObpResponse();
|
||||
obpResponse.setStatus(response.getCode());
|
||||
obpResponse.setBody(EntityUtils.toString(response.getEntity(), "UTF-8"));
|
||||
|
||||
Arrays.asList(response.getHeaders()).forEach(header ->
|
||||
obpResponse.getHeaders().put(header.getName(), header.getValue()));
|
||||
|
||||
return obpResponse;
|
||||
})
|
||||
);
|
||||
|
||||
ObpResponse response = future.get(property.getObpTimeout(), TimeUnit.SECONDS);
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("[OBP] 응답: status={}, body={}", response.getStatus(), response.getBody());
|
||||
}
|
||||
|
||||
return response;
|
||||
|
||||
} catch (InterruptedException | ExecutionException | TimeoutException e) {
|
||||
log.error("[OBP] 호출 실패: {} {}", request.getMethod(), request.getRequestUri(), e);
|
||||
ObpResponse errorResponse = new ObpResponse();
|
||||
errorResponse.setStatus(-1);
|
||||
errorResponse.setBody(e.getMessage());
|
||||
return errorResponse;
|
||||
} finally {
|
||||
executor.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 실제 모드 여부
|
||||
*/
|
||||
public boolean isRealMode() {
|
||||
return isRealMode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.eactive.ext.kjb.obp;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* OBP Organization 조회 응답
|
||||
* - 필수 필드만 명시적으로 선언하고, 나머지는 rawJson으로 보관하여 유연성 확보
|
||||
*/
|
||||
@Data
|
||||
public class ObpOrganization {
|
||||
private static final Gson gson = new Gson();
|
||||
|
||||
// 핵심 필드
|
||||
@SerializedName("partnerCode")
|
||||
private String partnerCode;
|
||||
|
||||
@SerializedName("id")
|
||||
private String id;
|
||||
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
|
||||
@SerializedName("state")
|
||||
private String state;
|
||||
|
||||
@SerializedName("status")
|
||||
private String status;
|
||||
|
||||
@SerializedName("businessManRegistrationNo")
|
||||
private String businessManRegistrationNo;
|
||||
|
||||
@SerializedName("corporateRegistrationNo")
|
||||
private String corporateRegistrationNo;
|
||||
|
||||
@SerializedName("representativeName")
|
||||
private String representativeName;
|
||||
|
||||
// 원본 JSON (추가 필드 접근용
|
||||
private transient JsonObject rawJson;
|
||||
|
||||
/**
|
||||
* JSON 문자열에서 파싱
|
||||
*/
|
||||
public static ObpOrganization fromJson(String json) {
|
||||
if (json == null || json.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ObpOrganization org = gson.fromJson(json, ObpOrganization.class);
|
||||
org.rawJson = new JsonParser().parse(json).getAsJsonObject();
|
||||
return org;
|
||||
}
|
||||
|
||||
/**
|
||||
* ObpResponse에서 파싱
|
||||
*/
|
||||
public static ObpOrganization fromResponse(ObpResponse response) {
|
||||
if (response == null || response.getStatus() != 200) {
|
||||
return null;
|
||||
}
|
||||
return fromJson(response.getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* 원본 JSON에서 추가 필드 조회
|
||||
* @param fieldName 필드명 (예: "englishName", "description")
|
||||
* @return 필드 값 (없으면 null)
|
||||
*/
|
||||
public String getField(String fieldName) {
|
||||
if (rawJson == null || !rawJson.has(fieldName) || rawJson.get(fieldName).isJsonNull()) {
|
||||
return null;
|
||||
}
|
||||
return rawJson.get(fieldName).getAsString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 원본 JSON에서 중첩 필드 조회
|
||||
* @param path 경로 (예: "type.name", "type.parent.name")
|
||||
* @return 필드 값 (없으면 null)
|
||||
*/
|
||||
public String getNestedField(String path) {
|
||||
if (rawJson == null || path == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] parts = path.split("\\.");
|
||||
JsonObject current = rawJson;
|
||||
|
||||
for (int i = 0; i < parts.length - 1; i++) {
|
||||
if (!current.has(parts[i]) || current.get(parts[i]).isJsonNull()) {
|
||||
return null;
|
||||
}
|
||||
current = current.getAsJsonObject(parts[i]);
|
||||
}
|
||||
|
||||
String lastField = parts[parts.length - 1];
|
||||
if (!current.has(lastField) || current.get(lastField).isJsonNull()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return current.get(lastField).getAsString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 원본 JSON 객체 반환
|
||||
*/
|
||||
public JsonObject getRawJson() {
|
||||
return rawJson;
|
||||
}
|
||||
|
||||
/**
|
||||
* partnerCode 유효성 확인
|
||||
*/
|
||||
public boolean hasPartnerCode() {
|
||||
return partnerCode != null && !partnerCode.trim().isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.eactive.ext.kjb.obp;
|
||||
|
||||
public class ObpRequest {
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.eactive.ext.kjb.obp.common;
|
||||
package com.eactive.ext.kjb.obp;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
package com.eactive.ext.kjb.obp.common;
|
||||
|
||||
import com.eactive.ext.kjb.common.KjbProperty;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
|
||||
@Slf4j
|
||||
public class ObpClient {
|
||||
private static ObpClient _instance;
|
||||
|
||||
public synchronized static ObpClient getInstance(KjbProperty kjbProperty) {
|
||||
if (_instance == null) {
|
||||
_instance = new ObpClient(kjbProperty);
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
|
||||
private ObpClient(KjbProperty kjbProperty) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.eactive.ext.kjb.ums.test;
|
||||
|
||||
import com.eactive.ext.kjb.common.KjbProperty;
|
||||
import com.eactive.ext.kjb.utils.ValidationUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@Slf4j
|
||||
public class KjbPropertyTest {
|
||||
|
||||
@Test
|
||||
void testKjbProperty() {
|
||||
Assumptions.assumeTrue(
|
||||
"true".equalsIgnoreCase(System.getenv("KJB_EAPIM_TEST_ENABLED")),
|
||||
"OS 환경변수 내 KJB_EAPIM_TEST_ENABLED=TRUE 설정되어 있어야 동작함");
|
||||
|
||||
|
||||
log.info("KjbProperty 테스트 시작");
|
||||
|
||||
|
||||
log.info("기본값 Validation 테스트");
|
||||
KjbProperty prop = new KjbProperty();
|
||||
ValidationUtil.validateOrThrow(prop);
|
||||
|
||||
log.info("KjbProperty 테스트 완료");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user