155 lines
5.0 KiB
Java
155 lines
5.0 KiB
Java
package com.banesco.common.infraestructure.helpers;
|
|
|
|
import com.banesco.common.domain.dto.bian.device.BianDevice;
|
|
import com.banesco.common.domain.model.Device;
|
|
import com.banesco.common.infraestructure.config.DeviceTypeValues;
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import java.util.Objects;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Stream;
|
|
|
|
public class DeviceHelper {
|
|
|
|
private boolean readDeviceFromRequest;
|
|
private final String DESKTOP = "Desktop";
|
|
private static final Logger logger = Logger.getLogger(DeviceHelper.class.getName());
|
|
/**
|
|
* Nombres de cabeceras HTTP que pueden contener la dirección IP del
|
|
* cliente. Se revisan en orden para encontrar la IP real considerando
|
|
* proxies y balanceadores.
|
|
*/
|
|
private 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"
|
|
};
|
|
|
|
public DeviceHelper() {
|
|
// Lee la propiedad del sistema. Si no existe, asume false por defecto.
|
|
String readDeviceProperty = System.getProperty("api.server-request.read-device");
|
|
this.readDeviceFromRequest = readDeviceProperty == null ? false : Boolean.parseBoolean(readDeviceProperty);
|
|
}
|
|
|
|
/**
|
|
* Obtiene la dirección IP remota del cliente a partir de la solicitud HTTP.
|
|
* Revisa varias cabeceras HTTP que podrían contener la IP real del cliente
|
|
* considerando proxies y balanceadores de carga.
|
|
*
|
|
* @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 (!StringHelper.isEmpty(ipList) && !"unknown".equalsIgnoreCase(ipList)) {
|
|
return ipList.split(",")[0];
|
|
}
|
|
}
|
|
|
|
return request.getRemoteAddr();
|
|
}
|
|
|
|
/**
|
|
* Llena la información del dispositivo remoto del cliente en el objeto
|
|
* Device. Si se configura readDeviceFromRequest como true, siempre se
|
|
* obtendrá la información del dispositivo desde la solicitud HTTP,
|
|
* independientemente de si ya existe.
|
|
*
|
|
* @param servletRequest La solicitud HTTP
|
|
* @param device El objeto Device existente a actualizar o null para crear
|
|
* uno nuevo
|
|
* @return El objeto Device con la información del cliente actualizada
|
|
*/
|
|
public Device fillRemoteDevice(HttpServletRequest servletRequest, Device device) {
|
|
if (device == null) {
|
|
device = new Device();
|
|
}
|
|
if (StringHelper.isEmpty(device.getIpAddress()) || readDeviceFromRequest) {
|
|
device.setIpAddress(getRemoteIP(servletRequest));
|
|
String userAgent = servletRequest.getHeader("user-agent");
|
|
if (userAgent == null) {
|
|
|
|
device.setType(DESKTOP);
|
|
device.setDescription(DESKTOP);
|
|
} else {
|
|
device.setDescription(userAgent);
|
|
if (userAgent.toLowerCase().contains("mobi")) {
|
|
device.setType("Mobile");
|
|
} else {
|
|
device.setType(DESKTOP);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return device;
|
|
}
|
|
|
|
/**
|
|
* Mapea el tipo de dispositivo desde el objeto BianDevice al enum DeviceTypeValues.
|
|
*
|
|
* @param device
|
|
* @return
|
|
*/
|
|
public static DeviceTypeValues getDeviceTypeValue(
|
|
BianDevice device
|
|
) {
|
|
var deviceTypeValue = DeviceTypeValues.Unknown;
|
|
|
|
if (!Objects.isNull(device) && !StringHelper.isEmpty(device.getDeviceType())) {
|
|
try {
|
|
deviceTypeValue = DeviceTypeValues.valueOf(device.getDeviceType());
|
|
} catch (Exception e) {
|
|
logger.log(Level.WARNING, "Error Mapping Device Type: %s -> %s".formatted(device.getDeviceType(), e.getMessage()));
|
|
}
|
|
}
|
|
|
|
return deviceTypeValue;
|
|
}
|
|
|
|
/**
|
|
* Valida si el tipo de dispositivo es válido según el enum DeviceTypeValues.
|
|
*
|
|
* @param type
|
|
* @return
|
|
*/
|
|
public static boolean isValidDeviceType(String type) {
|
|
|
|
for (DeviceTypeValues deviceType : DeviceTypeValues.values()) {
|
|
if (deviceType.name().equals(type)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Obtiene una cadena con todos los tipos de dispositivos válidos.
|
|
*
|
|
* @return
|
|
*/
|
|
public static String getDeviceTypes() {
|
|
return Stream.of(DeviceTypeValues.values()).map(Enum::name).collect(
|
|
Collectors.joining(", ")
|
|
);
|
|
}
|
|
|
|
}
|
|
|