KjbProperty 리팩토링

This commit is contained in:
Rinjae
2026-01-15 15:21:00 +09:00
parent c004e6a515
commit 5df860b4c1
6 changed files with 325 additions and 246 deletions
@@ -0,0 +1,92 @@
package com.eactive.ext.kjb.common;
import lombok.extern.slf4j.Slf4j;
import java.util.function.Function;
/**
* KjbProperty 싱글톤 홀더.
*
* <p>모든 곳에서 {@code KjbPropertyHolder.get()}으로 현재 KjbProperty에 접근합니다.
* eapim-admin에서 초기화 시 {@code initialize()}를 호출하고,
* MonitoringContext.refresh() 시 {@code reload()}를 호출하여 값을 갱신합니다.</p>
*
* <p>사용 예시:</p>
* <pre>
* // 값 접근
* String url = KjbPropertyHolder.get().getUmsHostUrl();
*
* // 초기화 (eapim-admin에서)
* KjbPropertyInjector injector = new KjbPropertyInjector(service, "Monitoring");
* KjbPropertyHolder.initialize(injector::inject);
*
* // reload (MonitoringContext.refresh() 시)
* KjbPropertyHolder.reload();
*
* // 테스트용
* KjbPropertyHolder.setForTest(mockProperty);
* </pre>
*/
@Slf4j
public class KjbPropertyHolder {
private static volatile KjbProperty instance = new KjbProperty();
private static volatile Function<KjbProperty, KjbProperty> injector;
private KjbPropertyHolder() {
// 유틸리티 클래스
}
/**
* 현재 KjbProperty 인스턴스를 반환합니다.
*/
public static KjbProperty get() {
return instance;
}
/**
* 초기화 함수를 등록하고 최초 로딩을 수행합니다.
* eapim-admin 부팅 시 MonitoringContextImpl.init()에서 호출됩니다.
*
* @param injectorFn KjbProperty를 DB에서 로딩하는 함수 (KjbPropertyInjector::inject)
*/
public static void initialize(Function<KjbProperty, KjbProperty> injectorFn) {
injector = injectorFn;
reload();
log.info("KjbPropertyHolder 초기화 완료");
}
/**
* DB에서 프로퍼티를 다시 로딩합니다.
* MonitoringContext.refresh() 호출 시 함께 호출됩니다.
*/
public static void reload() {
if (injector != null) {
try {
instance = injector.apply(new KjbProperty());
log.info("KjbProperty reload 완료");
} catch (Exception e) {
log.error("KjbProperty reload 실패: {}", e.getMessage(), e);
}
} else {
log.debug("KjbPropertyHolder: injector가 설정되지 않음 (테스트 환경일 수 있음)");
}
}
/**
* 테스트용 - 직접 인스턴스를 설정합니다.
*/
public static void setForTest(KjbProperty testProperty) {
instance = testProperty;
log.debug("KjbProperty 테스트 인스턴스 설정");
}
/**
* 테스트용 - 기본값으로 초기화합니다.
*/
public static void resetForTest() {
instance = new KjbProperty();
injector = null;
log.debug("KjbPropertyHolder 테스트 초기화");
}
}
@@ -2,7 +2,7 @@ package com.eactive.ext.kjb.obp;
import com.eactive.ext.kjb.common.KjbObpException; import com.eactive.ext.kjb.common.KjbObpException;
import com.eactive.ext.kjb.common.KjbProperty; import com.eactive.ext.kjb.common.KjbProperty;
import lombok.Getter; import com.eactive.ext.kjb.common.KjbPropertyHolder;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -10,30 +10,29 @@ import org.apache.commons.lang3.StringUtils;
public class KjbObpModule { public class KjbObpModule {
private static final String FAKE_PARTNER_CODE = "999999-99"; private static final String FAKE_PARTNER_CODE = "999999-99";
private static KjbObpModule _instance; private static volatile KjbObpModule instance;
@Getter private KjbObpModule() {
private final KjbProperty property; // 싱글톤
private final ObpClient client;
public static synchronized KjbObpModule getInstance(KjbProperty kjbProperty) {
if (_instance == null) {
_instance = new KjbObpModule(kjbProperty);
} else {
if (kjbProperty.equals(_instance.getProperty())) {
log.debug("KjbProperty 파라미터가 변경되어 KjbObpModule 인스턴스 재 생성");
_instance = new KjbObpModule(kjbProperty);
}
}
return _instance;
} }
private KjbObpModule(KjbProperty kjbProperty) { public static KjbObpModule getInstance() {
if (kjbProperty == null) { if (instance == null) {
throw new IllegalArgumentException("KjbProperty cannot be null"); synchronized (KjbObpModule.class) {
if (instance == null) {
instance = new KjbObpModule();
}
}
} }
this.property = kjbProperty; return instance;
this.client = ObpClient.getInstance(kjbProperty); }
private static KjbProperty getProperty() {
return KjbPropertyHolder.get();
}
private ObpClient getClient() {
return ObpClient.getInstance();
} }
/** /**
@@ -53,13 +52,15 @@ public class KjbObpModule {
throw new IllegalArgumentException("BizNo must be 10 digits. (input: " + bizNo + ")"); throw new IllegalArgumentException("BizNo must be 10 digits. (input: " + bizNo + ")");
} }
ObpClient client = getClient();
// 가상모드: URL 미설정 시 가상 파트너코드 반환 // 가상모드: URL 미설정 시 가상 파트너코드 반환
if (!client.isRealMode()) { if (!client.isRealMode()) {
log.info("[OBP] 가상모드 - 가상 partnerCode 반환: {}", FAKE_PARTNER_CODE); log.info("[OBP] 가상모드 - 가상 partnerCode 반환: {}", FAKE_PARTNER_CODE);
return FAKE_PARTNER_CODE; return FAKE_PARTNER_CODE;
} }
String path = String.format(property.getObpUrlOrganizationFmt(), bizNo); String path = String.format(getProperty().getObpUrlOrganizationFmt(), bizNo);
log.debug("[OBP] queryPartnerCode - bizNo: {}, path: {}", bizNo, path); log.debug("[OBP] queryPartnerCode - bizNo: {}, path: {}", bizNo, path);
ObpResponse response = client.get(path); ObpResponse response = client.get(path);
@@ -81,11 +82,4 @@ public class KjbObpModule {
return org.getPartnerCode(); return org.getPartnerCode();
} }
/**
* ObpClient 반환 (직접 API 호출용)
*/
public ObpClient getClient() {
return client;
}
} }
@@ -1,7 +1,7 @@
package com.eactive.ext.kjb.obp; package com.eactive.ext.kjb.obp;
import com.eactive.ext.kjb.common.KjbProperty; import com.eactive.ext.kjb.common.KjbProperty;
import lombok.Getter; import com.eactive.ext.kjb.common.KjbPropertyHolder;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpGet;
@@ -22,46 +22,40 @@ import java.util.concurrent.*;
@Slf4j @Slf4j
public class ObpClient { public class ObpClient {
private static ObpClient _instance; private static volatile ObpClient instance;
@Getter private ObpClient() {
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);
} else {
if (kjbProperty.equals(_instance.getProperty())) {
log.debug("KjbProperty 파라미터가 변경되어 ObpClient 인스턴스 재 생성");
_instance = new ObpClient(kjbProperty);
}
}
return _instance;
} }
private ObpClient(KjbProperty kjbProperty) { public static ObpClient getInstance() {
if (kjbProperty == null) { if (instance == null) {
throw new IllegalArgumentException("KjbProperty cannot be null"); synchronized (ObpClient.class) {
if (instance == null) {
instance = new ObpClient();
}
}
} }
return instance;
}
this.property = kjbProperty; private static KjbProperty getProperty() {
this.isRealMode = StringUtils.isNotEmpty(kjbProperty.getObpUrl()); return KjbPropertyHolder.get();
}
this.requestConfig = RequestConfig.custom() /**
.setConnectTimeout(Timeout.ofSeconds(kjbProperty.getObpConnectionTimeout())) * 실제 모드 여부 (URL이 설정되어 있는지 확인)
.setResponseTimeout(Timeout.ofSeconds(kjbProperty.getObpResponseTimeout())) */
public boolean isRealMode() {
return StringUtils.isNotEmpty(getProperty().getObpUrl());
}
private RequestConfig createRequestConfig() {
KjbProperty prop = getProperty();
return RequestConfig.custom()
.setConnectTimeout(Timeout.ofSeconds(prop.getObpConnectionTimeout()))
.setResponseTimeout(Timeout.ofSeconds(prop.getObpResponseTimeout()))
.build(); .build();
if (isRealMode) {
this.httpClient = HttpClients.createDefault();
} else {
this.httpClient = null;
log.warn("[OBP] URL이 설정되지 않음. 실제 OBP 연동 없이 동작함");
}
} }
/** /**
@@ -80,11 +74,11 @@ public class ObpClient {
* @return ObpResponse * @return ObpResponse
*/ */
public ObpResponse get(String path, Map<String, String> additionalHeaders) { public ObpResponse get(String path, Map<String, String> additionalHeaders) {
String url = property.getObpUrl() + path; String url = getProperty().getObpUrl() + path;
HttpGet httpGet = new HttpGet(url); HttpGet httpGet = new HttpGet(url);
applyDefaultHeaders(httpGet); applyDefaultHeaders(httpGet);
applyAdditionalHeaders(httpGet, additionalHeaders); applyAdditionalHeaders(httpGet, additionalHeaders);
httpGet.setConfig(requestConfig); httpGet.setConfig(createRequestConfig());
return execute(httpGet); return execute(httpGet);
} }
@@ -107,11 +101,11 @@ public class ObpClient {
* @return ObpResponse * @return ObpResponse
*/ */
public ObpResponse post(String path, String jsonBody, Map<String, String> additionalHeaders) { public ObpResponse post(String path, String jsonBody, Map<String, String> additionalHeaders) {
String url = property.getObpUrl() + path; String url = getProperty().getObpUrl() + path;
HttpPost httpPost = new HttpPost(url); HttpPost httpPost = new HttpPost(url);
applyDefaultHeaders(httpPost); applyDefaultHeaders(httpPost);
applyAdditionalHeaders(httpPost, additionalHeaders); applyAdditionalHeaders(httpPost, additionalHeaders);
httpPost.setConfig(requestConfig); httpPost.setConfig(createRequestConfig());
if (StringUtils.isNotEmpty(jsonBody)) { if (StringUtils.isNotEmpty(jsonBody)) {
httpPost.setEntity(EntityBuilder.create() httpPost.setEntity(EntityBuilder.create()
@@ -124,9 +118,10 @@ public class ObpClient {
} }
private void applyDefaultHeaders(HttpUriRequestBase request) { private void applyDefaultHeaders(HttpUriRequestBase request) {
KjbProperty prop = getProperty();
request.setHeader("Content-Type", "application/json; charset=utf-8"); request.setHeader("Content-Type", "application/json; charset=utf-8");
request.setHeader(property.getObpTrustSystemKey(), property.getObpTrustSystemValue()); request.setHeader(prop.getObpTrustSystemKey(), prop.getObpTrustSystemValue());
request.setHeader(property.getObpPartnerCodeKey(), property.getObpPartnerCodeValue()); request.setHeader(prop.getObpPartnerCodeKey(), prop.getObpPartnerCodeValue());
} }
private void applyAdditionalHeaders(HttpUriRequestBase request, Map<String, String> additionalHeaders) { private void applyAdditionalHeaders(HttpUriRequestBase request, Map<String, String> additionalHeaders) {
@@ -136,7 +131,7 @@ public class ObpClient {
} }
private ObpResponse execute(HttpUriRequestBase request) { private ObpResponse execute(HttpUriRequestBase request) {
if (!isRealMode) { if (!isRealMode()) {
log.warn("[OBP] URL 미설정으로 실제 호출하지 않음. 요청: {} {}", request.getMethod(), request.getRequestUri()); log.warn("[OBP] URL 미설정으로 실제 호출하지 않음. 요청: {} {}", request.getMethod(), request.getRequestUri());
ObpResponse mockResponse = new ObpResponse(); ObpResponse mockResponse = new ObpResponse();
mockResponse.setStatus(200); mockResponse.setStatus(200);
@@ -146,7 +141,7 @@ public class ObpClient {
ExecutorService executor = Executors.newSingleThreadExecutor(); ExecutorService executor = Executors.newSingleThreadExecutor();
try { try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
log.debug("[OBP] 요청: {} {}", request.getMethod(), request.getRequestUri()); log.debug("[OBP] 요청: {} {}", request.getMethod(), request.getRequestUri());
Future<ObpResponse> future = executor.submit(() -> Future<ObpResponse> future = executor.submit(() ->
@@ -162,7 +157,7 @@ public class ObpClient {
}) })
); );
ObpResponse response = future.get(property.getObpTimeout(), TimeUnit.SECONDS); ObpResponse response = future.get(getProperty().getObpTimeout(), TimeUnit.SECONDS);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("[OBP] 응답: status={}, body={}", response.getStatus(), response.getBody()); log.debug("[OBP] 응답: status={}, body={}", response.getStatus(), response.getBody());
@@ -170,7 +165,7 @@ public class ObpClient {
return response; return response;
} catch (InterruptedException | ExecutionException | TimeoutException e) { } catch (InterruptedException | ExecutionException | TimeoutException | java.io.IOException e) {
log.error("[OBP] 호출 실패: {} {}", request.getMethod(), request.getRequestUri(), e); log.error("[OBP] 호출 실패: {} {}", request.getMethod(), request.getRequestUri(), e);
ObpResponse errorResponse = new ObpResponse(); ObpResponse errorResponse = new ObpResponse();
errorResponse.setStatus(-1); errorResponse.setStatus(-1);
@@ -180,11 +175,4 @@ public class ObpClient {
executor.shutdown(); executor.shutdown();
} }
} }
/**
* 실제 모드 여부
*/
public boolean isRealMode() {
return isRealMode;
}
} }
@@ -1,6 +1,7 @@
package com.eactive.ext.kjb.sso; package com.eactive.ext.kjb.sso;
import com.eactive.ext.kjb.common.KjbProperty; import com.eactive.ext.kjb.common.KjbProperty;
import com.eactive.ext.kjb.common.KjbPropertyHolder;
import com.initech.eam.api.*; import com.initech.eam.api.*;
import com.initech.eam.base.APIException; import com.initech.eam.base.APIException;
import com.initech.eam.base.EmptyResultException; import com.initech.eam.base.EmptyResultException;
@@ -21,76 +22,75 @@ import java.util.Vector;
@Slf4j @Slf4j
public class KjbSsoModule { public class KjbSsoModule {
private static KjbSsoModule instance; private static volatile KjbSsoModule instance;
private KjbProperty prop;
private final NXContext context;
@Getter
private final Vector<String> providerList;
/***[SERVICE CONFIGURATION]***********************************************************************/
private final String SERVICE_NAME;
@Getter
private final String ascpUrl;
/***[SSO CONFIGURATION]**]***********************************************************************/
private final String NLS_URL;
private final String NLS_PORT;
private final String NLS_LOGIN_URL;
private final String NLS_LOGOUT_URL;
private final String NLS_ERROR_URL;
/***[SSO ND LIST 운영]**]***********************************************************************/
private final String ND_URL1;
private final Vector<String> PROVIDER_LIST = new Vector<String>(); private final Vector<String> PROVIDER_LIST = new Vector<String>();
private final int COOKIE_SESSTION_TIME_OUT = 3000000; private final int COOKIE_SESSTION_TIME_OUT = 3000000;
// 인증 타입 (ID/PW 방식 : 1, 인증서 : 3) // 인증 타입 (ID/PW 방식 : 1, 인증서 : 3)
private final String TOA = "1"; private final String TOA = "1";
private final String PROVIDER_DOMAIN;
private final String SSO_DOMAIN = ".kjbank.com"; private final String SSO_DOMAIN = ".kjbank.com";
private final String COOKIE_PADDING = "_V42"; private final String COOKIE_PADDING = "_V42";
private static final int timeout = 15000; private static final int timeout = 15000;
private KjbSsoModule() {
CookieManager.setEncStatus(true);
SECode.setCookiePadding(COOKIE_PADDING);
}
public synchronized static KjbSsoModule getInstance(KjbProperty kjbProperty) { public static KjbSsoModule getInstance() {
if (instance == null) { if (instance == null) {
instance = new KjbSsoModule(kjbProperty); synchronized (KjbSsoModule.class) {
} else { if (instance == null) {
if (!instance.prop.equals(kjbProperty)) { instance = new KjbSsoModule();
instance.prop = kjbProperty; }
} }
} }
return instance; return instance;
} }
private KjbSsoModule(KjbProperty kjbProperty) { private static KjbProperty getProperty() {
this.prop = kjbProperty; return KjbPropertyHolder.get();
}
ascpUrl = prop.getUrl() + prop.getSsoAscpUri(); private String getServiceName() {
return getProperty().getSsoServiceName();
}
SERVICE_NAME = prop.getSsoServiceName(); public String getAscpUrl() {
NLS_URL = "http://" + prop.getSsoDomain(); KjbProperty prop = getProperty();
NLS_PORT = String.valueOf(prop.getSsoNlsPort()); return prop.getUrl() + prop.getSsoAscpUri();
NLS_LOGIN_URL = NLS_URL + ":" + NLS_PORT + "/nls3/clientLogin.jsp"; }
NLS_LOGOUT_URL = NLS_URL + ":" + NLS_PORT + "/nls3/NCLogout.jsp";
NLS_ERROR_URL = NLS_URL + ":" + NLS_PORT + "/nls3/error.jsp";
ND_URL1 = "http://" + prop.getSsoDomain() + ":5480";
PROVIDER_DOMAIN = prop.getSsoDomain();
this.providerList = new Vector<>(); private String getNlsUrl() {
PROVIDER_LIST.add(prop.getSsoDomain()); return "http://" + getProperty().getSsoDomain();
}
context = new NXContext(Collections.singletonList(ND_URL1), timeout); private String getNlsPort() {
CookieManager.setEncStatus(true); return String.valueOf(getProperty().getSsoNlsPort());
SECode.setCookiePadding(COOKIE_PADDING); }
private String getNlsLoginUrl() {
log.debug("KjbProperty : {}", prop.toString()); return getNlsUrl() + ":" + getNlsPort() + "/nls3/clientLogin.jsp";
}
private String getNlsLogoutUrl() {
return getNlsUrl() + ":" + getNlsPort() + "/nls3/NCLogout.jsp";
}
private String getNlsErrorUrl() {
return getNlsUrl() + ":" + getNlsPort() + "/nls3/error.jsp";
}
private String getNdUrl1() {
return "http://" + getProperty().getSsoDomain() + ":5480";
}
public Vector<String> getProviderList() {
Vector<String> list = new Vector<>();
list.add(getProperty().getSsoDomain());
return list;
} }
@@ -99,18 +99,15 @@ public class KjbSsoModule {
NXContext context = null; NXContext context = null;
try { try {
List<String> serverurlList = new ArrayList<>(); List<String> serverurlList = new ArrayList<>();
serverurlList.add(ND_URL1); serverurlList.add(getNdUrl1());
context = new NXContext(serverurlList); context = new NXContext(serverurlList);
CookieManager.setEncStatus(true); CookieManager.setEncStatus(true);
SECode.setCookiePadding(COOKIE_PADDING);
PROVIDER_LIST.add(prop.getSsoDomain());
//NLS3 web.xml의 CookiePadding 값과 같아야 한다. 안그럼 검증 페일남
SECode.setCookiePadding("_V42");
} }
catch (Exception e) catch (Exception e)
{ {
log.warn("getContext", e); log.warn("getContext", e);
} }
return context; return context;
} }
@@ -134,11 +131,12 @@ public class KjbSsoModule {
try { try {
context = getContext(); context = getContext();
userAPI = new NXUserAPI(context); userAPI = new NXUserAPI(context);
String serviceName = getServiceName();
log.info("##############################################"); log.info("##############################################");
log.info("sso_id 2: "+sso_id); log.info("sso_id 2: "+sso_id);
log.info("SERVICE_NAME : "+ SERVICE_NAME); log.info("SERVICE_NAME : "+ serviceName);
log.info("##############################################"); log.info("##############################################");
NXAccount account = userAPI.getUserAccount(sso_id, SERVICE_NAME); NXAccount account = userAPI.getUserAccount(sso_id, serviceName);
log.info(account.toString()); log.info(account.toString());
retValue = account.getAccountName(); retValue = account.getAccountName();
log.info("retValue = " + retValue); log.info("retValue = " + retValue);
@@ -156,9 +154,9 @@ public class KjbSsoModule {
*/ */
public void goLoginPage(HttpServletResponse response, String uurl) public void goLoginPage(HttpServletResponse response, String uurl)
throws Exception { throws Exception {
CookieManager.addCookie(SECode.USER_URL, uurl, ".kjbank.com", response); CookieManager.addCookie(SECode.USER_URL, uurl, SSO_DOMAIN, response);
CookieManager.addCookie(SECode.R_TOA, TOA, ".kjbank.com", response); CookieManager.addCookie(SECode.R_TOA, TOA, SSO_DOMAIN, response);
response.sendRedirect(NLS_LOGIN_URL + "?UURL=" + uurl); response.sendRedirect(getNlsLoginUrl() + "?UURL=" + uurl);
} }
/** /**
@@ -167,9 +165,9 @@ public class KjbSsoModule {
* @throws Exception * @throws Exception
*/ */
public void goLoginPage(HttpServletResponse response) throws Exception { public void goLoginPage(HttpServletResponse response) throws Exception {
CookieManager.addCookie(SECode.USER_URL, ascpUrl, SSO_DOMAIN, response); CookieManager.addCookie(SECode.USER_URL, getAscpUrl(), SSO_DOMAIN, response);
CookieManager.addCookie(SECode.R_TOA, TOA, SSO_DOMAIN, response); CookieManager.addCookie(SECode.R_TOA, TOA, SSO_DOMAIN, response);
response.sendRedirect(NLS_LOGIN_URL); response.sendRedirect(getNlsLoginUrl());
} }
/** /**
@@ -178,13 +176,12 @@ public class KjbSsoModule {
* @param response * @param response
* @return * @return
*/ */
public String getEamSessionCheck(HttpServletRequest request,HttpServletResponse response){ public String getEamSessionCheck(HttpServletRequest request, HttpServletResponse response) {
String retCode = ""; String retCode = "";
try { try {
retCode = CookieManager.verifyNexessCookie(request, response, 10, COOKIE_SESSTION_TIME_OUT,PROVIDER_LIST); retCode = CookieManager.verifyNexessCookie(request, response, 10, COOKIE_SESSTION_TIME_OUT, getProviderList());
} catch(Exception npe) { } catch(Exception npe) {
log.warn("getEamSessionCheck", npe); log.warn("getEamSessionCheck", npe);
// npe.printStackTrace();
} }
return retCode; return retCode;
} }
@@ -195,11 +192,11 @@ public class KjbSsoModule {
* @param response * @param response
* @return * @return
*/ */
public String getEamSessionCheck2(HttpServletRequest request,HttpServletResponse response) public String getEamSessionCheck2(HttpServletRequest request, HttpServletResponse response) {
{
String retCode = ""; String retCode = "";
try { try {
NXNLSAPI nxNLSAPI = new NXNLSAPI(context); NXContext ctx = getContext();
NXNLSAPI nxNLSAPI = new NXNLSAPI(ctx);
retCode = nxNLSAPI.readNexessCookie(request, response, 0, 0); retCode = nxNLSAPI.readNexessCookie(request, response, 0, 0);
} catch(Exception npe) { } catch(Exception npe) {
log.error("KjbSsoModule-getEamSessionCheck2 Exception", npe); log.error("KjbSsoModule-getEamSessionCheck2 Exception", npe);
@@ -213,10 +210,10 @@ public class KjbSsoModule {
* @param error_code * @param error_code
* @throws Exception * @throws Exception
*/ */
public void goErrorPage(HttpServletResponse response, int error_code)throws Exception { public void goErrorPage(HttpServletResponse response, int error_code) throws Exception {
CookieManager.removeNexessCookie(SSO_DOMAIN, response); CookieManager.removeNexessCookie(SSO_DOMAIN, response);
CookieManager.addCookie(SECode.USER_URL, ascpUrl, SSO_DOMAIN, response); CookieManager.addCookie(SECode.USER_URL, getAscpUrl(), SSO_DOMAIN, response);
response.sendRedirect(NLS_ERROR_URL + "?errorCode=" + error_code); response.sendRedirect(getNlsErrorUrl() + "?errorCode=" + error_code);
} }
/** /**
@@ -5,6 +5,7 @@ import com.eactive.apim.portal.template.entity.MessageRequest;
import com.eactive.apim.portal.template.repository.MessageRequestRepository; import com.eactive.apim.portal.template.repository.MessageRequestRepository;
import com.eactive.ext.kjb.common.KjbEaiBatchException; import com.eactive.ext.kjb.common.KjbEaiBatchException;
import com.eactive.ext.kjb.common.KjbProperty; import com.eactive.ext.kjb.common.KjbProperty;
import com.eactive.ext.kjb.common.KjbPropertyHolder;
import com.eactive.ext.kjb.utils.ValidationUtil; import com.eactive.ext.kjb.utils.ValidationUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -18,24 +19,35 @@ import java.util.function.BiConsumer;
public class KjbEmailSendModule { public class KjbEmailSendModule {
public final static int[] ALLOW_CHANNELS = { MessageCode.Channels.EMAIL.getValue() }; public final static int[] ALLOW_CHANNELS = { MessageCode.Channels.EMAIL.getValue() };
private static KjbEmailSendModule instance = null; private static volatile KjbEmailSendModule instance;
private static KjbProperty prop; private MessageRequestRepository repo;
private final MessageRequestRepository repo; private KjbEmailSendModule() {
// 싱글톤
}
public static synchronized KjbEmailSendModule getInstance(KjbProperty property,
MessageRequestRepository messageRequestRepository) {
ValidationUtil.validateOrThrow(property);
public static KjbEmailSendModule getInstance() {
if (instance == null) { if (instance == null) {
instance = new KjbEmailSendModule(property, messageRequestRepository); synchronized (KjbEmailSendModule.class) {
if (instance == null) {
instance = new KjbEmailSendModule();
}
}
} }
return instance; return instance;
} }
/**
* MessageRequestRepository 설정 (eapim-admin 초기화 시 호출)
*/
public void setRepository(MessageRequestRepository repository) {
this.repo = repository;
}
private static KjbProperty getProperty() {
return KjbPropertyHolder.get();
}
public static boolean isAllowChannel(MessageRequest message) { public static boolean isAllowChannel(MessageRequest message) {
for (int channel : ALLOW_CHANNELS) { for (int channel : ALLOW_CHANNELS) {
if ((message.getMessageCode().getChannels() & channel) == channel) { if ((message.getMessageCode().getChannels() & channel) == channel) {
@@ -47,6 +59,8 @@ public class KjbEmailSendModule {
public static void environmentCheck() { public static void environmentCheck() {
KjbProperty prop = getProperty();
if (StringUtils.isEmpty(prop.getEaiBatchUrl())) { if (StringUtils.isEmpty(prop.getEaiBatchUrl())) {
log.warn("EAI_BATCH_URL 가 설정되지 않음. 실제 EAI 배치 연동 없이 동작함"); log.warn("EAI_BATCH_URL 가 설정되지 않음. 실제 EAI 배치 연동 없이 동작함");
} }
@@ -101,19 +115,6 @@ public class KjbEmailSendModule {
log.info("KjbEmailSendModule - Environment check passed."); log.info("KjbEmailSendModule - Environment check passed.");
} }
private KjbEmailSendModule(KjbProperty property,
MessageRequestRepository repo) {
this.repo = repo;
if (property != null && prop == null) {
prop = property;
}
environmentCheck();
}
public void sendEmail(MessageRequest messageRequest) throws KjbEaiBatchException { public void sendEmail(MessageRequest messageRequest) throws KjbEaiBatchException {
String serviceId = "UNKNOWN"; String serviceId = "UNKNOWN";
@@ -135,7 +136,7 @@ public class KjbEmailSendModule {
repo.save(messageRequest); repo.save(messageRequest);
} }
EmailJob job = EmailJob.create(prop, messageRequest, repo); EmailJob job = EmailJob.create(getProperty(), messageRequest, repo);
job.sendEmail(); job.sendEmail();
log.debug("JSON : {}", job.generateJSON(true)); log.debug("JSON : {}", job.generateJSON(true));
@@ -3,6 +3,7 @@ package com.eactive.ext.kjb.ums;
import com.eactive.apim.portal.template.entity.MessageCode; import com.eactive.apim.portal.template.entity.MessageCode;
import com.eactive.apim.portal.template.entity.MessageRequest; import com.eactive.apim.portal.template.entity.MessageRequest;
import com.eactive.ext.kjb.common.KjbProperty; import com.eactive.ext.kjb.common.KjbProperty;
import com.eactive.ext.kjb.common.KjbPropertyHolder;
import com.eactive.ext.kjb.common.KjbUmsException; import com.eactive.ext.kjb.common.KjbUmsException;
import com.eactive.ext.kjb.ums.gson.IUmsGsonObject; import com.eactive.ext.kjb.ums.gson.IUmsGsonObject;
import com.eactive.ext.kjb.ums.gson.UmsRequestPayload; import com.eactive.ext.kjb.ums.gson.UmsRequestPayload;
@@ -39,39 +40,42 @@ public class KjbUmsService {
private final static String CONTENT_TYPE = "application/json; charset=utf-8"; private final static String CONTENT_TYPE = "application/json; charset=utf-8";
private final static String AUTHORIZATION_FMT = "Bearer %s"; private final static String AUTHORIZATION_FMT = "Bearer %s";
private final KjbProperty property; private static volatile KjbUmsService instance;
private final boolean isRealMode;
private final CloseableHttpClient httpClient;
private final RequestConfig requestConfig;
private KjbUmsService() {
// 싱글톤
}
public KjbUmsService(KjbProperty property) { public static KjbUmsService getInstance() {
if (property == null) { if (instance == null) {
log.error("[KJB-UMS] 파라미터 설정 되지 않음"); synchronized (KjbUmsService.class) {
throw new IllegalArgumentException("property is null"); if (instance == null) {
} instance = new KjbUmsService();
}
isRealMode = property.getUmsHostUrl() != null && StringUtils.isNotEmpty(property.getUmsHostUrl().trim());
if (isRealMode) {
try {
ValidationUtil.validateOrThrow(property);
} catch (Exception e) {
log.error("[KJB-UMS] 파라미터 설정 오류", e);
throw e;
} }
httpClient = HttpClients.createDefault();
requestConfig = RequestConfig.custom()
.setConnectTimeout(Timeout.ofSeconds(property.getEaiBatchConnectionTimeout()))
.setResponseTimeout(Timeout.ofSeconds(property.getEaiBatchResponseTimeout()))
.build();
} else {
httpClient = HttpClients.createDefault();
requestConfig = null;
} }
return instance;
}
this.property = property; private KjbProperty getProperty() {
return KjbPropertyHolder.get();
}
private boolean isRealMode() {
String url = getProperty().getUmsHostUrl();
return url != null && StringUtils.isNotEmpty(url.trim());
}
private CloseableHttpClient createHttpClient() {
return HttpClients.createDefault();
}
private RequestConfig createRequestConfig() {
KjbProperty prop = getProperty();
return RequestConfig.custom()
.setConnectTimeout(Timeout.ofSeconds(prop.getUmsConnectionTimeout()))
.setResponseTimeout(Timeout.ofSeconds(prop.getUmsResponseTimeout()))
.build();
} }
@@ -142,13 +146,14 @@ public class KjbUmsService {
} }
private UmsCallResult call(String url, UmsRequestPayload requestPayload) throws KjbUmsException { private UmsCallResult call(String url, UmsRequestPayload requestPayload) throws KjbUmsException {
KjbProperty prop = getProperty();
ExecutorService executor = Executors.newSingleThreadExecutor(); ExecutorService executor = Executors.newSingleThreadExecutor();
Gson gson = new Gson(); Gson gson = new Gson();
String json = gson.toJson(requestPayload); String json = gson.toJson(requestPayload);
HttpPost httpPost = new HttpPost(property.getUmsHostUrl() + url); HttpPost httpPost = new HttpPost(prop.getUmsHostUrl() + url);
httpPost.setHeader("Content-Type", CONTENT_TYPE); httpPost.setHeader("Content-Type", CONTENT_TYPE);
httpPost.setHeader("Authorization", String.format(AUTHORIZATION_FMT, property.getUmsApiKey())); httpPost.setHeader("Authorization", String.format(AUTHORIZATION_FMT, prop.getUmsApiKey()));
httpPost.setEntity(EntityBuilder.create().setText(json).setContentType(ContentType.APPLICATION_JSON).build()); httpPost.setEntity(EntityBuilder.create().setText(json).setContentType(ContentType.APPLICATION_JSON).build());
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
@@ -161,52 +166,54 @@ public class KjbUmsService {
} }
} }
httpPost.setConfig(requestConfig); httpPost.setConfig(createRequestConfig());
if (isRealMode) { if (isRealMode()) {
Future<UmsCallResult> future = executor.submit(() -> { try (CloseableHttpClient httpClient = createHttpClient()) {
return httpClient.execute(httpPost, res -> { Future<UmsCallResult> future = executor.submit(() -> {
try { return httpClient.execute(httpPost, res -> {
UmsCallResult result; try {
String body = EntityUtils.toString(res.getEntity()); UmsCallResult result;
if (log.isDebugEnabled()) { String body = EntityUtils.toString(res.getEntity());
log.debug("Response - {}", body); if (log.isDebugEnabled()) {
} log.debug("Response - {}", body);
result = gson.fromJson(body, UmsCallResult.class); }
result.setUmsMessageId(requestPayload.getMessageIdentityNo()); result = gson.fromJson(body, UmsCallResult.class);
result.setSuccess(true); result.setUmsMessageId(requestPayload.getMessageIdentityNo());
return result; result.setSuccess(true);
} catch (JsonSyntaxException e) { return result;
log.error("UMS Call error(JSON Syntax)", e); } catch (JsonSyntaxException e) {
return UmsCallResult.builder() log.error("UMS Call error(JSON Syntax)", e);
.umsMessageId(requestPayload.getMessageIdentityNo()) return UmsCallResult.builder()
.isSuccess(false) .umsMessageId(requestPayload.getMessageIdentityNo())
.throwable(e) .isSuccess(false)
.build(); .throwable(e)
} catch (Exception e) { .build();
log.error("UMS Call error", e); } catch (Exception e) {
return UmsCallResult.builder() log.error("UMS Call error", e);
.umsMessageId(requestPayload.getMessageIdentityNo()) return UmsCallResult.builder()
.isSuccess(false) .umsMessageId(requestPayload.getMessageIdentityNo())
.throwable(e) .isSuccess(false)
.build(); .throwable(e)
} finally { .build();
log.debug("Response status - {}", res.getCode()); } finally {
log.debug("Response status - {}", res.getCode());
if (res.getCode() != 200) { if (res.getCode() != 200) {
Arrays.asList(res.getHeaders()).forEach(o -> { Arrays.asList(res.getHeaders()).forEach(o -> {
log.warn("[Header] {}: {}", o.getName(), o.getValue()); log.warn("[Header] {}: {}", o.getName(), o.getValue());
}); });
}
} }
} });
}); });
});
try { return future.get(prop.getUmsTimeout(), TimeUnit.SECONDS);
return future.get(property.getUmsTimeout(), TimeUnit.SECONDS); } catch (InterruptedException | ExecutionException | TimeoutException | IOException e) {
} catch (InterruptedException | ExecutionException | TimeoutException e) { log.error("UMS call exception", e);
log.error("EAI Batch call exception", e); throw new KjbUmsException("UMS call failed", e);
throw new KjbUmsException("EAI Ums call failed", e); } finally {
executor.shutdown();
} }
} else { } else {
log.warn("UMS URL 미지정으로 실제 호출을 진행하지 않음."); log.warn("UMS URL 미지정으로 실제 호출을 진행하지 않음.");