오류 처리 로직 추가

- 역방향(당발) 거래 시 circuitbreaker 오류에 대해 유량제어 오류가 발생하도록 수정
- Adapter Error handler에 Outbound Process(RestProcess)에서 호출 할 수 있는 메소드
추가
This commit is contained in:
curry772
2026-06-12 09:18:24 +09:00
parent a616cd6334
commit 5551affe3e
4 changed files with 121 additions and 17 deletions
@@ -5,13 +5,47 @@ import java.util.Properties;
import com.eactive.eai.common.message.EAIMessage; import com.eactive.eai.common.message.EAIMessage;
public interface AdapterErrorMessageHandler { public interface AdapterErrorMessageHandler {
/**
* 비표준 -> 표준 거래
* 아웃바운드 DefaultProcess에서 응답 표준헤더에 에러응답이 세팅되어 있는 경우, 비표준 응답 메시지 생성용
*/
public Object generateNonStandardErrorResponseMessage(String inboudnAdapterGroupName, String inboudnAdapterName, public Object generateNonStandardErrorResponseMessage(String inboudnAdapterGroupName, String inboudnAdapterName,
Properties callProp, Object outboundRequestData, EAIMessage resEaiMsg) throws Exception; Properties callProp, Object outboundRequestData, EAIMessage resEaiMsg) throws Exception;
/**
* 비표준 -> 표준 거래
* GW 내부 오류가 발생한 경우, RequestPrcessor에서 에러 응답을 생성하는 경우, ExceptionHandler에 의해 호출, 비표준 응답 메시지 생성용
*/
public Object generateNonStandardInternalErrorResponseMessage(String inboudnAdapterGroupName, public Object generateNonStandardInternalErrorResponseMessage(String inboudnAdapterGroupName,
String inboudnAdapterName, Properties callProp, Object inboundRequestData, EAIMessage resEaiMsg) String inboudnAdapterName, Properties callProp, Object inboundRequestData, EAIMessage resEaiMsg)
throws Exception; 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;
}
} }
@@ -442,6 +442,22 @@ public class TemplateAdapterErrorMsgHandler implements AdapterErrorMessageHandle
HttpStatus.INTERNAL_SERVER_ERROR.value()); 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, private Object genInboundErrorResponse(String adapterGroupName, Properties callProp, Properties httpProp,
String adptMsgType, String encode, Throwable e1, int httpCode) { String adptMsgType, String encode, Throwable e1, int httpCode) {
@@ -415,6 +415,10 @@ public final class MessageUtil {
if ("RECEAIIRP072".equals(oldErrCode)) { // 유량제어 초과 에러 if ("RECEAIIRP072".equals(oldErrCode)) { // 유량제어 초과 에러
return STDMessageErrorKeys.RATELIMIT_ERROR_CODE_VALUE; return STDMessageErrorKeys.RATELIMIT_ERROR_CODE_VALUE;
} }
if ("RECEAIOHP201".equals(oldErrCode)) { // CIRCUITBREAKER 초과 에러
return STDMessageErrorKeys.RATELIMIT_ERROR_CODE_VALUE;
}
if (EAIServiceMonitor.getInstance().isTimeOutCodes(oldErrCode)){ //TIMEOUT일경우 if (EAIServiceMonitor.getInstance().isTimeOutCodes(oldErrCode)){ //TIMEOUT일경우
return STDMessageErrorKeys.TIMEOUT_ERROR_CODE_VALUE; return STDMessageErrorKeys.TIMEOUT_ERROR_CODE_VALUE;
}else if (EAIServiceMonitor.getInstance().isBizErrorCodes(oldErrCode)){ //업무오류일경우 }else if (EAIServiceMonitor.getInstance().isBizErrorCodes(oldErrCode)){ //업무오류일경우
@@ -448,6 +452,9 @@ public final class MessageUtil {
if ("RECEAIIRP072".equals(oldErrCode)) { // 유량제어 초과 에러 if ("RECEAIIRP072".equals(oldErrCode)) { // 유량제어 초과 에러
return STDMessageErrorKeys.RATELIMIT_ERROR_MSG_VALUE; return STDMessageErrorKeys.RATELIMIT_ERROR_MSG_VALUE;
} }
if ("RECEAIOHP201".equals(oldErrCode)) { // CIRCUITBREAKER 초과 에러
return STDMessageErrorKeys.RATELIMIT_ERROR_MSG_VALUE;
}
if (EAIServiceMonitor.getInstance().isTimeOutCodes(oldErrCode) ){ //TIMEOUT일경우 if (EAIServiceMonitor.getInstance().isTimeOutCodes(oldErrCode) ){ //TIMEOUT일경우
return STDMessageErrorKeys.TIMEOUT_ERROR_MSG_VALUE; return STDMessageErrorKeys.TIMEOUT_ERROR_MSG_VALUE;
}else if (EAIServiceMonitor.getInstance().isBizErrorCodes(oldErrCode)){ //업무오류일경우 }else if (EAIServiceMonitor.getInstance().isBizErrorCodes(oldErrCode)){ //업무오류일경우
@@ -1,29 +1,25 @@
package com.eactive.eai.outbound; package com.eactive.eai.outbound;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.util.Map;
import java.util.Properties; 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 org.apache.commons.lang3.StringUtils;
import com.eactive.eai.adapter.AdapterGroupVO; import com.eactive.eai.adapter.AdapterGroupVO;
import com.eactive.eai.adapter.AdapterManager; import com.eactive.eai.adapter.AdapterManager;
import com.eactive.eai.adapter.AdapterPropManager; import com.eactive.eai.adapter.AdapterPropManager;
import com.eactive.eai.adapter.AdapterVO; 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.HttpStatusException;
import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport;
import com.eactive.eai.common.EAIKeys; 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.exception.ExceptionUtil;
import com.eactive.eai.common.header.HeaderAction; import com.eactive.eai.common.header.HeaderAction;
import com.eactive.eai.common.header.HeaderActionFactory; 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.HttpSender;
import com.eactive.eai.control.LogSender; import com.eactive.eai.control.LogSender;
import com.eactive.eai.control.Transform; 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.env.ElinkConfig;
import com.eactive.eai.inbound.processor.Processor; 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.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 { public class RESTProcess extends HTTPProcess {
static final long serialVersionUID = 1L; static final long serialVersionUID = 1L;
@@ -148,6 +146,16 @@ public class RESTProcess extends HTTPProcess {
logger.error(guidLogPrefix + rspErrorMsg, hse); logger.error(guidLogPrefix + rspErrorMsg, hse);
this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg);
throw new RuntimeException(rspErrorCode); 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) { } catch (Exception e) {
String[] msgArgs = new String[1]; String[] msgArgs = new String[1];
msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); msgArgs[0] = this.reqEaiMsg.getEAISvcCd();
@@ -682,5 +690,44 @@ public class RESTProcess extends HTTPProcess {
public void storeMessage() throws Exception { 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<String, Object> map = (Map<String, Object>) this.tempProp.get(HttpAdapterServiceKey.OUTBOUND_PROPERTY_MAP);
this.callProp.put(HttpAdapterServiceKey.OUTBOUND_PROPERTY_MAP, map);
}
}
} }