diff --git a/src/main/java/com/eactive/eai/adapter/handler/AdapterErrorMessageHandler.java b/src/main/java/com/eactive/eai/adapter/handler/AdapterErrorMessageHandler.java index 0668ecf..59774b9 100644 --- a/src/main/java/com/eactive/eai/adapter/handler/AdapterErrorMessageHandler.java +++ b/src/main/java/com/eactive/eai/adapter/handler/AdapterErrorMessageHandler.java @@ -5,13 +5,47 @@ import java.util.Properties; import com.eactive.eai.common.message.EAIMessage; public interface AdapterErrorMessageHandler { + /** + * 비표준 -> 표준 거래 + * 아웃바운드 DefaultProcess에서 응답 표준헤더에 에러응답이 세팅되어 있는 경우, 비표준 응답 메시지 생성용 + */ public Object generateNonStandardErrorResponseMessage(String inboudnAdapterGroupName, String inboudnAdapterName, Properties callProp, Object outboundRequestData, EAIMessage resEaiMsg) throws Exception; + /** + * 비표준 -> 표준 거래 + * GW 내부 오류가 발생한 경우, RequestPrcessor에서 에러 응답을 생성하는 경우, ExceptionHandler에 의해 호출, 비표준 응답 메시지 생성용 + */ public Object generateNonStandardInternalErrorResponseMessage(String inboudnAdapterGroupName, String inboudnAdapterName, Properties callProp, Object inboundRequestData, EAIMessage resEaiMsg) throws Exception; + + /** + * 비표준 -> 표준 거래 + * GW RequestProcess 호출 전에 Adapter(Filter)에서 오류가 발생한 경우, ApiAdapterController에 Exception에 맞추어, 비표준 응답 메시지 생성용 + */ + public Object generateNonStandardInboundErrorResponseMessage(String inboudnAdapterGroupName, + String inboudnAdapterName, Properties callProp, Object inboundRequestData, Object inboundResponseData, + Throwable e) throws Exception; + + /** + * 표준 -> 비표준 거래 + * 아웃바운드 어댑터에서 Exception이 발생했을 때, Outbound 어댑터에 의해서 호출하여 응답 메시지 생성 + * 수신한 응답 메시지가 있을 수도 있고 없을 수도 있다. + */ + default public Object generateOutboundErrorResponseMessage(String outboundadapterGroupName, + String outboundadapterName, Properties callProp, Object outboundRequestData, Object outboundResponseData, + Throwable e) throws Exception { + return null; + } - public Object generateNonStandardInboundErrorResponseMessage(String adapterGroupName, String adapterName, - Properties callProp, Object inboundRequestData, Object inboundResponseData, Throwable e) throws Exception; + /** + * 표준 -> 비표준 거래 + * 아웃바운드 어댑터에서 Exception이 발생했을 때, Outbound Process 응답 메시지 생성 + */ + default public Object generateOutboundErrorResponseMessage(String outboundadapterGroupName, + String outboundadapterName, Properties callProp, Object outboundRequestData, EAIMessage resEaiMsg) + throws Exception { + return null; + } } diff --git a/src/main/java/com/eactive/eai/adapter/handler/TemplateAdapterErrorMsgHandler.java b/src/main/java/com/eactive/eai/adapter/handler/TemplateAdapterErrorMsgHandler.java index 346e016..4211761 100644 --- a/src/main/java/com/eactive/eai/adapter/handler/TemplateAdapterErrorMsgHandler.java +++ b/src/main/java/com/eactive/eai/adapter/handler/TemplateAdapterErrorMsgHandler.java @@ -442,6 +442,22 @@ public class TemplateAdapterErrorMsgHandler implements AdapterErrorMessageHandle HttpStatus.INTERNAL_SERVER_ERROR.value()); } } + + /** + * 표준 -> 비표준 거래 + * 아웃바운드 어댑터에서 Exception이 발생했을 때, Outbound Process 응답 메시지 생성 + */ + @Override + public Object generateOutboundErrorResponseMessage(String outboundadapterGroupName, + String outboundadapterName, Properties callProp, Object outboundRequestData, EAIMessage resEaiMsg) + throws Exception { + String templateKey = outboundadapterGroupName + ".template"; + String template = PropManager.getInstance().getProperty(PROP_GROUP, templateKey); + if (StringUtils.isBlank(template)) { + return null; + } + return render(template, resEaiMsg.getStandardMessage(), callProp); + } private Object genInboundErrorResponse(String adapterGroupName, Properties callProp, Properties httpProp, String adptMsgType, String encode, Throwable e1, int httpCode) { diff --git a/src/main/java/com/eactive/eai/common/util/MessageUtil.java b/src/main/java/com/eactive/eai/common/util/MessageUtil.java index 9adfbf9..5acb653 100644 --- a/src/main/java/com/eactive/eai/common/util/MessageUtil.java +++ b/src/main/java/com/eactive/eai/common/util/MessageUtil.java @@ -415,6 +415,10 @@ public final class MessageUtil { if ("RECEAIIRP072".equals(oldErrCode)) { // 유량제어 초과 에러 return STDMessageErrorKeys.RATELIMIT_ERROR_CODE_VALUE; } + if ("RECEAIOHP201".equals(oldErrCode)) { // CIRCUITBREAKER 초과 에러 + return STDMessageErrorKeys.RATELIMIT_ERROR_CODE_VALUE; + } + if (EAIServiceMonitor.getInstance().isTimeOutCodes(oldErrCode)){ //TIMEOUT일경우 return STDMessageErrorKeys.TIMEOUT_ERROR_CODE_VALUE; }else if (EAIServiceMonitor.getInstance().isBizErrorCodes(oldErrCode)){ //업무오류일경우 @@ -448,6 +452,9 @@ public final class MessageUtil { if ("RECEAIIRP072".equals(oldErrCode)) { // 유량제어 초과 에러 return STDMessageErrorKeys.RATELIMIT_ERROR_MSG_VALUE; } + if ("RECEAIOHP201".equals(oldErrCode)) { // CIRCUITBREAKER 초과 에러 + return STDMessageErrorKeys.RATELIMIT_ERROR_MSG_VALUE; + } if (EAIServiceMonitor.getInstance().isTimeOutCodes(oldErrCode) ){ //TIMEOUT일경우 return STDMessageErrorKeys.TIMEOUT_ERROR_MSG_VALUE; }else if (EAIServiceMonitor.getInstance().isBizErrorCodes(oldErrCode)){ //업무오류일경우 diff --git a/src/main/java/com/eactive/eai/outbound/RESTProcess.java b/src/main/java/com/eactive/eai/outbound/RESTProcess.java index 98b74c0..179a1d6 100644 --- a/src/main/java/com/eactive/eai/outbound/RESTProcess.java +++ b/src/main/java/com/eactive/eai/outbound/RESTProcess.java @@ -1,29 +1,25 @@ package com.eactive.eai.outbound; import java.net.SocketTimeoutException; +import java.util.Map; import java.util.Properties; -import com.eactive.eai.common.TransactionContextKeys; -import com.eactive.eai.common.circuitBreaker.CircuitBreakerManager; -import com.eactive.eai.common.circuitBreaker.type.TypedCircuitBreakerManager; -import com.eactive.eai.message.StandardMessage; -import com.eactive.eai.util.PropertiesUtil; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.initech.core.util.PropertiesManager; -import io.github.resilience4j.circuitbreaker.CircuitBreaker; import org.apache.commons.lang3.StringUtils; import com.eactive.eai.adapter.AdapterGroupVO; import com.eactive.eai.adapter.AdapterManager; import com.eactive.eai.adapter.AdapterPropManager; import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.handler.AdapterErrorMessageHandler; +import com.eactive.eai.adapter.handler.AdapterErrorMessageHandlerFactory; import com.eactive.eai.adapter.http.HttpStatusException; import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; import com.eactive.eai.common.EAIKeys; +import com.eactive.eai.common.TransactionContextKeys; +import com.eactive.eai.common.circuitBreaker.CircuitBreakerManager; +import com.eactive.eai.common.circuitBreaker.type.TypedCircuitBreakerManager; import com.eactive.eai.common.exception.ExceptionUtil; import com.eactive.eai.common.header.HeaderAction; import com.eactive.eai.common.header.HeaderActionFactory; @@ -43,14 +39,16 @@ import com.eactive.eai.common.worker.ResponseMap; import com.eactive.eai.control.HttpSender; import com.eactive.eai.control.LogSender; import com.eactive.eai.control.Transform; -import com.eactive.eai.custom.alarm.AlarmStateManager; -import com.eactive.eai.custom.alarm.condition.AlarmCondition; -import com.eactive.eai.custom.alarm.event.AlarmEvent; -import com.eactive.eai.custom.alarm.key.AlarmKey; -import com.eactive.eai.custom.alarm.key.CoreAlarmKey; import com.eactive.eai.env.ElinkConfig; import com.eactive.eai.inbound.processor.Processor; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.util.PropertiesUtil; import com.ext.eai.common.stdmessage.STDMessageKeys; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import io.github.resilience4j.circuitbreaker.CallNotPermittedException; +import io.github.resilience4j.circuitbreaker.CircuitBreaker; public class RESTProcess extends HTTPProcess { static final long serialVersionUID = 1L; @@ -148,6 +146,16 @@ public class RESTProcess extends HTTPProcess { logger.error(guidLogPrefix + rspErrorMsg, hse); this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); throw new RuntimeException(rspErrorCode); + + } catch (CallNotPermittedException e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP201"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); } catch (Exception e) { String[] msgArgs = new String[1]; msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); @@ -682,5 +690,44 @@ public class RESTProcess extends HTTPProcess { public void storeMessage() throws Exception { } + + public void setOutboundErrorMessage() throws Exception { + this.logPssSno = TranLogUtil.getResLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); + + boolean setResObject = false; + AdapterGroupVO outboundAdapterGroupVO = AdapterManager.getInstance().getAdapterGroupVO(adapterGroupName); + if (outboundAdapterGroupVO != null) { + AdapterVO outboundAdapterVo = null; + if(adapterName != null) + outboundAdapterVo = outboundAdapterGroupVO.getAdapterVO(adapterName); + else + outboundAdapterVo = outboundAdapterGroupVO.nextAdapterVO(); + + if (outboundAdapterVo != null) { + String errorHandlerClass = AdapterPropManager.getInstance().getProperty( + outboundAdapterVo.getPropGroupName(), "ERR_MSG_HANDLER"); + if (StringUtils.isNotBlank(errorHandlerClass)) { + if (logger.isInfo()) + logger.info("ExceptionHandler] errorSyncSend ERR_MSG_HANDLER=" + errorHandlerClass); + AdapterErrorMessageHandler handler = AdapterErrorMessageHandlerFactory.createHandler(errorHandlerClass); + this.resObject = handler.generateOutboundErrorResponseMessage(adapterGroupName, adapterGroupName, + callProp, this.reqObject, this.resEaiMsg); + setResObject = true; + } + } + } + if (!setResObject) { + this.resObject = ""; + } + StandardMessage standardMessage = this.resEaiMsg.getStandardMessage(); + standardMessage.setBizData(this.resObject, this.inboundCharset); + + // 에러에 대한 응답메시지 + if(this.tempProp.get(HttpAdapterServiceKey.OUTBOUND_PROPERTY_MAP) instanceof Map) { + @SuppressWarnings("unchecked") + Map map = (Map) this.tempProp.get(HttpAdapterServiceKey.OUTBOUND_PROPERTY_MAP); + this.callProp.put(HttpAdapterServiceKey.OUTBOUND_PROPERTY_MAP, map); + } + } }