mirror of
https://github.com/KeymonSoft/jRDC-Multi.git
synced 2026-04-17 21:06:24 +00:00
- 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:
@@ -63,11 +63,12 @@ Sub Handle(req As ServletRequest, resp As ServletResponse)
|
||||
|
||||
' Validación inicial: Si no hay JSON, se envía un error 400.
|
||||
If jsonString = Null Or jsonString = "" Then
|
||||
SendErrorResponse(resp, 400, "Falta el parámetro 'j' en el URL o el cuerpo JSON en la petición.")
|
||||
Dim ErrorMsg As String = "Falta el parámetro 'j' en el URL o el cuerpo JSON en la petición."
|
||||
SendErrorResponse(resp, 400, ErrorMsg)
|
||||
Main.LogServerError("ERROR", "DBHandlerJSON.Handle", ErrorMsg, finalDbKey, queryNameForLog, req.RemoteAddress) ' <-- Nuevo Log
|
||||
duration = DateTime.Now - start
|
||||
' Llama a CleanupAndLog para registrar que hubo un error, pero con contadores a 0 o inicializados.
|
||||
CleanupAndLog(finalDbKey, queryNameForLog, duration, req.RemoteAddress, requestsBeforeDecrement, poolBusyConnectionsForLog, con)
|
||||
Return ' Salida temprana si no hay JSON válido.
|
||||
Return
|
||||
End If
|
||||
|
||||
Dim parser As JSONParser
|
||||
@@ -108,10 +109,12 @@ Sub Handle(req As ServletRequest, resp As ServletResponse)
|
||||
|
||||
' Validación: Si el dbKey no es válido o no está configurado en Main.listaDeCP.
|
||||
If Main.listaDeCP.IndexOf(finalDbKey) = -1 Then
|
||||
SendErrorResponse(resp, 400, "Parámetro 'DB' inválido. El nombre '" & finalDbKey & "' no es válido.")
|
||||
Dim ErrorMsg As String = "Parámetro 'DB' inválido. El nombre '" & finalDbKey & "' no es válido."
|
||||
SendErrorResponse(resp, 400, ErrorMsg)
|
||||
Main.LogServerError("ERROR", "DBHandlerJSON.Handle", ErrorMsg, finalDbKey, queryNameForLog, req.RemoteAddress) ' <-- Nuevo Log
|
||||
duration = DateTime.Now - start
|
||||
CleanupAndLog(finalDbKey, queryNameForLog, duration, req.RemoteAddress, requestsBeforeDecrement, poolBusyConnectionsForLog, con)
|
||||
Return ' Salida temprana si la DB no es válida.
|
||||
Return
|
||||
End If
|
||||
|
||||
con = Connector.GetConnection(finalDbKey) ' ¡La conexión a la BD se obtiene aquí del pool de conexiones!
|
||||
@@ -135,31 +138,30 @@ Sub Handle(req As ServletRequest, resp As ServletResponse)
|
||||
If sqlCommand = Null Or sqlCommand = "null" Or sqlCommand.Trim = "" Then
|
||||
Dim errorMessage As String = $"El comando '${queryNameForLog}' no fue encontrado en el config.properties de '${finalDbKey}'."$
|
||||
Log(errorMessage)
|
||||
Main.LogServerError("ERROR", "DBHandlerJSON.Handle", errorMessage, finalDbKey, queryNameForLog, req.RemoteAddress) ' <-- Nuevo Log
|
||||
SendErrorResponse(resp, 400, errorMessage)
|
||||
duration = DateTime.Now - start
|
||||
CleanupAndLog(finalDbKey, queryNameForLog, duration, req.RemoteAddress, requestsBeforeDecrement, poolBusyConnectionsForLog, con)
|
||||
Return ' Salida temprana.
|
||||
Return
|
||||
End If
|
||||
|
||||
' --- Lógica para ejecutar diferentes tipos de comandos basados en el parámetro 'execType' ---
|
||||
If execType.ToLowerCase = "executequery" Then
|
||||
Dim rs As ResultSet
|
||||
' Validación de parámetros para ExecuteQuery.
|
||||
If sqlCommand.Contains("?") Or paramsList.Size > 0 Then
|
||||
Dim expectedParams As Int = sqlCommand.Length - sqlCommand.Replace("?", "").Length
|
||||
Dim receivedParams As Int = paramsList.Size
|
||||
Log($"expectedParams: ${expectedParams}, receivedParams: ${receivedParams}"$)
|
||||
If expectedParams <> receivedParams Then
|
||||
SendErrorResponse(resp, 400, $"Número de parámetros equivocado para '${queryNameForLog}'. Se esperaban ${expectedParams} y se recibieron ${receivedParams}."$)
|
||||
duration = DateTime.Now - start
|
||||
CleanupAndLog(finalDbKey, queryNameForLog, duration, req.RemoteAddress, requestsBeforeDecrement, poolBusyConnectionsForLog, con)
|
||||
Return ' Salida temprana.
|
||||
End If
|
||||
rs = con.ExecQuery2(sqlCommand, paramsList) ' Ejecuta la consulta con parámetros.
|
||||
Else
|
||||
rs = con.ExecQuery(sqlCommand) ' Ejecuta la consulta sin parámetros.
|
||||
' --- INICIO VALIDACIÓN DE PARÁMETROS CENTRALIZADA ---
|
||||
Dim validationResult As ParameterValidationResult = ParameterValidationUtils.ValidateAndAdjustParameters(queryNameForLog, finalDbKey, sqlCommand, paramsList, Connector.IsParameterToleranceEnabled)
|
||||
|
||||
If validationResult.Success = False Then
|
||||
SendErrorResponse(resp, 400, validationResult.ErrorMessage)
|
||||
duration = DateTime.Now - start
|
||||
CleanupAndLog(finalDbKey, queryNameForLog, duration, req.RemoteAddress, requestsBeforeDecrement, poolBusyConnectionsForLog, con)
|
||||
Return ' Salida temprana.
|
||||
End If
|
||||
|
||||
Dim rs As ResultSet
|
||||
' Ejecuta la consulta SQL con la lista de parámetros validada.
|
||||
rs = con.ExecQuery2(sqlCommand, validationResult.ParamsToExecute)
|
||||
' --- FIN VALIDACIÓN DE PARÁMETROS CENTRALIZADA ---
|
||||
|
||||
Dim ResultList As List
|
||||
ResultList.Initialize ' Lista para almacenar los resultados de la consulta.
|
||||
Dim jrs As JavaObject = rs ' Objeto Java subyacente del ResultSet para metadatos.
|
||||
@@ -180,29 +182,29 @@ Sub Handle(req As ServletRequest, resp As ServletResponse)
|
||||
SendSuccessResponse(resp, CreateMap("result": ResultList)) ' Envía la respuesta JSON de éxito.
|
||||
|
||||
Else If execType.ToLowerCase = "executecommand" Then
|
||||
' Validación de parámetros para ExecuteCommand.
|
||||
If sqlCommand.Contains("?") Then
|
||||
Dim expectedParams As Int = sqlCommand.Length - sqlCommand.Replace("?", "").Length
|
||||
Dim receivedParams As Int = paramsList.Size
|
||||
If expectedParams <> receivedParams Then
|
||||
SendErrorResponse(resp, 400, $"Número de parámetros equivocado para '${queryNameForLog}'. Se esperaban ${expectedParams} y se recibieron ${receivedParams}."$)
|
||||
duration = DateTime.Now - start
|
||||
CleanupAndLog(finalDbKey, queryNameForLog, duration, req.RemoteAddress, requestsBeforeDecrement, poolBusyConnectionsForLog, con)
|
||||
Return ' Salida temprana.
|
||||
End If
|
||||
End If
|
||||
con.ExecNonQuery2(sqlCommand, paramsList) ' Ejecuta un comando (INSERT, UPDATE, DELETE).
|
||||
SendSuccessResponse(resp, CreateMap("message": "Command executed successfully")) ' Envía confirmación de éxito.
|
||||
' --- INICIO VALIDACIÓN DE PARÁMETROS CENTRALIZADA ---
|
||||
Dim validationResult As ParameterValidationResult = ParameterValidationUtils.ValidateAndAdjustParameters(queryNameForLog, finalDbKey, sqlCommand, paramsList, Connector.IsParameterToleranceEnabled)
|
||||
|
||||
If validationResult.Success = False Then
|
||||
SendErrorResponse(resp, 400, validationResult.ErrorMessage)
|
||||
duration = DateTime.Now - start
|
||||
CleanupAndLog(finalDbKey, queryNameForLog, duration, req.RemoteAddress, requestsBeforeDecrement, poolBusyConnectionsForLog, con)
|
||||
Return ' Salida temprana.
|
||||
End If
|
||||
|
||||
con.ExecNonQuery2(sqlCommand, validationResult.ParamsToExecute) ' Ejecuta un comando con la lista de parámetros validada.
|
||||
SendSuccessResponse(resp, CreateMap("message": "Command executed successfully")) ' Envía confirmación de éxito.
|
||||
' --- FIN VALIDACIÓN DE PARÁMETROS CENTRALIZADA ---
|
||||
Else
|
||||
' Si el tipo de ejecución no es reconocido.
|
||||
SendErrorResponse(resp, 400, "Parámetro 'exec' inválido. '" & execType & "' no es un valor permitido.")
|
||||
Dim ErrorMsg As String = "Parámetro 'exec' inválido. '" & execType & "' no es un valor permitido."
|
||||
SendErrorResponse(resp, 400, ErrorMsg)
|
||||
Main.LogServerError("ERROR", "DBHandlerJSON.Handle", ErrorMsg, finalDbKey, queryNameForLog, req.RemoteAddress) ' <-- Nuevo Log
|
||||
' El flujo continúa hasta la limpieza final si no hay un Return explícito.
|
||||
End If
|
||||
|
||||
Catch ' --- CATCH: Maneja errores generales de ejecución o de SQL/JSON ---
|
||||
' Si ocurre una excepción inesperada durante el procesamiento de la petición.
|
||||
Log(LastException) ' Registra la excepción completa en el log.
|
||||
Main.LogServerError("ERROR", "DBHandlerJSON.Handle", LastException.Message, finalDbKey, queryNameForLog, req.RemoteAddress) ' <-- Nuevo Log
|
||||
SendErrorResponse(resp, 500, LastException.Message) ' Envía un error 500 al cliente.
|
||||
queryNameForLog = "error_processing_json" ' Para registrar que hubo un error en el log.
|
||||
End Try ' --- FIN: Bloque Try principal ---
|
||||
|
||||
Reference in New Issue
Block a user