Compare commits

...

5 Commits

6 changed files with 117 additions and 88 deletions
@@ -7,11 +7,7 @@ import java.net.ConnectException;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.net.URI; import java.net.URI;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
@@ -22,10 +18,6 @@ import java.util.Properties;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
// encrypt test by jwhong
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.StopWatch; import org.apache.commons.lang3.time.StopWatch;
@@ -58,44 +50,33 @@ import org.json.simple.JSONObject;
import org.json.simple.JSONValue; import org.json.simple.JSONValue;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
import com.eactive.eai.adapter.AdapterPropManager;
import com.eactive.eai.adapter.http.HttpMemoryLogger; import com.eactive.eai.adapter.http.HttpMemoryLogger;
import com.eactive.eai.adapter.http.HttpMethodType; import com.eactive.eai.adapter.http.HttpMethodType;
import com.eactive.eai.adapter.http.client.HttpClient5AdapterServiceSupport; import com.eactive.eai.adapter.http.client.HttpClient5AdapterServiceSupport;
import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey;
import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; import com.eactive.eai.adapter.http.client.HttpClientAdapterVO;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.authserver.service.OAuth2Manager;
import com.eactive.eai.common.TransactionContextKeys; import com.eactive.eai.common.TransactionContextKeys;
import com.eactive.eai.common.authoutbound.AccessTokenManagerByDB; import com.eactive.eai.common.authoutbound.AccessTokenManagerByDB;
import com.eactive.eai.common.exception.ExceptionUtil; import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.message.MessageType; import com.eactive.eai.common.message.MessageType;
import com.eactive.eai.common.property.PropManager; import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.util.CommonLib; import com.eactive.eai.common.util.CommonLib;
import com.eactive.eai.common.util.JSONUtils; import com.eactive.eai.common.util.JacksonUtil;
import com.eactive.eai.common.util.TxFileLogger; import com.eactive.eai.common.util.TxFileLogger;
import com.eactive.eai.common.util.XMLUtils; import com.eactive.eai.common.util.XMLUtils;
import com.eactive.eai.util.JsonPathUtil; import com.eactive.eai.util.JsonPathUtil;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.JsonPath;
import com.kjbank.encrypt.exchange.crypto.AES256Cipher;
import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher;
import com.kjbank.encrypt.exchange.crypto.AESCipher;
import com.kjbank.encrypt.exchange.crypto.ECDHESA256Cipher;
import com.nimbusds.jwt.SignedJWT;
import com.openbanking.eai.common.token.AccessTokenManager; import com.openbanking.eai.common.token.AccessTokenManager;
import com.openbanking.eai.common.token.AccessTokenVO; import com.openbanking.eai.common.token.AccessTokenVO;
import com.openbanking.eai.common.token.OAuth2AccessTokenVO; import com.openbanking.eai.common.token.OAuth2AccessTokenVO;
import edu.emory.mathcs.backport.java.util.Arrays;
/** /**
* 1. 기능 : EAI HTTP OutBound 용 어댑터로 수동 시스템의 HTTP 웹 컴포넌트를 GET/POST 방식으로 호출할 수 있는 * 1. 기능 : EAI HTTP OutBound 용 어댑터로 수동 시스템의 HTTP 웹 컴포넌트를 GET/POST 방식으로 호출할 수 있는
* 기능을 제공한다.<br> * 기능을 제공한다.<br>
@@ -128,8 +109,6 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp
private boolean useAdapterToken; private boolean useAdapterToken;
private ObjectMapper mapper = new ObjectMapper();
/** /**
* 1. 기능 : REST API 통신에 사용 <br> * 1. 기능 : REST API 통신에 사용 <br>
* 2. 처리 개요 : - 속성 정보를 설정 하고 수동 시스템 서비스를 호출 한다. <br> * 2. 처리 개요 : - 속성 정보를 설정 하고 수동 시스템 서비스를 호출 한다. <br>
@@ -235,7 +214,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp
} else if(sendData instanceof JSONObject) { } else if(sendData instanceof JSONObject) {
dataObject = sendData; dataObject = sendData;
} else { } else {
dataObject = JsonPathUtil.toTree(sendData); dataObject = JacksonUtil.readTree(sendData);
} }
} else if (MessageType.XML.equals(messageType)) { } else if (MessageType.XML.equals(messageType)) {
Document doc = XMLUtils.convertXmlDocument(sendData); Document doc = XMLUtils.convertXmlDocument(sendData);
@@ -771,7 +750,6 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp
* @return * @return
* @throws Exception * @throws Exception
*/ */
@SuppressWarnings("unchecked")
private Object assignResponseHeaders(HttpUriRequestBase method, byte[] responseMessage, String headerGroupName, private Object assignResponseHeaders(HttpUriRequestBase method, byte[] responseMessage, String headerGroupName,
String encode, String responseContentType, String relayHeaderKeys, int status, Properties responseHeaderProp) throws Exception { String encode, String responseContentType, String relayHeaderKeys, int status, Properties responseHeaderProp) throws Exception {
String messageType = MessageType.JSON; String messageType = MessageType.JSON;
@@ -798,7 +776,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp
} }
if(StringUtils.equalsAny(messageType, MessageType.JSON)) { if(StringUtils.equalsAny(messageType, MessageType.JSON)) {
JSONObject headerJson = new JSONObject(); ObjectNode headerJson = JacksonUtil.createObjectNode();
if (StringUtils.equalsIgnoreCase(relayHeaderKeys, "ALL")) { if (StringUtils.equalsIgnoreCase(relayHeaderKeys, "ALL")) {
for (Enumeration<Object> e = responseHeaderProp.keys(); e.hasMoreElements(); ) { for (Enumeration<Object> e = responseHeaderProp.keys(); e.hasMoreElements(); ) {
String key = (String) e.nextElement(); String key = (String) e.nextElement();
@@ -816,23 +795,31 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp
headerJson.put(HTTP_STATUS, String.valueOf(status)); headerJson.put(HTTP_STATUS, String.valueOf(status));
if (headerJson.size() <= 0) { if (headerJson.isEmpty()) {
return new String(responseMessage, charset); return new String(responseMessage, charset);
} }
JSONObject message = null; ObjectNode message;
if (responseMessage == null || responseMessage.length == 0) { if (responseMessage == null || responseMessage.length == 0) {
message = new JSONObject(); message = JacksonUtil.createObjectNode();
} else { } else {
message = parseJson(new String(responseMessage, charset)); JsonNode parsed = null;
if (message == null) { try {
message = new JSONObject(); parsed = JacksonUtil.readTree(new String(responseMessage, charset));
} catch (Exception e) {
logger.warn("response message parse error", e);
}
if (parsed == null || !parsed.isObject()) {
message = JacksonUtil.createObjectNode();
message.put("Malformed_Response_Message", new String(responseMessage, charset)); message.put("Malformed_Response_Message", new String(responseMessage, charset));
} else {
message = (ObjectNode) parsed;
} }
} }
if (StringUtils.isNotBlank(headerGroupName) && message != null) if (StringUtils.isNotBlank(headerGroupName) && message != null) {
message.put(headerGroupName, headerJson); message.set(headerGroupName, headerJson);
}
return message; return message;
} else if (StringUtils.equalsAny(messageType, MessageType.XML)) { } else if (StringUtils.equalsAny(messageType, MessageType.XML)) {
@@ -951,24 +938,31 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp
} }
try { try {
JSONObject httpValues = (JSONObject) JSONValue.parse(httpSettingJsonStr); JsonNode httpValues = JacksonUtil.readTree(httpSettingJsonStr);
for (Object key : httpValues.keySet()) { if (httpValues == null || !httpValues.isObject()) {
Object obj = httpValues.get(key); logger.error("HTTP_HEADER_SETTING value is not json Type, skip.");
if ((obj instanceof JSONObject) || (obj instanceof JSONArray)) { } else {
Iterator<String> fieldNames = httpValues.fieldNames();
while (fieldNames.hasNext()) {
String key = fieldNames.next();
JsonNode obj = httpValues.get(key);
if (obj == null || obj.isObject() || obj.isArray()) {
continue; continue;
} }
method.setHeader((String) key, obj); String headerValue = obj.isNull() ? "" : obj.asText();
method.setHeader(key, headerValue);
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Request Header :" + (String) key + "=[" + (String) obj + "]"); logger.debug("Request Header :" + key + "=[" + headerValue + "]");
}
} }
} }
} catch (Exception e) { } catch (Exception e) {
logger.error("HTTP_HEADER_SETTING value is not JSONObject Type, skip.", e); logger.error("HTTP_HEADER_SETTING value is not json Type, skip.", e);
} }
} }
@@ -1042,7 +1036,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp
} else if(eaiBody instanceof JSONObject) { } else if(eaiBody instanceof JSONObject) {
body = ((JSONObject)eaiBody).toJSONString(); body = ((JSONObject)eaiBody).toJSONString();
} else if(eaiBody instanceof ObjectNode) { } else if(eaiBody instanceof ObjectNode) {
body = mapper.writeValueAsString((ObjectNode) eaiBody); body = JacksonUtil.writeAsString((ObjectNode) eaiBody);
} else { } else {
body = eaiBody.toString(); body = eaiBody.toString();
} }
@@ -1170,7 +1164,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp
uriVariables.add(fieldName); uriVariables.add(fieldName);
} }
if (MessageType.JSON.equals(messageType)) { if (MessageType.JSON.equals(messageType)) {
JsonNode jsonNode = JsonPathUtil.toTree(sendData); JsonNode jsonNode = JacksonUtil.readTree(sendData);
// JSONObject jsonObject; // JSONObject jsonObject;
// if (sendData instanceof JSONObject) { // if (sendData instanceof JSONObject) {
// jsonObject = (JSONObject) sendData; // jsonObject = (JSONObject) sendData;
@@ -99,7 +99,7 @@ public abstract class HttpAdapterServiceSupport implements HttpAdapterService, H
} else if (obj instanceof JSONObject) { } else if (obj instanceof JSONObject) {
return ((JSONObject) obj).toJSONString(); return ((JSONObject) obj).toJSONString();
} else if (obj instanceof JsonNode) { } else if (obj instanceof JsonNode) {
return mapper.writeValueAsString((JsonNode) obj); return (JsonNode) obj;
} else { } else {
throw new Exception("RECEAIAHA001"); throw new Exception("RECEAIAHA001");
} }
@@ -52,6 +52,7 @@ public class HsmManager implements Lifecycle {
private static final String GROUP_NAME = "HSM"; private static final String GROUP_NAME = "HSM";
private static final String PROP_CONFIG = "PKCS11_CONFIG"; private static final String PROP_CONFIG = "PKCS11_CONFIG";
private static final String PROP_PIN = "PIN"; private static final String PROP_PIN = "PIN";
private static final String PROP_RELOAD_INTERVAL_MINUTES = "RELOAD_INTERVAL_MINUTES";
private Provider pkcs11Provider; private Provider pkcs11Provider;
private volatile KeyStore keyStore; private volatile KeyStore keyStore;
@@ -62,7 +63,7 @@ public class HsmManager implements Lifecycle {
private volatile char[] pin; private volatile char[] pin;
// 재로드 주기 (분 단위). 필요시 PropManager로 외부화 가능. // 재로드 주기 (분 단위). 필요시 PropManager로 외부화 가능.
private static final long RELOAD_INTERVAL_MINUTES = 1; private static long RELOAD_INTERVAL_MINUTES = 1;
private ScheduledExecutorService scheduler; private ScheduledExecutorService scheduler;
private ScheduledFuture<?> reloadFuture; private ScheduledFuture<?> reloadFuture;
@@ -92,6 +93,9 @@ public class HsmManager implements Lifecycle {
} }
private void init() throws Exception { private void init() throws Exception {
String reloadIntervalStr = PropManager.getInstance().getProperty(GROUP_NAME, PROP_RELOAD_INTERVAL_MINUTES, "10");
RELOAD_INTERVAL_MINUTES = Long.parseLong(reloadIntervalStr);
EncryptionManager encManager = EncryptionManager.getInstance(); EncryptionManager encManager = EncryptionManager.getInstance();
String configContent = encManager.decryptDBData(PropManager.getInstance().getProperty(GROUP_NAME, PROP_CONFIG)); String configContent = encManager.decryptDBData(PropManager.getInstance().getProperty(GROUP_NAME, PROP_CONFIG));
@@ -35,6 +35,10 @@ public final class JacksonUtil {
private static final Pattern TOKEN_PATTERN = Pattern.compile("([^\\[\\]]*)((?:\\[\\d+\\])*)"); private static final Pattern TOKEN_PATTERN = Pattern.compile("([^\\[\\]]*)((?:\\[\\d+\\])*)");
private static final Pattern INDEX_PATTERN = Pattern.compile("\\[(\\d+)\\]"); private static final Pattern INDEX_PATTERN = Pattern.compile("\\[(\\d+)\\]");
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
private JacksonUtil() { private JacksonUtil() {
// 인스턴스화 방지 // 인스턴스화 방지
} }
@@ -76,6 +80,18 @@ public final class JacksonUtil {
return objectMapper.readTree(jsonStr); return objectMapper.readTree(jsonStr);
} }
public static JsonNode readTree(Object jsonData) throws JsonMappingException, JsonProcessingException {
return readTree(jsonData, OBJECT_MAPPER);
}
public static String writeAsString(JsonNode node) throws JsonProcessingException {
return OBJECT_MAPPER.writeValueAsString(node);
}
public static ObjectNode createObjectNode() {
return OBJECT_MAPPER.createObjectNode();
}
/** /**
* path 표현식으로 JsonNode를 탐색한다. * path 표현식으로 JsonNode를 탐색한다.
* 경로가 존재하지 않으면 null을 반환한다 (MissingNode가 아닌 진짜 null). * 경로가 존재하지 않으면 null을 반환한다 (MissingNode가 아닌 진짜 null).
@@ -258,4 +274,6 @@ public final class JacksonUtil {
} }
return indices; return indices;
} }
} }
@@ -11,6 +11,7 @@ import org.springframework.http.HttpStatus;
import com.eactive.eai.adapter.AdapterGroupVO; import com.eactive.eai.adapter.AdapterGroupVO;
import com.eactive.eai.adapter.AdapterManager; import com.eactive.eai.adapter.AdapterManager;
import com.eactive.eai.adapter.http.HttpStatusException; import com.eactive.eai.adapter.http.HttpStatusException;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException; import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException;
import com.eactive.eai.common.exception.ExceptionHandler; import com.eactive.eai.common.exception.ExceptionHandler;
import com.eactive.eai.common.message.EAIMessage; import com.eactive.eai.common.message.EAIMessage;
@@ -111,7 +112,13 @@ public abstract class RequestProcessorSupport implements Processor
**/ **/
public Object execute(Object message, Properties prop) throws HttpStatusException public Object execute(Object message, Properties prop) throws HttpStatusException
{ {
long msgRcvTm = System.currentTimeMillis(); String receivedTimestamp = prop.getProperty(HttpAdapterServiceKey.INBOUND_REQUESTED_TIME);
long msgRcvTm = 0L;
if(receivedTimestamp == null)
msgRcvTm = System.currentTimeMillis();
else
msgRcvTm = Long.parseLong(receivedTimestamp);
increaseRcvCount(); increaseRcvCount();
local.set(new Long(msgRcvTm)); local.set(new Long(msgRcvTm));
@@ -684,11 +684,17 @@ public abstract class DefaultProcess extends Process {
AdapterVO inboundAdapterVO = AdapterManager.getInstance().getAdapterVO(inboudnAdapterGroupName, inboudnAdapterName); AdapterVO inboundAdapterVO = AdapterManager.getInstance().getAdapterVO(inboudnAdapterGroupName, inboudnAdapterName);
String errorResponseHandlerClass = AdapterPropManager.getInstance().getProperty(inboundAdapterVO.getPropGroupName(), "ERR_MSG_HANDLER"); String errorResponseHandlerClass = AdapterPropManager.getInstance().getProperty(inboundAdapterVO.getPropGroupName(), "ERR_MSG_HANDLER");
if(StringUtils.isBlank(errorResponseHandlerClass)) { if(StringUtils.isBlank(errorResponseHandlerClass)) {
if ((com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)
||com.eactive.eai.adapter.Keys.IF_SUBSTANDARD.equals(this.adptrMsgPtrnCd))) {
String errorCode = mapper.getErrorCode(resStandardMessage); String errorCode = mapper.getErrorCode(resStandardMessage);
String errorMsg = StringUtils.trim(mapper.getErrorMsg(resStandardMessage)); String errorMsg = StringUtils.trim(mapper.getErrorMsg(resStandardMessage));
String errorDesc = StringUtils.trim(resStandardMessage.findItemValue("MSG.MAIN_MSG.outp_msg_desc")); String errorDesc = StringUtils.trim(resStandardMessage.findItemValue("MSG.MAIN_MSG.outp_msg_desc"));
this.resEaiMsg.setRspErr("RECEAIINA001", String.format("[%s] %s (%s)", errorCode, errorMsg, errorDesc)); this.resEaiMsg.setRspErr("RECEAIINA001", String.format("[%s] %s (%s)", errorCode, errorMsg, errorDesc));
return; return;
} else {
this.resEaiMsg.setRspErr("RECEAIINA001", "비표준 오류 응답 수신");
return;
}
} }
logger.info(inboudnAdapterName+", Handle Error Message Class-"+errorResponseHandlerClass); logger.info(inboudnAdapterName+", Handle Error Message Class-"+errorResponseHandlerClass);