diff --git a/src/main/java/com/banesco/common/application/helper/MessageHelper.java b/src/main/java/com/banesco/common/application/helper/MessageHelper.java index 811c2d4..01d1e37 100644 --- a/src/main/java/com/banesco/common/application/helper/MessageHelper.java +++ b/src/main/java/com/banesco/common/application/helper/MessageHelper.java @@ -123,7 +123,7 @@ public class MessageHelper { } if (json == null || json.isEmpty()) { - log.warn("No se encontró JSON de errores"); + log.warn("No se encontro JSON de errores"); return createDefaultMappings(); } @@ -138,11 +138,11 @@ public class MessageHelper { result.put(mapping.getBackendCode(), mapping); } } else { - log.warn("Ignorando mapping sin backendCode válido: {}", mapping.getDescription()); + log.warn("Ignorando mapping sin backendCode valido: {}", mapping.getDescription()); } } - log.info("Mappings de errores cargados exitosamente, total válidos: {}", result.size()); + log.info("Mappings de errores cargados exitosamente, total validos: {}", result.size()); return result; } catch (Exception e) { log.error("Error cargando mappings de errores: {}", e.getMessage()); @@ -153,7 +153,7 @@ public class MessageHelper { private String loadFromJsonFile() { try (InputStream is = MessageHelper.class.getClassLoader().getResourceAsStream(ERROR_FILE_PATH)) { if (is == null) { - log.warn("No se encontró el archivo de errores: {}", ERROR_FILE_PATH); + log.warn("No se encontro el archivo de errores: {}", ERROR_FILE_PATH); return ""; } return new String(is.readAllBytes()); @@ -184,7 +184,7 @@ public class MessageHelper { mapping.setBackendCode(SUCCESS_DEFAULT); mapping.setHttpCode(200); mapping.setStatusCode("200"); - mapping.setDescription("Operación exitosa"); + mapping.setDescription("Operacion exitosa"); return mapping; } diff --git a/src/main/java/com/banesco/common/application/service/HttpClientService.java b/src/main/java/com/banesco/common/application/service/HttpClientService.java index da6262c..122e6e8 100644 --- a/src/main/java/com/banesco/common/application/service/HttpClientService.java +++ b/src/main/java/com/banesco/common/application/service/HttpClientService.java @@ -3,10 +3,10 @@ package com.banesco.common.application.service; import com.banesco.common.application.usecase.HttpClientUseCase; import com.banesco.common.domain.exception.HttpApiResponseException; import com.banesco.common.domain.exception.HttpStatusCodeException; -import com.banesco.common.domain.model.ApiResponse; -import com.banesco.common.domain.model.HttpRequest; +import com.banesco.common.domain.model.*; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -15,6 +15,9 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import lombok.extern.slf4j.Slf4j; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -31,43 +34,71 @@ public class HttpClientService implements HttpClientUseCase { @Override public T execute(HttpRequest request) { + return executeInternal(request); + } + + @Override + public ApiResponse executeApiResponse(HttpRequest request) { + return executeInternal(request); + } + + @Override + public ApiResponse> executeApiResponseList( + HttpRequest request + ) { + return executeInternal(request); + } + + @Override + public ApiPrivateResponse> executeApiPrivateResponse( + HttpRequest request + ) { + return executeInternal(request); + } + + @Override + public ApiPrivateResponse, ApiPrivateError>> executeApiPrivateResponseList( + HttpRequest request + ) { + return executeInternal(request); + } + + private T executeInternal(HttpRequest request) { String finalUrl = buildFinalUrl(request); - log.info("URL final: {}", finalUrl); + if (request.isLogRequestBody()) { + log.info("URL final: {}", finalUrl); - if (request.getHeaders() != null) { - log.info("Headers request: {}", request.getHeaders()); - } + if (request.getHeaders() != null && !request.getHeaders().isEmpty()) { + log.info("Headers: {}", request.getHeaders()); + } - if (request.getQueryParams() != null) { - log.info("Query params request: {}", request.getQueryParams()); - } + if (request.getQueryParams() != null && !request.getQueryParams().isEmpty()) { + log.info("Query params: {}", request.getQueryParams()); + } - if (request.getBody() != null) { - log.info("Body request: {}", request.getBody()); + if (request.getBody() != null) { + log.info("Body: {}", request.getBody()); + } } try (Client client = createClient(request.getConnectTimeout(), request.getReadTimeout())) { WebTarget target = client.target(finalUrl); - Invocation.Builder builder = target.request(MediaType.APPLICATION_JSON); - if (request.getHeaders() != null && !request.getHeaders().isEmpty()) { - for (Map.Entry entry : request.getHeaders().entrySet()) { - builder.header(entry.getKey(), entry.getValue()); - } + if (request.getHeaders() != null) { + request.getHeaders().forEach(builder::header); } Response response = buildRequest(builder, request); - return handleResponse(request, response); } catch (HttpStatusCodeException | HttpApiResponseException e) { throw e; } catch (Exception e) { - log.error("Error de conexión {}: {}", request.getMethod(), e.getMessage()); + log.error("Error de conexion {}: {}", request.getMethod(), e.getMessage()); throw HttpStatusCodeException.serviceUnavailable( - "503", - "Error de conexión con el servicio externo: " + e.getMessage() + "503", + "Error de conexion con el servicio externo: " + e.getMessage() ); } } @@ -76,18 +107,13 @@ public class HttpClientService implements HttpClientUseCase { String finalUrl = request.getUrl(); if (request.getPathParams() != null && !request.getPathParams().isEmpty()) { - log.debug("PathParams antes de reemplazar: {}", request.getPathParams()); - log.debug("URL original: {}", finalUrl); - for (Map.Entry entry : request.getPathParams().entrySet()) { String placeholder = "{" + entry.getKey() + "}"; finalUrl = finalUrl.replace(placeholder, entry.getValue()); } } - finalUrl = appendQueryParams(finalUrl, request.getQueryParams()); - - return finalUrl; + return appendQueryParams(finalUrl, request.getQueryParams()); } private String appendQueryParams(String url, Map queryParams) { @@ -96,7 +122,6 @@ public class HttpClientService implements HttpClientUseCase { } StringBuilder urlBuilder = new StringBuilder(url); - boolean firstParam = !url.contains("?"); for (Map.Entry entry : queryParams.entrySet()) { @@ -119,11 +144,7 @@ public class HttpClientService implements HttpClientUseCase { Invocation.Builder builder, HttpRequest request ) { - log.info( - "Método HTTP: {}, Headers enviados: {}", - request.getMethod().name(), - request.getHeaders() - ); + log.info("Metodo HTTP: {}", request.getMethod().name()); return switch (request.getMethod()) { case GET -> builder.get(); @@ -133,14 +154,11 @@ public class HttpClientService implements HttpClientUseCase { case PATCH -> builder.method("PATCH", Entity.entity(request.getBody(), MediaType.APPLICATION_JSON)); case HEAD -> builder.head(); case OPTIONS -> builder.options(); - default -> throw new IllegalArgumentException("Método HTTP no soportado: " + request.getMethod()); + default -> throw new IllegalArgumentException("Metodo HTTP no soportado: " + request.getMethod()); }; } - private Client createClient( - int connectTimeout, - int readTimeout - ) { + private Client createClient(int connectTimeout, int readTimeout) { return ClientBuilder.newBuilder() .connectTimeout(connectTimeout, TimeUnit.MILLISECONDS) .readTimeout(readTimeout, TimeUnit.MILLISECONDS) @@ -157,7 +175,9 @@ public class HttpClientService implements HttpClientUseCase { try (response) { String responseBody = response.readEntity(String.class); - log.info("Respuesta Cuerpo: {}", responseBody); + if (request.isLogResponseBody()) { + log.info("Respuesta Cuerpo: {}", responseBody); + } if (statusCode >= 200 && statusCode < 300) { if (request.getResponseType() == Void.class || request.getResponseType() == void.class) { @@ -195,8 +215,7 @@ public class HttpClientService implements HttpClientUseCase { e.getMessage() ); throw HttpStatusCodeException.internalServer( - "500", - "Error procesando respuesta del servicio externo: " + e.getMessage() + "500", "Error procesando respuesta del servicio externo: " + e.getMessage() ); } } @@ -205,26 +224,166 @@ public class HttpClientService implements HttpClientUseCase { HttpRequest request, String responseBody ) throws JsonProcessingException { + if (request.isApiPrivateResponse() && request.isEitherResponse()) { + return handleApiPrivateResponseWithEither(request, responseBody); + } + T result; if (request.getResponseType() == ApiResponse.class) { result = deserializeApiResponse(responseBody, request); + } else if (request.getComplexType() != null) { + JavaType javaType = objectMapper.getTypeFactory().constructParametricType( + request.getResponseType(), objectMapper.getTypeFactory().constructType(request.getComplexType()) + ); + result = objectMapper.readValue(responseBody, javaType); + } else if (request.getGenericType() != null) { + JavaType javaType = objectMapper.getTypeFactory().constructParametricType( + request.getResponseType(), objectMapper.getTypeFactory().constructType(request.getGenericType()) + ); + result = objectMapper.readValue(responseBody, javaType); } else { - result = (request.getGenericType() != null) ? objectMapper.readValue( - responseBody, - objectMapper.getTypeFactory().constructParametricType( - request.getResponseType(), - objectMapper.getTypeFactory().constructType(request.getGenericType()) - ) - ) : objectMapper.readValue( - responseBody, - objectMapper.getTypeFactory().constructType(request.getResponseType()) + result = objectMapper.readValue( + responseBody, objectMapper.getTypeFactory().constructType(request.getResponseType()) ); } return result; } + private T handleApiPrivateResponseWithEither( + HttpRequest request, + String responseBody + ) throws JsonProcessingException { + JsonNode rootNode = objectMapper.readTree(responseBody); + String status = rootNode.has("estatus") ? rootNode.get("estatus").asText() : null; + String message = rootNode.has("mensaje") ? rootNode.get("mensaje").asText() : null; + JsonNode detailNode = rootNode.get("detalle"); + + if (request.getStatusSuccess().equals(status)) { + return handleSuccessResponse(request, status, message, detailNode); + } else { + return handleErrorResponse(status, message, detailNode); + } + } + + @SuppressWarnings("unchecked") + private T handleSuccessResponse( + HttpRequest request, + String status, + String message, + JsonNode detailNode + ) { + Object successData; + + if (request.isListResponse()) { + successData = handleListSuccess(request, detailNode); + ApiPrivateResponse, ApiPrivateError>> response = new ApiPrivateResponse<>(); + + response.setEstatus(status); + response.setMensaje(message); + response.setDetalle(Either.left((List) successData)); + return (T) response; + } else { + successData = handleObjectSuccess(request, detailNode); + ApiPrivateResponse> response = new ApiPrivateResponse<>(); + + response.setEstatus(status); + response.setMensaje(message); + response.setDetalle(Either.left(successData)); + return (T) response; + } + } + + private Object handleListSuccess( + HttpRequest request, + JsonNode detailNode + ) { + Class elementType = getElementTypeFromRequest(request); + JavaType listType = objectMapper.getTypeFactory().constructCollectionType(List.class, elementType); + + if (detailNode != null && !detailNode.isNull()) { + return objectMapper.convertValue(detailNode, listType); + } + + return List.of(); + } + + private Object handleObjectSuccess( + HttpRequest request, + JsonNode detailNode + ) { + Class elementType = getElementTypeFromRequest(request); + + if (detailNode != null && !detailNode.isNull()) { + return objectMapper.convertValue(detailNode, elementType); + } + + return null; + } + + @SuppressWarnings("unchecked") + private T handleErrorResponse( + String status, + String message, + JsonNode detailNode + ) { + ApiPrivateError error = buildApiPrivateError(detailNode, message); + ApiPrivateResponse> response = new ApiPrivateResponse<>(); + + response.setEstatus(status); + response.setMensaje(message); + response.setDetalle(Either.right(error)); + + return (T) response; + } + + private ApiPrivateError buildApiPrivateError( + JsonNode detailNode, + String message + ) { + if (detailNode != null && !detailNode.isNull()) { + try { + return objectMapper.convertValue(detailNode, ApiPrivateError.class); + } catch (Exception e) { + log.warn("Cannot map detail to ApiPrivateError, creating default error. Detail: {}", detailNode); + } + } + + return ApiPrivateError.builder() + .codError(null) + .mensajeError(message) + .constraintName(null) + .build(); + } + + private Class getElementTypeFromRequest(HttpRequest request) { + if (request.getGenericType() != null) { + return request.getGenericType(); + } + + if (request.getComplexType() instanceof ParameterizedType pt) { + Type[] typeArgs = pt.getActualTypeArguments(); + + if (typeArgs.length > 0) { + Type firstArg = typeArgs[0]; + + if (firstArg instanceof ParameterizedType innerPt) { + Type[] innerArgs = innerPt.getActualTypeArguments(); + + if (innerArgs.length > 0 && innerArgs[0] instanceof Class innerClass) { + return innerClass; + } + } else if (firstArg instanceof Class elementClass) { + return elementClass; + } + } + } + + log.warn("No se pudo determinar el elementType del request, usando Object.class"); + return Object.class; + } + @SuppressWarnings("unchecked") private T deserializeApiResponse( String responseBody, @@ -243,14 +402,12 @@ public class HttpClientService implements HttpClientUseCase { } catch (JsonProcessingException e) { log.error("Error deserializando respuesta JSON: {}", e.getMessage()); throw HttpStatusCodeException.internalServer( - "500", - "Error deserializando respuesta JSON: " + e.getMessage() + "500", "Error deserializando respuesta JSON: " + e.getMessage() ); } catch (Exception e) { log.error("Error desconocido al deserializar respuesta: {}", e.getMessage()); throw HttpStatusCodeException.internalServer( - "500", - "Error desconocido al deserializar respuesta: " + e.getMessage() + "500", "Error desconocido al deserializar respuesta: " + e.getMessage() ); } } diff --git a/src/main/java/com/banesco/common/application/usecase/HttpClientUseCase.java b/src/main/java/com/banesco/common/application/usecase/HttpClientUseCase.java index c09feaf..c7a0b7b 100644 --- a/src/main/java/com/banesco/common/application/usecase/HttpClientUseCase.java +++ b/src/main/java/com/banesco/common/application/usecase/HttpClientUseCase.java @@ -1,7 +1,18 @@ package com.banesco.common.application.usecase; -import com.banesco.common.domain.model.HttpRequest; +import com.banesco.common.domain.model.*; + +import java.util.List; public interface HttpClientUseCase { + T execute(HttpRequest request); -} + + ApiResponse executeApiResponse(HttpRequest request); + + ApiResponse> executeApiResponseList(HttpRequest request); + + ApiPrivateResponse> executeApiPrivateResponse(HttpRequest request); + + ApiPrivateResponse, ApiPrivateError>> executeApiPrivateResponseList(HttpRequest request); +} \ No newline at end of file diff --git a/src/main/java/com/banesco/common/domain/model/Agreement.java b/src/main/java/com/banesco/common/domain/model/Agreement.java index eabbaff..ce8c3f0 100644 --- a/src/main/java/com/banesco/common/domain/model/Agreement.java +++ b/src/main/java/com/banesco/common/domain/model/Agreement.java @@ -15,6 +15,6 @@ import java.util.List; @RegisterForReflection @JsonInclude(JsonInclude.Include.NON_NULL) public class Agreement { - @Schema(description = "Información del arreglo de la cuenta") + @Schema(description = "Informacion del arreglo de la cuenta") private List arrangement; } diff --git a/src/main/java/com/banesco/common/domain/model/ApiPrivateError.java b/src/main/java/com/banesco/common/domain/model/ApiPrivateError.java new file mode 100644 index 0000000..f333114 --- /dev/null +++ b/src/main/java/com/banesco/common/domain/model/ApiPrivateError.java @@ -0,0 +1,16 @@ +package com.banesco.common.domain.model; + +import io.quarkus.runtime.annotations.RegisterForReflection; +import lombok.*; + +@Getter +@ToString +@Builder +@NoArgsConstructor +@AllArgsConstructor +@RegisterForReflection +public class ApiPrivateError { + private Long codError; + private String mensajeError; + private String constraintName; +} \ No newline at end of file diff --git a/src/main/java/com/banesco/common/domain/model/ApiPrivateResponse.java b/src/main/java/com/banesco/common/domain/model/ApiPrivateResponse.java new file mode 100644 index 0000000..b66edb5 --- /dev/null +++ b/src/main/java/com/banesco/common/domain/model/ApiPrivateResponse.java @@ -0,0 +1,17 @@ +package com.banesco.common.domain.model; + +import lombok.*; + +@Getter +@Setter +@ToString +@NoArgsConstructor +@AllArgsConstructor +public class ApiPrivateResponse { + private String estatus; + private String mensaje; + private T detalle; + private String codeline; + private String __equalsCalc; + private Boolean __hashCodeCalc; +} \ No newline at end of file diff --git a/src/main/java/com/banesco/common/domain/model/Arrangement.java b/src/main/java/com/banesco/common/domain/model/Arrangement.java index 52ee99a..7342502 100644 --- a/src/main/java/com/banesco/common/domain/model/Arrangement.java +++ b/src/main/java/com/banesco/common/domain/model/Arrangement.java @@ -13,6 +13,6 @@ import org.eclipse.microprofile.openapi.annotations.media.Schema; @RegisterForReflection @JsonInclude(JsonInclude.Include.NON_NULL) public class Arrangement { - @Schema(description = "Información del tipo de arreglo de la cuenta (Si la cuenta corriente tiene interés)") + @Schema(description = "Informacion del tipo de arreglo de la cuenta (Si la cuenta corriente tiene interes)") private ArrangementType arrangementType; } diff --git a/src/main/java/com/banesco/common/domain/model/Either.java b/src/main/java/com/banesco/common/domain/model/Either.java new file mode 100644 index 0000000..a8ff953 --- /dev/null +++ b/src/main/java/com/banesco/common/domain/model/Either.java @@ -0,0 +1,33 @@ +package com.banesco.common.domain.model; + +import lombok.Getter; + +@Getter +public class Either { + private final L left; + private final R right; + + private final boolean leftFlag; + + private Either(L left, R right, boolean leftFlag) { + this.left = left; + this.right = right; + this.leftFlag = leftFlag; + } + + public static Either left(L left) { + return new Either<>(left, null, true); + } + + public static Either right(R right) { + return new Either<>(null, right, false); + } + + public boolean isLeft() { + return leftFlag; + } + + public boolean isRight() { + return !leftFlag; + } +} \ No newline at end of file diff --git a/src/main/java/com/banesco/common/domain/model/HttpRequest.java b/src/main/java/com/banesco/common/domain/model/HttpRequest.java index a14d04a..af48ca7 100644 --- a/src/main/java/com/banesco/common/domain/model/HttpRequest.java +++ b/src/main/java/com/banesco/common/domain/model/HttpRequest.java @@ -2,6 +2,7 @@ package com.banesco.common.domain.model; import lombok.*; +import java.lang.reflect.Type; import java.util.Map; @Getter @@ -23,6 +24,24 @@ public class HttpRequest { private Class genericType; + private Type complexType; + + private Class errorType; + + private String statusSuccess; + + @Builder.Default + private boolean eitherResponse = false; + + @Builder.Default + private boolean apiPrivateResponse = false; + + @Builder.Default + private boolean apiResponse = false; + + @Builder.Default + private boolean listResponse = false; + @Builder.Default private int connectTimeout = 5000; @@ -32,6 +51,172 @@ public class HttpRequest { @Builder.Default private boolean returnFullResponse = false; + @Builder.Default + private boolean logRequestBody = true; + + @Builder.Default + private boolean logResponseBody = true; + + public static HttpRequest forApiResponse( + String url, + HttpMethod method, + Class dataType + ) { + return HttpRequest.builder() + .url(url) + .method(method) + .responseType(ApiResponse.class) + .genericType(dataType) + .apiResponse(true) + .build(); + } + + public static HttpRequest forApiResponseList( + String url, + HttpMethod method, + Class elementType + ) { + return HttpRequest.builder() + .url(url) + .method(method) + .responseType(ApiResponse.class) + .complexType(TypeBuilder.listOf(elementType)) + .apiResponse(true) + .listResponse(true) + .build(); + } + + public static HttpRequest forApiPrivateResponse( + String url, + String statusSuccess, + HttpMethod method, + Class successType + ) { + return HttpRequest.builder() + .url(url) + .method(method) + .responseType(ApiPrivateResponse.class) + .complexType(TypeBuilder.parametricType( + Either.class, + successType, + ApiPrivateError.class + )) + .apiPrivateResponse(true) + .eitherResponse(true) + .errorType(ApiPrivateError.class) + .statusSuccess(statusSuccess) + .build(); + } + + public static HttpRequest forApiPrivateResponseList( + String url, + String statusSuccess, + HttpMethod method, + Class elementType + ) { + return HttpRequest.builder() + .url(url) + .method(method) + .responseType(ApiPrivateResponse.class) + .complexType(TypeBuilder.parametricType( + Either.class, + TypeBuilder.listOf(elementType), + ApiPrivateError.class + )) + .apiPrivateResponse(true) + .eitherResponse(true) + .listResponse(true) + .errorType(ApiPrivateError.class) + .statusSuccess(statusSuccess) + .build(); + } + + public static HttpRequest forDirectResponse( + String url, + HttpMethod method, + Class responseType + ) { + return HttpRequest.builder() + .url(url) + .method(method) + .responseType(responseType) + .build(); + } + + public static HttpRequest forGenericResponse( + String url, + HttpMethod method, + Class rawType, + Class genericType + ) { + return HttpRequest.builder() + .url(url) + .method(method) + .responseType(rawType) + .complexType(TypeBuilder.parametricType(rawType, genericType)) + .build(); + } + + public HttpRequest withHeaders(Map headers) { + this.headers = headers; + return this; + } + + public HttpRequest withQueryParams(Map queryParams) { + this.queryParams = queryParams; + return this; + } + + public HttpRequest withPathParams(Map pathParams) { + this.pathParams = pathParams; + return this; + } + + public HttpRequest withBody(Object body) { + this.body = body; + return this; + } + + public HttpRequest withTimeout(int connectTimeout, int readTimeout) { + this.connectTimeout = connectTimeout; + this.readTimeout = readTimeout; + return this; + } + + public HttpRequest disableRequestLogging() { + this.logRequestBody = false; + return this; + } + + public HttpRequest disableResponseLogging() { + this.logResponseBody = false; + return this; + } + + public ResponseType getExpectedResponseType() { + if (apiPrivateResponse && eitherResponse) { + return listResponse ? ResponseType.API_PRIVATE_WITH_EITHER_LIST : ResponseType.API_PRIVATE_WITH_EITHER; + } else if (apiResponse) { + return listResponse ? ResponseType.API_RESPONSE_LIST : ResponseType.API_RESPONSE; + } else if (complexType != null) { + return ResponseType.COMPLEX_TYPE; + } else if (genericType != null) { + return ResponseType.GENERIC_TYPE; + } else { + return ResponseType.DIRECT_TYPE; + } + } + + public enum ResponseType { + API_RESPONSE, + API_RESPONSE_LIST, + API_PRIVATE_WITH_EITHER, + API_PRIVATE_WITH_EITHER_LIST, + GENERIC_TYPE, + COMPLEX_TYPE, + DIRECT_TYPE + } + public enum HttpMethod { GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS } diff --git a/src/main/java/com/banesco/common/domain/model/TypeBuilder.java b/src/main/java/com/banesco/common/domain/model/TypeBuilder.java new file mode 100644 index 0000000..3120444 --- /dev/null +++ b/src/main/java/com/banesco/common/domain/model/TypeBuilder.java @@ -0,0 +1,67 @@ +package com.banesco.common.domain.model; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +public class TypeBuilder { + + private TypeBuilder() {} + + public static Type listOf(Class elementType) { + return new ParameterizedType() { + @Override + public Type[] getActualTypeArguments() { + return new Type[]{elementType}; + } + + @Override + public Type getRawType() { + return java.util.List.class; + } + + @Override + public Type getOwnerType() { + return null; + } + }; + } + + public static Type parametricType(Class rawType, Type... typeArguments) { + return new ParameterizedType() { + @Override + public Type[] getActualTypeArguments() { + return typeArguments; + } + + @Override + public Type getRawType() { + return rawType; + } + + @Override + public Type getOwnerType() { + return null; + } + }; + } + + public static Type apiPrivateResponseWithEither(Class successType, Class errorType) { + Type eitherType = parametricType(Either.class, successType, errorType); + return parametricType(ApiPrivateResponse.class, eitherType); + } + + public static Type apiPrivateResponseWithListEither(Class successType, Class errorType) { + Type listType = listOf(successType); + Type eitherType = parametricType(Either.class, listType, errorType); + return parametricType(ApiPrivateResponse.class, eitherType); + } + + public static Type apiResponseType(Class dataType) { + return parametricType(ApiResponse.class, dataType); + } + + public static Type apiResponseListType(Class elementType) { + Type listType = listOf(elementType); + return parametricType(ApiResponse.class, listType); + } +} \ No newline at end of file diff --git a/src/main/java/com/banesco/common/infrastructure/config/ApiAllowedConfig.java b/src/main/java/com/banesco/common/infrastructure/config/ApiAllowedConfig.java index 0bc08ff..8c037ec 100644 --- a/src/main/java/com/banesco/common/infrastructure/config/ApiAllowedConfig.java +++ b/src/main/java/com/banesco/common/infrastructure/config/ApiAllowedConfig.java @@ -40,7 +40,7 @@ public class ApiAllowedConfig { log.info("Configurando {}: {}", fullConfigName, json); if (json == null || json.trim().isEmpty()) { - throw new IllegalStateException("Configuración no encontrada para: " + fullConfigName); + throw new IllegalStateException("Configuracion no encontrada para: " + fullConfigName); } List> configList = objectMapper.readValue(json, new TypeReference<>() {}); diff --git a/src/main/java/com/banesco/common/infrastructure/config/RestClientConfig.java b/src/main/java/com/banesco/common/infrastructure/config/RestClientConfig.java index d6ac36e..20a6fc9 100644 --- a/src/main/java/com/banesco/common/infrastructure/config/RestClientConfig.java +++ b/src/main/java/com/banesco/common/infrastructure/config/RestClientConfig.java @@ -58,15 +58,15 @@ public class RestClientConfig { log.info("Configurando {}: {}", fullConfigName, json); if (json == null || json.trim().isEmpty()) { - throw new IllegalStateException("Configuración no encontrada para: " + fullConfigName); + throw new IllegalStateException("Configuracion no encontrada para: " + fullConfigName); } Map configMap = objectMapper.readValue(json, new TypeReference<>() {}); return objectMapper.convertValue(configMap, configType); } catch (JsonProcessingException e) { - throw new IllegalArgumentException("Formato JSON inválido para " + configName + ": " + e.getMessage(), e); + throw new IllegalArgumentException("Formato JSON invalido para " + configName + ": " + e.getMessage(), e); } catch (Exception e) { - throw new IllegalStateException("Error cargando configuración del servicio " + configName + ": " + e.getMessage(), e); + throw new IllegalStateException("Error cargando configuracion del servicio " + configName + ": " + e.getMessage(), e); } } } \ No newline at end of file diff --git a/src/main/java/com/banesco/module/account/domain/model/Account.java b/src/main/java/com/banesco/module/account/domain/model/Account.java index c3d5ca4..a38ae7e 100644 --- a/src/main/java/com/banesco/module/account/domain/model/Account.java +++ b/src/main/java/com/banesco/module/account/domain/model/Account.java @@ -18,18 +18,18 @@ import java.util.List; public class Account { @Schema(description = "Estado de la cuenta") private AccountStatus accountStatus; - @Schema(description = "Lista de datos de identificación de la cuenta") + @Schema(description = "Lista de datos de identificacion de la cuenta") private List accountIdentification; @Schema(description = "Tipo de cuenta") private AccountType accountType; - @Schema(description = "Información de los tipos de balances de la cuenta") + @Schema(description = "Informacion de los tipos de balances de la cuenta") private List accountBalance; - @Schema(description = "Información de la moneda de la cuenta") + @Schema(description = "Informacion de la moneda de la cuenta") private List accountCurrency; - @Schema(description = "Información complementaria de la cuenta") + @Schema(description = "Informacion complementaria de la cuenta") private List accountInvolvement; - @Schema(description = "Información relacional de la cuenta con otras o consigo misma") + @Schema(description = "Informacion relacional de la cuenta con otras o consigo misma") private List accountRelationship; - @Schema(description = "Información del acuerdo de la cuenta") + @Schema(description = "Informacion del acuerdo de la cuenta") private List agreement; } \ No newline at end of file diff --git a/src/main/java/com/banesco/module/account/domain/model/AccountInvolvement.java b/src/main/java/com/banesco/module/account/domain/model/AccountInvolvement.java index 1c983d6..fda6f86 100644 --- a/src/main/java/com/banesco/module/account/domain/model/AccountInvolvement.java +++ b/src/main/java/com/banesco/module/account/domain/model/AccountInvolvement.java @@ -13,6 +13,6 @@ import org.eclipse.microprofile.openapi.annotations.media.Schema; @RegisterForReflection public class AccountInvolvement { private AccountInvolvementType accountInvolvementType; - @Schema(description = "Información del cliente") + @Schema(description = "Informacion del cliente") private Party partyReference; } diff --git a/src/main/java/com/banesco/module/legal_customer_product_directory/application/service/LegalCustomerProductDirectoryService.java b/src/main/java/com/banesco/module/legal_customer_product_directory/application/service/LegalCustomerProductDirectoryService.java index 9a8385d..7c78fad 100644 --- a/src/main/java/com/banesco/module/legal_customer_product_directory/application/service/LegalCustomerProductDirectoryService.java +++ b/src/main/java/com/banesco/module/legal_customer_product_directory/application/service/LegalCustomerProductDirectoryService.java @@ -53,7 +53,7 @@ public class LegalCustomerProductDirectoryService implements LegalCustomerProduc public ApiResponse execute( LegalCustomerProductDirectoryRequest request ) { - log.info("Iniciando ejecución para el cliente: {}", request.getCustomerIbsNumber()); + log.info("Iniciando ejecucion para el cliente: {}", request.getCustomerIbsNumber()); LegalCustomerProductDirectoryRequest requestFromAppId = getRequestFromAppId(request); @@ -76,10 +76,10 @@ public class LegalCustomerProductDirectoryService implements LegalCustomerProduc throw HttpStatusCodeException.serviceUnavailable("503"); } catch (HttpStatusCodeException e) { - log.error("Excepción HTTP del api de dominio: {} - {}", e.getStatusCode(), e.getErrorCode()); + log.error("Excepcion HTTP del api de dominio: {} - {}", e.getStatusCode(), e.getErrorCode()); throw e; } catch (Exception e) { - log.error("Excepción genérica del api de dominio: {}", e.getMessage()); + log.error("Excepcion generica del api de dominio: {}", e.getMessage()); throw e; } finally { securityTrace(); @@ -91,7 +91,7 @@ public class LegalCustomerProductDirectoryService implements LegalCustomerProduc ) { if(appIdsAllowed.isEmpty()) { log.info( - "Configuración de la Lista App ID no disponible: {} -> {}", + "Configuracion de la Lista App ID no disponible: {} -> {}", request.getCustomerIbsNumber(), request.getAppId() ); @@ -110,7 +110,7 @@ public class LegalCustomerProductDirectoryService implements LegalCustomerProduc AppIdConfig appIdConfig = appIdAllowed.get(); if(!request.hasValidRequestParameters(appIdConfig)) { - log.info("App ID sin configuración: {} -> {}", request.getCustomerIbsNumber(), request.getAppId()); + log.info("App ID sin configuracion: {} -> {}", request.getCustomerIbsNumber(), request.getAppId()); throw HttpStatusCodeException.unauthorized("401"); } diff --git a/src/main/java/com/banesco/module/legal_customer_product_directory/domain/dto/request/LegalCustomerProductDirectoryRequest.java b/src/main/java/com/banesco/module/legal_customer_product_directory/domain/dto/request/LegalCustomerProductDirectoryRequest.java index a6e3f76..5801595 100644 --- a/src/main/java/com/banesco/module/legal_customer_product_directory/domain/dto/request/LegalCustomerProductDirectoryRequest.java +++ b/src/main/java/com/banesco/module/legal_customer_product_directory/domain/dto/request/LegalCustomerProductDirectoryRequest.java @@ -20,16 +20,16 @@ public class LegalCustomerProductDirectoryRequest { @NonNull private String appId; // Header obligatorio @NonNull - private String customerIbsNumber; // VCUSCUN - Obligatorio (Número de cliente IBS) + private String customerIbsNumber; // VCUSCUN - Obligatorio (Numero de cliente IBS) - private String bankNumber; // VACMBNK - Número de Banco (filtro) + private String bankNumber; // VACMBNK - Numero de Banco (filtro) private String currencyCode; // VACMCCY - Moneda (filtro) private String accountStatus; // VACMAST - Estatus de Cuenta (filtro) - private String productCvCode; // VACMPROCV - Código de Producto Cuenta Verde (filtro) - private String productCode; // VACMPRO - Código de Producto (filtro) - private String channelCode; // VAFILICANAL - Código de Canal (filtro) + private String productCvCode; // VACMPROCV - Codigo de Producto Cuenta Verde (filtro) + private String productCode; // VACMPRO - Codigo de Producto (filtro) + private String channelCode; // VAFILICANAL - Codigo de Canal (filtro) private String serviceType; // VAFILICOSER - Tipo de Servicio (filtro) - private String affiliationStatus; // VAFILISTATU - Estatus de afiliación (filtro) + private String affiliationStatus; // VAFILISTATU - Estatus de afiliacion (filtro) private String limitType; // VALIMIT - Pagador/Receptor (PAG/REC) (filtro) private String casheaIndicator; // VCASHEA - SI/NO (filtro) diff --git a/src/main/java/com/banesco/module/legal_customer_product_directory/infrastructure/client/DomLegalCustomerProductDirectoryClient.java b/src/main/java/com/banesco/module/legal_customer_product_directory/infrastructure/client/DomLegalCustomerProductDirectoryClient.java index 1b4c595..83986e7 100644 --- a/src/main/java/com/banesco/module/legal_customer_product_directory/infrastructure/client/DomLegalCustomerProductDirectoryClient.java +++ b/src/main/java/com/banesco/module/legal_customer_product_directory/infrastructure/client/DomLegalCustomerProductDirectoryClient.java @@ -28,7 +28,7 @@ public class DomLegalCustomerProductDirectoryClient implements DomainUseCase { ) { this.httpClientUseCase = httpClientUseCase; this.domainConfig = restClientConfig.getDomLegalCustomerConfig(); - log.info("Configuración cargada para bus-legal-customer-directory: {}", domainConfig); + log.info("Configuracion cargada para bus-legal-customer-directory: {}", domainConfig); } @Override @@ -37,16 +37,17 @@ public class DomLegalCustomerProductDirectoryClient implements DomainUseCase { Class responseType ) { String customerIbsNumber = params.getCustomerIbsNumber(); - HttpRequest request = HttpRequest.builder() - .url(domainConfig.getUrl()) - .method(HttpRequest.HttpMethod.GET) - .pathParams(Map.of("customerIbsNumber", customerIbsNumber)) - .queryParams(params.toQueryString()) - .responseType(ApiResponse.class) - .genericType(responseType) - .connectTimeout(domainConfig.getTimeout().getConnect()) - .readTimeout(domainConfig.getTimeout().getResponse()) - .build(); + HttpRequest request = HttpRequest.forApiResponse( + domainConfig.getUrl(), + HttpRequest.HttpMethod.GET, + responseType + ) + .withPathParams(Map.of("customerIbsNumber", customerIbsNumber)) + .withQueryParams(params.toQueryString()) + .withTimeout( + domainConfig.getTimeout().getConnect(), + domainConfig.getTimeout().getResponse() + ); log.debug("Request configurado: {}", request); diff --git a/src/main/java/com/banesco/module/legal_customer_product_directory/infrastructure/resource/LegalCustomerProductDirectoryResource.java b/src/main/java/com/banesco/module/legal_customer_product_directory/infrastructure/resource/LegalCustomerProductDirectoryResource.java index 513f8c0..ad2bdcc 100644 --- a/src/main/java/com/banesco/module/legal_customer_product_directory/infrastructure/resource/LegalCustomerProductDirectoryResource.java +++ b/src/main/java/com/banesco/module/legal_customer_product_directory/infrastructure/resource/LegalCustomerProductDirectoryResource.java @@ -45,12 +45,12 @@ public class LegalCustomerProductDirectoryResource { @Path("/retrieve/{customerIbsNumber : (?!retrieve$).*}") @Operation( summary = "Recuperar productos de cliente legal", - description = "Consulta masiva de cuentas por número de cliente IBS" + description = "Consulta masiva de cuentas por numero de cliente IBS" ) @APIResponses(value = { @APIResponse( responseCode = "200", - description = "Operación exitosa", + description = "Operacion exitosa", content = @Content( mediaType = MediaType.APPLICATION_JSON, schema = @Schema( @@ -142,7 +142,7 @@ public class LegalCustomerProductDirectoryResource { "fullName": "TASCA RESTAURANT GOOD WORLD CEN, C.A." } ], - "partyType": "ORGANISATION", + "partyType": "ORGANIZATION", "partyIdentification": [ { "partyIdentificationType": "TAX_IDENTIFICATION_NUMBER", @@ -186,7 +186,7 @@ public class LegalCustomerProductDirectoryResource { }, "statusResponse": { "statusCode": "200", - "message": "Operación exitosa" + "message": "Operacion exitosa" } } """ @@ -259,7 +259,7 @@ public class LegalCustomerProductDirectoryResource { ), examples = { @ExampleObject( - name = "Error VRN08 - Identificación del fintechId no coincide", + name = "Error VRN08 - Identificacion del fintechId no coincide", value = """ { "data": null, @@ -299,7 +299,7 @@ public class LegalCustomerProductDirectoryResource { "data": null, "statusResponse": { "statusCode": "VRN04", - "message": "El servicio no está disponible fuera del horario operativo" + "message": "El servicio no esta disponible fuera del horario operativo" } } """ @@ -311,7 +311,7 @@ public class LegalCustomerProductDirectoryResource { "data": null, "statusResponse": { "statusCode": "VDR13", - "message": "El servicio OSB no está disponible en este momento" + "message": "El servicio OSB no esta disponible en este momento" } } """ @@ -322,11 +322,11 @@ public class LegalCustomerProductDirectoryResource { }) public Response retrieve( @PathParam("customerIbsNumber") - @Parameter(description = "Número de cliente IBS (VCUSCUN)", example = "200053197") + @Parameter(description = "Numero de cliente IBS (VCUSCUN)", example = "200053197") String customerIbsNumber, @QueryParam("appId") - @Parameter(description = "ID de la aplicación", required = true, example = "DANIAPP") + @Parameter(description = "ID de la aplicacion", required = true, example = "DANIAPP") String appId, @QueryParam("customerReferenceFintechId") diff --git a/src/main/java/com/banesco/module/party/domain/model/PartyType.java b/src/main/java/com/banesco/module/party/domain/model/PartyType.java index ec99c5f..07d5e83 100644 --- a/src/main/java/com/banesco/module/party/domain/model/PartyType.java +++ b/src/main/java/com/banesco/module/party/domain/model/PartyType.java @@ -2,5 +2,5 @@ package com.banesco.module.party.domain.model; public enum PartyType { PERSON, - ORGANISATION + ORGANIZATION } diff --git a/src/main/java/com/banesco/module/security_trace/infrastructure/client/SecurityTraceClient.java b/src/main/java/com/banesco/module/security_trace/infrastructure/client/SecurityTraceClient.java index c017201..f4cdcc9 100644 --- a/src/main/java/com/banesco/module/security_trace/infrastructure/client/SecurityTraceClient.java +++ b/src/main/java/com/banesco/module/security_trace/infrastructure/client/SecurityTraceClient.java @@ -24,20 +24,22 @@ public class SecurityTraceClient implements SecurityTraceUseCase { ) { this.httpClientUseCase = httpClientUseCase; this.securityTraceConfig = restClientConfig.getSecurityTraceConfig(); - log.info("Configuración cargada para security-trace: {}", securityTraceConfig); + log.info("Configuracion cargada para security-trace: {}", securityTraceConfig); } @Override public T execute(Class responseType) { SecurityTraceRequest body = securityTraceConfig.getRequest(); - HttpRequest request = HttpRequest.builder() - .url(securityTraceConfig.getUrl()) - .method(HttpRequest.HttpMethod.POST) - .body(body) - .responseType(responseType) - .connectTimeout(securityTraceConfig.getTimeout().getConnect()) - .readTimeout(securityTraceConfig.getTimeout().getResponse()) - .build(); + HttpRequest request = HttpRequest.forDirectResponse( + securityTraceConfig.getUrl(), + HttpRequest.HttpMethod.POST, + responseType + ) + .withBody(body) + .withTimeout( + securityTraceConfig.getTimeout().getConnect(), + securityTraceConfig.getTimeout().getResponse() + ); log.debug("Request configurado: {}", request); diff --git a/src/main/java/com/banesco/module/service_status/infrastructure/client/ServiceStatusClient.java b/src/main/java/com/banesco/module/service_status/infrastructure/client/ServiceStatusClient.java index e5f7060..f362237 100644 --- a/src/main/java/com/banesco/module/service_status/infrastructure/client/ServiceStatusClient.java +++ b/src/main/java/com/banesco/module/service_status/infrastructure/client/ServiceStatusClient.java @@ -24,7 +24,7 @@ public class ServiceStatusClient implements ServiceStatusUseCase { ) { this.httpClientUseCase = httpClientUseCase; this.serviceStatusConfig = restClientConfig.getServiceStatusConfig(); - log.info("Configuración cargada para service-status: {}", serviceStatusConfig); + log.info("Configuracion cargada para service-status: {}", serviceStatusConfig); } @Override @@ -37,14 +37,16 @@ public class ServiceStatusClient implements ServiceStatusUseCase { .transactionId(params.getTransactionId()) .bankService(serviceStatusConfig.getRequest().getBankService()) .build(); - HttpRequest request = HttpRequest.builder() - .url(serviceStatusConfig.getUrl()) - .method(HttpRequest.HttpMethod.POST) - .body(body) - .responseType(responseType) - .connectTimeout(serviceStatusConfig.getTimeout().getConnect()) - .readTimeout(serviceStatusConfig.getTimeout().getResponse()) - .build(); + HttpRequest request = HttpRequest.forDirectResponse( + serviceStatusConfig.getUrl(), + HttpRequest.HttpMethod.POST, + responseType + ) + .withBody(body) + .withTimeout( + serviceStatusConfig.getTimeout().getConnect(), + serviceStatusConfig.getTimeout().getResponse() + ); log.debug("Request configurado: {}", request); @@ -59,14 +61,14 @@ public class ServiceStatusClient implements ServiceStatusUseCase { return response; } catch (HttpStatusCodeException e) { log.error( - "Error HTTP ejecutando verificación de estado del servicio: {} - {}", + "Error HTTP ejecutando verificacion de estado del servicio: {} - {}", e.getStatusCode(), e.getMessage() ); throw e; } catch (Exception e) { - log.error("Error ejecutando verificación de estado del servicio: {}", e.getMessage()); + log.error("Error ejecutando verificacion de estado del servicio: {}", e.getMessage()); throw HttpStatusCodeException.serviceUnavailable("503"); } } diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 2f05938..feae550 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -15,7 +15,7 @@ api: bus-legal-customer-product-directory: messages: key: 'bus-legal-customer-product-directory' - content: '[{"backendCode":"200","httpCode":200,"statusCode":"200","description":"Operacion exitosa"},{"backendCode":"R404","httpCode":404,"statusCode":"404","description":"Datos de validación no encontrado."},{"backendCode":"503","httpCode":503,"statusCode":"503","description":"Uso interno"},{"backendCode":"422","httpCode":422,"statusCode":"422","description":"Uso interno"},{"backendCode":"500","httpCode":500,"statusCode":"500","description":"Uso interno"},{"backendCode":"100","httpCode":503,"statusCode":"503","description":"VDR13 - OSB Disponible"},{"backendCode":"OSB-382505","httpCode":503,"statusCode":"503","description":"VDR13 - OSB Disponible"},{"backendCode":"OSB-380002","httpCode":503,"statusCode":"503","description":"VDR13 - OSB Disponible"},{"backendCode":"ERROR","httpCode":400,"statusCode":"400","description":"Uso interno"},{"backendCode":"400","httpCode":400,"statusCode":"400","description":"Uso interno"},{"backendCode":"401","httpCode":401,"statusCode":"401","description":"Uso interno"},{"backendCode":"403","httpCode":403,"statusCode":"403","description":"Uso interno"},{"backendCode":"404","httpCode":404,"statusCode":"404","description":"Uso interno"},{"backendCode":"default","httpCode":409,"statusCode":"409","description":"Conflicto"},{"backendCode":"424","httpCode":424,"statusCode":"424","description":"Error de dependencia"},{"backendCode":"VDE01","httpCode":400,"statusCode":"VDE01","description":"VDE01 - Error en dato de entrada obligatorio: %s"},{"backendCode":"VDE02","httpCode":400,"statusCode":"VDE02","description":"VDE02 - Error en valor permitido para campo: %s"},{"backendCode":"VRN04","httpCode":"503","statusCode":"VRN04","description":"Servicio en horario de mantenimiento","status":"error"},{"backendCode":"204","httpCode":"200","statusCode":"200","description":"Cliente sin productos","status":"ok"}]' + content: '[{"backendCode":"200","httpCode":200,"statusCode":"200","description":"Operacion exitosa"},{"backendCode":"R404","httpCode":404,"statusCode":"404","description":"Datos de validacion no encontrado."},{"backendCode":"503","httpCode":503,"statusCode":"503","description":"Uso interno"},{"backendCode":"422","httpCode":422,"statusCode":"422","description":"Uso interno"},{"backendCode":"500","httpCode":500,"statusCode":"500","description":"Uso interno"},{"backendCode":"100","httpCode":503,"statusCode":"503","description":"VDR13 - OSB Disponible"},{"backendCode":"OSB-382505","httpCode":503,"statusCode":"503","description":"VDR13 - OSB Disponible"},{"backendCode":"OSB-380002","httpCode":503,"statusCode":"503","description":"VDR13 - OSB Disponible"},{"backendCode":"ERROR","httpCode":400,"statusCode":"400","description":"Uso interno"},{"backendCode":"400","httpCode":400,"statusCode":"400","description":"Uso interno"},{"backendCode":"401","httpCode":401,"statusCode":"401","description":"Uso interno"},{"backendCode":"403","httpCode":403,"statusCode":"403","description":"Uso interno"},{"backendCode":"404","httpCode":404,"statusCode":"404","description":"Uso interno"},{"backendCode":"default","httpCode":409,"statusCode":"409","description":"Conflicto"},{"backendCode":"424","httpCode":424,"statusCode":"424","description":"Error de dependencia"},{"backendCode":"VDE01","httpCode":400,"statusCode":"VDE01","description":"VDE01 - Error en dato de entrada obligatorio: %s"},{"backendCode":"VDE02","httpCode":400,"statusCode":"VDE02","description":"VDE02 - Error en valor permitido para campo: %s"},{"backendCode":"VRN04","httpCode":"503","statusCode":"VRN04","description":"Servicio en horario de mantenimiento","status":"error"},{"backendCode":"204","httpCode":"200","statusCode":"200","description":"Cliente sin productos","status":"ok"}]' rest-client: dom-legal-customer-product-directory: '{"url":"http://localhost:8083/dom-legal-customer-product-directory/retrieve/{customerIbsNumber}","timeout":{"connect":10000,"response":10000}}' security-trace: '{"url":"http://api-register-security-route-apis-banesco-dev.apps.desplakur3.desintra.banesco.com/register-security/save","timeout":{"connect":10000,"response":10000},"request":{"sp":"spAPI_Traza","eventCod":"CANCTARJ","bankCod":"01","curCod":"BS"}}'