- VERSION 5.09.16

- feat: Implementa tolerancia de parámetros configurable y mejora estabilidad general del servidor.
- La tolerancia de parametros 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.

- Este commit introduce la funcionalidad de `parameterTolerance` configurable y aborda varias mejoras críticas para la estabilidad y eficiencia del jRDC2-Multi.

- Principales cambios y beneficios:
- **Tolerancia de Parámetros**: Añade la propiedad `parameterTolerance` en `config.properties` para controlar el manejo de parámetros de más. Cuando está habilitada, recorta los parámetros excesivos; si está deshabilitada (modo estricto, por defecto), genera un error, aumentando la robustez de la validación.
- **Inicialización Multi-DB Confiable**: Corrige la lógica de inicialización en `Main.AppStart` para `RDCConnector` de DB3 y DB4, asegurando que cada base de datos tenga su propio *pool* de conexiones correctamente configurado.
- **Optimización de Ejecución SQL**: Elimina llamadas duplicadas a `ExecQuery2` y `ExecNonQuery2` en `DBHandlerB4X.bas`, garantizando que solo los parámetros validados se utilicen y evitando ejecuciones redundantes en la base de datos.
- **Refactorización y Limpieza**: Se eliminó la declaración duplicada de `ActiveRequestsCountByDB` en `Main.bas` y la subrutina `Handle0` obsoleta en `Manager.bas`, mejorando la claridad y mantenibilidad del código.
This commit is contained in:
2025-09-18 22:30:22 -06:00
parent 51c829b876
commit 3b352bb105
14 changed files with 537 additions and 466 deletions

View File

