package com.mfsys.uco.service; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.mfsys.comm.exception.ApplicationException; import com.mfsys.comm.exception.ApplicationExceptionMapper; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClientResponseException; import reactor.core.publisher.Mono; import java.io.IOException; import java.util.Map; @Service public class WebClientCrmService { private final WebClient webClientCrm; public WebClientCrmService(WebClient webClientCrm) { this.webClientCrm = webClientCrm; } public Object getUcoAccountBalance(String url, String porOrgacode) { return handleResponse(webClientCrm.get().uri(url).accept(MediaType.APPLICATION_JSON) .header("SUS_USERCODE", porOrgacode) .header("POR_ORGACODE", porOrgacode).retrieve().toEntity(Object.class), null); } public Object onboardCustomer(Map onBoardingData, String url, String porOrgaCode) { return handleResponse(webClientCrm.post().uri(url).bodyValue(onBoardingData).accept(MediaType.APPLICATION_JSON) .header("SUS_USERCODE", porOrgaCode) .header("POR_ORGACODE", porOrgaCode).retrieve() .toEntity(Object.class), porOrgaCode); } private T handleResponse(Mono> responseMono, String porgaCode) { try { ResponseEntity response = responseMono.block(); return response.getBody(); } catch (WebClientResponseException e) { ApplicationExceptionMapper.APIError errorDetails = parseErrorDetails(e); throw new ApplicationException(porgaCode, errorDetails.getErrorCode(), errorDetails.getArguments()); } } private ApplicationExceptionMapper.APIError parseErrorDetails(WebClientResponseException e) { String errorCode = null; Object[] arguments = new Object[0]; if (e.getResponseBodyAsString() != null) { try { ObjectMapper objectMapper = new ObjectMapper(); JsonNode errorNode = objectMapper.readTree(e.getResponseBodyAsString()); JsonNode errorCodeNode = errorNode.get("errorCode"); if (errorCodeNode != null && !errorCodeNode.isNull()) { errorCode = errorCodeNode.asText(); } else { JsonNode debugNode = errorNode.get("debugMessage"); errorCode = (debugNode != null && !debugNode.isNull()) ? debugNode.asText() : "ERR_REMOTE_" + e.getStatusCode().value(); } JsonNode argsNode = errorNode.get("arguments"); if (argsNode != null && !argsNode.isNull()) { arguments = objectMapper.convertValue(argsNode, String[].class); } } catch (IOException ex) { errorCode = "ERR_REMOTE_" + e.getStatusCode().value(); } } else { errorCode = "ERR_REMOTE_" + e.getStatusCode().value(); } return new ApplicationExceptionMapper.APIError(errorCode, arguments); } }