update clients

This commit is contained in:
Ramon Ramirez 2026-01-10 20:00:09 -04:00
parent 64a5253a69
commit 1179fd2877
14 changed files with 106 additions and 218 deletions

View File

@ -41,7 +41,11 @@ public class MessageResponseHelper {
}
public Response handleException(HttpStatusCodeException exception) {
log.error("Error interno controlado: {}", exception.getMessage());
log.error(
"Error interno controlado: {} -> {}",
exception.getStatusCode(),
exception.getErrorCode()
);
return buildErrorResponse(exception);
}

View File

@ -5,7 +5,7 @@ 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.StatusResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.enterprise.context.ApplicationScoped;
@ -76,10 +76,10 @@ public class HttpClientService implements HttpClientUseCase {
} catch (HttpStatusCodeException | HttpApiResponseException e) {
throw e;
} catch (Exception e) {
log.error("Error de conexión {} {}: {}", request.getMethod(), request.getUrl(), e.getMessage());
log.error("Error de conexión {}: {}", request.getMethod(), e.getMessage());
throw HttpStatusCodeException.serviceUnavailable(
"HTTP_CONNECTION_ERROR",
"Error de conexión con el servicio externo: " + e.getMessage()
"503",
"Error de conexión con el servicio externo: " + e.getMessage()
);
}
}
@ -106,33 +106,45 @@ public class HttpClientService implements HttpClientUseCase {
};
}
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)
.build();
.connectTimeout(connectTimeout, TimeUnit.MILLISECONDS)
.readTimeout(readTimeout, TimeUnit.MILLISECONDS)
.build();
}
@SuppressWarnings("unchecked")
private <T> T handleResponse(
HttpRequest request,
Response response
) {
int statusCode = response.getStatus();
log.info("Respuesta {} {} - Status: {}", request.getMethod(), request.getUrl(), statusCode);
log.info("Respuesta {} - Status: {}", request.getMethod(), statusCode);
try (response) {
String responseBody = response.readEntity(String.class);
if (statusCode >= 200 && statusCode < 300) {
if (request.getResponseType() == Void.class || request.getResponseType() == void.class) {
return null;
}
T result = (T) response.readEntity(request.getResponseType());
T result;
if (request.getResponseType() == ApiResponse.class) {
result = deserializeApiResponse(responseBody, request);
} else {
result = objectMapper.readValue(
responseBody,
objectMapper.getTypeFactory().constructType(request.getResponseType())
);
}
log.debug("Respuesta exitosa {} {}: {}", request.getMethod(), request.getUrl(), result);
return result;
} else {
String responseBody = response.readEntity(String.class);
log.error(
"Error HTTP {} {} - Status: {} - Body: {}",
request.getMethod(),
@ -142,7 +154,7 @@ public class HttpClientService implements HttpClientUseCase {
);
if (isApiResponseFormat(responseBody)) {
ApiResponse<?> apiResponse = parseApiResponse(responseBody, request.getResponseType());
ApiResponse<?> apiResponse = deserializeApiResponse(responseBody, request);
throw new HttpApiResponseException(statusCode, apiResponse);
} else {
throw mapHttpStatusToException(statusCode, responseBody);
@ -158,12 +170,40 @@ public class HttpClientService implements HttpClientUseCase {
e.getMessage()
);
throw HttpStatusCodeException.internalServer(
"ERROR",
"500",
"Error procesando respuesta del servicio externo: " + e.getMessage()
);
}
}
@SuppressWarnings("unchecked")
private <T> T deserializeApiResponse(
String responseBody,
HttpRequest request
) {
try {
if (request.getGenericType() != null) {
JavaType javaType = objectMapper.getTypeFactory().constructParametricType(
ApiResponse.class,
objectMapper.getTypeFactory().constructType(request.getGenericType())
);
return objectMapper.readValue(responseBody, javaType);
} else {
return (T) objectMapper.readValue(responseBody, ApiResponse.class);
}
} catch (JsonProcessingException e) {
throw HttpStatusCodeException.internalServer(
"500",
"Error deserializando respuesta JSON: " + e.getMessage()
);
} catch (Exception e) {
throw HttpStatusCodeException.internalServer(
"500",
"Error desconocido al deserializar respuesta: " + e.getMessage()
);
}
}
private boolean isApiResponseFormat(String responseBody) {
try {
if (responseBody == null || responseBody.trim().isEmpty()) {
@ -171,47 +211,14 @@ public class HttpClientService implements HttpClientUseCase {
}
return responseBody.contains("\"data\"") &&
responseBody.contains("\"statusResponse\"") &&
responseBody.contains("\"statusCode\"") &&
responseBody.contains("\"message\"");
responseBody.contains("\"statusResponse\"") &&
responseBody.contains("\"statusCode\"") &&
responseBody.contains("\"message\"");
} catch (Exception e) {
return false;
}
}
private <T> ApiResponse<T> parseApiResponse(
String responseBody,
Class<?> responseType
) {
try {
JavaType javaType;
if (responseType == ApiResponse.class) {
javaType = objectMapper.getTypeFactory().constructParametricType(
ApiResponse.class,
objectMapper.getTypeFactory().constructType(Object.class)
);
} else {
javaType = objectMapper.getTypeFactory().constructParametricType(
ApiResponse.class,
objectMapper.getTypeFactory().constructType(responseType)
);
}
return objectMapper.readValue(responseBody, javaType);
} catch (Exception e) {
log.error("Error parseando ApiResponse: {}", e.getMessage());
return new ApiResponse<>(
StatusResponse.builder()
.statusCode("500")
.message("Error parseando respuesta del servicio")
.build()
);
}
}
private HttpStatusCodeException mapHttpStatusToException(
int statusCode,
String errorBody
@ -219,8 +226,8 @@ public class HttpClientService implements HttpClientUseCase {
String errorCode = "HTTP_" + statusCode;
String defaultMessage = "Error en servicio externo: HTTP " + statusCode;
String message = errorBody != null && !errorBody.isEmpty()
? errorBody
: defaultMessage;
? errorBody
: defaultMessage;
return switch (statusCode) {
case 400 -> HttpStatusCodeException.badRequest(errorCode, message);

View File

@ -6,14 +6,14 @@ import lombok.Getter;
@Getter
public class HttpApiResponseException extends RuntimeException {
private final int statusCode;
private final ApiResponse<?> apiResponse;
private final transient ApiResponse<?> apiResponse;
public HttpApiResponseException(int statusCode, ApiResponse<?> apiResponse) {
super(
String.format("HTTP %d: %s", statusCode,
super(String.format(
"HTTP %d: %s", statusCode,
apiResponse.getStatusResponse() != null ?
apiResponse.getStatusResponse().getMessage() : "Error sin mensaje")
);
apiResponse.getStatusResponse().getMessage() : "Error sin mensaje"
));
this.statusCode = statusCode;
this.apiResponse = apiResponse;
}

View File

@ -1,6 +1,5 @@
package com.banesco.common.domain.model;
import com.banesco.common.domain.model.Arrangement;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.*;

View File

@ -1,26 +1,38 @@
package com.banesco.common.domain.model;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
import lombok.*;
import java.util.Map;
@Getter
@Builder
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class HttpRequest {
private String url;
private HttpMethod method;
private Object body;
private Map<String, String> pathParams;
private Map<String, String> queryParams;
private Map<String, String> headers;
private Class<?> responseType;
private int connectTimeout;
private int readTimeout;
private Map<String, String> queryParams;
private Map<String, String> pathParams;
@Builder.Default
private Class<?> responseType = Object.class;
private Class<?> genericType;
@Builder.Default
private int connectTimeout = 5000;
@Builder.Default
private int readTimeout = 10000;
@Builder.Default
private boolean returnFullResponse = false;
public enum HttpMethod {
GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS
}
}
}

View File

@ -1,6 +1,5 @@
package com.banesco.module.account.domain.model;
import com.banesco.module.account.domain.model.AccountStatusType;
import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.*;

View File

@ -66,7 +66,7 @@ public class LegalCustomerProductDirectoryService implements LegalCustomerProduc
throw HttpStatusCodeException.serviceUnavailable("503");
} catch (HttpStatusCodeException e) {
log.error("Excepción HTTP del api de dominio: {} - {}", e.getStatusCode(), e.getMessage());
log.error("Excepción 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());

View File

@ -3,8 +3,6 @@ package com.banesco.module.legal_customer_product_directory.application.usecase;
import com.banesco.common.domain.model.ApiResponse;
import com.banesco.module.legal_customer_product_directory.domain.dto.request.LegalCustomerProductDirectoryRequest;
import java.util.Map;
public interface DomainUseCase {
<T> ApiResponse<T> execute(
LegalCustomerProductDirectoryRequest params,

View File

@ -6,7 +6,6 @@ import com.banesco.common.domain.exception.HttpStatusCodeException;
import com.banesco.common.domain.model.ApiResponse;
import com.banesco.common.domain.model.DominionConfig;
import com.banesco.common.domain.model.HttpRequest;
import com.banesco.common.domain.model.StatusResponse;
import com.banesco.common.infrastructure.config.RestClientConfig;
import com.banesco.module.legal_customer_product_directory.application.usecase.DomainUseCase;
import com.banesco.module.legal_customer_product_directory.domain.dto.request.LegalCustomerProductDirectoryRequest;
@ -33,21 +32,18 @@ public class DomLegalCustomerDirectoryClient implements DomainUseCase {
}
@Override
@SuppressWarnings("unchecked")
public <T> ApiResponse<T> execute(
LegalCustomerProductDirectoryRequest params,
Class<T> responseType
) {
String customerIbsNumber = params.getCustomerIbsNumber();
log.info("Consultando información del cliente: {}", customerIbsNumber);
HttpRequest request = HttpRequest.builder()
.url(dominionConfig.getUrl())
.method(HttpRequest.HttpMethod.GET)
.pathParams(Map.of("customerIbsNumber", customerIbsNumber))
.queryParams(params.toQueryString())
.responseType(ApiResponse.class)
.genericType(responseType)
.connectTimeout(dominionConfig.getTimeout().getConnect())
.readTimeout(dominionConfig.getTimeout().getResponse())
.build();
@ -58,9 +54,8 @@ public class DomLegalCustomerDirectoryClient implements DomainUseCase {
ApiResponse<T> response = httpClientUseCase.execute(request);
log.info(
"Solicitud del api de dominio exitoso: {} -> {}",
response.getStatusResponse(),
response.getData()
"Solicitud del api de dominio exitoso: {}",
response.getStatusResponse()
);
return response;
@ -71,7 +66,10 @@ public class DomLegalCustomerDirectoryClient implements DomainUseCase {
e.getApiResponse()
);
return (ApiResponse<T>) e.getApiResponse();
throw new HttpStatusCodeException(
e.getStatusCode(),
e.getApiResponse().getStatusResponse().getStatusCode()
);
} catch (HttpStatusCodeException e) {
log.error(
"Error HTTP consultando cliente {}: {} - {}",
@ -80,16 +78,10 @@ public class DomLegalCustomerDirectoryClient implements DomainUseCase {
e.getMessage()
);
return new ApiResponse<>(
StatusResponse.builder()
.statusCode(String.valueOf(e.getStatusCode()))
.message(e.getMessage())
.build()
);
throw e;
} catch (Exception e) {
log.error("Error consultando cliente {}: {}", customerIbsNumber, e.getMessage());
return new ApiResponse<>(StatusResponse.builder().statusCode("503").build());
throw HttpStatusCodeException.serviceUnavailable("503");
}
}
}

View File

@ -1,7 +1,6 @@
package com.banesco.module.party.domain.model;
import com.banesco.common.domain.model.Identifier;
import com.banesco.module.party.domain.model.PartyIdentificationType;
import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.*;

View File

@ -4,8 +4,6 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.*;
import java.math.BigDecimal;
@Getter
@ToString
@Builder
@ -14,120 +12,8 @@ import java.math.BigDecimal;
@RegisterForReflection
@JsonInclude(JsonInclude.Include.NON_NULL)
public class SecurityTraceRequest {
private String codBan;
private String codMon;
private String codEve;
private String codEve2;
private String login;
private String fecHor;
private String nacCli;
private Integer cedRifCli;
private String tipoProductoCli;
private String tipoProductoBen;
private String productoCli;
private String codEmpresa;
private String nacBen;
private Integer cedBen;
private String nombreBen;
private String productoBen;
private BigDecimal monto;
private String referencia;
private String nroDePago;
private String desPago;
private String objeto;
private Integer tipoRespuesta;
private String msgRespuesta;
private Integer tiempoRespuesta;
private String codFintech;
private String cedRifFintech;
private String nombreFintech;
private String tipoDispositivo;
private String desDispositivo;
private String ipCli;
private String refInternacional;
private BigDecimal montoReceptor;
private String refBanco;
private String stsTransaccion;
private String tipoMonedaEmi;
private String tipoMonedaRec;
private String paisEmisor;
private String paisReceptor;
private BigDecimal montoEmisor;
private String numeroCuentaEmi;
private String numeroCuentaRec;
private String numeroTelefonoRec;
private String propositoTransaccion;
private BigDecimal montoComision;
private String tipoIdEmisor;
private String idEmisor;
private BigDecimal numeroTarjeta;
private Integer codigoAutoriza;
private String refUniversal;
private String fechaAprobacion;
private String refBanesco;
private String fecHorCarga;
private String tipoProductoEmisor;
private String ctaEmisor;
private String tipoProductoReceptor;
private String ctaReceptor;
private String idReceptor;
private String nombreReceptor;
private String refExterna;
private String origenFondos;
private String destinoFondos;
private String fecHorTransaccion;
private String metodoPagoEmisor;
private String valorMetodoPagoEmisor;
private String entFinancieraEmisor;
private String nombreEmisor;
private String monedaEmisor;
private String metodoPagoReceptor;
private String valorMetodoPagoReceptor;
private String entFinancieraReceptor;
private String monedaReceptor;
private String descPago;
private String descTransaccion;
private BigDecimal tasaComision;
private BigDecimal numTarjeta;
private String codAutorizacion;
private String fecHorAprobacion;
private BigDecimal montoIgtf;
private BigDecimal montoLbtr;
private BigDecimal tasaCambio;
private BigDecimal montoTotalBs;
private String sp;
private String cn;
private String OU;
private String distinguishedName;
private String userPassword;
private Integer Enabled;
private String givenName;
private String sn;
private String mail;
private String employeeNumber;
private String employeeID;
private String mobile;
private String homePhone;
private String company;
private String personalTitle;
private String title;
private String description;
private String departament;
private String otherMobile;
private String otherHomePhone;
private String telephoneNumber;
private String facsimileTelephoneNumber;
private String postalAddress;
private String postalCode;
private String st;
private String owner;
private String serialNumber;
private String usuarioMaster;
private Integer lockoutTime;
private Integer lockoutDuration;
private Integer lockoutThreshold;
private Integer badPwdCount;
private String badPasswordTime;
private String oU;
private Integer enabled;
private String eventCod;
private String bankCod;
private String curCod;
}

View File

@ -30,9 +30,6 @@ public class SecurityTraceClient implements SecurityTraceUseCase {
@Override
public <T> T execute(Class<T> responseType) {
SecurityTraceRequest body = securityTraceConfig.getRequest();
log.info("Ejecutando traza de seguridad: {}", body);
HttpRequest request = HttpRequest.builder()
.url(securityTraceConfig.getUrl())
.method(HttpRequest.HttpMethod.POST)
@ -60,7 +57,6 @@ public class SecurityTraceClient implements SecurityTraceUseCase {
throw e;
} catch (Exception e) {
log.error("Error ejecutando traza de seguridad: {}", e.getMessage());
throw HttpStatusCodeException.serviceUnavailable("503");
}
}

View File

@ -37,9 +37,6 @@ public class ServiceStatusClient implements ServiceStatusUseCase {
.transactionId(params.getTransactionId())
.bankService(serviceStatusConfig.getRequest().getBankService())
.build();
log.info("Ejecutando verificación de estado del servicio: {}", body);
HttpRequest request = HttpRequest.builder()
.url(serviceStatusConfig.getUrl())
.method(HttpRequest.HttpMethod.POST)
@ -67,7 +64,6 @@ public class ServiceStatusClient implements ServiceStatusUseCase {
throw e;
} catch (Exception e) {
log.error("Error ejecutando verificación de estado del servicio: {}", e.getMessage());
throw HttpStatusCodeException.serviceUnavailable("503");
}
}

View File

@ -15,6 +15,6 @@ api:
key: 'busLogalCustomerProductDirectory'
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"},{"backend_code":"VRN04","http_code":"503","status_code":"VRN04","description":"Servicio en horario de mantenimiento","status":"error"},{"backend_code":"204","http_code":"200","status_code":"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}/{appId}/{customerReferenceFintechId}","timeout":{"connect":20000,"response":20000}}'
dom-legal-customer-product-directory: '{"url":"http://localhost:8083/dom-legal-customer-product-directory/retrieve/{customerIbsNumber}","timeout":{"connect":20000,"response":20000}}'
security-trace: '{"url":"http://api-register-security-route-apis-banesco-dev.apps.desplakur3.desintra.banesco.com/register-security/save","timeout":{"connect":20000,"response":20000},"request":{"sp":"spAPI_Traza","eventCod":"CANCTARJ","bankCod":"01","curCod":"BS"}}'
service-status: '{"url":"http://api-get-service-status-route-apis-banesco-dev.apps.desplakur3.desintra.banesco.com/service/status","timeout":{"connect":20000,"response":20000},"request":{"applicationId": "","transactionId": "","bankService": {"bankCode": "01","serviceCode": "APIFI","eventCode": "P2PVUEL"}}}'