From 7397a3266aca5dd5f910e3027e8e6e9951a31cf8 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Tue, 6 Jan 2026 19:00:00 +0900 Subject: [PATCH 01/18] =?UTF-8?q?dummy=20adapter=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClientAdapterServiceNoop.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceNoop.java diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceNoop.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceNoop.java new file mode 100644 index 0000000..73ac941 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceNoop.java @@ -0,0 +1,21 @@ +package com.eactive.eai.adapter.http.client.impl; + +import com.eactive.eai.adapter.http.client.HttpClientAdapterService; +import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoVO; + +import java.util.Properties; + +public class HttpClientAdapterServiceNoop implements HttpClientAdapterService { + public Object execute(Properties prop, Object data, Properties tempProp) throws Exception { + return null; + } + + @Override + public void close() { + } + + @Override + public void init(String adapterName, boolean useMtls, HttpOutTlsInfoVO mtlsInfo, int maxTotalConnections, int maxHostConnections) { + } +} + From e2d3ad593dc9afd14a3325c2be90566c5ac25112 Mon Sep 17 00:00:00 2001 From: yunjy-hp Date: Wed, 7 Jan 2026 16:44:32 +0900 Subject: [PATCH 02/18] =?UTF-8?q?ElinkTransactionContext=20=EC=9E=91?= =?UTF-8?q?=EC=97=85(=EB=B3=80=ED=99=98=20=ED=95=A8=EC=88=98=EC=97=90=20?= =?UTF-8?q?=EA=B0=92=20=EC=A0=84=EB=8B=AC=20=EC=B2=B4=EA=B3=84=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eai/common/message/EAIMessage.java | 41 +++++++++++++++++++ .../common/routing/ElinkESBProcessProxy.java | 40 +++++++++++++----- .../eai/common/routing/FlowRouter.java | 5 +++ 3 files changed, 76 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/eactive/eai/common/message/EAIMessage.java b/src/main/java/com/eactive/eai/common/message/EAIMessage.java index 255e974..4a68991 100644 --- a/src/main/java/com/eactive/eai/common/message/EAIMessage.java +++ b/src/main/java/com/eactive/eai/common/message/EAIMessage.java @@ -3,7 +3,9 @@ package com.eactive.eai.common.message; import java.io.Serializable; import java.nio.charset.Charset; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import com.eactive.eai.message.StandardMessage; import com.eactive.eai.message.manager.StandardMessageManager; @@ -107,6 +109,7 @@ public class EAIMessage implements EAIMessageKeys, Serializable, Comparable(); this.svcPssSeq = 1; @@ -624,6 +627,42 @@ public class EAIMessage implements EAIMessageKeys, Serializable, Comparable transactionContextTransfer; + + /** + * [비동기 전달 전용] 컨텍스트 전달용 Map 반환 + * @see #transactionContextTransfer + */ + public Map getTransactionContextTransfer() { + return transactionContextTransfer; + } + + /** + * [비동기 전달 전용] 컨텍스트 전달용 Map 설정 + * @see #transactionContextTransfer + */ + public void setTransactionContextTransfer(Map transactionContextTransfer) { + this.transactionContextTransfer = transactionContextTransfer; + } + @Override public Object clone() throws CloneNotSupportedException { EAIMessage cloned = (EAIMessage) super.clone(); @@ -636,6 +675,8 @@ public class EAIMessage implements EAIMessageKeys, Serializable, Comparable(transactionContextTransfer)); return cloned; } diff --git a/src/main/java/com/eactive/eai/common/routing/ElinkESBProcessProxy.java b/src/main/java/com/eactive/eai/common/routing/ElinkESBProcessProxy.java index 72e8e32..cf183ed 100644 --- a/src/main/java/com/eactive/eai/common/routing/ElinkESBProcessProxy.java +++ b/src/main/java/com/eactive/eai/common/routing/ElinkESBProcessProxy.java @@ -1,11 +1,13 @@ package com.eactive.eai.common.routing; -import com.eactive.eai.common.message.EAIMessage; -import com.eactive.eai.common.util.Logger; - import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; +import com.eactive.eai.common.context.ElinkTransactionContext; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.util.Logger; + /** * 1. 기능 : ElinkESBProcess를 호출하는 공통 Class @@ -42,17 +44,30 @@ public class ElinkESBProcessProxy public static EAIMessage callElinkESBProcess(String serviceURI, EAIMessage eaiMessage, boolean isLocal, Properties prop) throws Exception { EAIMessage retMsg = null; + + // [ElinkTransactionContext] 비동기 거래 시 컨텍스트 초기화 여부 판단 + // - ASYNC 거래이고, outbound Process 호출이 아닌 경우에만 초기화 + boolean shouldManageContext = eaiMessage != null + && EAIMessageKeys.ASYNC_SVC.equals(eaiMessage.getSvcTsmtUsgTp()) + && (serviceURI == null || !serviceURI.startsWith("com.eactive.eai.outbound")); + try { - if (isLocal){ + // [ElinkTransactionContext] 비동기 거래 진입점 - 컨텍스트 복원 + if (shouldManageContext) { + ElinkTransactionContext.restore(eaiMessage.getTransactionContextTransfer()); + eaiMessage.setTransactionContextTransfer(null); // 복원 후 전달용 필드 초기화 + } + + if (isLocal){ Class cl = classLocalCache.get(serviceURI); - + if(cl == null) { cl = Class.forName(serviceURI); classLocalCache.put(serviceURI, cl); } Process proc = (Process)cl.newInstance(); proc.callService(eaiMessage, prop); - + retMsg = proc.clientReturn(); }else{ if(eaiMessage == null) { @@ -62,12 +77,17 @@ public class ElinkESBProcessProxy retMsg = RemoteProxyClient.callProxyBean(eaiMessage, prop); } } - } catch( ClassNotFoundException e) { + } catch( ClassNotFoundException e) { if (logger.isError()) logger.error("ElinkProcessProxy] callElinkESBProcess["+serviceURI+"] Class Not Found Exception : "); - throw new Exception(PROXY_ERROR_CODE); - } catch( Exception e) { + throw new Exception(PROXY_ERROR_CODE); + } catch( Exception e) { if (logger.isError()) logger.error("ElinkProcessProxy] callElinkESBProcess["+serviceURI+"] Exception : "+e.getMessage(),e); - throw new Exception(PROXY_ERROR_CODE); + throw new Exception(PROXY_ERROR_CODE); + } finally { + // [ElinkTransactionContext] 비동기 거래 - 해제 + if (shouldManageContext) { + ElinkTransactionContext.clear(); + } } return retMsg; } diff --git a/src/main/java/com/eactive/eai/common/routing/FlowRouter.java b/src/main/java/com/eactive/eai/common/routing/FlowRouter.java index 466c797..8c9158f 100644 --- a/src/main/java/com/eactive/eai/common/routing/FlowRouter.java +++ b/src/main/java/com/eactive/eai/common/routing/FlowRouter.java @@ -2,6 +2,7 @@ package com.eactive.eai.common.routing; import java.util.Properties; +import com.eactive.eai.common.context.ElinkTransactionContext; import com.eactive.eai.common.exception.ExceptionUtil; import com.eactive.eai.common.message.EAIMessage; import com.eactive.eai.common.property.PropManager; @@ -136,6 +137,8 @@ public class FlowRouter } try { + // [ElinkTransactionContext] 비동기 송신 전 컨텍스트 복사 + eaiMessage.setTransactionContextTransfer(ElinkTransactionContext.getAll()); JMSSender.sendToQueue(eaiMessage, queueConFactory, routeQueueName, prop); } catch(Exception e) { if (logger.isError()) logger.error(guidLogPrefix +" process.Queue Error. Queue Name[" + routeQueueName + "]- " + e.getMessage(), e); @@ -164,6 +167,8 @@ public class FlowRouter } try { + // [ElinkTransactionContext] 비동기 송신 전 컨텍스트 복사 + eaiMessage.setTransactionContextTransfer(ElinkTransactionContext.getAll()); if (ElinkConfig.isUseCacheTopic()) { SessionManager.getInstance().putTopic(traceKey, eaiMessage); } From 1965391ac74c49d10074436c47b3d57a77e2dea4 Mon Sep 17 00:00:00 2001 From: yunjy-hp Date: Wed, 7 Jan 2026 17:42:37 +0900 Subject: [PATCH 03/18] =?UTF-8?q?DefaultUserAgent,=20ContentCompression=20?= =?UTF-8?q?=EB=81=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/http/client/HttpClient5AdapterServiceSupport.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java b/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java index 80655b5..ab1dc80 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java @@ -418,6 +418,8 @@ public abstract class HttpClient5AdapterServiceSupport implements HttpClientAdap }; this.client = HttpClients.custom() + .disableDefaultUserAgent() + .disableContentCompression() .addRequestInterceptorLast(requestLogInterceptor) .addResponseInterceptorFirst(responseLogInterceptor) .setConnectionManager(connectionManager) From 87fccf4c2b1a4932b662a72c71a804a8c5ca3759 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Thu, 8 Jan 2026 10:43:02 +0900 Subject: [PATCH 04/18] =?UTF-8?q?accept-encoding=20=EC=A0=9C=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/impl/HttpClientAccessTokenServiceWithParam.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java index 45e7c60..c2a6dd1 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java @@ -193,7 +193,8 @@ public class HttpClientAccessTokenServiceWithParam implements HttpClientAccessTo connectionManager.setMaxTotal(maxTotalConnections); connectionManager.setDefaultMaxPerRoute(maxHostConnections); - try (CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();) { + // http header에 zip 제외하려면 disableContentCompression() 추가해서 제외할것 + try (CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).disableContentCompression().disableDefaultUserAgent().build();) { HttpPost httpPost = new HttpPost(uri); httpPost.setEntity(new UrlEncodedFormEntity(formParams, charset)); httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=" + encode); From 48eee97caaa1a0a12d653e2cb7d9f4968d879d45 Mon Sep 17 00:00:00 2001 From: cho Date: Thu, 8 Jan 2026 11:06:35 +0900 Subject: [PATCH 05/18] =?UTF-8?q?CA=20Gateway=20=ED=86=A0=ED=81=B0=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 기존메모리에서 따로 관리하던것을 인터스끼리 공유 할수있도록 sessionManager에서 토큰을 관리.(CAToken 관리용 cache 추가 작업) 2. ApiAuthFilter.java 에 ca 방식 토큰 인증 로직 추가. 나머지는 CA토큰 발급(BearerTokenController)처리 및 BeareTokenInfo 는 어윤삼 부장 작업본 그대로 사용. --- .../http/dynamic/filter/ApiAuthFilter.java | 21 +++++- .../authserver/service/BearerTokenInfo.java | 49 +++++++++++++ .../service/BearerTokenService.java | 73 +++++++++++++++++++ .../eai/common/session/SessionManager.java | 10 +++ .../session/SessionManagerForEhcache.java | 16 ++++ .../session/SessionManagerForIgnite.java | 36 ++++++++- 6 files changed, 202 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/eactive/eai/authserver/service/BearerTokenInfo.java create mode 100644 src/main/java/com/eactive/eai/authserver/service/BearerTokenService.java diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java index 2babcee..590da9b 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java @@ -1,6 +1,7 @@ package com.eactive.eai.adapter.http.dynamic.filter; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; +import com.eactive.eai.authserver.service.BearerTokenInfo; //import com.eactive.eai.authserver.vo.BearerTokenInfo; //import com.eactive.eai.authserver.custom.BearerTokenService; import com.eactive.eai.authserver.service.OAuth2Manager; @@ -9,6 +10,7 @@ import com.eactive.eai.common.message.EAIMessage; import com.eactive.eai.common.message.EAIMessageManager; import com.eactive.eai.common.property.PropGroupVO; import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.session.SessionManager; import com.eactive.eai.common.stdmessage.STDMessageManager; import com.eactive.eai.common.util.Logger; import com.eactive.eai.common.util.StringUtil; @@ -113,7 +115,7 @@ public class ApiAuthFilter implements HttpAdapterFilter { switch (eaiMessage.getAuthType()){ case "oauth": try { - String token = ApiAuthFilter.extractJWTToken(request); + String token = extractBearerToken(request); SignedJWT signedJWT = SignedJWT.parse(token); if (signedJWT.getJWTClaimsSet().getExpirationTime() == null) { @@ -169,6 +171,21 @@ public class ApiAuthFilter implements HttpAdapterFilter { prop.setProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID, apiKey); isPassScope = true; break; + case "ca": + String token = extractBearerToken(request); + BearerTokenInfo bearerTokenInfo = SessionManager.getInstance().getCAToken(token); + if ( bearerTokenInfo != null ) { + if( bearerTokenInfo.isExpired() ) { + SessionManager.getInstance().removeCAToken(token); + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "expried API key \""+token+"\" in Http Authrozation Header"); + } + prop.setProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID, bearerTokenInfo.getClientId()); + isPassScope = true; + } + else { + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Invalid or missing API key \""+token+"\" in Http Authrozation Header"); + } + break; case "none": return message; } @@ -276,7 +293,7 @@ public class ApiAuthFilter implements HttpAdapterFilter { return false; } - public static String extractJWTToken(HttpServletRequest request) throws JwtAuthException { + public static String extractBearerToken(HttpServletRequest request) throws JwtAuthException { String authorization = request.getHeader("Authorization"); if (StringUtils.isBlank(authorization)) { throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "No have header info: Authorization"); diff --git a/src/main/java/com/eactive/eai/authserver/service/BearerTokenInfo.java b/src/main/java/com/eactive/eai/authserver/service/BearerTokenInfo.java new file mode 100644 index 0000000..390ad6d --- /dev/null +++ b/src/main/java/com/eactive/eai/authserver/service/BearerTokenInfo.java @@ -0,0 +1,49 @@ +package com.eactive.eai.authserver.service; + +import java.util.Set; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class BearerTokenInfo { + @JsonProperty("client_id") + private String clientId; + private Long expiresIn; + private Long expiresAt; + private Set scopeSet; + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public Long getExpiresIn() { + return expiresIn; + } + + public void setExpiresIn(Long expiresIn) { + this.expiresIn = expiresIn; + } + + public Long getExpiresAt() { + return expiresAt; + } + + public void setExpiresAt(Long expiresIn) { + this.expiresAt = System.currentTimeMillis() + (expiresIn * 1000); + } + + public Set getScopeSet() { + return scopeSet; + } + + public void setScopeSet(Set scopeSet) { + this.scopeSet = scopeSet; + } + + public boolean isExpired() { + return System.currentTimeMillis() > expiresAt; + } +} diff --git a/src/main/java/com/eactive/eai/authserver/service/BearerTokenService.java b/src/main/java/com/eactive/eai/authserver/service/BearerTokenService.java new file mode 100644 index 0000000..f4b29d6 --- /dev/null +++ b/src/main/java/com/eactive/eai/authserver/service/BearerTokenService.java @@ -0,0 +1,73 @@ +package com.eactive.eai.authserver.service; + +import java.security.SecureRandom; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.eactive.eai.common.session.SessionManager; +import com.eactive.eai.common.session.SessionManagerForIgnite; + +@Service +public class BearerTokenService { + + + + + public String generateCAToken(String clientId, Long expiresIn, Set scopeSet) { + + + + String token = UUID.randomUUID().toString(); + + BearerTokenInfo CATokenInfo = new BearerTokenInfo(); + CATokenInfo.setClientId(clientId); + CATokenInfo.setExpiresIn(expiresIn); + CATokenInfo.setExpiresAt(expiresIn); + CATokenInfo.setScopeSet(scopeSet); + + //CATokenStore.put(token, CATokenInfo); + + SessionManager.getInstance().putCAToken(token, CATokenInfo); + + return token; + } + + public boolean validateCA(String token) { + BearerTokenInfo CATokenInfo = SessionManager.getInstance().getCAToken(token); + if (CATokenInfo == null) return false; + + if (CATokenInfo.isExpired()) { + SessionManager.getInstance().removeCAToken(token); + return false; + }else { + return true; + } + } + + public String getClientIdFromCA(String token) { + BearerTokenInfo CATokenInfo = SessionManager.getInstance().getCAToken(token); + return CATokenInfo.getClientId(); + } + +// private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; +// private static final SecureRandom secureRandom = new SecureRandom(); +// +// public static String generateTokenString(int length) { +// // Java 8의 IntStream과 Collectors.joining을 사용한 효율적인 방법 +// return IntStream.range(0, length) +// .map(i -> secureRandom.nextInt(CHARACTERS.length())) +// .mapToObj(CHARACTERS::charAt) +// .map(String::valueOf) +// .collect(Collectors.joining()); +// } +} + diff --git a/src/main/java/com/eactive/eai/common/session/SessionManager.java b/src/main/java/com/eactive/eai/common/session/SessionManager.java index fcf007a..acfa0f1 100644 --- a/src/main/java/com/eactive/eai/common/session/SessionManager.java +++ b/src/main/java/com/eactive/eai/common/session/SessionManager.java @@ -1,5 +1,6 @@ package com.eactive.eai.common.session; +import com.eactive.eai.authserver.service.BearerTokenInfo; import com.eactive.eai.common.lifecycle.Lifecycle; import com.eactive.eai.common.lifecycle.LifecycleException; import com.eactive.eai.common.lifecycle.LifecycleListener; @@ -58,6 +59,7 @@ public abstract class SessionManager implements Lifecycle { public static final String USERID_CAHCE_NAME = "convertUserIdSession"; public static final String WEBSOCKER_CAHCE_NAME = "webSocketTimeout"; public static final String TERMINAL_CAHCE_NAME = "terminalSession"; + public static final String CAGATEWAY_TOKEN_CACHE_NAME = "CAGatewayToken"; public static final String SESSION_MANAGER_GROUPNAME = "RMIInfo"; public static final String SESSION_MANAGER_CACHETYPE = "cacheType"; @@ -193,6 +195,14 @@ public abstract class SessionManager implements Lifecycle { public abstract void putLogin(String key, SessionVO value); public abstract void removeLogin(String key); + + //CA Token Cache + public abstract BearerTokenInfo getCAToken(String key); + + public abstract void putCAToken(String key, BearerTokenInfo value); + + public abstract void removeCAToken(String key); + // HTTP Cache public abstract SessionVO getHttpLogin(String key); diff --git a/src/main/java/com/eactive/eai/common/session/SessionManagerForEhcache.java b/src/main/java/com/eactive/eai/common/session/SessionManagerForEhcache.java index 8c876c3..e23b465 100644 --- a/src/main/java/com/eactive/eai/common/session/SessionManagerForEhcache.java +++ b/src/main/java/com/eactive/eai/common/session/SessionManagerForEhcache.java @@ -3,6 +3,7 @@ package com.eactive.eai.common.session; import java.util.Properties; import java.util.concurrent.TimeUnit; +import com.eactive.eai.authserver.service.BearerTokenInfo; import com.eactive.eai.common.ehcache.CustomRMICacheReplicatorFactory; import com.eactive.eai.common.logger.EAIDBLogControl; import com.eactive.eai.common.message.EAIMessage; @@ -921,4 +922,19 @@ public class SessionManagerForEhcache extends SessionManager { sb.append(""); return sb.toString(); } + + @Override + public BearerTokenInfo getCAToken(String key) { + throw new UnsupportedOperationException(); + } + + @Override + public void putCAToken(String key, BearerTokenInfo value) { + throw new UnsupportedOperationException(); + } + + @Override + public void removeCAToken(String key) { + throw new UnsupportedOperationException(); + } } diff --git a/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java b/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java index fa397a5..55650a4 100644 --- a/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java +++ b/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java @@ -42,6 +42,7 @@ import org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMultic import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; import com.eactive.eai.adapter.socket2.common.Env; +import com.eactive.eai.authserver.service.BearerTokenInfo; import com.eactive.eai.common.logger.EAIDBLogControl; import com.eactive.eai.common.message.EAIMessage; import com.eactive.eai.common.property.PropManager; @@ -63,6 +64,7 @@ import ch.qos.logback.classic.Level; // 에러내용 : Failed to execute the cache operation // (all partition owners have left the grid, partition data has been lost) //------------------------------------------------------------------------------------ + public class SessionManagerForIgnite extends SessionManager { // evictMaster Instance - single socket 관련 private static IgniteCache evictMasterCache = null; @@ -72,7 +74,8 @@ public class SessionManagerForIgnite extends SessionManager { private static IgniteCache cacheTopic = null; // 비동기 거래 복원용 private static IgniteCache cacheStore = null; - + // CA Gateway Token 관리용 + private static IgniteCache cacheCAToken = null; // webSocket Login cache 정보 private static IgniteCache cacheLogin = null; // key = loginId private static IgniteCache cacheConvertUserId = null; // 단말ID 를 userID로 변경 @@ -364,6 +367,7 @@ public class SessionManagerForIgnite extends SessionManager { caches.add(initCache(config, sessionTimeout, bootstrapAsynchronously, USERID_CAHCE_NAME, 20000, false)); caches.add(initCache(config, webSocketTimeout, bootstrapAsynchronously, WEBSOCKER_CAHCE_NAME, 20000, false)); caches.add(initCache(config, sessionTimeout, bootstrapAsynchronously, TERMINAL_CAHCE_NAME, 20000, false)); + caches.add(initCache(config, 0, bootstrapAsynchronously, CAGATEWAY_TOKEN_CACHE_NAME, 1000, false)); config.setCacheConfiguration(caches.stream().toArray(CacheConfiguration[]::new)); @@ -391,6 +395,7 @@ public class SessionManagerForIgnite extends SessionManager { cacheSocket = manager.cache(ADAPTER_CAHCE_NAME); cacheTopic = manager.cache(TOPIC_CAHCE_NAME); cacheStore = manager.cache(STORE_CAHCE_NAME); + cacheCAToken = manager.cache(CAGATEWAY_TOKEN_CACHE_NAME); cacheLogin = manager.cache(LOGIN_CAHCE_NAME); httpLogin = manager.cache(HTTP_CAHCE_NAME); @@ -810,4 +815,33 @@ public class SessionManagerForIgnite extends SessionManager { sb.append(""); return sb.toString(); } + + @Override + public BearerTokenInfo getCAToken(String key) { + try { + return cacheCAToken.get(key); + } catch (Exception e) { + logger.error("getCAToken null key=" + key, e); + return null; + } + } + + @Override + public void putCAToken(String key, BearerTokenInfo value) { + if (logger.isWarn()) { + logger.warn("Put CAToken key - " + key + ", CAToken - " + value.toString()); + } + cacheCAToken.put(key, value); + + } + + @Override + public void removeCAToken(String key) { + if (logger.isWarn()) { + logger.warn("Remove CAToken key - " + key); + } + cacheCAToken.remove(key); + + } + } From 31146886bd12922d648f02c06568686155155e07 Mon Sep 17 00:00:00 2001 From: yunjy-hp Date: Thu, 8 Jan 2026 15:07:58 +0900 Subject: [PATCH 06/18] =?UTF-8?q?ElinkTransactionContext=EC=97=90=20?= =?UTF-8?q?=EC=B5=9C=EC=B4=88=EC=9A=94=EC=B2=AD=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=20=EC=A0=80=EC=9E=A5=20=EB=B0=8F=20=EA=B0=80=EC=A0=B8=EB=8B=A4?= =?UTF-8?q?=20=EC=93=B0=EB=8A=94=20=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inbound/processor/RequestProcessor.java | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) 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 66872e1..f2f06be 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -5,6 +5,7 @@ import java.util.Properties; import java.util.Set; import com.eactive.eai.common.TransactionContextKeys; +import com.eactive.eai.common.context.ElinkTransactionContext; import com.eactive.eai.common.util.*; import org.apache.commons.lang3.StringUtils; import org.springframework.http.HttpStatus; @@ -59,7 +60,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; @@ -75,7 +76,7 @@ import java.util.Map; * - 응답 거래로깅 * 3. 주의사항 * - * @author : + * @author : * @version : v 1.0.0 * @see : * @since : @@ -176,7 +177,7 @@ public class RequestProcessor extends RequestProcessorSupport { * @param prop 호출시 전달할 Property 값(추후 확장을 위해) * @param msgRcvTm 메시지 수신시각 * @return Object - * @throws Exception + * @throws Exception **/ protected Object hookup(Object message, Properties prop, long msgRcvTm) throws Exception { EAIMessage retEaiMsg = null; @@ -184,7 +185,7 @@ public class RequestProcessor extends RequestProcessorSupport { ProcessVO vo = setVO(prop, msgRcvTm); prop.setProperty(TransactionContextKeys.TRANSACTION_UUID, vo.getUuid()); - String inboundCharset = prop.getProperty(Keys.CHARSET_KEY_IN); + String inboundCharset = prop.getProperty(Keys.CHARSET_KEY_IN); // Unknown Message 로깅시 표준메시지일 경우 원본 자체를 남기기 위해 변수로 저장한다. // logUnknownMessage 호출시 사용하도록 함 @@ -199,7 +200,7 @@ public class RequestProcessor extends RequestProcessorSupport { } catch (Exception e1) { logger.error("deep copy error : " + e1.getMessage(), e1); } - + // 2. StandardMessage 생성 EAIServerManager eaiServerManager = EAIServerManager.getInstance(); StandardMessage standardMessage = null; @@ -207,17 +208,17 @@ public class RequestProcessor extends RequestProcessorSupport { StandardReader reader = null; InterfaceMapper mapper = standardManager.getMapper(); StandardMessage subMessage = null; - + if(Keys.IF_STANDARD.equals(vo.getStdMsgTypeCode())) { if (logger.isDebug()) logger.debug("RequestProcessor] Get Message from INPUT MESSAGE"); try { - standardMessage = standardManager.getStandardMessage(); - reader = standardManager.getReader(vo.getAdptrMsgType()); + standardMessage = standardManager.getStandardMessage(); + reader = standardManager.getReader(vo.getAdptrMsgType()); reader.parse(standardMessage, message); // 표준전문 파싱 후 어댑터의 charset을 설정한다. standardMessage.setBizDataCharset(inboundCharset); standardManager.getMessageCoordinator().coordinateAfterParsing(standardMessage, vo, prop); - + } catch(Exception e) { vo.setRspErrorCode("RECEAIIRP008"); vo.setRspErrorMsg(ExceptionUtil.make(e, vo.getRspErrorCode(), new String[]{ e.getMessage()})); @@ -226,7 +227,7 @@ public class RequestProcessor extends RequestProcessorSupport { logUnknownMessage(vo,orgMessage); throw new RequestProcessorException(vo.getRspErrorMsg()); } - } + } else { try { if(eaiServerManager.isTASEnabledEAIServer() && Keys.TESTMASTER_TAS.equals(vo.getTestMasterYn())) { //비표준 시뮬레이터 @@ -269,7 +270,7 @@ public class RequestProcessor extends RequestProcessorSupport { else { throw ex; } - } + } } else { if (logger.isInfo()) logger.info("RequestProcessor] The RequestAction is null in Adapter properties. - "+vo.getAdapterName()); } @@ -290,7 +291,7 @@ public class RequestProcessor extends RequestProcessorSupport { } } } - + if(Keys.IF_SUBSTANDARD.equals(vo.getStdMsgTypeCode())) { if (logger.isDebug()) logger.debug("RequestProcessor] Mapping StandardMessage from INPUT MESSAGE - SUBSTANDARD"); try { @@ -301,7 +302,7 @@ public class RequestProcessor extends RequestProcessorSupport { subMessage = versionMapper.parseSub(vo.getAdptrMsgType(), message); subMessage.setBizDataCharset(inboundCharset); standardMessage = versionMapper.mapFromSub(subMessage, standardMessage); - + // 변경된 값이 있을 수 있으므로 재처리. standardManager.getMessageCoordinator().coordinateAfterParsing(standardMessage, vo, prop); if(logger.isDebug() && standardMessage !=null) { @@ -350,9 +351,9 @@ public class RequestProcessor extends RequestProcessorSupport { String guid = mapper.getGuid(standardMessage); String guidSeq = mapper.getGuidSeq(standardMessage); String returnType = mapper.getSendRecvDivision(standardMessage); // S|R - + String receivedBizData = standardMessage.getBizData(); - + vo.setEaiSvcCd(eaiSvcCd); if (StringUtils.isBlank(eaiSvcCd)) { vo.setRspErrorCode("RECEAIIRP009"); @@ -383,7 +384,7 @@ public class RequestProcessor extends RequestProcessorSupport { return getInboundErrorResponse(prop, standardMessage, mapper, vo.getRspErrorCode(), vo.getRspErrorMsg(), inboundCharset); } } - + // 채널분류코드별로 GUID 중복체크 if (eaiServerManager.isMCI() && STDMessageKeys.SEND_RECV_CD_SEND.equals(mapper.getSendRecvDivision(standardMessage)) && PropManager.getInstance().isContainProperties("DUPLICATION_GUID") ) { @@ -414,7 +415,11 @@ public class RequestProcessor extends RequestProcessorSupport { } } prop.setProperty(TransactionContextKeys.GUID, guid); - + + // INBOUND MESSAGE 스레드 로컬에 저장 + String bizData = standardMessage.getBizData(); + ElinkTransactionContext.setRequestBizData(bizData); + // INBOUND_HEADER 가 NULL인 경우는 HTTP가 아닌것으로 간주함. if(prop.get(HttpClientAdapterServiceKey.INBOUND_HEADER) != null) { HttpAdapterExtraLogUtil.insertHttpAdapterExtraLog(vo.getUuid(), 100, From 9155ad51ff978bbc6dfd942d93f4b1cd63cf789f Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Fri, 9 Jan 2026 14:41:24 +0900 Subject: [PATCH 07/18] =?UTF-8?q?Body=EA=B0=92=EC=9D=B4=20"",=20Null,=20"{?= =?UTF-8?q?}"=20=EC=9D=BC=20=EA=B2=BD=EC=9A=B0=EC=99=80=20Method=EA=B0=80?= =?UTF-8?q?=20GET/DELETE=EC=9D=BC=20=EA=B2=BD=EC=9A=B0=20signature-body=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EC=A0=9C=EC=99=B8(by=20=EC=9D=B4=EC=83=81?= =?UTF-8?q?=EC=9A=B1D)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filter/HmacSha256VerifyFilterKjb.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java index 4cd3bcf..4d73b4e 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HmacSha256VerifyFilterKjb.java @@ -15,6 +15,7 @@ import javax.servlet.http.HttpServletResponse; import org.springframework.http.HttpStatus; import org.apache.commons.lang3.StringUtils; +import com.eactive.eai.adapter.http.HttpMethodType; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; import com.eactive.eai.authserver.service.OAuth2Manager; @@ -43,8 +44,7 @@ public class HmacSha256VerifyFilterKjb implements HttpAdapterFilter { String xObpSignatureUrl = request.getHeader("x-obp-signature-url"); String xObpSignatureBody = request.getHeader("x-obp-signature-body"); if (StringUtils.isBlank(xObpPartnercode) - || StringUtils.isBlank(xObpSignatureUrl) - || StringUtils.isBlank(xObpSignatureBody)) { + || StringUtils.isBlank(xObpSignatureUrl)) { throw new JwtAuthException( String.valueOf(HttpStatus.UNAUTHORIZED.value()), "Can not find mandatory Http Header"); @@ -67,10 +67,19 @@ public class HmacSha256VerifyFilterKjb implements HttpAdapterFilter { "Signature verifying failed : x-obp-signature-url"); } - if (!StringUtils.equals(xObpSignatureBody, macBody)) { - throw new JwtAuthException( - String.valueOf(HttpStatus.UNAUTHORIZED.value()), - "Signature verifying failed : x-obp-signature-body"); + switch (HttpMethodType.getValue(request.getMethod())) { + case GET: + case DELETE: + break; + default: + if (StringUtils.isNotBlank(inboundBody) && !StringUtils.equals("{}", inboundBody)) { + if (!StringUtils.equals(xObpSignatureBody, macBody)) { + throw new JwtAuthException( + String.valueOf(HttpStatus.UNAUTHORIZED.value()), + "Signature verifying failed : x-obp-signature-body"); + } + break; + } } } catch (JwtAuthException e) { From acfe440310b72278edce55f688ae0f5d7e09529d Mon Sep 17 00:00:00 2001 From: jaewohong Date: Fri, 9 Jan 2026 15:44:14 +0900 Subject: [PATCH 08/18] =?UTF-8?q?http=20status=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=A0=95=EC=83=81=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) 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 4ee9b4c..f3e34ea 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 @@ -164,6 +164,9 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp //Outbound 요청에 대한 응답 메시지의 복호화 여부 결정위해 jwhong encryptResponseApply = StringUtils.equalsIgnoreCase(prop.getProperty("ENCRYPT_RESPONSE_APPLY", "N"), "Y"); + + //업체 300응답시 특정 http status code 경우 에러 아닌걸로 처리. 광주은행 + String errIgnore = prop.getProperty("ERROR_IGNORE_CODE", ""); /** * @formatter:off @@ -496,7 +499,10 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp map.put(HttpAdapterServiceKey.OUTBOUND_RESPONSE_MESSAGE, responseString); map.put(HttpAdapterServiceKey.OUTBOUND_RESPONSE_STATUS, status); - if (status >= 200 && status <= 207) { + + if (isStatusInIgnore(status,errIgnore )) { + // 이경우 정상임 + } else if (status >= 200 && status <= 207) { if (useAdapterToken && StringUtils.equals(tokenErrorHttpStatusCode, "200")) { needReissue = checkTokenRetry(responseMessage, tokenErrorCodeKey, tokenErrorCodeValues, vo.getEncode()); @@ -1563,4 +1569,31 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp logger.debug("HttpClientAdapterServiceRest] after concatenate url=[" + targetUrl + "] "); return targetUrl; } + + + private boolean isStatusInIgnore(int status, String errIgnore) { + if (errIgnore == null || errIgnore.isEmpty()) return false; + + String[] tokens = errIgnore.split(","); + for (String token : tokens) { + token = token.trim(); + if (token.contains("-")) { + // 범위 처리 + String[] range = token.split("-"); + int start = Integer.parseInt(range[0].trim()); + int end = Integer.parseInt(range[1].trim()); + if (status >= start && status <= end) { + return true; + } + } else { + // 단일 숫자 처리 + int code = Integer.parseInt(token); + if (status == code) { + return true; + } + } + } + return false; + } + } From 1a6fd332a7442994a95f24e57e74e49bdd188bef Mon Sep 17 00:00:00 2001 From: jaewohong Date: Fri, 9 Jan 2026 15:48:43 +0900 Subject: [PATCH 09/18] http status code check --- .../adapter/http/client/impl/HttpClient5AdapterServiceRest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 f3e34ea..17e3579 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 @@ -93,7 +93,7 @@ import java.util.Date; * 기능을 제공한다.
* 2. 처리 개요 :
* * - 2020-09-25: Http Header 받아서 처리할 수 있게 기능 추가
- * 3. 주의사항
+ * 3. 주의사항
* * @author : * @version : v 1.0.0 From 27ebdb86730efbb9a55bc015e805832670640be1 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Fri, 9 Jan 2026 16:33:05 +0900 Subject: [PATCH 10/18] =?UTF-8?q?http=20status=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/http/client/impl/HttpClient5AdapterServiceRest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 17e3579..b826016 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 @@ -501,7 +501,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if (isStatusInIgnore(status,errIgnore )) { - // 이경우 정상임 + // 이경우 정상으로 처리함 } else if (status >= 200 && status <= 207) { if (useAdapterToken && StringUtils.equals(tokenErrorHttpStatusCode, "200")) { needReissue = checkTokenRetry(responseMessage, tokenErrorCodeKey, tokenErrorCodeValues, From daf33df5af9fd622d44b0b75fd84c6158daa3c6c Mon Sep 17 00:00:00 2001 From: cho Date: Sat, 10 Jan 2026 13:55:31 +0900 Subject: [PATCH 11/18] =?UTF-8?q?inbound=EC=97=90=20json=20=EC=A0=84?= =?UTF-8?q?=EB=AC=B8=EC=9D=BC=20=EB=95=8C,=20=EC=B5=9C=EC=83=81=EC=9C=84?= =?UTF-8?q?=EC=97=90=20Array('[]')=ED=83=80=EC=9E=85=EC=9D=B4=20=EB=B0=94?= =?UTF-8?q?=EB=A1=9C=20=EC=98=AC=EB=95=8C,=20=EB=B3=80=ED=99=98=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=EB=A5=BC=20=EC=9C=84=ED=95=B4,=20KJB=5FROOTLESS=5FARR?= =?UTF-8?q?AY=20=EB=9D=BC=EB=8A=94=20=ED=82=A4=EC=9D=98=20Object=EB=A5=BC?= =?UTF-8?q?=20warraped=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 31 ++++++++++++++++--- .../impl/HttpAdapterServiceStandard.java | 31 ++++++++++++++++++- 2 files changed, 57 insertions(+), 5 deletions(-) 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 4ee9b4c..a34e183 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 @@ -949,11 +949,23 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if (eaiBody == null) { return; } + + if (eaiBody instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) eaiBody; + if( jsonObject.containsKey("KJB_ROOTLESS_ARRAY") ) { + ContentType contentTypeObj = ContentType.create(contentType, charset); + JSONArray array = (JSONArray) jsonObject.get("KJB_ROOTLESS_ARRAY"); + StringEntity entity = new StringEntity(array.toJSONString(), contentTypeObj); + method.setEntity(entity); + return; + } + } if (StringUtils.contains(contentType, "application/x-www-form-urlencoded")) { if (eaiBody instanceof JSONObject) { List params = new ArrayList<>(); JSONObject jsonObject = (JSONObject) eaiBody; + for (Object key : jsonObject.keySet()) { //String encryptedValue = encrypt((String) jsonObject.get(key)); // encrypt by jwhong //params.add(new BasicNameValuePair((String) key, encryptedValue )); @@ -1456,11 +1468,22 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp @SuppressWarnings("deprecation") private JSONObject parseJson(String message) throws Exception { - if (message == null) { - return null; - } + if (message == null || message.trim().isEmpty()) { + return null; + } - return (JSONObject) JSONValue.parse(message); + Object obj = JSONValue.parse(message); + + if (obj instanceof JSONObject) { + return (JSONObject) obj; + } else if (obj instanceof JSONArray) { + // 배열일 경우 새로운 객체로 감싸서 반환 + JSONObject wrapper = new JSONObject(); + wrapper.put("KJB_ROOTLESS_ARRAY", obj); + return wrapper; + } + + return null; // 혹은 상황에 맞는 예외 처리 } private Document convertXmlDocument(String message) throws Exception { diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java index 002999f..f50d367 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java @@ -19,6 +19,9 @@ import com.eactive.eai.inbound.processor.Processor; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.StopWatch; import org.apache.mina.common.ByteBuffer; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; import javax.servlet.ServletException; import javax.servlet.ServletInputStream; @@ -180,6 +183,21 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport prop.put(PROPERTIES_NAME_HTTP_REQUEST_METHOD, request.getMethod()); prop.put(ALLOW_IP, httpProp.getProperty(ALLOW_IP, "")); + String body = new String ( requestBytes,encode); + + try { + Object root = JSONValue.parse(body); + if( root instanceof JSONArray ) { + JSONObject wrappedObject = new JSONObject(); + wrappedObject.put("KJB_ROOTLESS_ARRAY", root); + requestBytes = wrappedObject.toJSONString().getBytes(encode); + } + + }catch (Exception e) { + // ignore json이 아니기에 해줄것이 없음. + } + + // 로컬 서비스 호출 Object result = null; if (MessageUtil.isBytesMessage(messageType)) { @@ -208,7 +226,7 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport responseData = ElinkConfig.getAsyncDummyDataForAdapterGroup(adptGrpName, adptName); } } - + response.setCharacterEncoding(encode); response.getWriter().print(responseData); if (traceLevel >= 3){ @@ -230,6 +248,17 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport responseData = addData + responseData; } + + try { + Object root = JSONValue.parse(responseData); + if( root instanceof JSONObject ) { + JSONObject wrappedObject = (JSONObject) root; + responseData = wrappedObject.get("KJB_ROOTLESS_ARRAY").toString(); + } + + }catch (Exception e) { + // ignore json이 아니기에 해줄것이 없음. + } // 300응답에서 받은 Header정보 사용하기 위해 읽어옴. Map responsePropertyMap = new HashMap(); responsePropertyMap = (Map) prop.get(OUTBOUND_PROPERTY_MAP); From a61ced84c5a24eae4aeb95211c0ab9dff8f53a55 Mon Sep 17 00:00:00 2001 From: cho Date: Sat, 10 Jan 2026 15:13:11 +0900 Subject: [PATCH 12/18] =?UTF-8?q?fixedToken=ED=83=80=EC=9E=85=EC=9D=84=20?= =?UTF-8?q?=EB=A7=8C=EB=93=A4=EB=A0=A4=EA=B3=A0=20=ED=96=88=EC=9C=BC?= =?UTF-8?q?=EB=82=98,=20=EC=9D=B4=EB=AF=B8=20HttpClient5AdapterServiceRest?= =?UTF-8?q?.java=EC=97=90=EC=84=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 인터페이스타입(AccessTokenVO)를 사용하지않고 구현체인, OAuth2AccessTokenVO를 캐스팅해서 써버림. 테스트중이고, 영향도가 높아보여 fixed토큰이지만 OAuth2AccessTokenVO를 사용함. --- ...lientAccessTokenServiceWithFixedToken.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithFixedToken.java diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithFixedToken.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithFixedToken.java new file mode 100644 index 0000000..aae9f06 --- /dev/null +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithFixedToken.java @@ -0,0 +1,27 @@ +package com.eactive.eai.authoutbound.client.impl; + +import java.util.Properties; + +import com.eactive.eai.authoutbound.OutboundOAuthCredentialVo; +import com.eactive.eai.authoutbound.client.HttpClientAccessTokenServiceByDB; +import com.openbanking.eai.common.token.OAuth2AccessTokenVO; + +public class HttpClientAccessTokenServiceWithFixedToken implements HttpClientAccessTokenServiceByDB { + + @Override + public Object execute(String adapterGroupName, Properties adapterProp, OutboundOAuthCredentialVo oAuthCredentialVo) + throws Exception { + + OAuth2AccessTokenVO fixedAccessToken = new OAuth2AccessTokenVO(); + + fixedAccessToken.setAccessToken(oAuthCredentialVo.getClientSecret()); + fixedAccessToken.setClientId("none"); + fixedAccessToken.setClientUseCode("anyone"); + fixedAccessToken.setExpiresIn(60 * 60 * 24 * 365); //1년 + fixedAccessToken.setScope("none"); + fixedAccessToken.setTokenType("fixed"); + + return fixedAccessToken; + } + +} From 8957b763ffa3c9118b1d0e2563d698e7137266da Mon Sep 17 00:00:00 2001 From: cho Date: Sat, 10 Jan 2026 16:02:28 +0900 Subject: [PATCH 13/18] =?UTF-8?q?=EC=96=B4=EB=8C=91=ED=84=B0=20=ED=97=A4?= =?UTF-8?q?=EB=8D=94=EC=85=8B=ED=8C=85=20=ED=94=84=EB=A1=9C=ED=8D=BC?= =?UTF-8?q?=ED=8B=B0=20=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 78 ++++++++++++------- .../HttpClientAccessTokenServiceByDB.java | 2 +- 2 files changed, 51 insertions(+), 29 deletions(-) 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 10524af..0f076cf 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 @@ -9,15 +9,22 @@ import java.net.URI; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Base64; +import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; -import com.eactive.eai.common.property.PropManager; +// encrypt test by jwhong +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; + import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.StopWatch; @@ -60,34 +67,26 @@ import com.eactive.eai.adapter.http.client.HttpClient5AdapterServiceSupport; import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; 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.authoutbound.AccessTokenManagerByDB; import com.eactive.eai.common.exception.ExceptionUtil; import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.property.PropManager; import com.eactive.eai.common.util.CommonLib; import com.jayway.jsonpath.DocumentContext; 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.AccessTokenVO; import com.openbanking.eai.common.token.OAuth2AccessTokenVO; import edu.emory.mathcs.backport.java.util.Arrays; -// encrypt test by jwhong -import javax.crypto.Cipher; -import javax.crypto.spec.SecretKeySpec; -import java.nio.charset.StandardCharsets; -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.kjbank.encrypt.exchange.crypto.AES256GCMCipher; -import com.kjbank.encrypt.exchange.crypto.ECDHESA256Cipher; -import com.eactive.eai.authserver.service.OAuth2Manager; -import java.util.Set; -import java.util.HashSet; -import java.util.Date; - /** * 1. 기능 : EAI HTTP OutBound 용 어댑터로 수동 시스템의 HTTP 웹 컴포넌트를 GET/POST 방식으로 호출할 수 있는 * 기능을 제공한다.
@@ -112,11 +111,13 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp public static final String HTTP_STATUS = "HTTP_STATUS"; public static final String HEADER_KEYS = "HEADER_KEYS"; public static final String AUTH_TOKEN = "AUTH_TOKEN"; + public static final String HTTP_HEADER_SETTING = "HTTP_HEADER_SETTING"; public static final String PAYLOAD_PARAM_NAME_CLIENT_ID = "client_id"; // jwhong private boolean useAdapterToken; private boolean encryptResponseApply; + private String httpHeaderSettingByAdapter = "{}"; /** * 1. 기능 : REST API 통신에 사용
@@ -393,7 +394,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // 전달 header 셋팅 // Adapter 레벨 header 보다 data로 넘어온 httpHeader를 우선 적용(header명이 같다면 덮어씀) - assignRequestHeaders(method, httpHeader); + assignRequestHeaders(method, httpHeader, prop); // KJBank API 추적정보를 Header에 제공. jwhong //assignRequestKJHeaders(method, prop, tempProp ); @@ -790,27 +791,48 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return false; } - private void assignRequestHeaders(HttpUriRequestBase method, Object httpHeader) { - if (httpHeader == null) { - return; - } + private void assignRequestHeaders(HttpUriRequestBase method, Object httpHeader, Properties prop) { + if (httpHeader != null) { + if (httpHeader instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) httpHeader; + for (Object key : jsonObject.keySet()) { + Object obj = jsonObject.get(key); + if ((obj instanceof JSONObject) || (obj instanceof JSONArray)) { + continue; + } - if (httpHeader instanceof JSONObject) { - JSONObject jsonObject = (JSONObject) httpHeader; - for (Object key : jsonObject.keySet()) { - Object obj = jsonObject.get(key); + method.setHeader((String) key, (String) obj); + + if (logger.isDebugEnabled()) { + logger.debug("Request Header :" + (String) key + "=[" + (String) obj + "]"); + } + + } + } + } + //전문에서 추출한 httpHeader값 외 어댑터에서 최종적으로 적용되도록, + String httpSettingJsonStr = prop.getProperty( HTTP_HEADER_SETTING , "{}"); + try { + JSONObject httpValues = (JSONObject) JSONValue.parse(httpSettingJsonStr); + + for (Object key : httpValues.keySet()) { + Object obj = httpValues.get(key); if ((obj instanceof JSONObject) || (obj instanceof JSONArray)) { continue; } - - method.setHeader((String) key, (String) obj); - + + method.setHeader((String) key, obj); + if (logger.isDebugEnabled()) { logger.debug("Request Header :" + (String) key + "=[" + (String) obj + "]"); } } + + }catch (Exception e) { + logger.error("HTTP_HEADER_SETTING value is not JSONObject Type, skip.", e); } + } private void assignFilterHeaders(HttpUriRequestBase method, Properties tempProp) { diff --git a/src/main/java/com/eactive/eai/authoutbound/client/HttpClientAccessTokenServiceByDB.java b/src/main/java/com/eactive/eai/authoutbound/client/HttpClientAccessTokenServiceByDB.java index 40ac62a..fd589d1 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/HttpClientAccessTokenServiceByDB.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/HttpClientAccessTokenServiceByDB.java @@ -31,6 +31,6 @@ public interface HttpClientAccessTokenServiceByDB { * @return 반환 된 AccessTokenVO * @exception Exception 수동 시스템 간 통신 중 발생 **/ - public Object execute(String name, Properties adapterProp, OutboundOAuthCredentialVo oAuthCredentialVo) throws Exception ; + public Object execute(String adapterGroupName, Properties adapterProp, OutboundOAuthCredentialVo oAuthCredentialVo) throws Exception ; } From 6c43443faf5f5e3c00ffaad0f47a61823505ef59 Mon Sep 17 00:00:00 2001 From: cho Date: Sat, 10 Jan 2026 18:58:30 +0900 Subject: [PATCH 14/18] KJB_ROOTLESS_ARRAY -> kjbrootlessarray --- .../http/client/impl/HttpClient5AdapterServiceRest.java | 6 +++--- .../http/dynamic/impl/HttpAdapterServiceStandard.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) 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 0f076cf..595e8c3 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 @@ -980,9 +980,9 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if (eaiBody instanceof JSONObject) { JSONObject jsonObject = (JSONObject) eaiBody; - if( jsonObject.containsKey("KJB_ROOTLESS_ARRAY") ) { + if( jsonObject.containsKey("kjbrootlessarray") ) { ContentType contentTypeObj = ContentType.create(contentType, charset); - JSONArray array = (JSONArray) jsonObject.get("KJB_ROOTLESS_ARRAY"); + JSONArray array = (JSONArray) jsonObject.get("kjbrootlessarray"); StringEntity entity = new StringEntity(array.toJSONString(), contentTypeObj); method.setEntity(entity); return; @@ -1507,7 +1507,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } else if (obj instanceof JSONArray) { // 배열일 경우 새로운 객체로 감싸서 반환 JSONObject wrapper = new JSONObject(); - wrapper.put("KJB_ROOTLESS_ARRAY", obj); + wrapper.put("kjbrootlessarray", obj); return wrapper; } diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java index f50d367..ec008c4 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java @@ -189,7 +189,7 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport Object root = JSONValue.parse(body); if( root instanceof JSONArray ) { JSONObject wrappedObject = new JSONObject(); - wrappedObject.put("KJB_ROOTLESS_ARRAY", root); + wrappedObject.put("kjbrootlessarray", root); requestBytes = wrappedObject.toJSONString().getBytes(encode); } @@ -253,7 +253,7 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport Object root = JSONValue.parse(responseData); if( root instanceof JSONObject ) { JSONObject wrappedObject = (JSONObject) root; - responseData = wrappedObject.get("KJB_ROOTLESS_ARRAY").toString(); + responseData = wrappedObject.get("kjbrootlessarray").toString(); } }catch (Exception e) { From 6d60bd2dd1660d552575f661eb05c0b374120108 Mon Sep 17 00:00:00 2001 From: cho Date: Sat, 10 Jan 2026 19:34:47 +0900 Subject: [PATCH 15/18] =?UTF-8?q?ROOTLESSARRAY=20=EC=9B=90=EB=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 23 +---------------- .../impl/HttpAdapterServiceStandard.java | 25 +------------------ 2 files changed, 2 insertions(+), 46 deletions(-) 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 595e8c3..1cce281 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 @@ -978,16 +978,6 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return; } - if (eaiBody instanceof JSONObject) { - JSONObject jsonObject = (JSONObject) eaiBody; - if( jsonObject.containsKey("kjbrootlessarray") ) { - ContentType contentTypeObj = ContentType.create(contentType, charset); - JSONArray array = (JSONArray) jsonObject.get("kjbrootlessarray"); - StringEntity entity = new StringEntity(array.toJSONString(), contentTypeObj); - method.setEntity(entity); - return; - } - } if (StringUtils.contains(contentType, "application/x-www-form-urlencoded")) { if (eaiBody instanceof JSONObject) { @@ -1500,18 +1490,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return null; } - Object obj = JSONValue.parse(message); - - if (obj instanceof JSONObject) { - return (JSONObject) obj; - } else if (obj instanceof JSONArray) { - // 배열일 경우 새로운 객체로 감싸서 반환 - JSONObject wrapper = new JSONObject(); - wrapper.put("kjbrootlessarray", obj); - return wrapper; - } - - return null; // 혹은 상황에 맞는 예외 처리 + return (JSONObject) JSONValue.parse(message); } private Document convertXmlDocument(String message) throws Exception { diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java index ec008c4..8bcd3f4 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java @@ -185,18 +185,6 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport String body = new String ( requestBytes,encode); - try { - Object root = JSONValue.parse(body); - if( root instanceof JSONArray ) { - JSONObject wrappedObject = new JSONObject(); - wrappedObject.put("kjbrootlessarray", root); - requestBytes = wrappedObject.toJSONString().getBytes(encode); - } - - }catch (Exception e) { - // ignore json이 아니기에 해줄것이 없음. - } - // 로컬 서비스 호출 Object result = null; @@ -247,18 +235,7 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport if (addData.length() > 0){ responseData = addData + responseData; } - - - try { - Object root = JSONValue.parse(responseData); - if( root instanceof JSONObject ) { - JSONObject wrappedObject = (JSONObject) root; - responseData = wrappedObject.get("kjbrootlessarray").toString(); - } - - }catch (Exception e) { - // ignore json이 아니기에 해줄것이 없음. - } + // 300응답에서 받은 Header정보 사용하기 위해 읽어옴. Map responsePropertyMap = new HashMap(); responsePropertyMap = (Map) prop.get(OUTBOUND_PROPERTY_MAP); From e158393cce93f477ae8b30f2efd455f49ee583b2 Mon Sep 17 00:00:00 2001 From: cho Date: Mon, 12 Jan 2026 14:00:06 +0900 Subject: [PATCH 16/18] =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=85=8B=ED=8C=85?= =?UTF-8?q?=EA=B0=92=20blank=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/impl/HttpClient5AdapterServiceRest.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) 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 1cce281..846d66e 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 @@ -811,7 +811,17 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } } //전문에서 추출한 httpHeader값 외 어댑터에서 최종적으로 적용되도록, - String httpSettingJsonStr = prop.getProperty( HTTP_HEADER_SETTING , "{}"); + String httpSettingJsonStr = prop.getProperty( HTTP_HEADER_SETTING ); + + if( StringUtils.isBlank(httpSettingJsonStr) ) + { + if( logger.isInfoEnabled() ) { + logger.info("HTTP_HEADER_SETTING value is not JSONObject Type, skip."); + } + + return; + } + try { JSONObject httpValues = (JSONObject) JSONValue.parse(httpSettingJsonStr); From 51db6c88cfc2d827f90141ceeef0d798b7d2abf3 Mon Sep 17 00:00:00 2001 From: cho Date: Mon, 12 Jan 2026 15:20:30 +0900 Subject: [PATCH 17/18] =?UTF-8?q?RootlessArray=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/HttpClient5AdapterServiceRest.java | 23 +++++++++++++++++- .../impl/HttpAdapterServiceStandard.java | 24 ++++++++++++++++++- 2 files changed, 45 insertions(+), 2 deletions(-) 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 846d66e..ad296ca 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 @@ -988,6 +988,16 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return; } + if (eaiBody instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) eaiBody; + if( jsonObject.containsKey("KJB_ROOTLESS_ARRAY") ) { + ContentType contentTypeObj = ContentType.create(contentType, charset); + JSONArray array = (JSONArray) jsonObject.get("KJB_ROOTLESS_ARRAY"); + StringEntity entity = new StringEntity(array.toJSONString(), contentTypeObj); + method.setEntity(entity); + return; + } + } if (StringUtils.contains(contentType, "application/x-www-form-urlencoded")) { if (eaiBody instanceof JSONObject) { @@ -1500,7 +1510,18 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return null; } - return (JSONObject) JSONValue.parse(message); + Object obj = JSONValue.parse(message); + + if (obj instanceof JSONObject) { + return (JSONObject) obj; + } else if (obj instanceof JSONArray) { + // 배열일 경우 새로운 객체로 감싸서 반환 + JSONObject wrapper = new JSONObject(); + wrapper.put("KJB_ROOTLESS_ARRAY", obj); + return wrapper; + } + + return null; // 혹은 상황에 맞는 예외 처리 } private Document convertXmlDocument(String message) throws Exception { diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java index 8bcd3f4..f41e532 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java @@ -184,7 +184,18 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport prop.put(ALLOW_IP, httpProp.getProperty(ALLOW_IP, "")); String body = new String ( requestBytes,encode); - + + try { + Object root = JSONValue.parse(body); + if( root instanceof JSONArray ) { + JSONObject wrappedObject = new JSONObject(); + wrappedObject.put("KJB_ROOTLESS_ARRAY", root); + requestBytes = wrappedObject.toJSONString().getBytes(encode); + } + + }catch (Exception e) { + // ignore json이 아니기에 해줄것이 없음. + } // 로컬 서비스 호출 Object result = null; @@ -235,6 +246,17 @@ public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport if (addData.length() > 0){ responseData = addData + responseData; } + + try { + Object root = JSONValue.parse(responseData); + if( root instanceof JSONObject ) { + JSONObject wrappedObject = (JSONObject) root; + responseData = wrappedObject.get("KJB_ROOTLESS_ARRAY").toString(); + } + + }catch (Exception e) { + // ignore json이 아니기에 해줄것이 없음. + } // 300응답에서 받은 Header정보 사용하기 위해 읽어옴. Map responsePropertyMap = new HashMap(); From bc27d706958b599fea8853c81c86ba673569e8f6 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Mon, 12 Jan 2026 15:23:50 +0900 Subject: [PATCH 18/18] merge --- .../impl/HttpClient5AdapterServiceRest.java | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) 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 1cce281..ad296ca 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 @@ -811,7 +811,17 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } } //전문에서 추출한 httpHeader값 외 어댑터에서 최종적으로 적용되도록, - String httpSettingJsonStr = prop.getProperty( HTTP_HEADER_SETTING , "{}"); + String httpSettingJsonStr = prop.getProperty( HTTP_HEADER_SETTING ); + + if( StringUtils.isBlank(httpSettingJsonStr) ) + { + if( logger.isInfoEnabled() ) { + logger.info("HTTP_HEADER_SETTING value is not JSONObject Type, skip."); + } + + return; + } + try { JSONObject httpValues = (JSONObject) JSONValue.parse(httpSettingJsonStr); @@ -978,6 +988,16 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return; } + if (eaiBody instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) eaiBody; + if( jsonObject.containsKey("KJB_ROOTLESS_ARRAY") ) { + ContentType contentTypeObj = ContentType.create(contentType, charset); + JSONArray array = (JSONArray) jsonObject.get("KJB_ROOTLESS_ARRAY"); + StringEntity entity = new StringEntity(array.toJSONString(), contentTypeObj); + method.setEntity(entity); + return; + } + } if (StringUtils.contains(contentType, "application/x-www-form-urlencoded")) { if (eaiBody instanceof JSONObject) { @@ -1490,7 +1510,18 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return null; } - return (JSONObject) JSONValue.parse(message); + Object obj = JSONValue.parse(message); + + if (obj instanceof JSONObject) { + return (JSONObject) obj; + } else if (obj instanceof JSONArray) { + // 배열일 경우 새로운 객체로 감싸서 반환 + JSONObject wrapper = new JSONObject(); + wrapper.put("KJB_ROOTLESS_ARRAY", obj); + return wrapper; + } + + return null; // 혹은 상황에 맞는 예외 처리 } private Document convertXmlDocument(String message) throws Exception {