From 6ad52cf26b6ea54f9ed77dcc92e0a5d8638513de Mon Sep 17 00:00:00 2001 From: limju Date: Tue, 17 Oct 2023 16:36:26 +0900 Subject: [PATCH] fix: WebClient call log fix CORS filter class add --- .../xit/biz/kt/service/BizKtMmsService.java | 57 +++++++++++++++++ .../xit/biz/kt/service/IBizKtMmsService.java | 3 + .../kr/xit/biz/kt/web/BizKtMmsController.java | 59 +++++++++++++++++ .../xit/ens/nice/service/NiceCiService.java | 2 +- .../resources/config/application-local.yml | 2 +- .../kr/xit/biz/ens/model/kt/KtMmsSendDTO.java | 17 ++--- .../config/support/WebClientConfig.java | 42 +++++-------- .../core/spring/filter/SimpleCORSFilter.java | 63 +++++++++++++++++++ 8 files changed, 207 insertions(+), 38 deletions(-) create mode 100644 mens-core/src/main/java/kr/xit/core/spring/filter/SimpleCORSFilter.java diff --git a/mens-api/src/main/java/kr/xit/biz/kt/service/BizKtMmsService.java b/mens-api/src/main/java/kr/xit/biz/kt/service/BizKtMmsService.java index 2b58560..953af06 100644 --- a/mens-api/src/main/java/kr/xit/biz/kt/service/BizKtMmsService.java +++ b/mens-api/src/main/java/kr/xit/biz/kt/service/BizKtMmsService.java @@ -1,14 +1,20 @@ package kr.xit.biz.kt.service; +import java.util.ArrayList; +import java.util.List; import kr.xit.biz.cmm.service.ICmmEnsCacheService; import kr.xit.biz.ens.model.cmm.CmmEnsRequestDTO; import kr.xit.biz.ens.model.cmm.CmmEnsRlaybsnmDTO; +import kr.xit.biz.ens.model.kt.KtCommonDTO.KtCommonResponse; import kr.xit.biz.ens.model.kt.KtCommonDTO.KtMnsRequest; +import kr.xit.biz.ens.model.kt.KtMmsSendDTO.KtMainSendReqData; +import kr.xit.biz.ens.model.kt.KtMmsSendDTO.KtMainSendRequest; import kr.xit.biz.ens.model.kt.KtTokenDTO.KtTokenResponse; import kr.xit.biz.kt.mapper.IBizKtMmsMapper; import kr.xit.core.exception.BizRuntimeException; import kr.xit.ens.kt.service.IKtMmsService; import lombok.RequiredArgsConstructor; +import org.apache.commons.collections4.ListUtils; import org.apache.commons.lang3.StringUtils; import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl; import org.springframework.stereotype.Service; @@ -32,6 +38,7 @@ import org.springframework.stereotype.Service; @Service public class BizKtMmsService extends EgovAbstractServiceImpl implements IBizKtMmsService { private static final String profile = System.getProperty("spring.profiles.active"); + private static final int MAX_KT_SEND_CNT = 100; private final IKtMmsService ktMmsService; private final ICmmEnsCacheService cacheService; @@ -73,6 +80,56 @@ public class BizKtMmsService extends EgovAbstractServiceImpl implements IBizKtMm return resDTO; } + + @Override + public KtCommonResponse mainSend(final KtMnsRequest reqDTO) { + List mainSendReqs = new ArrayList<>(); + + KtMainSendReqData reqData = KtMainSendReqData.builder() + .srcKey("db") + .srcSeq("1++") + .ci("1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678") + .mmsDtlCnts("db") + .docHash("db") + .mmsTitle("") + .url("/api/biz/kt/v1/receiveMain?kkk=llll") //distInfoCrtYn - N이면 필수 + .mmsBinary("") + .fileFmat("") + .mdn("") + .distInfoCrtYn("N") + //.infoCfrmStr("") + .build(); + mainSendReqs.add(reqData); + + List> parts = ListUtils.partition(mainSendReqs, MAX_KT_SEND_CNT); + KtCommonResponse ktTokenResponse = null; + + for(List reqs : parts) { + KtMainSendRequest ktReqDTO = KtMainSendRequest.builder() + .signguCode(reqDTO.getSignguCode()) + .ffnlgCode(reqDTO.getFfnlgCode()) + .profile(profile) + //.serviceCd("cache") + //.serviceKey("cache") + .msgCd("db") + //.msgType("2") + .makeDt("123456789012db") + .sndnExTime("123456789012db") + .exTime("123456789012db") + //.mType("4") + .sndnTotCnt(reqs.size()) //-> 요청건수 count + .mmsBinary("db") + .fileFmat("db") + .testSndnYn("N") + .reqs(reqs) + .build(); + + ktTokenResponse = ktMmsService.mainSend(ktReqDTO); + } + return ktTokenResponse; + } + + // /** // * 사전 문자 수신 등록 요청(BC-AG-SN-001) // * @param reqDTO diff --git a/mens-api/src/main/java/kr/xit/biz/kt/service/IBizKtMmsService.java b/mens-api/src/main/java/kr/xit/biz/kt/service/IBizKtMmsService.java index e6b12ec..220331a 100644 --- a/mens-api/src/main/java/kr/xit/biz/kt/service/IBizKtMmsService.java +++ b/mens-api/src/main/java/kr/xit/biz/kt/service/IBizKtMmsService.java @@ -1,6 +1,7 @@ package kr.xit.biz.kt.service; +import kr.xit.biz.ens.model.kt.KtCommonDTO.KtCommonResponse; import kr.xit.biz.ens.model.kt.KtCommonDTO.KtMnsRequest; import kr.xit.biz.ens.model.kt.KtTokenDTO.KtTokenResponse; @@ -23,6 +24,8 @@ import kr.xit.biz.ens.model.kt.KtTokenDTO.KtTokenResponse; public interface IBizKtMmsService { KtTokenResponse requestToken(final KtMnsRequest paramDTO); + KtCommonResponse mainSend(final KtMnsRequest reqDTO); + // KtCommonResponse beforeSend(final KtBefSendRequest reqDTO); // KtCommonResponse mainSend(final KtMainSendRequest reqDTO); // KtCommonResponse blacklist(final KtBlacklistRequest reqDTO); diff --git a/mens-api/src/main/java/kr/xit/biz/kt/web/BizKtMmsController.java b/mens-api/src/main/java/kr/xit/biz/kt/web/BizKtMmsController.java index 3da6940..2dfda87 100644 --- a/mens-api/src/main/java/kr/xit/biz/kt/web/BizKtMmsController.java +++ b/mens-api/src/main/java/kr/xit/biz/kt/web/BizKtMmsController.java @@ -1,11 +1,16 @@ package kr.xit.biz.kt.web; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.Map; +import kr.xit.biz.ens.model.kt.KtCommonDTO.KtCommonResponse; import kr.xit.biz.ens.model.kt.KtCommonDTO.KtMnsRequest; import kr.xit.biz.kt.service.IBizKtMmsService; import kr.xit.core.model.ApiResponseDTO; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -31,14 +36,68 @@ import org.springframework.web.bind.annotation.RestController; @RequiredArgsConstructor @RestController @RequestMapping(value = "/api/biz/kt/v1") +@Slf4j public class BizKtMmsController { + private static final String PARAM1 = """ + { + "signguCode": "88328", + "ffnlgCode": "11", + "juminId": "9901011263512" + } + """; + private static final String PARAM2 = """ + { + "signguCode": "88316", + "ffnlgCode": "11", + "juminId": "9901011263512" + } + """; + private final IBizKtMmsService service; + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content( + mediaType = "application/json", + examples = { + @ExampleObject( + name = "교통시설운영처", + value = PARAM1), + @ExampleObject( + name = "승화원", + value = PARAM2) + }) + }) @Operation(summary = "기관용 토큰 발급 요청", description = "기관용 토큰 발급 요청") @PostMapping(value = "/requestToken", produces = MediaType.APPLICATION_JSON_VALUE) public ApiResponseDTO requestToken(@RequestBody final KtMnsRequest paramDTO) { return ApiResponseDTO.success(service.requestToken(paramDTO)); } + + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content( + mediaType = "application/json", + examples = { + @ExampleObject( + name = "교통시설운영처", + value = PARAM1), + @ExampleObject( + name = "승화원", + value = PARAM2) + }) + }) + @Operation(summary = "본문자 수신 등록 요청", description = "본문자 수신 등록 요청(BC-AG-SN-002)") + @PostMapping(value = "/mainSend", produces = MediaType.APPLICATION_JSON_VALUE) + public ApiResponseDTO mainSend(@RequestBody final KtMnsRequest reqDTO) { + KtCommonResponse dto = service.mainSend(reqDTO); + return ApiResponseDTO.success(dto); + } + + + @Operation(summary = "본문자 수신", description = "본문자 수신") + @PostMapping(value = "/receiveMain", produces = MediaType.APPLICATION_JSON_VALUE) + public void requestToken(@RequestBody final Map paramMap) { + log.debug("{}", paramMap); + } // // /* // @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { diff --git a/mens-api/src/main/java/kr/xit/ens/nice/service/NiceCiService.java b/mens-api/src/main/java/kr/xit/ens/nice/service/NiceCiService.java index b7b4344..eb9e3dc 100644 --- a/mens-api/src/main/java/kr/xit/ens/nice/service/NiceCiService.java +++ b/mens-api/src/main/java/kr/xit/ens/nice/service/NiceCiService.java @@ -237,7 +237,7 @@ public class NiceCiService extends EgovAbstractServiceImpl implements INiceCiSer //.infoReqType() //default: 1-CI제공 .juminId(reqDTO.getJuminId()) .reqNo(CmmEnsUtils.generateLengthUuid(30)) - .reqDtim(DateUtils.getTodayAndNowTime("yyyyMMddHHmmss")) + .clientIp(IpMacUtils.getIpAddress().get(0)) .build(); CmmEnsUtils.validate(encDataDTO); diff --git a/mens-api/src/main/resources/config/application-local.yml b/mens-api/src/main/resources/config/application-local.yml index 77b5564..b4a2338 100644 --- a/mens-api/src/main/resources/config/application-local.yml +++ b/mens-api/src/main/resources/config/application-local.yml @@ -51,7 +51,7 @@ logging: # Spring Security cors 설정 :: CorsConfiguration 설정 값 cors: - allowed-origins: http://localhost:8082 + allowed-origins: http://localhost:8080, http://localhost:8082 # ================================================================================================================== # SQL logging lib setting diff --git a/mens-core/src/main/java/kr/xit/biz/ens/model/kt/KtMmsSendDTO.java b/mens-core/src/main/java/kr/xit/biz/ens/model/kt/KtMmsSendDTO.java index 3e34b25..8fa7175 100644 --- a/mens-core/src/main/java/kr/xit/biz/ens/model/kt/KtMmsSendDTO.java +++ b/mens-core/src/main/java/kr/xit/biz/ens/model/kt/KtMmsSendDTO.java @@ -406,7 +406,7 @@ public class KtMmsSendDTO { * */ @Schema(requiredMode = RequiredMode.REQUIRED, title = "문서코드", example = "DP112") - @Size(min = 5, max = 5, message = "문서 코드는 필수 입니다(max:5)") + @Size(min = 1, max = 5, message = "문서 코드는 필수 입니다(max:5)") private String msgCd; /** @@ -416,8 +416,8 @@ public class KtMmsSendDTO { * */ @Schema(requiredMode = RequiredMode.REQUIRED, title = "발송 메시지 타입", example = "2") - @Size(min = 1, max = 1, message = "발송 메시지 타입은 필수 입니다") - private String msgType; + @Size(min = 1, max = 1, message = "발송 메시지 타입은 필수 입니다(1|2)") + private final String msgType = "2"; /** *
@@ -426,7 +426,7 @@ public class KtMmsSendDTO {
          * 
*/ @Schema(requiredMode = RequiredMode.REQUIRED, title = "발송시작일시", example = "20211229102000") - @Size(min = 14, max = 14, message = "발송시작일시는 필수 입니다") + @Size(min = 14, max = 14, message = "발송시작일시는 필수 입니다(YYYYMMDDHHMiSS)") private String makeDt; /** @@ -436,7 +436,7 @@ public class KtMmsSendDTO { * */ @Schema(requiredMode = RequiredMode.REQUIRED, title = "발송마감시간", example = "20211229180000") - @Size(min = 14, max = 14, message = "발송마감시간은 필수 입니다") + @Size(min = 14, max = 14, message = "발송마감시간은 필수 입니다(YYYYMMDDHHMiSS)") private String sndnExTime; /** @@ -446,7 +446,7 @@ public class KtMmsSendDTO { * */ @Schema(requiredMode = RequiredMode.REQUIRED, title = "열람마감시간", example = "20211229180000") - @Size(min = 14, max = 14, message = "열람마감시간은 필수 입니다") + @Size(min = 14, max = 14, message = "열람마감시간은 필수 입니다(YYYYMMDDHHMiSS)") private String exTime; /** @@ -460,9 +460,8 @@ public class KtMmsSendDTO { */ @Schema(requiredMode = RequiredMode.REQUIRED, title = "문서종류", example = "2") @NotEmpty(message = "문서종류는 필수 입니다(max:3)") - @Size(max = 3) @JsonProperty("m_type") - private String mType; + private final String mType = "4"; /** *
@@ -700,10 +699,12 @@ public class KtMmsSendDTO {
         private String ci;
 
         /**
+         * 
          * MMS 상세내용 : max 4000
          * URL 없음
          * {#INFO_CFRM_STR}, {#RCVE_RF_STR} 문자열이 없는 경우 요청 거부 처리 함.
          * 단, 유통정보미생성여부가 'Y'인 경우 {#RCVE_RF_STR} 문자열만 체크.
+         * 
*/ @Schema(requiredMode = RequiredMode.REQUIRED, title = "MMS 상세내용", example = "gdlIa53FZGQz5aKa3wLk33nW57N3mDpcwHytWlWMhzxHKulk7EZs143442394326642342364238648423864237") @Size(min = 1, max = 4000, message = "MMS 상세내용은 4000자를 넘을 수 없습니다.") diff --git a/mens-core/src/main/java/kr/xit/core/spring/config/support/WebClientConfig.java b/mens-core/src/main/java/kr/xit/core/spring/config/support/WebClientConfig.java index adff64a..a106e00 100644 --- a/mens-core/src/main/java/kr/xit/core/spring/config/support/WebClientConfig.java +++ b/mens-core/src/main/java/kr/xit/core/spring/config/support/WebClientConfig.java @@ -101,7 +101,7 @@ public class WebClientConfig { * pendingAcquireTimeout : 커넥션 풀에서 커넥션을 얻기 위해 기다리는 최대 시간 * pendingAcquireMaxCount : 커넥션 풀에서 커넥션을 가져오는 시도 횟수 (-1: no limit) * maxIdleTime : 커넥션 풀에서 idle 상태의 커넥션을 유지하는 시간 - * @return + * @return ConnectionProvider */ @Bean public ConnectionProvider connectionProvider() { @@ -136,15 +136,15 @@ public class WebClientConfig { } private ExchangeFilterFunction requestFilter() { - return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> { + return ExchangeFilterFunction.ofRequestProcessor(cr -> { if (log.isDebugEnabled()) { StringBuilder sb = new StringBuilder("\n>>>>>>>>>> WebClient Http Request <<<<<<<<<<<<<\n"); - sb.append(logMethodAndUrl(clientRequest)); - sb.append(logHeaders(clientRequest)); + sb.append(logMethodAndUrl(cr)); + sb.append(logHeaders(cr)); sb.append("-------------------------------------------------------"); log.debug(sb.toString()); } - return Mono.just(clientRequest); + return Mono.just(cr); }); } @@ -153,29 +153,28 @@ public class WebClientConfig { * @return ExchangeFilterFunction */ private ExchangeFilterFunction responseFilter() { - return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> { + return ExchangeFilterFunction.ofResponseProcessor(cr -> { - HttpStatus status = clientResponse.statusCode(); + HttpStatus status = cr.statusCode(); - if(clientResponse.statusCode().is4xxClientError()) { - return clientResponse.bodyToMono(String.class) + if(cr.statusCode().is4xxClientError()) { + return cr.bodyToMono(String.class) .flatMap(errorBody -> Mono.error(new ClientError(status, errorBody))); - } else if(clientResponse.statusCode().is5xxServerError()) { - return clientResponse.bodyToMono(String.class) + } else if(cr.statusCode().is5xxServerError()) { + return cr.bodyToMono(String.class) .flatMap(errorBody -> Mono.error(new ServerError(status, errorBody))); } if(log.isDebugEnabled()) { StringBuilder sb = new StringBuilder( "\n>>>>>>>>>> WebClient Http Response <<<<<<<<<<<<<\n"); - sb.append(logStatus(clientResponse)); - sb.append(logHeaders(clientResponse)); + sb.append(logStatus(cr)); + sb.append(logHeaders(cr)); sb.append("-------------------------------------------------------"); log.debug(sb.toString()); - return logBody(clientResponse); } - return Mono.just(clientResponse); + return Mono.just(cr); }); } @@ -184,19 +183,6 @@ public class WebClientConfig { return String.format("Returned staus code %s (%s)", status.value(), status.getReasonPhrase()); } - - private static Mono logBody(ClientResponse response) { - if (response.statusCode() != null && (response.statusCode().is4xxClientError() || response.statusCode().is5xxServerError())) { - return response.bodyToMono(String.class) - .flatMap(body -> { - log.debug("Body is {}", body); - return Mono.just(response); - }); - } else { - return Mono.just(response); - } - } - private static String logHeaders(ClientRequest request) { StringBuilder sb = new StringBuilder(); diff --git a/mens-core/src/main/java/kr/xit/core/spring/filter/SimpleCORSFilter.java b/mens-core/src/main/java/kr/xit/core/spring/filter/SimpleCORSFilter.java new file mode 100644 index 0000000..c548a3b --- /dev/null +++ b/mens-core/src/main/java/kr/xit/core/spring/filter/SimpleCORSFilter.java @@ -0,0 +1,63 @@ +package kr.xit.core.spring.filter; + +import java.io.IOException; +import java.util.Arrays; +import java.util.stream.Collectors; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; +import kr.xit.core.spring.config.properties.CorsProperties; +import kr.xit.core.spring.util.CoreSpringUtils; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + *
+ * description : Cors filter
+ *               {@code @Override} {@link WebMvcConfigurer#addCorsMappings}
+ * packageName : kr.xit.core.spring.filter
+ * fileName    : SimpleCORSFilter
+ * author      : julim
+ * date        : 2023-04-28
+ * ======================================================================
+ * 변경일         변경자        변경 내용
+ * ----------------------------------------------------------------------
+ * 2023-04-28    julim       최초 생성
+ *
+ * 
+ */ +@Deprecated +public class SimpleCORSFilter implements Filter { + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + CorsProperties corsProperties = CoreSpringUtils.getCorsProperties(); + HttpServletResponse httpResponse = (HttpServletResponse) response; + httpResponse.setHeader("Access-Control-Allow-Origins", toArrayString(corsProperties.getAllowedOrigins())); + httpResponse.setHeader("Access-Control-Allow-Methods", toArrayString(corsProperties.getAllowedMethods())); + httpResponse.setHeader("Access-Control-Allow-Headers", toArrayString(corsProperties.getAllowedHeaders())); + httpResponse.setHeader("Access-Control-Allow-Credentials", corsProperties.getAllowCredentials().toString()); + httpResponse.setHeader("Access-Control-Max-Age", corsProperties.getMaxAge().toString()); + httpResponse.setHeader("Access-Control-Expose-Headers", corsProperties.getExposeHeader()); + chain.doFilter(request, response); + } + + @Override + public void init(FilterConfig filterConfig) { + // Do nothing + } + + @Override + public void destroy() { + // Do nothing + } + + private String toArrayString(String[] arrStr){ + return Arrays.stream(arrStr) + .map(s -> s.trim()) + .collect(Collectors.joining(",")); + } +}