From 5af11f8d55cd12ae59e93bfa02043e1cec9db3ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=98=84=EC=84=B1=ED=95=84?= Date: Sun, 16 Nov 2025 21:58:55 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B3=BC=EA=B8=88=20=EC=BB=A8=ED=8A=B8?= =?UTF-8?q?=EB=A1=A4=EB=9F=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apps/commission/constant/Constants.java | 30 ++ .../controller/CommissionController.java | 271 ++++++++++++++++++ .../apps/commission/dto/CommissionDTO.java | 28 ++ .../apps/commission/dto/CommissionList.java | 32 +++ .../apps/commission/dto/CommissionSearch.java | 21 ++ .../apps/commission/exception/ErrorUtil.java | 27 ++ .../apps/commission/exception/ErrorVM.java | 43 +++ .../commission/exception/FieldErrorVM.java | 33 +++ .../commission/service/ExternalService.java | 68 +++++ .../portal/config/RestTemplateConfig.java | 35 +++ 10 files changed, 588 insertions(+) create mode 100755 src/main/java/com/eactive/apim/portal/apps/commission/constant/Constants.java create mode 100755 src/main/java/com/eactive/apim/portal/apps/commission/controller/CommissionController.java create mode 100755 src/main/java/com/eactive/apim/portal/apps/commission/dto/CommissionDTO.java create mode 100755 src/main/java/com/eactive/apim/portal/apps/commission/dto/CommissionList.java create mode 100755 src/main/java/com/eactive/apim/portal/apps/commission/dto/CommissionSearch.java create mode 100755 src/main/java/com/eactive/apim/portal/apps/commission/exception/ErrorUtil.java create mode 100755 src/main/java/com/eactive/apim/portal/apps/commission/exception/ErrorVM.java create mode 100755 src/main/java/com/eactive/apim/portal/apps/commission/exception/FieldErrorVM.java create mode 100755 src/main/java/com/eactive/apim/portal/apps/commission/service/ExternalService.java create mode 100644 src/main/java/com/eactive/apim/portal/config/RestTemplateConfig.java diff --git a/src/main/java/com/eactive/apim/portal/apps/commission/constant/Constants.java b/src/main/java/com/eactive/apim/portal/apps/commission/constant/Constants.java new file mode 100755 index 0000000..8a001b7 --- /dev/null +++ b/src/main/java/com/eactive/apim/portal/apps/commission/constant/Constants.java @@ -0,0 +1,30 @@ +package com.eactive.apim.portal.apps.commission.constant; + +/** + * Application constants. + */ +public final class Constants { + + public static final String SYSTEM_ACCOUNT = "system"; + + public static final String APIM_FOR_OBP_KEY = "x-obp-trust-system"; + + public static final String APIM_FOR_OBP_VALUE = "APIMPT-0002-QVBJTVBULTAwMDI="; + + public static final String APIM_CODE_FOR_OBP_KEY = "x-obp-partnercode"; + + public static final String APIM_CODE_FOR_OBP_VALUE = "100001-01"; + + public static final String SMS_URL = "/api/messaging/sms"; + + public static final String COMMISSION_URL = "/api/billing/billing/findBillingForCondition"; + + public static final String COMMISSION_PRINT_URL = "/api/billing/billing/findBillingForCondition/print"; + + public static final String OBP_ORGANIZATION_URL = "/api/customer/findCustomerByBusinessManRegistrationNo/"; + + public static String LANGUAGE = "ko"; + + private Constants() { + } +} diff --git a/src/main/java/com/eactive/apim/portal/apps/commission/controller/CommissionController.java b/src/main/java/com/eactive/apim/portal/apps/commission/controller/CommissionController.java new file mode 100755 index 0000000..709e0e7 --- /dev/null +++ b/src/main/java/com/eactive/apim/portal/apps/commission/controller/CommissionController.java @@ -0,0 +1,271 @@ +package com.eactive.apim.portal.apps.commission.controller; + +import com.eactive.apim.portal.apps.commission.constant.Constants; +import com.eactive.apim.portal.apps.commission.dto.CommissionDTO; +import com.eactive.apim.portal.apps.commission.dto.CommissionSearch; +import com.eactive.apim.portal.apps.commission.exception.ErrorUtil; +import com.eactive.apim.portal.apps.commission.service.ExternalService; +import com.eactive.apim.portal.common.util.SecurityUtil; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lombok.RequiredArgsConstructor; +import org.apache.commons.collections.MapUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.annotation.Secured; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; + + +@Controller +@RequestMapping(value = "/commission") +@Secured("ROLE_APP") +@RequiredArgsConstructor +public class CommissionController { + + private final Logger log = LoggerFactory.getLogger(CommissionController.class); + + private final ExternalService externalService; + + @Value("${obm-url:http://localhost:8080}") + private String obmUrl; + + @Value("${provider-code:100001-01}") + private String providerCode; + + // ==================== View Controllers ==================== + + @GetMapping("/manage") + public String commissionManagePage(Model model) { + // 기본 정보 설정 + model.addAttribute("organization", SecurityUtil.getUserOrg()); + return "apps/commission/commissionManage"; + } + + @GetMapping("/print/{year}/{month}") + public String commissionPrintPage( + @PathVariable("year") String year, + @PathVariable("month") String month, + Model model) { + + CommissionDTO commissionDTO = null; + CommissionSearch search = new CommissionSearch(); + search.setPartnerCode(SecurityUtil.getUserOrg().getOrgCode()); + search.setYear(year); + search.setMonth(month); + + search.setProvider(providerCode); + + if (!StringUtils.isEmpty(search.getPartnerCode())) { + try { + String url = obmUrl + Constants.COMMISSION_URL; + String result = externalService.getResponseHttpPost(url, toJson(search)); + HashMap returnObj = new ObjectMapper().readValue(result, HashMap.class); + + if (!StringUtils.isEmpty(returnObj.get("error"))) { + HashMap error = (HashMap) returnObj.get("error"); + model.addAttribute("error", error.get("message").toString()); + return "apps/commission/commissionPrint"; + } + + if (StringUtils.pathEquals(search.getPartnerCode(), "000002-01")) { + log.debug("Found Together : " + search.getPartnerCode()); + search.setPartnerCode("000002-02"); + String togetherResult = externalService.getResponseHttpPost(url, toJson(search)); + + HashMap togetherLendingReturnObj = new ObjectMapper().readValue(togetherResult, HashMap.class); + log.debug("togetherLendingReturnObj : " + togetherLendingReturnObj.toString()); + if (!StringUtils.isEmpty(togetherLendingReturnObj.get("error"))) { + HashMap error = (HashMap) togetherLendingReturnObj.get("error"); + model.addAttribute("error", error.get("message").toString()); + return "apps/commission/commissionPrint"; + } + + HashMap mergeMap = mergeCommissionData(returnObj, togetherLendingReturnObj); + result = new ObjectMapper().writeValueAsString(mergeMap); + } + commissionDTO = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).readValue(result, CommissionDTO.class); + } catch (Exception e) { + log.warn(e.getMessage(), e); + model.addAttribute("error", "수수료 조회에 실패하였습니다."); + return "apps/commission/commissionPrint"; + } + } + + // Model에 데이터 바인딩 + model.addAttribute("commission", commissionDTO); + model.addAttribute("organization", SecurityUtil.getUserOrg().getOrgName()); + model.addAttribute("year", year); + model.addAttribute("month", month); + model.addAttribute("toDay", java.time.LocalDate.now().toString()); + + return "apps/commission/commissionPrint"; + } + + // ==================== API Endpoints ==================== + + @PostMapping() + public ResponseEntity list(@RequestBody CommissionSearch search) { + CommissionDTO commissionDTO = null; + + search.setPartnerCode(SecurityUtil.getUserOrg().getOrgCode()); + + if (!StringUtils.isEmpty(search.getPartnerCode())) { + try { + String url = obmUrl + Constants.COMMISSION_URL; + String result = externalService.getResponseHttpPost(url, toJson(search)); + HashMap returnObj = new ObjectMapper().readValue(result, HashMap.class); + if (!StringUtils.isEmpty(returnObj.get("error"))) { + HashMap error = (HashMap) returnObj.get("error"); + return ErrorUtil.create("fail.commission.serverError", error.get("message").toString()); + } + + if (StringUtils.pathEquals(search.getPartnerCode(), "000002-01")) { + log.debug("Found Together : " + search.getPartnerCode()); + search.setPartnerCode("000002-02"); + String togetherResult = externalService.getResponseHttpPost(url, toJson(search)); + + HashMap togetherLendingReturnObj = new ObjectMapper().readValue(togetherResult, HashMap.class); + log.debug("togetherLendingReturnObj : " + togetherLendingReturnObj.toString()); + if (!StringUtils.isEmpty(togetherLendingReturnObj.get("error"))) { + HashMap error = (HashMap) togetherLendingReturnObj.get("error"); + return ErrorUtil.create("fail.commission.serverError", error.get("message").toString()); + } + + HashMap mergeMap = mergeCommissionData(returnObj, togetherLendingReturnObj); + result = new ObjectMapper().writeValueAsString(mergeMap); + } + commissionDTO = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).readValue(result, CommissionDTO.class); + } catch (Exception e) { + log.warn(e.getMessage(), e); + return ErrorUtil.create("fail.commission.list", "수수료 조회에 실패하였습니다."); + } + return ResponseEntity.ok().body(commissionDTO); + } + return ErrorUtil.create("fail.commission.needPartnerCode"); + } + + @GetMapping("/print1/{year}/{month}") + public ResponseEntity print( + @PathVariable("year") String year, + @PathVariable("month") String month) { + CommissionDTO commissionDTO = null; + CommissionSearch search = new CommissionSearch(); + search.setOrganization(SecurityUtil.getPortalAuthenticatedUser().getPortalOrg()); + + search.setProvider(providerCode); + search.setYear(year); + search.setMonth(month); + + search.setPartnerCode(SecurityUtil.getUserOrg().getOrgCode()); + + if (!StringUtils.isEmpty(search.getPartnerCode())) { + try { + String url = obmUrl + Constants.COMMISSION_PRINT_URL; + String result = externalService.getResponseHttpPost(url, toJson(search)); + HashMap returnObj = new ObjectMapper().readValue(result, HashMap.class); + if (StringUtils.pathEquals(search.getPartnerCode(), "000002-01")) { + log.debug("Found Together : " + search.getPartnerCode()); + search.setPartnerCode("000002-02"); + String togetherResult = externalService.getResponseHttpPost(url, toJson(search)); + + HashMap togetherLendingReturnObj = new ObjectMapper().readValue(togetherResult, HashMap.class); + log.debug("togetherLendingReturnObj : " + togetherLendingReturnObj.toString()); + if (!StringUtils.isEmpty(togetherLendingReturnObj.get("error"))) { + HashMap error = (HashMap) togetherLendingReturnObj.get("error"); + return ErrorUtil.create("fail.commission.serverError", error.get("message").toString()); + } + + HashMap mergeMap = mergeCommissionData(returnObj, togetherLendingReturnObj); + result = new ObjectMapper().writeValueAsString(mergeMap); + } + commissionDTO = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).readValue(result, CommissionDTO.class); + } catch (Exception e) { + log.warn(e.getMessage(), e); + return ErrorUtil.create("fail.commission.list", "수수료 조회에 실패하였습니다."); + } + return ResponseEntity.ok().body(commissionDTO); + } + return ErrorUtil.create("fail.commission.needPartnerCode"); + } + + private String toJson(CommissionSearch search) { + try { + Map jsonMap = new HashMap<>(); + jsonMap.put("partnerCode", search.getPartnerCode()); + jsonMap.put("targetOnMonth", search.getYear() + search.getMonth()); + + return new ObjectMapper().writeValueAsString(jsonMap); + } catch (Exception e) { + log.warn("Failed to serialize CommissionSearch to JSON", e); + return "{}"; + } + } + + public HashMap mergeCommissionData(HashMap o1, HashMap o2) { + + HashMap mergeMap = new HashMap(); + + String o1Status = MapUtils.getString(o1, "status"); + String o2Status = MapUtils.getString(o2, "status"); + String resultStatus = null; + if (Integer.parseInt(o1Status) <= Integer.parseInt(o2Status)) { + resultStatus = o1Status; + } else { + resultStatus = o2Status; + } + double apiTotalValueSum = MapUtils.getDouble(o1, "apiTotalValueSum") + MapUtils.getDouble(o2, "apiTotalValueSum"); + double apiSum = MapUtils.getDouble(o1, "apiSum") + MapUtils.getDouble(o2, "apiSum"); + double apiTotalValueSum2 = MapUtils.getDouble(o1, "apiTotalValueSum2") + MapUtils.getDouble(o2, "apiTotalValueSum2"); + double apiSum2 = MapUtils.getDouble(o1, "apiSum2") + MapUtils.getDouble(o2, "apiSum2"); + double productTotalValueCountSum = MapUtils.getDouble(o1, "productTotalValueCountSum") + MapUtils.getDouble(o2, "productTotalValueCountSum"); + double productTotalValueAmountSum = MapUtils.getDouble(o1, "productTotalValueAmountSum") + MapUtils.getDouble(o2, "productTotalValueAmountSum"); + double productSum = MapUtils.getDouble(o1, "productSum") + MapUtils.getDouble(o2, "productSum"); + double productTotalValueCountSum2 = MapUtils.getDouble(o1, "productTotalValueCountSum2") + MapUtils.getDouble(o2, "productTotalValueCountSum2"); + double productTotalValueAmountSum2 = MapUtils.getDouble(o1, "productTotalValueAmountSum2") + MapUtils.getDouble(o2, "productTotalValueAmountSum2"); + double productSum2 = MapUtils.getDouble(o1, "productSum2") + MapUtils.getDouble(o2, "productSum2"); + double totalValueCountSum = MapUtils.getDouble(o1, "totalValueCountSum") + MapUtils.getDouble(o2, "totalValueCountSum"); + double totalValueCountSum2 = MapUtils.getDouble(o1, "totalValueCountSum2") + MapUtils.getDouble(o2, "totalValueCountSum2"); + double totalValueAmountSum = MapUtils.getDouble(o1, "totalValueAmountSum") + MapUtils.getDouble(o2, "totalValueAmountSum"); + double totalValueAmountSum2 = MapUtils.getDouble(o1, "totalValueAmountSum2") + MapUtils.getDouble(o2, "totalValueAmountSum2"); + double sum = MapUtils.getDouble(o1, "sum") + MapUtils.getDouble(o2, "sum"); + double sum2 = MapUtils.getDouble(o1, "sum2") + MapUtils.getDouble(o2, "sum2"); + + List o1List = (ArrayList) o1.get("list"); + List o2pList = (ArrayList) o2.get("list"); + o1List.addAll(o2pList); + + mergeMap.put("status", resultStatus); + mergeMap.put("apiTotalValueSum", String.format("%.2f", apiTotalValueSum)); + mergeMap.put("apiSum", String.format("%.2f", apiSum)); + mergeMap.put("apiTotalValueSum2", String.format("%.2f", apiTotalValueSum2)); + mergeMap.put("apiSum2", String.format("%.2f", apiSum2)); + mergeMap.put("productTotalValueCountSum", String.format("%.2f", productTotalValueCountSum)); + mergeMap.put("productTotalValueAmountSum", String.format("%.2f", productTotalValueAmountSum)); + mergeMap.put("productSum", String.format("%.2f", productSum)); + mergeMap.put("productTotalValueCountSum2", String.format("%.2f", productTotalValueCountSum2)); + mergeMap.put("productTotalValueAmountSum2", String.format("%.2f", productTotalValueAmountSum2)); + mergeMap.put("productSum2", String.format("%.2f", productSum2)); + mergeMap.put("totalValueCountSum", String.format("%.2f", totalValueCountSum)); + mergeMap.put("totalValueCountSum2", String.format("%.2f", totalValueCountSum2)); + mergeMap.put("totalValueAmountSum", String.format("%.2f", totalValueAmountSum)); + mergeMap.put("totalValueAmountSum2", String.format("%.2f", totalValueAmountSum2)); + mergeMap.put("sum", String.format("%.2f", sum)); + mergeMap.put("sum2", String.format("%.2f", sum2)); + mergeMap.put("list", o1List); + + return mergeMap; + } +} diff --git a/src/main/java/com/eactive/apim/portal/apps/commission/dto/CommissionDTO.java b/src/main/java/com/eactive/apim/portal/apps/commission/dto/CommissionDTO.java new file mode 100755 index 0000000..52281a3 --- /dev/null +++ b/src/main/java/com/eactive/apim/portal/apps/commission/dto/CommissionDTO.java @@ -0,0 +1,28 @@ +package com.eactive.apim.portal.apps.commission.dto; + +import java.util.List; +import lombok.Data; + +@Data +public class CommissionDTO { + + private String status; + private String apiTotalValueSum; + private String apiSum; + private String apiTotalValueSum2; + private String apiSum2; + private String productTotalValueCountSum; + private String productTotalValueAmountSum; + private String productSum; + private String productTotalValueCountSum2; + private String productTotalValueAmountSum2; + private String productSum2; + private String totalValueCountSum; + private String totalValueCountSum2; + private String totalValueAmountSum; + private String totalValueAmountSum2; + private String sum; + private String sum2; + private List list; + private String documentFormatNo; +} diff --git a/src/main/java/com/eactive/apim/portal/apps/commission/dto/CommissionList.java b/src/main/java/com/eactive/apim/portal/apps/commission/dto/CommissionList.java new file mode 100755 index 0000000..d967539 --- /dev/null +++ b/src/main/java/com/eactive/apim/portal/apps/commission/dto/CommissionList.java @@ -0,0 +1,32 @@ +package com.eactive.apim.portal.apps.commission.dto; + +import lombok.Data; + +/** + * Created by jskim on 17. 01. 26. + * + * @author jskim + */ +@Data +public class CommissionList { + + private String paymentTargetName; + private String paymentTargetType; + private String value; + private String minimumAmount; + private String maximumAmount; + private String totalCount; + private String totalCount2; + private String totalValue; + private String totalValue2; + private String minimumAmount2; + private String maximumAmount2; + private String paymentBaseName; + private String paymentTimingName; + private String valueDivisionName; + private String sum; + private String sum2; + private String detailFeeTypeName; + private String value2; + private String changeReason2; +} diff --git a/src/main/java/com/eactive/apim/portal/apps/commission/dto/CommissionSearch.java b/src/main/java/com/eactive/apim/portal/apps/commission/dto/CommissionSearch.java new file mode 100755 index 0000000..ec8c4fe --- /dev/null +++ b/src/main/java/com/eactive/apim/portal/apps/commission/dto/CommissionSearch.java @@ -0,0 +1,21 @@ +package com.eactive.apim.portal.apps.commission.dto; + +import com.eactive.apim.portal.portalorg.entity.PortalOrg; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class CommissionSearch { + + @ApiModelProperty(value = "대상년") + private String year; + + @ApiModelProperty(value = "대상월") + private String month; + + private String partnerCode; + + private PortalOrg organization; + + private String provider; +} diff --git a/src/main/java/com/eactive/apim/portal/apps/commission/exception/ErrorUtil.java b/src/main/java/com/eactive/apim/portal/apps/commission/exception/ErrorUtil.java new file mode 100755 index 0000000..ce0f6db --- /dev/null +++ b/src/main/java/com/eactive/apim/portal/apps/commission/exception/ErrorUtil.java @@ -0,0 +1,27 @@ +package com.eactive.apim.portal.apps.commission.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +/** + * Created by ybsong on 16. 12. 7. + * + * @author ybsong + */ +public class ErrorUtil { + public static ResponseEntity create(HttpStatus status, String message, String description) { + return new ResponseEntity<>(new ErrorVM(message, description), status); + } + + public static ResponseEntity create(HttpStatus status, String message) { + return create(status, message, null); + } + + public static ResponseEntity create(String message, String description) { + return create(HttpStatus.BAD_REQUEST, message, description); + } + + public static ResponseEntity create(String message) { + return create(message, null); + } +} diff --git a/src/main/java/com/eactive/apim/portal/apps/commission/exception/ErrorVM.java b/src/main/java/com/eactive/apim/portal/apps/commission/exception/ErrorVM.java new file mode 100755 index 0000000..8a00cd6 --- /dev/null +++ b/src/main/java/com/eactive/apim/portal/apps/commission/exception/ErrorVM.java @@ -0,0 +1,43 @@ +package com.eactive.apim.portal.apps.commission.exception; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import lombok.Data; + +/** + * View Model for transferring error message with a list of field errors. + */ +@Data +public class ErrorVM implements Serializable { + + private static final long serialVersionUID = 1L; + + private final String message; + private final String description; + + private List fieldErrors; + + public ErrorVM(String message) { + this(message, null); + } + + public ErrorVM(String message, String description) { + this.message = message; + this.description = description; + } + + public ErrorVM(String message, String description, List fieldErrors) { + this.message = message; + this.description = description; + this.fieldErrors = fieldErrors; + } + + public void add(String objectName, String field, String message) { + if (fieldErrors == null) { + fieldErrors = new ArrayList<>(); + } + fieldErrors.add(new FieldErrorVM(objectName, field, message)); + } + +} diff --git a/src/main/java/com/eactive/apim/portal/apps/commission/exception/FieldErrorVM.java b/src/main/java/com/eactive/apim/portal/apps/commission/exception/FieldErrorVM.java new file mode 100755 index 0000000..7b5315f --- /dev/null +++ b/src/main/java/com/eactive/apim/portal/apps/commission/exception/FieldErrorVM.java @@ -0,0 +1,33 @@ +package com.eactive.apim.portal.apps.commission.exception; + +import java.io.Serializable; + +public class FieldErrorVM implements Serializable { + + private static final long serialVersionUID = 1L; + + private final String objectName; + + private final String field; + + private final String message; + + public FieldErrorVM(String dto, String field, String message) { + this.objectName = dto; + this.field = field; + this.message = message; + } + + public String getObjectName() { + return objectName; + } + + public String getField() { + return field; + } + + public String getMessage() { + return message; + } + +} diff --git a/src/main/java/com/eactive/apim/portal/apps/commission/service/ExternalService.java b/src/main/java/com/eactive/apim/portal/apps/commission/service/ExternalService.java new file mode 100755 index 0000000..9087c90 --- /dev/null +++ b/src/main/java/com/eactive/apim/portal/apps/commission/service/ExternalService.java @@ -0,0 +1,68 @@ +package com.eactive.apim.portal.apps.commission.service; + +import com.eactive.apim.portal.apps.commission.constant.Constants; +import javax.inject.Inject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +/** + * 외부 API 호출 서비스 + * RestTemplate 기반으로 외부 시스템과 HTTP 통신을 수행합니다. + * + * @author ybsong + * @since 2017-03-02 + */ +@Service +@Transactional +public class ExternalService { + + private final Logger log = LoggerFactory.getLogger(ExternalService.class); + + private final RestTemplate restTemplate; + + @Inject + public ExternalService(RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } + + /** + * HTTP POST 요청을 통해 외부 API를 호출하고 응답을 받습니다. + * + * @param url 호출할 API URL + * @param payload 요청 본문 (JSON 문자열) + * @return API 응답 본문 (문자열), 오류 발생 시 null + */ + public String getResponseHttpPost(String url, String payload) { + try { + // HTTP 헤더 설정 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.set(Constants.APIM_FOR_OBP_KEY, Constants.APIM_FOR_OBP_VALUE); + headers.set(Constants.APIM_CODE_FOR_OBP_KEY, Constants.APIM_CODE_FOR_OBP_VALUE); + + // HTTP 요청 엔티티 생성 (헤더 + 본문) + HttpEntity requestEntity = new HttpEntity<>(payload, headers); + + // POST 요청 실행 + ResponseEntity response = restTemplate.postForEntity(url, requestEntity, String.class); + + // 응답 본문 반환 + return response.getBody(); + + } catch (RestClientException e) { + log.error("Failed to call external API: url={}, error={}", url, e.getMessage(), e); + return null; + } catch (Exception e) { + log.error("Unexpected error during HTTP POST: url={}", url, e); + return null; + } + } +} diff --git a/src/main/java/com/eactive/apim/portal/config/RestTemplateConfig.java b/src/main/java/com/eactive/apim/portal/config/RestTemplateConfig.java new file mode 100644 index 0000000..314d12d --- /dev/null +++ b/src/main/java/com/eactive/apim/portal/config/RestTemplateConfig.java @@ -0,0 +1,35 @@ +package com.eactive.apim.portal.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; + +/** + * RestTemplate 설정 클래스 + * 외부 API 호출을 위한 RestTemplate Bean을 제공합니다. + * + * @author sungpilhyun + * @since 2025-01-16 + */ +@Configuration +public class RestTemplateConfig { + + /** + * RestTemplate Bean 생성 + * + * @return 설정된 RestTemplate 인스턴스 + */ + @Bean + public RestTemplate restTemplate() { + SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); + + // 연결 타임아웃: 10초 + factory.setConnectTimeout(10000); + + // 읽기 타임아웃: 30초 + factory.setReadTimeout(30000); + + return new RestTemplate(factory); + } +}