From 63cadcaf7236dc3cce67ab614289d1711ee08f3b Mon Sep 17 00:00:00 2001 From: jaguerrau <143662442+jaguerrau@users.noreply.github.com> Date: Tue, 28 Oct 2025 21:04:31 -0600 Subject: [PATCH] Add files via upload --- README.md | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..361f446 --- /dev/null +++ b/README.md @@ -0,0 +1,177 @@ +# Servidor jRDC2-Multi Mod (B4J) + +## 1. Introducción y Arquitectura (HikariCP) + +Este proyecto es una versión modificada del servidor [jRDC2 original](https://www.b4x.com/android/forum/threads/b4x-jrdc2-b4j-implementation-of-rdc-remote-database-connector.61801/#content) con dos cambios principales: + +* Se migró el pool de conexiones de **C3P0 a HikariCP (v4.0.3)**, reconocido por ser más rápido y eficiente. Esta migración fue posible gracias al código base adaptado del trabajo presentado en [este hilo del foro](https://www.b4x.com/android/forum/threads/heavily-modified-jrdc2-testing-server-code-dump.128258/). +* Se añadió un nuevo *handler* que acepta peticiones y devuelve respuestas en formato `JSON`, permitiendo la conexión desde clientes web (`JavaScript, NodeJS, React, Vue, Angular, etc`.), además de los clientes nativos (`B4A/B4i`). + + +## 2. Características Principales + +* **Pool de Conexiones de Alto Rendimiento:** Migración completa y consolidada a HikariCP. +* **Soporte para Múltiples Bases de Datos Dinámicas:** El servidor puede cargar y gestionar un número "ilimitado" de configuraciones (`config.XXX.properties`) simultáneamente, dependiendo este número únicamente de los recursos del hardware. +* **Doble Handler de Peticiones**: Incluye un handler clásico para clientes B4X y un handler JSON para clientes web. +* **Validaciones de Seguridad**: Verifica la existencia de comandos sql y la correspondencia en el número de parámetros antes de la ejecución. +* **Gestión de Configuración en Caliente (Hot-Swap Granular):** El comando `reload` permite recargar la configuración de cada base de datos por separado y de forma segura, sin necesidad de reiniciar el servidor. +* **Monitoreo Avanzado:** Se exponen métricas precisas del pool (Busy Connections, Total Connections) y de la aplicación (Active Requests), capturadas justo después de la adquisición de la conexión para garantizar la fiabilidad del diagnóstico. +* **Administración Remota**: Permite verificar el estado, recargar la configuración y reiniciar el servidor a través de URLs específicas, con un sistema de autenticación. +* **Tolerancia de Parámetros Configurable:** La propiedad `parameterTolerance=1` permite recortar parámetros sobrantes en un query, registrando una advertencia en lugar de forzar un error. +* **Comandos SQL Externalizados:** Las sentencias SQL se definen en los archivos de configuración (`.properties`). + +## 3. Configuración + +### 3.1. Archivos de Configuración (Nomenclatura Dinámica) + +El servidor detecta y carga cualquier archivo que siga el patrón `config.XXX.properties`. La porción `XXX` se convierte en la clave de conexión (DBKey) en mayúsculas. + +| Archivo | Clave de Conexión (DBKey) | +| :--- | :--- | +| `config.properties` | `DB1` (Por defecto) | +| `config.mi_cliente.properties` | `MI_CLIENTE` | + +**Notas importantes:** + * El **puerto** del servidor se toma **únicamente** del archivo principal `config.properties`, sin importar lo que digan los demás. + * Los datos de conexión (`JdbcUrl`, `usuario`, `contraseña`) sí se toman del archivo correspondiente a cada base de datos. + +### 3.2. Configuración del Pool y del Driver + +Advertencia Técnica: Solo los parámetros listados a continuación están explícitamente mapeados y soportados en la lógica de SetProperties del wrapper B4J. Cualquier otra propiedad de HikariCP que no esté en esta lista será ignorada por el código del servidor. + +Todas las propiedades de HikariCP para tuning deben ser prefijadas con pool.hikari. Todos los valores de tiempo se expresan en milisegundos (ms). + +* #### Configuración del Pool (Parámetros Soportados) + + | Parámetro | Tipo | Valor Por Defecto (Código) | Descripción Técnica y Recomendación | + | :--- | :--- | :--- | :--- | + | maximumPoolSize | INT | 10 | Límite máximo de conexiones. Debe basarse en los recursos del servidor de la DB (aprox. (Núcleos DB * 2) + Husillos). | + | minimumIdle | INT | Igual a maximumPoolSize | Axioma de Pool Fijo. Recomendado igualarlo a maximumPoolSize para eliminar la inestabilidad del pool (thrashing). | + | maxLifetime | LONG | 1,750,000 ms (30 min) | CRÍTICO. Tiempo máximo de vida de una conexión. Debe ser menor que el timeout del firewall/DB para prevenir conexiones zombis (stale). | + | keepalivetime | LONG | 300,000 ms (5 min) | Frecuencia de "ping" a conexiones inactivas. Actúa para evitar que la infraestructura mate la conexión por inactividad. | + | connectionTimeout | LONG | 30,000 ms (30 seg) | Tiempo máximo de espera del cliente por una conexión disponible. Se recomienda un valor bajo para fail-fast. | + | leakDetectionThreshold | LONG | 35,000 ms | Diagnóstico. Umbral de tiempo que una conexión puede estar retenida. SOLO avisa, no recupera la conexión. | + | idletimeout | LONG | 600,000 ms (10 min) | Tiempo inactivo antes de retirar la conexión. Solo se aplica si minimumIdle < maximumPoolSize. | + | initializationfailtimeout | INT | 1 | Tiempo para adquirir la primera conexión. Recomendado 1 (o mayor) para fail-fast. | + | validationtimeout | INT | 5,000 ms (5 seg) | Tiempo máximo que se le da a una prueba de vida. | + | autocommit | BOOLEAN | true | Controla el comportamiento por defecto de auto-commit. | + | poolname | STRING | Auto-generado | Nombre definido por el usuario para el pool. | + | connectiontestquery | STRING | none | Consulta para validar la conexión. (Usar solo si el driver NO soporta JDBC4). | + | registermbeans | BOOLEAN | true | Controla si los Management Beans (MBeans) de JMX se registran. | + | isolateinternalqueries | BOOLEAN | false | Propiedad avanzada. | + | allowpoolsuspension | BOOLEAN | false | Propiedad avanzada. | + | readonly | BOOLEAN | false | Indica si las conexiones se obtienen en modo solo lectura. | + | connectioninitsql | STRING | none | SQL que se ejecuta al establecer una nueva conexión. | + +--- + + +* #### Configuración del Driver (Crucial para Rendimiento): + Para optimizaciones a bajo nivel (ej., Statement Caching), se debe definir `DriverShortName` y usar el prefijo `driver.SHORTNAME.` en las propiedades. + + ```properties + DriverShortName=mysql + driver.mysql.cachePrepStmts=true + ``` + +## 4. Validaciones de Seguridad y Parámetros + +1. **Verificación de Existencia del Comando**: El servidor comprueba que el nombre del comando SQL solicitado (ej. `"get_user"`) exista como una clave válida en el archivo `.properties` correspondiente. Si no lo encuentra, devolverá un error y no intentará ejecutar nada. + +2. **Conteo de Parámetros**: Si el comando SQL en el archivo de configuración espera parámetros (contiene `?`), el servidor cuenta cuántos son y lo compara con el número de parámetros recibidos en la petición. Si las cantidades no coinciden, devolverá un error específico, evitando una ejecución fallida en la base de datos. + +3. **Tolerancia de Parámetros**: Implementa tolerancia de parámetros **configurable**, esto permite que si un query requiere 3 parametros y se mandan 4, NO mande un error, solo manda a la base de datos los parametros correctos y tira los extras, y guarda una "ADVERTENCIA" en el Log de errores. + + * `parameterTolerance=0` (Estricto): Rechaza peticiones si el número de parámetros recibidos es mayor al esperado. + * `parameterTolerance=1` (Tolerante): Recorta los parámetros sobrantes para ajustarse al SQL y registra una advertencia. + +Estas validaciones aseguran que el desarrollador reciba feedback inmediato y claro si una petición está mal formada. + +## **5. Uso del Handler Clásico (Para Clientes B4X)** + +Este handler mantiene la compatibilidad con `DBRequestManager`. La selección de la base de datos se realiza dinámicamente a través de la URL. + + * Para `config.properties` =\> `http://tu-dominio.com:8090` + * Para `config.CLIENT2.properties` =\> `http://tu-dominio.com:8090/CLIENT2` + * Para `config.DB2.properties` =\> `http://tu-dominio.com:8090/DB2` + * Para `config.TEST.properties` =\> `http://tu-dominio.com:8090/TEST` + +## 6. **Uso del DBHandlerJSON (Para Clientes Web)** + +Este handler está diseñado para clientes que se comunican vía `JSON`, como aplicaciones web JavaScript. + +### **6.1. Endpoint y Métodos de Envío** + +Las peticiones van dirigidas al endpoint `/DBJ`. El handler es flexible y acepta datos de dos maneras: + +**Método Recomendado: POST con Body JSON** + + * **Método HTTP**: POST + * **URL**: `http://tu-dominio.com:8090/DBJ` + * **Header Requerido**: `Content-Type: application/json` + * **Body (Payload)**: El objeto JSON se envía directamente en el cuerpo de la petición. + +**Ejemplo de Body:** + +```json +{ + "dbx": "DB2", + "query": "get_user", + "exec": "executeQuery", + "params": [ + "CDAZA" + ] +} +``` + +**Método Legacy: GET con Parámetro `j`** + + * **Método HTTP**: GET + * **URL**: El JSON completo se envía como el valor del parámetro `j` en la URL. + +**Ejemplo con GET:** +`http://tu-dominio.com:8090/DBJ?j={"dbx":"DB2","query":"get_user","exec":"executeQuery","params":["CDAZA"]}` + +### **6.2. Formato del Payload JSON** + +La estructura del objeto JSON es la misma para ambos métodos: + +```json +{ + "exec": "executeQuery", + "query": "nombre_del_comando_sql", + "dbx": "DB1", + "params": [ + "valor1", + 123 + ] +} +``` + + * `exec`: `"executeQuery"` (para `SELECT`) o `"executeCommand"` (para `INSERT`, `UPDATE`, `DELETE`). + * `query`: Nombre del comando SQL tal como está definido en el archivo de configuración. + * `dbx` (opcional): La llave de la base de datos (`DB1`, `DB2`, etc.). Si se omite, se usará **DB1**. + * `params` (opcional): Un **array** que contiene los parámetros para la consulta SQL, en el orden exacto que se esperan. + +### **6.3. Respuestas JSON** + +Las respuestas del servidor siempre son en formato JSON e incluyen un campo booleano `success`. + + * **Si `success` es `true`**, los datos se encontrarán en la llave `result`. + * **Si `success` es `false`**, el mensaje de error se encontrará en la llave `error`. + +## 7. Administración del Servidor + +### 7.1. Comandos Protegidos (Recarga Hot-Swap) **(requiere autenticación)** + +La recarga granular permite actualizar un único conector sin afectar a los demás. + +* **Recarga Completa**: /manager?command=reload + +* **Recarga Selectiva**: /manager?command=reload&db=DBKEY (ej. DB2 o CLIENTE_A) + +### 7.2. Comandos de Monitoreo + +* **Verificar Conectividad**: /manager?command=test (Fuerza la adquisición/liberación de una conexión en todos los pools para verificar su estado de vida, implementando el mecanismo fail-fast). + +* **Configuración Detallada**: /manager?command=getconfiginfo (Muestra la configuración real de HikariCP aplicada y las Propiedades de Driver para diagnóstico de tuning). \ No newline at end of file