diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index db918b9..751abe7 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -87,8 +87,11 @@ import java.util.Base64; import com.kjbank.encrypt.exchange.crypto.AES256Cipher; import com.kjbank.encrypt.exchange.crypto.AESCipher; import com.nimbusds.jwt.SignedJWT; +import com.nimbusds.jwt.SignedJWT; import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher; +import com.kjbank.encrypt.exchange.crypto.ECDHESA256Cipher; import com.eactive.eai.authserver.service.OAuth2Manager; +import java.util.Set; /** @@ -164,6 +167,9 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp String messageType = prop.getProperty("MESSAGE_TYPE", MessageType.JSON); String inboundMethod = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_METHOD, "POST"); + //Outbound 요청에 대한 응답 메시지의 복호화 여부 결정위해 jwhong + encryptResponseApply = StringUtils.equalsIgnoreCase(prop.getProperty("ENCRYPT_RESPONSE_APPLY", "N"), "Y"); + //Outbound 요청에 대한 응답 메시지의 복호화 여부 결정위해 encryptResponseApply = StringUtils.equalsIgnoreCase(prop.getProperty("ENCRYPT_RESPONSE_APPLY", "N"), "Y"); @@ -365,7 +371,9 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp case POST: // assignPostBody(dataObject, contentType, vo.getEncode(), method); //assignPostBody(dataContent, contentType, vo.getEncode(), method); // jwhong commnet - assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName(), auth); + // KJBank API 추적정보를 Header에 제공. jwhong + String inboundToken= assignRequestKJHeaders(method, prop, tempProp ); + assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName(), auth, inboundToken); break; default: break; @@ -382,6 +390,9 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // Adapter 레벨 header 보다 data로 넘어온 httpHeader를 우선 적용(header명이 같다면 덮어씀) assignRequestHeaders(method, httpHeader); + // KJBank API 추적정보를 Header에 제공. jwhong + //assignRequestKJHeaders(method, prop, tempProp ); + int status = -1; try { @@ -438,7 +449,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // 역기서 responseMessage를 decryption 해야 하나 by jwhong responseMessageOri = EntityUtils.toByteArray(response.getEntity()); - System.out.println("responseMessageOri 바이트 배열 길이: " + responseMessageOri.length); + logger.debug("[responseMessageOri 바이트 배열 길이 ]" + responseMessageOri.length); responseMessage = doOutboundPostFilter(responseMessageOri, encryptAlgorithm, vo.getAdapterName(), accessToken); // jwhong // 여기까지 @@ -734,7 +745,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp tokenClientId = ""; } - System.out.println("Token Client ID: " + tokenClientId); + logger.debug("[ NICE Token Client ID ]" + tokenClientId); return tokenClientId; } @@ -793,8 +804,76 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } } + /* + * KJBank Target System으로 요청 보낼때 header에 clientId(업체정보), APIM거래추적자(UUID), 최초 요청시간, guid 추가해서 보낸다. jwhong + */ + private String assignRequestKJHeaders(HttpUriRequestBase method, Properties prop, Properties tempProp){ + + //weblogic 에서는 tempProp.get 이 property로 return 해어 아래처럼 수정함. ClassCastException 발생함. + //Properties inboundHeaders = (Properties) tempProp.get(HttpAdapterServiceKey.INBOUND_HEADER); + Properties inboundHeaders = null; + String authorization =""; + try { + Object headerObj = tempProp.get(HttpAdapterServiceKey.INBOUND_HEADER); + if (headerObj instanceof Properties) { //tomcat + inboundHeaders = (Properties) headerObj; + for ( String k : inboundHeaders.stringPropertyNames()) { + if(k.equalsIgnoreCase("authorization")) { + authorization = inboundHeaders.getProperty(k); + break; + } + } + } else if (headerObj instanceof String) { //weblogic + String str = (String) headerObj; + str = str.substring(1, str.length() - 1); + // 2. key=value 쌍 분리 + String[] entries = str.split(","); + // map에 담기 + Map map = new HashMap<>(); + for (String entry : entries) { + String[] kv = entry.split("=", 2); + if (kv.length == 2) { + map.put(kv[0].trim(), kv[1].trim()); + } + } + for (String k : map.keySet()) { + if (k.equalsIgnoreCase("authorization")) { + authorization = map.get(k); + break; + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + String jwtToken = ""; + + if (authorization != null && authorization.startsWith("Bearer ")) { + jwtToken = authorization.substring(7); // "Bearer " 이후의 JWT만 추출 + } + + /* 업체정보 */ + String clientId = JwtClientIdExtractor(jwtToken); + method.setHeader("clientId", clientId); + + /* APIM 거래추적자 */ + String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, ""); + method.setHeader("traceId", uuid); + + /* GUID */ + String guid = tempProp.getProperty(TransactionContextKeys.GUID, ""); + method.setHeader("guid", guid); + + /* 최초요청시간 */ + String receivedTimestamp = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_REQUESTED_TIME, ""); + method.setHeader("receivedTimestamp", receivedTimestamp); + + return jwtToken; + } + @SuppressWarnings("deprecation") - private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName, String niceAuth) { + private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName, String niceAuth, String inboundToken) { if (eaiBody == null) { return; } @@ -815,7 +894,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } else { ContentType contentTypeObj = ContentType.create(contentType, charset); - String eaiBodyMessage = doOutboundPreFilter(eaiBody, adapterName, niceAuth); // jwhong + String eaiBodyMessage = doOutboundPreFilter(eaiBody, adapterName, niceAuth, inboundToken); // jwhong StringEntity entity = new StringEntity(eaiBodyMessage, contentTypeObj); // 요청 본문을 StringEntity 객체로 생성 //StringEntity entity = new StringEntity(eaiBody.toString(), contentTypeObj); @@ -825,27 +904,35 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } } - // from here by jwhong - private String doOutboundPreFilter(Object eaiBody, String adapterName, String niceAuth) { + // from here by jwhong + private String doOutboundPreFilter(Object eaiBody, String adapterName, String niceAuth, String inboundToken) { Properties properties = AdapterPropManager.getInstance().getProperties(adapterName); // jwhong - String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong + String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM",""); // jwhong //String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); String encryptClientId = properties.getProperty("ENCRYPT_CLIENT_ID"); String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); + String certPath = properties.getProperty("ENCRYPT_CERT_PATH"); + String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); + String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); // outbound encrypt 는 SecretKey 또는 NICE-auth 가 암호화 key로 사용된다. + // outbound 알림결과는 SecretKey, NICE-auth, Token을 사용한다. // 참고로 inbound encrypt 에는 Token 또는 SecretKey 가 암호화 key로 사용된다. - // 여기에 NICE-auth 뭔지 파악하여 logic 추가해야 한다. - OAuth2Manager manager = OAuth2Manager.getInstance(); - ClientDetails clientDetail = manager.getClientDeatilsStore().get(encryptClientId); - String clientSecret = ""; - if ( clientDetail != null ) { // not null 이라는 것은 APIM Oauth Server에 등록된 client ID 이다. - // 이건 KJBank로 Outbound 나가는 것임 - clientSecret = clientDetail.getClientSecret(); - } else { // 그럼 업체로 Outbound 나가는것은, 업체에서 사용하는 secretkey를 사용한다. - clientSecret = encryptClientId; + // 여기에 NICE-auth logic 추가함 . + String clientSecret = ""; + if ("TOKEN".equalsIgnoreCase(encryptBaseKeyType)) { + clientSecret = inboundToken; + } else if ( "SECRETKEY".equalsIgnoreCase(encryptBaseKeyType)) { + OAuth2Manager manager = OAuth2Manager.getInstance(); + ClientDetails clientDetail = manager.getClientDeatilsStore().get(encryptClientId); + if ( clientDetail != null ) { // not null 이라는 것은 APIM Oauth Server에 등록된 client ID 이다. + // 업체가 우리 OAuth 를 사용하는 경우임 + clientSecret = clientDetail.getClientSecret(); + } else { // 이경우는 우리 OAuth를 사용안하는 경우임, 업체에서 사용하는 secretkey를 사용한다. + clientSecret = encryptClientId; + } } // Nice-auth , token 값을 substring 해서 사용한다. 나이스 지키미는 adapter token에서 추출된 token을 사용한다. @@ -855,11 +942,12 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // 여기서 SECRETY인지 nice-auth 인지 check 하여 clientSecret 값을 정하는 logic 추가하여 넘겨야한다. - String responseMessage = doOutboundPreEncrypt(eaiBody, encryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key); + String responseMessage = doOutboundPreEncrypt(eaiBody, encryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key, certPath); + logger.debug("outbound pre encrypte value is :"+responseMessage); return responseMessage; } - private String doOutboundPreEncrypt(Object eaiBody, String encryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key ) { + private String doOutboundPreEncrypt(Object eaiBody, String encryptAlgorithm, String clientSecretKey) { String encryptedMessage = ""; String encryptedJsonKey = ""; @@ -870,6 +958,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp case "AES": encryptedMessage = encrypt(eaiBody.toString()); // encrypt by jwhong break; + case "AES128": case "AES128-TOSS": try { String key = clientSecretKey.substring(22,38); @@ -934,6 +1023,27 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp logger.error("HttpClientAdapterServiceRest] AES256GCM Encryption error=" + e.getMessage()); } break; + case "ECDHESA256": + try { + ECDHESA256Cipher cipher = new ECDHESA256Cipher(); + + encryptedMessage = cipher.encrypt(eaiBody.toString()); + System.out.println("Encrypted JWE: " + encryptedMessage); + + String decrypted = cipher.decrypt(encryptedMessage); + System.out.println("Decrypted Payload: " + decrypted); + + //아래 인증서로 테스트 + ECDHESA256Cipher cipherCert = new ECDHESA256Cipher(certPath); + encryptedMessage = cipherCert.encrypt(eaiBody.toString()); + + decrypted = cipherCert.decrypt(encryptedMessage); + + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256GCM Encryption error=" + e.getMessage()); + } + break; default: encryptedMessage = eaiBody.toString(); return encryptedMessage; @@ -949,6 +1059,24 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } + private byte[] doOutboundPostFilter(byte[] eaiBody, String decryptAlgorithm, String adapterName, OAuth2AccessTokenVO niceAccessToken ) { + + if ( !encryptResponseApply) { + return eaiBody; + } + return encryptedMessage; + //break; + } + + Map map = new HashMap<>(); + map.put(encryptedJsonKey, encryptedMessage); + JSONObject json = new JSONObject(); + json.putAll(map); + return json.toJSONString(); + //return encryptedMessage; + } + + private byte[] doOutboundPostFilter(byte[] eaiBody, String decryptAlgorithm, String adapterName, OAuth2AccessTokenVO niceAccessToken ) { if ( !encryptResponseApply) { @@ -956,11 +1084,13 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } Properties properties = AdapterPropManager.getInstance().getProperties(adapterName); // jwhong - //String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong - //String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); + ////String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong + ////String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); String encryptClientId = properties.getProperty("ENCRYPT_CLIENT_ID"); String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); + String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); + String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); // outbound encrypt 는 SecretKey 또는 NICE-auth 가 암호화 key로 사용된다. OAuth2Manager manager = OAuth2Manager.getInstance(); @@ -972,6 +1102,16 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp clientSecret = encryptClientId; } + // Nice-auth , token 값을 substring 해서 사용한다. 나이스 지키미는 adapter token에서 추출된 token을 사용한다. + if (useAdapterToken && "AES256-NICEON".equals(decryptAlgorithm)) { + clientSecret = niceAccessToken.getAccessToken(); + } + + byte[] resPostMessage = doOutboundPostDecrypt(eaiBody, decryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key); + } else { + clientSecret = encryptClientId; + } + // Nice-auth , token 값을 substring 해서 사용한다. 나이스 지키미는 adapter token에서 추출된 token을 사용한다. if (useAdapterToken && "AES256-NICEON".equals(decryptAlgorithm)) { clientSecret = niceAccessToken.getAccessToken(); @@ -981,25 +1121,34 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return resPostMessage; } - private byte[] doOutboundPostDecrypt(byte[] eaiBody, String decryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key ) { + private byte[] doOutboundPostDecrypt(byte[] eaiBody, String decryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key , String encryptAES256Iv, String encryptAES256Key ) { byte[] decryptedMessage = null; String eaiStringBody = new String(eaiBody, StandardCharsets.UTF_8); + try { + eaiStringBody = extractBodyMsg(decryptAlgorithm, eaiStringBody); + } catch (ParseException e) { + logger.debug("[JSON 파싱 오류 발생 : ]" +e.getMessage()); + return eaiBody; + } + eaiStringBody = extractBodyMsg(decryptAlgorithm, eaiStringBody); //test source - System.out.println("eaiBody 바이트 배열 길이: " + eaiBody.length); - System.out.println("Base64 문자열: " + eaiStringBody); - System.out.println("Base64 문자열 길이: " + eaiStringBody.length()); - System.out.println("Base64 문자열 끝: " + eaiStringBody.substring(eaiStringBody.length() - 10)); + /* + logger.debug("eaiBody 바이트 배열 길이: " + eaiBody.length); + logger.debug("Base64 문자열: " + eaiStringBody); + logger.debug("Base64 문자열 길이: " + eaiStringBody.length()); + logger.debug("Base64 문자열 끝: " + eaiStringBody.substring(eaiStringBody.length() - 10)); + */ // Base64 디코딩 테스트 try { byte[] decoded = Base64.getDecoder().decode(eaiStringBody); - System.out.println("디코딩 성공, 길이: " + decoded.length); + logger.debug("[디코딩 성공, 길이: ]" + decoded.length); } catch (IllegalArgumentException e) { - System.out.println("Base64 디코딩 실패: " + e.getMessage()); + logger.debug("[Base64 디코딩 실패: ]" + e.getMessage()); } // end test source @@ -1007,6 +1156,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp case "AES": decryptedMessage = decrypt(eaiBody); // encrypt by jwhong break; + case "AES128": case "AES128-TOSS": try { String key128 = clientSecretKey.substring(22,38); @@ -1091,6 +1241,58 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } + private String extractBodyMsg(String decryptAlgorithm, String eaiStringBody) throws ParseException { + + String decryptedJsonKey = ""; + String decryptedBodyMessage = ""; + + decryptedJsonKey = getJsonKey(decryptAlgorithm); + + try { + JSONParser parser = new JSONParser(); + JSONObject jsonObject = (JSONObject) parser.parse(eaiStringBody); + decryptedBodyMessage = (String) jsonObject.get(decryptedJsonKey); + } catch (ParseException e) { + e.printStackTrace(); + logger.error("HttpClient5AdapterServiceRest] extractBodyMsg error : " + e.getMessage()); + throw e; + } + + return decryptedBodyMessage; + + } + + private String getJsonKey(String Algorithm) { + + String jsonKey = ""; + + switch (Algorithm) { + case "AES128": + case "AES128-TOSS": + jsonKey = "preScreeningRequest"; + break; + case "AES128-TOGETHER": + jsonKey = "obpTxData"; + break; + case "AES256": + jsonKey = "preScreeningRequest"; + break; + case "AES256-KAKAO": + jsonKey = "encrypted_data"; + break; + case "AES256-TOSS": + jsonKey = "encryptedData"; + break; + case "AES256-NICEON": + jsonKey = "preScreeningRequest"; + break; + case "AES256GCM": + break; + default: + break; + } + return jsonKey; + } private String extractBodyMsg(String decryptAlgorithm, String eaiStringBody) { String decryptedJsonKey = ""; diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java index a989dfd..5061ee1 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java @@ -1,7 +1,7 @@ package com.eactive.eai.adapter.http.dynamic; public interface HttpAdapterServiceKey { - // URL 파리미터 DEFAULT 이름 + // URL 파리미터 DEFAULT 이름 static final String PARAMETER_MESSAGE = "_message_"; // URL 파리미터 이름 @@ -77,6 +77,11 @@ public interface HttpAdapterServiceKey { static final String ENCRYPT_BASE_TYPE = "ENCRYPT_BASE_TYPE"; // jwhong static final String ENCRYPT_AES256_IV = "ENCRYPT_AES256_IV"; // jwhong static final String ENCRYPT_AES256_KEY = "ENCRYPT_AES256_KEY"; // jwhong + static final String INBOUND_REQUESTED_TIME = "INBOUND_REQUESTED_TIME"; // jwhong + static final String GUID = "GUID"; // jwhong + static final String API_SERVICE_CODE = "API_SERVICE_CODE"; // jwhong + static final String ENCRYPT_AES256_IV = "ENCRYPT_AES256_IV"; // jwhong + static final String ENCRYPT_AES256_KEY = "ENCRYPT_AES256_KEY"; // jwhong //응답 처리 용 표준 전문 오브젝트 static final String STANDARD_MESSAGE_OBJECT = "STANDARD_MESSAGE_OBJECT"; diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterManager.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterManager.java index cba7002..979052a 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterManager.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterManager.java @@ -24,8 +24,10 @@ public class HttpDynamicInAdapterManager implements Lifecycle { private static HttpDynamicInAdapterManager instance = new HttpDynamicInAdapterManager(); - private ConcurrentHashMap adptUriMap = new ConcurrentHashMap(); + //private ConcurrentHashMap adptUriMap = new ConcurrentHashMap(); + public ConcurrentHashMap adptUriMap = new ConcurrentHashMap(); + public static HttpDynamicInAdapterManager getInstance() { return instance; } diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java index 6316890..295c2f3 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java @@ -1,6 +1,6 @@ package com.eactive.eai.authoutbound.client.impl; - + import com.eactive.eai.adapter.AdapterGroupVO; import com.eactive.eai.adapter.AdapterManager; import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; diff --git a/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java index 4dfc052..40bd60f 100644 --- a/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java +++ b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java @@ -60,6 +60,10 @@ import com.ext.eai.common.stdmessage.STDMessageKeys; // safeDB import com.eactive.ext.kjb.safedb.KjbSafedbWrapper; import com.eactive.ext.kjb.safedb.Utils; +// until here +// safeDB +import com.eactive.ext.kjb.safedb.KjbSafedbWrapper; +import com.eactive.ext.kjb.safedb.Utils; // until here diff --git a/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraHeaderVo.java b/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraHeaderVo.java index 975f134..cce3a62 100644 --- a/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraHeaderVo.java +++ b/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraHeaderVo.java @@ -2,11 +2,15 @@ package com.eactive.eai.common.logger; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; @Data @AllArgsConstructor public class HttpAdapterExtraHeaderVo { private String name; - private String value; + + public HttpAdapterExtraHeaderVo() { + + } } diff --git a/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraLogVo.java b/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraLogVo.java index 4dcb0ac..318c57c 100644 --- a/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraLogVo.java +++ b/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraLogVo.java @@ -8,6 +8,7 @@ import java.util.List; public class HttpAdapterExtraLogVo { private String guid; private int serviceProcessNumber; + private String prcsDate; private String adapterGroupName; private String adapterName; private String url; diff --git a/src/main/java/com/eactive/eai/common/logger/async/HttpAdapterExtraLogH2Factory.java b/src/main/java/com/eactive/eai/common/logger/async/HttpAdapterExtraLogH2Factory.java index 7eb5292..93d9150 100644 --- a/src/main/java/com/eactive/eai/common/logger/async/HttpAdapterExtraLogH2Factory.java +++ b/src/main/java/com/eactive/eai/common/logger/async/HttpAdapterExtraLogH2Factory.java @@ -3,7 +3,7 @@ package com.eactive.eai.common.logger.async; import com.eactive.eai.common.property.PropManager; import com.eactive.eai.common.server.EAIServerManager; import com.eactive.eai.common.util.LogKeys; -import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeader; +//import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeader; import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraLog; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; @@ -66,7 +66,7 @@ public class HttpAdapterExtraLogH2Factory { // 엔티티 클래스 추가 configuration.addAnnotatedClass(HttpAdapterExtraLog.class); - configuration.addAnnotatedClass(HttpAdapterExtraHeader.class); +// configuration.addAnnotatedClass(HttpAdapterExtraHeader.class); return configuration.buildSessionFactory(); } catch (Throwable ex) { diff --git a/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java b/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java index e6eabe0..b609dee 100644 --- a/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java +++ b/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java @@ -1,22 +1,22 @@ -package com.eactive.eai.common.logger.mapper; - -import com.eactive.eai.common.logger.HttpAdapterExtraHeaderVo; -import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeader; -import com.eactive.eai.data.mapper.BaseMapperConfig; -import com.eactive.eai.data.mapper.GenericMapper; - -import org.mapstruct.InheritInverseConfiguration; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; - -@Mapper(config = BaseMapperConfig.class) -public interface HttpAdapterExtraHeaderMapper extends GenericMapper { - - @Override - @Mapping(source = "id.name", target = "name") - HttpAdapterExtraHeaderVo toVo(HttpAdapterExtraHeader entity); - - @Override - @InheritInverseConfiguration - HttpAdapterExtraHeader toEntity(HttpAdapterExtraHeaderVo vo); -} +//package com.eactive.eai.common.logger.mapper; +// +//import com.eactive.eai.common.logger.HttpAdapterExtraHeaderVo; +//import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeader; +//import com.eactive.eai.data.mapper.BaseMapperConfig; +//import com.eactive.eai.data.mapper.GenericMapper; +// +//import org.mapstruct.InheritInverseConfiguration; +//import org.mapstruct.Mapper; +//import org.mapstruct.Mapping; +// +//@Mapper(config = BaseMapperConfig.class) +//public interface HttpAdapterExtraHeaderMapper extends GenericMapper { +// +// @Override +// @Mapping(source = "id.name", target = "name") +// HttpAdapterExtraHeaderVo toVo(HttpAdapterExtraHeader entity); +// +// @Override +// @InheritInverseConfiguration +// HttpAdapterExtraHeader toEntity(HttpAdapterExtraHeaderVo vo); +//} diff --git a/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraLogMapper.java b/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraLogMapper.java index 73ba243..002e401 100644 --- a/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraLogMapper.java +++ b/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraLogMapper.java @@ -1,42 +1,80 @@ package com.eactive.eai.common.logger.mapper; +import com.eactive.eai.common.logger.HttpAdapterExtraHeaderVo; import com.eactive.eai.common.logger.HttpAdapterExtraLogVo; -import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeaderId; import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraLog; import com.eactive.eai.data.mapper.BaseMapperConfig; import com.eactive.eai.data.mapper.GenericMapper; - +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import org.mapstruct.*; -import java.time.DayOfWeek; import java.time.LocalDate; -import java.util.Optional; +import java.time.format.DateTimeFormatter; +import java.util.Collections; +import java.util.List; -@Mapper(config = BaseMapperConfig.class, uses = HttpAdapterExtraHeaderMapper.class) -public interface HttpAdapterExtraLogMapper extends GenericMapper { +@Slf4j +@Mapper(config = BaseMapperConfig.class) +public abstract class HttpAdapterExtraLogMapper implements GenericMapper { + + private final static ObjectMapper objectMapper = new ObjectMapper(); + private static final DateTimeFormatter SDF_YYYYMMDD = DateTimeFormatter.ofPattern( "yyyyMMdd"); @Override @Mapping(source = "id.guid", target = "guid") @Mapping(source = "id.serviceProcessNumber", target = "serviceProcessNumber") - HttpAdapterExtraLogVo toVo(HttpAdapterExtraLog entity); + abstract public HttpAdapterExtraLogVo toVo(HttpAdapterExtraLog entity); @Override @InheritInverseConfiguration - HttpAdapterExtraLog toEntity(HttpAdapterExtraLogVo vo); + abstract public HttpAdapterExtraLog toEntity(HttpAdapterExtraLogVo vo); @AfterMapping - default void setHeaderIdAndWeekday(@MappingTarget HttpAdapterExtraLog entity, HttpAdapterExtraLogVo vo) { - DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek(); // 현재 요일 - int dayOfWeekNumber = dayOfWeek.getValue() % 7 + 1; // 1 (일요일)부터 7 (토요일)까지 - entity.getId().setWeekday(dayOfWeekNumber); - Optional.ofNullable(entity.getHeaderList()) - .ifPresent(headers -> headers.forEach(header -> { - if (header.getId() == null) { - header.setId(new HttpAdapterExtraHeaderId()); - } - header.getId().setWeekday(dayOfWeekNumber); - header.getId().setGuid(vo.getGuid()); - header.getId().setServiceProcessNumber(vo.getServiceProcessNumber()); - })); + public void voToEntity(@MappingTarget HttpAdapterExtraLog entity, HttpAdapterExtraLogVo vo) { + + // 1. Set weekday for partition table +// DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek(); // 현재 요일 +// int dayOfWeekNumber = dayOfWeek.getValue() % 7 + 1; // 1 (일요일)부터 7 (토요일)까지 +// entity.getId().setWeekday(dayOfWeekNumber); + +// String prcs_date = SDF_YYYYMMDD.format(ZonedDateTime.now()); + String prcs_date = LocalDate.now().format(SDF_YYYYMMDD); + entity.getId().setPrcsDate(prcs_date); + + // 2. Set Content + try { + String headerContent = objectMapper.writeValueAsString(vo.getHeaderList()); + entity.setHeaderContent(headerContent); + } catch (JsonProcessingException e) { + log.warn("Http Header Json Parse 실패", e); + entity.setHeaderContent("[{ \"error\": \"parse error\"}]"); + } + + } + + /** + * Entity → VO 변환 후 추가 처리 + */ + @AfterMapping + protected void entityToVo(@MappingTarget HttpAdapterExtraLogVo vo, HttpAdapterExtraLog entity) { + String headerContent = entity.getHeaderContent(); + if (headerContent == null || headerContent.isEmpty()) { + vo.setHeaderList(Collections.emptyList()); + return; + } + + try { + List headerList = objectMapper.readValue( + headerContent, + new TypeReference>() {} + ); + vo.setHeaderList(headerList); + } catch (JsonProcessingException e) { + log.warn("Http Header 역직렬화 실패", e); + vo.setHeaderList(Collections.emptyList()); + } } } diff --git a/src/main/java/com/eactive/eai/common/stdmessage/STDMessageDAO.java b/src/main/java/com/eactive/eai/common/stdmessage/STDMessageDAO.java index 8b8c320..447fe75 100644 --- a/src/main/java/com/eactive/eai/common/stdmessage/STDMessageDAO.java +++ b/src/main/java/com/eactive/eai/common/stdmessage/STDMessageDAO.java @@ -224,4 +224,12 @@ public class STDMessageDAO extends BaseDAO { throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE111")); } } + + // jwhong 추가 + public StandardMessageInfo getSTDMsgByPath(String apiFullPath) throws DAOException { + Optional optional = standardMessageInfoLoader.findByApiFullPath(apiFullPath); + return optional.orElseThrow(() -> new DAOException("해당 full path의 TSEAIHS04 에 데이터가 없습니다.")); + } + + } diff --git a/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java b/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java index 8251e53..75f405c 100644 --- a/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java +++ b/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java @@ -101,7 +101,7 @@ public class HttpAdapterExtraLogUtil { public static List convertHeaderToListOfHttpAdapterExtraHeaderVo(Header[] headers) { Set seenNames = new HashSet<>(); return Arrays.stream(headers) - .filter(header -> seenNames.add(header.getName())) // 중복된 이름을 스킵 +// .filter(header -> seenNames.add(header.getName())) // 중복된 이름을 스킵 .map(header -> new HttpAdapterExtraHeaderVo(header.getName(), header.getValue())) .collect(Collectors.toList()); } diff --git a/src/main/java/com/eactive/eai/common/util/JMSSender.java b/src/main/java/com/eactive/eai/common/util/JMSSender.java index c775498..73b15d6 100644 --- a/src/main/java/com/eactive/eai/common/util/JMSSender.java +++ b/src/main/java/com/eactive/eai/common/util/JMSSender.java @@ -1,5 +1,5 @@ package com.eactive.eai.common.util; - + import java.util.Iterator; import java.util.Properties; @@ -69,6 +69,7 @@ public class JMSSender { throw new Exception("qconFactory not found -" + connectionFactory); queue = locator.getQueue(destination); + logger.info("resolved quene name is:" + "["+ queue + "]"); qsender = qsession.createSender(queue); ObjectMessage msg = qsession.createObjectMessage(); diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index 0aba908..750310f 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -58,7 +58,7 @@ import org.json.simple.JSONObject; import java.util.HashMap; import java.util.Map; //import org.apache.commons.lang3.StringUtils; -//import org.springframework.http.HttpStatus; +//import org.springframework.http.HttpStatus; //import java.util.Calendar; //import java.util.Properties; @@ -121,19 +121,20 @@ public class RequestProcessor extends RequestProcessorSupport { String bidInterface = adptGrpVO.getBidInterface(); String testMasterYn = adptGrpVO.getTestMasterYn(); - // UUID 생성 : UUID = server구분4자리 + UUID + // UUID 생성 : UUID = "-" 없는 32자리 UUID(광주은행 요청) String uuid = ""; + uuid = UUIDGenerator.getUUID().toString().replaceAll("-", ""); - if(instid != null) { - uuid = instid + UUIDGenerator.getUUID(); - if (logger.isDebug()) logger.debug("RequestProcessor] UUID ["+uuid+"]"); - } - else { - String rspErrorCode = "RECEAIIRP030"; - String rspErrorMsg = ErrorCodeHandler.getMessage(rspErrorCode); - if (logger.isError()) logger.error(rspErrorMsg); - throw new RequestProcessorException(rspErrorMsg); - } +// if(instid != null) { +// uuid = instid + UUIDGenerator.getUUID(); +// if (logger.isDebug()) logger.debug("RequestProcessor] UUID ["+uuid+"]"); +// } +// else { +// String rspErrorCode = "RECEAIIRP030"; +// String rspErrorMsg = ErrorCodeHandler.getMessage(rspErrorCode); +// if (logger.isError()) logger.error(rspErrorMsg); +// throw new RequestProcessorException(rspErrorMsg); +// } ProcessVO vo = new ProcessVO(); vo.setAdapterGroupName(adapterGroupName); @@ -336,7 +337,8 @@ public class RequestProcessor extends RequestProcessorSupport { } // 3. EAIMessage Object 생성 - String eaiSvcCd = mapper.getEaiSvcCode(standardMessage); + //String eaiSvcCd = mapper.getEaiSvcCode(standardMessage); // commnet by jwhong + String eaiSvcCd = prop.getProperty("API_SERVICE_CODE"); String guid = mapper.getGuid(standardMessage); String guidSeq = mapper.getGuidSeq(standardMessage); String returnType = mapper.getSendRecvDivision(standardMessage); // S|R diff --git a/src/main/java/com/eactive/eai/outbound/RESTProcess.java b/src/main/java/com/eactive/eai/outbound/RESTProcess.java index 1b2eb51..77e1d9d 100644 --- a/src/main/java/com/eactive/eai/outbound/RESTProcess.java +++ b/src/main/java/com/eactive/eai/outbound/RESTProcess.java @@ -1,5 +1,5 @@ package com.eactive.eai.outbound; - + import java.net.SocketTimeoutException; import java.util.Properties; @@ -439,6 +439,8 @@ public class RESTProcess extends HTTPProcess { PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_PATH_VARIABLES); PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_REMOTE_ADDR); PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_SCHEME); + PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_REQUESTED_TIME); // jwhong + PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.GUID); // jwhong String svcName = getServiceId(this.reqEaiMsg); if (svcName == null) {