package com.eactive.eai.adapter.controller; import java.util.Date; 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.http.HttpStatusException; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; import com.eactive.eai.adapter.http.dynamic.HttpDynamicInAdapterManager; import com.eactive.eai.adapter.http.dynamic.HttpDynamicInAdapterUri; import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException; import com.eactive.eai.adapter.service.ApiAdapterService; 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.stdmessage.STDMessageDAO; import com.eactive.eai.common.util.ApplicationContextProvider; import com.eactive.eai.common.util.DatetimeUtil; 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.UUIDGenerator; import com.eactive.eai.inbound.error.InboundErrorInfoVO; // jwhong import org.json.simple.JSONObject; import java.util.HashMap; import java.util.Map; import com.eactive.eai.data.entity.onl.stdmessage.StandardMessageInfo; @RestController public class ApiAdapterController implements HttpAdapterServiceKey { static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); @Autowired ApiAdapterService service; /** * KBANK 요구사항으로 /api/v1/oauth/token 과 같은 형태로 토큰 발급거래를 수행해야해서 예외처리함 * @See com.eactive.eai.authserver.config.AuthorizationServerConfig.configure(AuthorizationServerEndpointsConfigurer endpoints) */ @RequestMapping(value = {"/api/*", "/mapi/*", "/api/*/{path:^(?!.*oauth).*$}/**", "/mapi/*/{path:^(?!.*oauth).*$}/**"}) // @RequestMapping(value = {"/api/**"}) 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, "/"); //** jwhong TSEAIHS04의 api full path와 비교하여 adapter를 가져온다 String methodAndUri = servletRequest.getMethod() + "|" + apiUri; HttpDynamicInAdapterUri adptUri = null; String adapterGrpName =""; String apiSvcCode = ""; try { STDMessageDAO dao = ApplicationContextProvider.getContext().getBean(STDMessageDAO.class); StandardMessageInfo stdInfo = dao.getSTDMsgByPath(methodAndUri); String serviceKey = stdInfo.getBzwksvckeyname(); int idx = serviceKey.indexOf(":"); adapterGrpName = (idx != -1) ? serviceKey.substring(0, idx) : serviceKey; // ':' 이전 문자열 추출 apiSvcCode = stdInfo.getEaisvcname(); //아래 원래 Logic adptUri = findAdptUri(apiUri, HttpDynamicInAdapterManager.getInstance(), adapterGrpName); } catch (Exception e) { adptUri = null; } //*** if (logger.isDebug()) { logger.debug("ApiAdapterController] service request uri : " + servletRequest.getRequestURI()); } if (adptUri == null) { logError(servletRequest); // throw new Exception("can not find Adapter Uri"); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("can not find Adapter Uri"); } //Received time , jwhong long receivedTimeMillis = System.currentTimeMillis(); // 밀리세컨 단위로 보내야함 String receivedTimeStr = String.valueOf(receivedTimeMillis); String adapterGroupName = adptUri.getAdptGrpName(); String adapterName = adptUri.getAdptName(); AdapterGroupVO adapterGroupVO = AdapterManager.getInstance().getAdapterGroupVO(adapterGroupName); AdapterVO adapterVO = AdapterManager.getInstance().getAdapterVO(adapterGroupName, adapterName); if (adapterVO == null) { // throw new Exception("Adapter not found error"); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Adapter not found error"); } 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); String responseType = httpProp.getProperty(RESPONSE_TYPE, "SYNC"); ResponseEntity responseEntity = null; Properties transactionProp = new Properties(); // jwhong, put api received time, eaiSvcCode transactionProp.put(INBOUND_REQUESTED_TIME, receivedTimeStr); transactionProp.put(API_SERVICE_CODE, apiSvcCode); try { String responseData = service.callApi(servletRequest, servletResponse, httpProp, adapterGroupVO, adapterVO, transactionProp); // if (RESPONSE_TYPE_ASYNC.equals(responseType)) { // table의 값이 ASYNC 로 들어가 있는데 response_type_async는 ASYN 로 되어 있어 아래처럼 비교함 jwhong 2025 if ("ASYNC".equals(responseType)) { //responseEntity = ResponseEntity.ok("dummy"); // comment by jwhong servletResponse.addHeader("traceId", responseData); // uuid를 response header에 int httpStatus = servletResponse.getStatus(); if (httpStatus == 200) { // 업체별 aync response message 가 다르다. String asyncMsgStyle = httpProp.getProperty("ASYNC_RTNMSG_TYPE", "").toUpperCase(); String responseBody =""; if (asyncMsgStyle == null || asyncMsgStyle.trim().isEmpty()) { responseBody = makeResponseBodyMsg(); } else { responseBody = asyncMsgStyle; } responseEntity = ResponseEntity.status(httpStatus).contentType(mediaType).body(responseBody); // jwhong } else { responseEntity = ResponseEntity.status(httpStatus).contentType(mediaType).body(responseData); } } else { // responseEntity = ResponseEntity.ok().contentType(mediaType).body(responseData); // 버즈빌 포인트 적립 처리하기 위하여 정상응답이더라도 응답코드(apiRsltCd) 값이 200이 아닌 경우 처리를 위하여 수정 // Filter에서 설정한 response status값을 responseEntity 생성시 적용 modify by lwk 2025.03.24 int httpStatus = servletResponse.getStatus(); if (httpStatus != 200) { responseEntity = ResponseEntity.status(httpStatus).contentType(mediaType).body(responseData); } else { responseEntity = ResponseEntity.ok().contentType(mediaType).body(responseData); } } } catch (HttpStatusException e) { logger.warn("ApiAdapterController] " + adapterGroupName + "-" + adapterName + ">>" + e.getMessage()); String errorMsg = MessageUtil.makeErrorMessageByMessageType(adptMsgType, encode, e.getCode(), e.getMessage(), errorResponseFormat); responseEntity = ResponseEntity.status(e.getStatus()).contentType(mediaType).body(errorMsg); } catch (JwtAuthException e) { logger.error(adapterGroupName + "-" + adapterName + ">>" + e.getMessage(), e); String errorMsg = MessageUtil.makeErrorMessageByMessageType(adptMsgType, encode, e.getCode(), e.getMessage(), errorResponseFormat); responseEntity = ResponseEntity.status(HttpStatus.UNAUTHORIZED).contentType(mediaType).body(errorMsg); } catch (Exception e) { logger.error(adapterGroupName + "-" + adapterName + ">>" + e.getMessage(), e); responseEntity = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).contentType(mediaType).body(e); } finally { /** * 로깅 인터셉터에 데이터를 전달하기 위한 처리 * 이미 거래처리가 끝나서 영향도가 없을만한 servletRequest에 Attribute로 전달 * 추후 더 좋은방법이 생길경우 개선 요망 */ servletRequest.setAttribute(TransactionContextKeys.TRANSACTION_PROP, transactionProp); } return responseEntity; } /** * 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; } //* manager 출력 logger.warn("===== adptUriMap 상세 내용 ====="); for (Map.Entry entry : manager.adptUriMap.entrySet()) { HttpDynamicInAdapterUri uriObj = entry.getValue(); logger.warn("GroupName=" + uriObj.getAdptGrpName() + ", AdapterName=" + uriObj.getAdptName() + ", URI=" + uriObj.getUri()); } logger.warn("================================"); // for (int i = 0; i < 10; i++) { HttpDynamicInAdapterUri adptUri = manager.getAdptUri(apiUri); if (adptUri != null) { if (adptUri.getAdptGrpName().equals(adapterGrpName)) { return adptUri; } } // /api/v1/public apiUri = StringUtils.substringBeforeLast(apiUri, "/"); if (apiUri.length() < 4) { // /api return null; } } return null; } private void logError(HttpServletRequest request) { InboundErrorInfoVO errorInfoVO = new InboundErrorInfoVO(); EAIServerManager eaiServerManager = EAIServerManager.getInstance(); String serverName = eaiServerManager.getLocalServerName(); String uuid = null; StringBuffer sb = new StringBuffer(); String instanceid1 = serverName.substring(0, 2); String instanceid2 = serverName.substring(serverName.length() - 2, serverName.length()); String instid = instanceid1 + instanceid2; uuid = instid + UUIDGenerator.getUUID(); String[] msgArgs = new String[1]; msgArgs[0] = request.getRequestURI(); String errorCode = "RECEAIIRP010"; String errorMsg = ExceptionUtil.make(new Exception("cat not find uri"), errorCode, msgArgs); errorInfoVO.setEaiSvcSno(uuid); // EAI서비스일련번호 errorInfoVO.setAdptBwkGrpNm("HTTP_IN_NO_URI"); // 어댑터업무그룹명 errorInfoVO.setErrCd(errorCode); // 에러코드 errorInfoVO.setErrTxt(errorMsg); // 에러내용 errorInfoVO.setErrTm(DatetimeUtil.getCurrentTime(new Date().getTime())); // 에러발생시각 errorInfoVO.setErrDstcd(" "); sb.append("Remote Addr : ").append(request.getRemoteAddr()).append("\n").append("Request URI : ") .append(request.getRequestURI()); errorInfoVO.setBwkDataTxt(sb.toString()); // 업무데이터내용 errorInfoVO.setEaiSvrInstNm(serverName); // EAI서버인스턴스명 InboundErrorLogger.error(errorInfoVO); } 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(); } */ }