@@ -154,14 +154,14 @@ Sub Handle(req As ServletRequest, resp As ServletResponse)
Dim newPoolStats As Map = newRDC.GetPoolStats
sbTemp.Append($" -> ${dbKey}: Nuevo conector inicializado. Conexiones: ${newPoolStats.Get("TotalConnections")}"$).Append("<br>" & CRLF)
Catch
sbTemp.Append($" -> ERROR CRÍTICO al inicializar nuevo conector para ${dbKey}: ${LastException.Message}"$).Append("<br>" & CRLF)
reloadSuccessful = False
Exit ' Si uno falla, abortamos la recarga completa para evitar un estado inconsistente.
End Try
Next
sb.Append(sbTemp.ToString) ' Añadimos los logs acumulados de la inicialización al StringBuilder principal.
If reloadSuccessful Then
@@ -380,112 +380,3 @@ Sub Handle(req As ServletRequest, resp As ServletResponse)
If GlobalParameters.mpLogs.IsInitialized Then GlobalParameters.mpLogs.Put(Command, "Manager : " & Command & " - Time : " & DateTime.Time(DateTime.Now))
End Sub
Sub Handle0(req As ServletRequest, resp As ServletResponse)
' 1. --- Bloque de Seguridad (se mantiene igual) ---
If req.GetSession.GetAttribute2("user_is_authorized", False) = False Then
resp.SendRedirect("/login")
Return
End If
Dim Command As String = req.GetParameter("command")
If Command = "" Then Command = "ping"
Log($"Command: ${Command}"$)
resp.ContentType = "text/html"
' 2. --- Construimos la ESTRUCTURA de la página ---
Dim sb As StringBuilder
sb.Initialize
' Estilos para la página
sb.Append("<html><head><style>")
sb.Append("body {font-family: sans-serif; margin: 2em; background-color: #f9f9f9;} ")
sb.Append("h1, h2 {color: #333;} hr {margin: 2em 0; border: 0; border-top: 1px solid #ddd;} ")
sb.Append("form {background: #f0f0f0; padding: 1.5em; border-radius: 8px; max-width: 400px; margin-bottom: 2em;} ")
sb.Append("input {display: block; width: 95%; padding: 8px; margin-bottom: 10px; border: 1px solid #ccc; border-radius: 4px;} ")
sb.Append("button {padding: 10px 15px; border: none; background-color: #007bff; color: white; cursor: pointer; border-radius: 4px;} ")
sb.Append(".nav a, .logout a {text-decoration: none; margin-right: 10px; color: #007bff;} ")
sb.Append(".output {background: #fff; padding: 1em; border: 1px solid #eee; border-radius: 8px;} ")
sb.Append("</style></head><body>")
' Cabecera y bienvenida
sb.Append("<h1>Panel de Administración jRDC</h1>")
sb.Append($"Bienvenido, <b>${req.GetSession.GetAttribute("username")}</b><br>"$)
' Menú de navegación (se define una sola vez)
sb.Append("<p class='nav'>")
sb.Append($"<a href="/test">Test</a> | <a href="/manager?command=ping">Ping</a> | <a href="/manager?command=reload">Reload</a> | <a href="/manager?command=rpm2">Reiniciar (pm2)</a> | <a href="/manager?command=reviveBow">Revive Bow</a>"$)
sb.Append("</p>")
' Formulario para cambiar contraseña
sb.Append("<hr>")
sb.Append("<h2>Cambiar Contraseña</h2>")
sb.Append("<form action='/changepass' method='post'>")
sb.Append("Contraseña Actual: <input type='password' name='current_password' required><br>")
sb.Append("Nueva Contraseña: <input type='password' name='new_password' required><br>")
sb.Append("Confirmar Nueva Contraseña: <input type='password' name='confirm_password' required><br>")
sb.Append("<button type='submit'>Actualizar Contraseña</button>")
sb.Append("</form>")
' Sección para el resultado del comando
sb.Append("<hr><h2>Resultado del Comando: '" & Command & "'</h2>")
sb.Append("<div class='output'>")
' 3. --- Lógica de TUS COMANDOS (modificada para usar sb.Append) ---
If Command = "reload" Then
Private estaDB As String = ""
For i = 0 To Main.listaDeCP.Size - 1
Main.Connectors.Get(Main.listaDeCP.get(i)).As(RDCConnector).Initialize(Main.listaDeCP.get(i))
If Main.listaDeCP.get(i) <> "DB1" Then estaDB = "." & Main.listaDeCP.get(i) Else estaDB = ""
sb.Append($"Recargando config${estaDB}.properties ($DateTime{DateTime.Now})<br/>"$)
sb.Append($"Queries en config.properties: <b>${Main.Connectors.Get(Main.listaDeCP.get(i)).As(RDCConnector).commands.Size}</b><br/>"$)
sb.Append($"<b>JdbcUrl:</b> ${Main.Connectors.Get(Main.listaDeCP.get(i)).As(RDCConnector).config.Get("JdbcUrl")}</b><br/>"$)
sb.Append($"<b>User:</b> ${Main.Connectors.Get(Main.listaDeCP.get(i)).As(RDCConnector).config.Get("User")}</b><br/>"$)
sb.Append($"<b>ServerPort:</b> ${Main.srvr.Port}</b><br/><br/>"$)
Next
else If Command = "stop" Then
' Tu código para "stop"
else If Command = "rsx" Then
Log($"Ejecutamos ${File.DirApp}\start.bat"$)
sb.Append($"Ejecutamos ${File.DirApp}\start.bat"$)
Public shl As Shell
shl.Initialize("shl","cmd",Array("/c",File.DirApp & "\start.bat " & Main.srvr.Port))
shl.WorkingDirectory = File.DirApp
shl.Run(-1)
else If Command = "rpm2" Then
Log($"Ejecutamos ${File.DirApp}\reiniciaProcesoPM2.bat"$)
sb.Append($"Ejecutamos ${File.DirApp}\reiniciaProcesoPM2.bat"$)
Public shl As Shell
shl.Initialize("shl","cmd",Array("/c",File.DirApp & "\reiniciaProcesoPM2.bat " & Main.srvr.Port))
shl.WorkingDirectory = File.DirApp
shl.Run(-1)
else If Command = "reviveBow" Then
Log($"Ejecutamos ${File.DirApp}\reiniciaProcesoBow.bat"$)
sb.Append($"Ejecutamos ${File.DirApp}\reiniciaProcesoBow.bat<br><br>"$)
sb.Append($"!!!BOW REINICIANDO!!!"$)
Public shl As Shell
shl.Initialize("shl","cmd",Array("/c",File.DirApp & "\reiniciaProcesoBow.bat " & Main.srvr.Port))
shl.WorkingDirectory = File.DirApp
shl.Run(-1)
else if Command = "totalrequests" Then
If GlobalParameters.mpTotalRequests.IsInitialized Then
j.Initialize(GlobalParameters.mpTotalRequests)
sb.Append(j.ToString)
End If
else if Command = "ping" Then
sb.Append($"Pong ($DateTime{DateTime.Now})"$)
End If
'...(aquí continuaría el resto de tus Else If)...
' 4. --- Cerramos la página y la enviamos TODA JUNTA ---
sb.Append("</div>") ' Cierre de div.output
sb.Append("<p class='logout'><a href='/logout'>Cerrar Sesión</a></p>")
sb.Append("</body></html>")
resp.Write(sb.ToString) ' Se envía toda la página de una vez
' Lógica final de logs (se mantiene igual)
If GlobalParameters.mpLogs.IsInitialized Then GlobalParameters.mpLogs.Put(Command, "Manager : " & Command & " - Time : " & DateTime.Time(DateTime.Now))
End Sub