diff --git a/pom.xml b/pom.xml index f64012a..2706903 100644 --- a/pom.xml +++ b/pom.xml @@ -32,5 +32,10 @@ commons-lang3 3.13.0 + + javax.servlet + javax.servlet-api + 4.0.1 provided + diff --git a/src/main/java/com/banesco/App.java b/src/main/java/com/banesco/App.java index aa92054..eb77a38 100644 --- a/src/main/java/com/banesco/App.java +++ b/src/main/java/com/banesco/App.java @@ -1,7 +1,6 @@ package com.banesco; import com.banesco.domain.model.BackResponse; -import com.banesco.util.StringUtil; /** @@ -11,9 +10,6 @@ import com.banesco.util.StringUtil; public class App { public static void main( String[] args ) { - boolean value = StringUtil.isNumeric("45"); - System.out.println(value); - BackResponse backResponse = BackResponse.builder() .backendCode("200") .httpCode("420") diff --git a/src/main/java/com/banesco/domain/model/Device.java b/src/main/java/com/banesco/domain/model/Device.java index 041c03b..9035a01 100644 --- a/src/main/java/com/banesco/domain/model/Device.java +++ b/src/main/java/com/banesco/domain/model/Device.java @@ -3,7 +3,7 @@ package com.banesco.domain.model; public class Device { private final String type; - private final Integer description; + private final String description; private final String ipAddress; private Device(Builder builder) { @@ -16,7 +16,7 @@ public class Device { return type; } - public Integer getDescription() { + public String getDescription() { return description; } @@ -26,7 +26,7 @@ public class Device { public static class Builder { private String type; - private Integer description; + private String description; private String ipAddress; public Builder() {} @@ -36,7 +36,7 @@ public class Device { return Builder.this; } - public Builder description(Integer description) { + public Builder description(String description) { this.description = description; return Builder.this; } diff --git a/src/main/java/com/banesco/infraestructure/helpers/DateHelper.java b/src/main/java/com/banesco/infraestructure/helpers/DateHelper.java new file mode 100644 index 0000000..a250150 --- /dev/null +++ b/src/main/java/com/banesco/infraestructure/helpers/DateHelper.java @@ -0,0 +1,55 @@ +package com.banesco.infraestructure.helpers; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class DateHelper { + + private static final Logger logger = Logger.getLogger(DateHelper.class.getName()); + private static final String TIME_FORMAT = "HH:mm"; + + /** + * Verifica si la hora actual está dentro del rango de horas proporcionado. + * Si las horas de inicio y fin son iguales, devuelve false. + * + * @param inputHourOne Hora de inicio (formato HH:mm). + * @param inputHourTwo Hora de fin (formato HH:mm). + * @return true si la hora actual está dentro del rango, false de lo + * contrario. + * @throws ParseException Si ocurre un error al analizar las horas. + */ + public static boolean isTimeInRange(String inputHourOne, String inputHourTwo) throws ParseException { + if (inputHourOne.equals(inputHourTwo)) { + return false; + } + + DateFormat dateFormat = new SimpleDateFormat(TIME_FORMAT); + Date now = new Date(); + Date beginTime = dateFormat.parse(inputHourOne); + Date endTime = dateFormat.parse(inputHourTwo); + Date currentTime = dateFormat.parse(dateFormat.format(now)); + + long beginMillis = beginTime.getTime(); + long endMillis = endTime.getTime(); + long currentMillis = currentTime.getTime(); + + boolean isInRange; + + if (beginMillis > endMillis) { + // Rango que cruza la medianoche + isInRange = currentMillis >= beginMillis || currentMillis <= endMillis; + } else { + // Rango dentro del mismo día + isInRange = currentMillis >= beginMillis && currentMillis <= endMillis; + } + + String currentHourStr = dateFormat.format(now); + logger.log(Level.INFO, "La hora {0}{1}entre {2} y {3}", new Object[]{currentHourStr, isInRange ? " está " : " NO está ", inputHourOne, inputHourTwo}); + + return isInRange; + } +} diff --git a/src/main/java/com/banesco/infraestructure/helpers/JsonHelper.java b/src/main/java/com/banesco/infraestructure/helpers/JsonHelper.java new file mode 100644 index 0000000..a41120b --- /dev/null +++ b/src/main/java/com/banesco/infraestructure/helpers/JsonHelper.java @@ -0,0 +1,62 @@ +package com.banesco.infraestructure.helpers; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JsonHelper { + + private static final Logger logger = Logger.getLogger(JsonHelper.class.getName()); + private static final ObjectMapper MAPPER = new ObjectMapper(); + + static { + MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } + + /** + * Convierte un objeto Java en una cadena JSON. + * + * @param object El objeto a convertir en JSON. + * @return La cadena JSON resultante o null si ocurre un error. + * @throws JsonProcessingException si hay algún error al convertir el objeto + * a JSON + */ + public static String getJsonFromObject(Object object) { + if (object == null) { + return "null"; + } + try { + return MAPPER.writeValueAsString(object); + } catch (JsonProcessingException e) { + logger.log(Level.SEVERE, "Error al convertir objeto a JSON: {0}", e.getMessage()); + return null; + } + } + + /** + * Convierte una cadena JSON en un objeto Java de la clase especificada. + * + * @param json La cadena JSON a convertir. + * @param className La clase del objeto Java resultante. + * @param El tipo del objeto resultante. + * @return El objeto Java resultante, o null si ocurre un error o la cadena + * JSON está vacía. + * @throws JsonProcessingException Si ocurre un error al procesar JSON. + * @throws IllegalArgumentException Si alguno de los argumentos no es + * válido. + */ + public static T getObjectFromJson(String json, Class className) { + if (json == null || json.isEmpty()) { + return null; + } + try { + return MAPPER.readValue(json, className); + } catch (JsonProcessingException | IllegalArgumentException e) { + logger.log(Level.WARNING, "Error al convertir JSON a objeto: {0}", e.getMessage()); + return null; + } + } +} diff --git a/src/main/java/com/banesco/infraestructure/helpers/LoggerHelper.java b/src/main/java/com/banesco/infraestructure/helpers/LoggerHelper.java new file mode 100644 index 0000000..13602fa --- /dev/null +++ b/src/main/java/com/banesco/infraestructure/helpers/LoggerHelper.java @@ -0,0 +1,65 @@ +package com.banesco.infraestructure.helpers; + +public class LoggerHelper { + + /** + * Construye una cadena de información para una solicitud pública. + * + * @param requestId El ID de la solicitud. + * @param request El objeto de solicitud. + * @param El tipo del objeto de solicitud. + * @return Una cadena de información formateada. + */ + public String buildInfoRequest(String requestId, T request) { + return String.format("[RQ PUB: %s] [%s]", requestId, JsonHelper.getJsonFromObject(request)); + } + + /** + * Construye una cadena de información para una respuesta pública. + * + * @param requestId El ID de la solicitud. + * @param response El objeto de respuesta. + * @param El tipo del objeto de respuesta. + * @return Una cadena de información formateada. + */ + public String buildInfoResponse(String requestId, T response) { + return String.format("[RS PUB: %s] [%s]", requestId, JsonHelper.getJsonFromObject(response)); + } + + /** + * Construye una cadena de información para una solicitud privada. + * + * @param requestId El ID de la solicitud. + * @param name El nombre de la solicitud privada. + * @param request El objeto de solicitud. + * @param El tipo del objeto de solicitud. + * @return Una cadena de información formateada. + */ + public String buildInfoPrivateRequest(String requestId, String name, T request) { + return String.format("[RQ PRV %s: %s] [%s]", name, requestId, JsonHelper.getJsonFromObject(request)); + } + + /** + * Construye una cadena de información para una respuesta privada. + * + * @param requestId El ID de la solicitud. + * @param name El nombre de la respuesta privada. + * @param response El objeto de respuesta. + * @param El tipo del objeto de respuesta. + * @return Una cadena de información formateada. + */ + public String buildInfoPrivateResponse(String requestId, String name, T response) { + return String.format("[PRV RS %s: %s] [%s]", name, requestId, JsonHelper.getJsonFromObject(response)); + } + + /** + * Construye una cadena de error. + * + * @param requestId El ID de la solicitud asociada al error. + * @param out El mensaje de error. + * @return Una cadena de error formateada. + */ + public String buildError(String requestId, String out) { + return String.format("[ERROR %s] [%s]", requestId, out); + } +} diff --git a/src/main/java/com/banesco/infraestructure/helpers/RequestHelper.java b/src/main/java/com/banesco/infraestructure/helpers/RequestHelper.java new file mode 100644 index 0000000..80aaa4c --- /dev/null +++ b/src/main/java/com/banesco/infraestructure/helpers/RequestHelper.java @@ -0,0 +1,113 @@ +package com.banesco.infraestructure.helpers; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.StringUtils; + +import com.banesco.domain.model.Device; + +public class RequestHelper { + + private final boolean readDeviceFromRequest; + private static final String[] IP_HEADER_NAMES = { + "X-Forwarded-For", + "Proxy-Client-IP", + "WL-Proxy-Client-IP", + "HTTP_X_FORWARDED_FOR", + "HTTP_X_FORWARDED", + "HTTP_X_CLUSTER_CLIENT_IP", + "HTTP_CLIENT_IP", + "HTTP_FORWARDED_FOR", + "HTTP_FORWARDED", + "HTTP_VIA", + "REMOTE_ADDR" + }; + + /** + * Constructor de RequestHelper. Lee la propiedad de configuracion + * 'api.server-request.read-device' de las propiedades del sistema + */ + public RequestHelper() { + // Lee la propiedad del sistema. Si no existe, asume false por defecto. + String readDeviceProperty = System.getProperty("api.server-request.read-device"); + this.readDeviceFromRequest = Boolean.parseBoolean(readDeviceProperty); + } + + /** + * Genera un ID de instancia único. + * + * @return Un ID de instancia con el prefijo "INST". + */ + public String getInstanceId() { + return "INST" + RandomStringUtils.randomAlphanumeric(10); + } + + /** + * Genera un ID de solicitud único basado en el ID de instancia. + * + * @param instanceId El ID de la instancia. + * @return Un ID de solicitud con el prefijo "REQ". + */ + public String getRequestId(String instanceId) { + return instanceId + "REQ" + RandomStringUtils.randomAlphanumeric(20); + } + + /** + * Genera un ID de solicitud único. + * + * @return Un ID de solicitud con el prefijo "REQ". + */ + public String getRequestId() { + return getInstanceId() + "REQ" + RandomStringUtils.randomAlphanumeric(20); + } + + /** + * Obtiene la dirección IP remota del cliente a partir de la solicitud HTTP. + * + * @param request La solicitud HTTP. + * @return La dirección IP remota del cliente, o "0.0.0.0" si la solicitud + * es nula. + */ + public String getRemoteIP(HttpServletRequest request) { + if (request == null) { + return "0.0.0.0"; + } + + for (String header : IP_HEADER_NAMES) { + String ipList = request.getHeader(header); + if (StringUtils.isNotBlank(ipList) && !"unknown".equalsIgnoreCase(ipList)) { + return ipList.split(",")[0]; + } + } + + return request.getRemoteAddr(); + } + + /** + * Llena la información del dispositivo remoto del cliente en el objeto + * Device. + * + * @param servletRequest La solicitud HTTP. + * @param device El objeto Device a llenar. + * @return El objeto Device llenado con la información del cliente. + */ + public Device fillRemoteDevice(HttpServletRequest servletRequest, Device device) { + Device.Builder deviceBuilder = (device == null) ? Device.builder() : Device.builder() + .ipAddress(device.getIpAddress()) + .description(device.getDescription()) + .type(device.getType()); + + if (device == null || StringUtils.isEmpty(device.getIpAddress()) || readDeviceFromRequest) { + String remoteIP = getRemoteIP(servletRequest); + String userAgent = servletRequest.getHeader("user-agent"); + String deviceType = StringUtils.containsIgnoreCase(userAgent, "Mobi") ? "Mobile" : "Desktop"; + + deviceBuilder.ipAddress(remoteIP) + .description(userAgent) + .type(deviceType); + } + + return deviceBuilder.build(); + } +} diff --git a/src/main/java/com/banesco/infraestructure/helpers/StringHelper.java b/src/main/java/com/banesco/infraestructure/helpers/StringHelper.java new file mode 100644 index 0000000..1bea2ae --- /dev/null +++ b/src/main/java/com/banesco/infraestructure/helpers/StringHelper.java @@ -0,0 +1,50 @@ +package com.banesco.infraestructure.helpers; + +import org.apache.commons.lang3.StringUtils; + +public class StringHelper { + + /** + * Verifica si una cadena de texto representa un número entero. + * + * @param value La cadena de texto a verificar. + * @return true si la cadena es un número entero válido, false en caso + * contrario. + * @throws NumberFormatException Si el string no tiene el formato adeacuado + */ + public static boolean isNumeric(String value) { + if (value == null || value.isEmpty()) { + return false; + } + try { + Integer.parseInt(value); + return true; + } catch (NumberFormatException e) { + return false; + } + } + + /** + * Verifica si una cadena de texto no es nula y no está vacía después de + * eliminar espacios en blanco. + * + * @param value La cadena de texto a verificar. + * @return true si la cadena no está vacía, false en caso contrario. + */ + public static boolean isNotEmpty(String value) { + return value != null && !value.trim().isEmpty(); + } + + /** + * Rellena una cadena de texto con un carácter específico a la izquierda + * hasta alcanzar la longitud deseada. + * + * @param numberStr La cadena de texto a rellenar. + * @param strLen La longitud deseada de la cadena resultante. + * @param c El carácter de relleno. + * @return La cadena rellenada con el carácter especificado a la izquierda. + */ + public static String leftPad(String numberStr, int strLen, Character c) { + return StringUtils.leftPad(numberStr, strLen, c); + } +} diff --git a/src/main/java/com/banesco/util/JsonUtil.java b/src/main/java/com/banesco/util/JsonUtil.java deleted file mode 100644 index 050e519..0000000 --- a/src/main/java/com/banesco/util/JsonUtil.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.banesco.util; - -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; - -public class JsonUtil { - private static final Logger LOGGER = Logger.getLogger(JsonUtil.class.getName()); - - private static boolean mustInit = true; - - public static final ObjectMapper MAPPER = new ObjectMapper(); - - public static String getJsonFromObject(Object object) { - try { - return MAPPER.writeValueAsString(object); - } catch (JsonProcessingException e) { - LOGGER.log(Level.INFO, "Object To Json Exception: {}", e.getMessage()); - } - return null; - } - - public static T getObjectFromJson(String json, Class className) { - if (StringUtil.isNotEmpty(json)) { - try { - if (mustInit) { - mustInit = false; - MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - } - - return MAPPER.readValue(json, className); - } catch (JsonProcessingException | IllegalArgumentException e) { - LOGGER.log(Level.INFO, "JSON to Object Exception: {}", e.getMessage()); - } - } - return null; - } -} diff --git a/src/main/java/com/banesco/util/StringUtil.java b/src/main/java/com/banesco/util/StringUtil.java deleted file mode 100644 index e5facd7..0000000 --- a/src/main/java/com/banesco/util/StringUtil.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.banesco.util; - - -import org.apache.commons.lang3.StringUtils; - -public class StringUtil { - - public static boolean isNumeric(String value) { - try { - Integer.valueOf(value); - return true; - } catch (NumberFormatException e) { - return false; - } - } - - public static boolean isNotEmpty(String value) { - return value != null && !value.trim().isEmpty(); - } - - public static String leftPad(String numberStr, int strLen, Character c) { - return StringUtils.leftPad(numberStr,strLen,c); - } -}