Add files via upload

This commit is contained in:
jaguerrau
2025-10-28 21:04:31 -06:00
committed by GitHub
commit 63cadcaf72

177
README.md Normal file
View File

@@ -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).