package com.eactive.eai.adapter.controller; import java.util.Date; import java.util.Map; import java.util.Properties; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; 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.dynamic.HttpAdapterServiceKey; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; import com.eactive.eai.adapter.http.dynamic.HttpDynamicInAdapterManager; import com.eactive.eai.adapter.http.dynamic.HttpDynamicInAdapterUri; import com.eactive.eai.adapter.http.dynamic.filter.FilterException; import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException; import com.eactive.eai.adapter.service.DJBApiAdapterService; import com.eactive.eai.common.TransactionContextKeys; import com.eactive.eai.common.exception.ExceptionUtil; import com.eactive.eai.common.server.EAIServerManager; import com.eactive.eai.common.util.DatetimeUtil; import com.eactive.eai.common.util.HttpAdapterExtraLogUtil; import com.eactive.eai.common.util.InboundErrorLogger; import com.eactive.eai.common.util.Logger; import com.eactive.eai.common.util.MessageUtil; import com.eactive.eai.common.util.RestSendBodyLogUtils; import com.eactive.eai.common.util.TxFileLogger; import com.eactive.eai.common.util.TxSiftContext; import com.eactive.eai.common.util.UUIDGenerator; import com.eactive.eai.inbound.error.InboundErrorInfoVO; import com.eactive.eai.util.HexaConverter; @RestController public class DJBApiAdapterController implements HttpAdapterServiceKey { static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); @Autowired DJBApiAdapterService service; /** * DJErp OAuth 조기 적용을 위한 Controller * * @See com.eactive.eai.authserver.config.AuthorizationServerConfig.configure(AuthorizationServerEndpointsConfigurer * endpoints) */ @RequestMapping(value = { "/dj/{path:^(?!oauth).*$}", "/dj/{path:^(?!oauth).*$}/**", "/kp/{path:^(?!oauth).*$}", "/kp/{path:^(?!oauth).*$}/**", "/kkb/{path:^(?!oauth).*$}", "/kkb/{path:^(?!oauth).*$}/**", "/nf/{path:^(?!oauth).*$}", "/nf/{path:^(?!oauth).*$}/**", "/bsd/{path:^(?!oauth).*$}", "/bsd/{path:^(?!oauth).*$}/**", "/tss/{path:^(?!oauth).*$}", "/tss/{path:^(?!oauth).*$}/**", "/tsb/{path:^(?!oauth).*$}", "/tsb/{path:^(?!oauth).*$}/**", "/shb/{path:^(?!oauth).*$}", "/shb/{path:^(?!oauth).*$}/**", "/tst/{path:^(?!oauth).*$}", "/tst/{path:^(?!oauth).*$}/**", "/**/{path:^(?!oauth)(?!favicon\\.ico$).*$}", "/**/{path:^(?!oauth)(?!favicon\\.ico$).*$}/**", }) public ResponseEntity callApi(HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws Exception { // /ONLWeb/api/v1/public/getUserInfo.svc String apiUri = servletRequest.getRequestURI(); // /api/v1/public/getUserInfo.svc apiUri = StringUtils.removeStart(apiUri, servletRequest.getContextPath()); apiUri = StringUtils.removeEnd(apiUri, "/"); HttpDynamicInAdapterUri adptUri = findAdptUri(apiUri, HttpDynamicInAdapterManager.getInstance(), ""); if (logger.isDebug()) { logger.debug("ApiAdapterController] service request uri : " + servletRequest.getRequestURI()); } // Received time , jwhong long receivedTimeMillis = System.currentTimeMillis(); // 밀리세컨 단위로 보내야함 String receivedTimeStr = String.valueOf(receivedTimeMillis); ResponseEntity responseEntity = null; Properties transactionProp = new Properties(); String uuid = UUIDGenerator.getUUID().toString().replaceAll("-", ""); transactionProp.setProperty(TransactionContextKeys.TRANSACTION_UUID, uuid); transactionProp.put(INBOUND_REQUESTED_TIME, receivedTimeStr); if (adptUri == null) { //logError(servletRequest); String errorMsg = MessageUtil.makeJsonErrorMessage(MessageUtil.ERROR_CODE_SERVICE_NOT_FOUND, "can not find Adapter Uri"); logError(servletRequest, "HTTP_IN_NO_URI", MessageUtil.ERROR_CODE_SERVICE_NOT_FOUND, errorMsg, transactionProp, null); return ResponseEntity.status(HttpStatus.NOT_FOUND).contentType(MediaType.APPLICATION_JSON).body(errorMsg); } String adapterGroupName = adptUri.getAdptGrpName(); String adapterName = adptUri.getAdptName(); AdapterGroupVO adapterGroupVO = AdapterManager.getInstance().getAdapterGroupVO(adapterGroupName); AdapterVO adapterVO = AdapterManager.getInstance().getAdapterVO(adapterGroupName, adapterName); if (adapterVO == null) { String errorMsg = MessageUtil.makeJsonErrorMessage(MessageUtil.ERROR_CODE_AP_ERROR, "Adapter not found error"); logError(servletRequest, adapterGroupName, MessageUtil.ERROR_CODE_AP_ERROR, errorMsg, transactionProp, null); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).contentType(MediaType.APPLICATION_JSON) .body(errorMsg); } Properties httpProp = AdapterPropManager.getInstance().getProperties(adapterVO.getPropGroupName()); String adptMsgType = adapterVO.getAdapterGroupVO().getMessageType(); String encode = StringUtils.defaultIfBlank(adapterGroupVO.getMessageEncode(), "UTF-8"); MediaType mediaType = MediaType.valueOf("application/json;charset=" + encode); String errorResponseFormat = httpProp.getProperty(ERROR_RESPONSE_FORMAT); TxSiftContext.begin(uuid); // jwhong, put api received time, eaiSvcCode String responseData = ""; try { responseData = service.callApi(servletRequest, servletResponse, httpProp, adapterGroupVO, adapterVO, transactionProp); servletResponse.addHeader("traceId", transactionProp.getProperty(TransactionContextKeys.TRANSACTION_UUID)); // uuid를 response header에 int httpStatus = servletResponse.getStatus(); if (httpStatus != 200) { responseEntity = ResponseEntity.status(httpStatus).contentType(mediaType).body(responseData); } else { responseEntity = ResponseEntity.ok().contentType(mediaType).body(responseData); } } catch (Exception e) { logger.error(adapterGroupName + "-" + adapterName + ">>" + e.getMessage(), e); String responseErrorMsg = null; if (e instanceof FilterException) { responseErrorMsg = genErrorResponseMessage(adapterGroupName, adapterName, transactionProp, MessageUtil.ERROR_CODE_AP_ERROR, e, adptMsgType, encode, errorResponseFormat); FilterException e1 = (FilterException) e; this.logError(servletRequest, adapterGroupName, e1.getCode(), responseErrorMsg, transactionProp, e); logger.error("ApiAdapterController] " + adapterGroupName + "-" + adapterName + ">>" + e.getMessage()); responseEntity = ResponseEntity.status(e1.getStatus()).contentType(mediaType).body(responseErrorMsg); } else if (e instanceof JwtAuthException) { responseErrorMsg = genErrorResponseMessage(adapterGroupName, adapterName, transactionProp, MessageUtil.ERROR_CODE_AP_ERROR, e, adptMsgType, encode, errorResponseFormat); JwtAuthException e1 = (JwtAuthException) e; this.logError(servletRequest, adapterGroupName, e1.getCode(), responseErrorMsg, transactionProp, e); logger.error("ApiAdapterController] " + adapterGroupName + "-" + adapterName + ">>" + e.getMessage(), e); responseEntity = ResponseEntity.status(HttpStatus.UNAUTHORIZED).contentType(mediaType).body(responseErrorMsg); } else if (e instanceof HttpStatusException) { responseErrorMsg = genErrorResponseMessage(adapterGroupName, adapterName, transactionProp, MessageUtil.ERROR_CODE_AUTH_FAIL, e, adptMsgType, encode, errorResponseFormat); logger.error("ApiAdapterController] " + adapterGroupName + "-" + adapterName + ">>" + e.getMessage()); HttpStatusException e1 = (HttpStatusException) e; responseEntity = ResponseEntity.status(e1.getStatus()).contentType(mediaType).body(responseErrorMsg); } else { responseErrorMsg = genErrorResponseMessage(adapterGroupName, adapterName, transactionProp, MessageUtil.ERROR_CODE_AP_ERROR, e, adptMsgType, encode, errorResponseFormat); this.logError(servletRequest, adapterGroupName, MessageUtil.ERROR_CODE_AP_ERROR, responseErrorMsg, transactionProp, e); logger.error(adapterGroupName + "-" + adapterName + ">>" + e.getMessage(), e); responseEntity = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).contentType(mediaType).body(responseErrorMsg); } responseData = responseErrorMsg; } finally { // 어댑터 HTTP 로그에 응답 body 출력 if (RestSendBodyLogUtils.isBodyLoggingApi(transactionProp.getProperty("API_SERVICE_CODE"))) { String trimmedBody = RestSendBodyLogUtils.getBodyByMaxSize(responseData); transactionProp.setProperty(HttpAdapterExtraLogUtil.BODY_FIELD_NAME, trimmedBody); } servletRequest.setAttribute(TransactionContextKeys.TRANSACTION_PROP, transactionProp); /** * 로깅 인터셉터에 데이터를 전달하기 위한 처리 이미 거래처리가 끝나서 영향도가 없을만한 servletRequest에 Attribute로 전달 * 추후 더 좋은방법이 생길경우 개선 요망 */ try { TxFileLogger.logTxFile(transactionProp, responseData, "[IN_SEND]"); servletRequest.setAttribute(TransactionContextKeys.TRANSACTION_PROP, transactionProp); } catch (Exception e) { logger.warn("http header db logging fail.", e); } finally { TxSiftContext.end(); } } return responseEntity; } private String genErrorResponseMessage(String adapterGroupName, String adapterName, Properties callProp, String code, Throwable e, String adptMsgType, String encode, String errorResponseFormat) { String errorHandlerClass = AdapterPropManager.getInstance().getProperty(adapterName, "ERR_MSG_HANDLER"); if (StringUtils.isNotBlank(errorHandlerClass)) { if (logger.isInfo()) logger.info("ExceptionHandler] errorSyncSend ERR_MSG_HANDLER=" + errorHandlerClass); AdapterErrorMessageHandler handler = AdapterErrorMessageHandlerFactory.createHandler(errorHandlerClass); if (handler != null) { Object resposne; try { callProp.put("INBOUND_RESULT_CODE", code); resposne = handler.generateNonStandardInboundErrorResponseMessage(adapterGroupName, adapterName, callProp, null, null, e); return (String)resposne; } catch (Exception e1) { logger.warn("AdapterErrorMessageHandler error.", e); // handler 실패시 아래에서 처리한 } } } return MessageUtil.makeErrorMessageByMessageType(adptMsgType, encode, code, e.getMessage(), errorResponseFormat); } /** * url에서 뒤쪽 /이후를 제거하면서 찾는다.
* /api/v1/public/getUserInfo.svc * * @param apiUri * @return */ private HttpDynamicInAdapterUri findAdptUri(String apiUri, HttpDynamicInAdapterManager manager, String adapterGrpName) throws Exception { if (StringUtils.isBlank(apiUri)) { return null; } if(logger.isDebug()) { logger.debug("===== adptUriMap 상세 내용 ====="); for (Map.Entry entry : manager.adptUriMap.entrySet()) { HttpDynamicInAdapterUri uriObj = entry.getValue(); logger.debug("GroupName=" + uriObj.getAdptGrpName() + ", AdapterName=" + uriObj.getAdptName() + ", URI=" + uriObj.getUri()); } logger.debug("================================"); } // for (int i = 0; i < 10; i++) { HttpDynamicInAdapterUri adptUri = manager.getAdptUri(apiUri); if (adptUri != null) { if (StringUtils.isNotEmpty(adapterGrpName)) { if(adptUri.getAdptGrpName().equals(adapterGrpName)) { return adptUri; } } else { return adptUri; } } // /api/v1/public apiUri = StringUtils.substringBeforeLast(apiUri, "/"); if (apiUri.length() < 3) { // /api return null; } } return null; } private void logError(HttpServletRequest request) { try { String errorCode = "RECEAIIRP010"; String[] msgArgs = new String[1]; msgArgs[0] = request.getRequestURI(); this.logError(request, "HTTP_IN_NO_URI", errorCode, ExceptionUtil.make(new Exception("cat not find uri"), errorCode, msgArgs), null, null); } catch (Throwable t) { logger.warn("inbound logging failed", t); } } private void logError(HttpServletRequest request, String adapterGroupName, String errorCode, String errorMsg, Properties prop, Exception e) { try { EAIServerManager eaiServerManager = EAIServerManager.getInstance(); String serverName = eaiServerManager.getLocalServerName(); InboundErrorInfoVO errorInfoVO = new InboundErrorInfoVO(); String txId = prop.getProperty(TransactionContextKeys.TRANSACTION_UUID); if (StringUtils.isEmpty(txId)) { String instanceid1 = serverName.substring(0, 2); String instanceid2 = serverName.substring(serverName.length() - 2, serverName.length()); String instid = instanceid1 + instanceid2; txId = instid + UUIDGenerator.getUUID(); } errorInfoVO.setEaiSvcSno(txId); // EAI서비스일련번호 errorInfoVO.setAdptBwkGrpNm(adapterGroupName); // 어댑터업무그룹명 errorInfoVO.setErrCd(errorCode); // 에러코드 errorInfoVO.setErrTxt(errorMsg); // 에러내용 errorInfoVO.setErrTm(DatetimeUtil.getCurrentTime(new Date().getTime())); // 에러발생시각 errorInfoVO.setErrDstcd(" "); StringBuffer sb = new StringBuffer(); String clientId = prop.getProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID); String hexClientId = clientId != null ? HexaConverter.bytesToHexa(clientId.getBytes()) : ""; sb.append(errorMsg).append("\n").append("Remote Addr : ").append(request.getRemoteAddr()).append("\n") .append("Request URI : ").append(request.getRequestURI()).append("\n").append("clientId=") .append(clientId).append(",hexClientId=").append(hexClientId).append(",txProp=").append(prop) .append("\n"); if (e != null) sb.append("Exception : ").append(e.getMessage()); errorInfoVO.setBwkDataTxt(sb.toString()); // 업무데이터내용 errorInfoVO.setEaiSvrInstNm(serverName); // EAI서버인스턴스명 InboundErrorLogger.error(errorInfoVO); } catch (Throwable t) { logger.warn("inbound logging failed", t); } } // private String makeResponseBodyMsg() { // // Map dataMap = new HashMap<>(); // dataMap.put("result", 1); // Map map = new HashMap<>(); // // map.put("code", "200"); // map.put("data", dataMap); // map.put("message", "정상 처리 되었습니다."); // // JSONObject json = new JSONObject(); // json.putAll(map); // // return json.toJSONString(); // } /* * private String makeResponseBodyMsg(String asyncMsgStyle) { * * Map dataMap = new HashMap<>(); dataMap.put("result", 1); * Map map = new HashMap<>(); * * switch (asyncMsgStyle) { case "TB_SUC": map.put("rspCode", "TB_SUC_000"); * map.put("rspMsg", "정상"); map.put("data", dataMap); break; case "ONLYDATA": * map.put("data", dataMap); map.put("success", "true"); break; default: * map.put("code", "200"); map.put("data", dataMap); map.put("message", * "정상 처리 되었습니다."); break; } * * JSONObject json = new JSONObject(); json.putAll(map); * * return json.toJSONString(); } */ }