Reduce servlet logging verbosity from INFO to DEBUG
Move verbose per-request logging (request body, session management, SSE connections, method processing) from INFO to DEBUG level. Keep INFO for significant events like new Visit creation.
Showing
3 changed files
with
77 additions
and
90 deletions
| ... | @@ -145,7 +145,7 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -145,7 +145,7 @@ class EnhancedMcpServlet extends HttpServlet { |
| 145 | String requestBody = null | 145 | String requestBody = null |
| 146 | if ("POST".equals(request.getMethod())) { | 146 | if ("POST".equals(request.getMethod())) { |
| 147 | try { | 147 | try { |
| 148 | logger.info("Early reading request body, content length: ${request.getContentLength()}") | 148 | logger.debug("Early reading request body, content length: ${request.getContentLength()}") |
| 149 | BufferedReader reader = request.getReader() | 149 | BufferedReader reader = request.getReader() |
| 150 | StringBuilder body = new StringBuilder() | 150 | StringBuilder body = new StringBuilder() |
| 151 | String line | 151 | String line |
| ... | @@ -155,7 +155,7 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -155,7 +155,7 @@ class EnhancedMcpServlet extends HttpServlet { |
| 155 | lineCount++ | 155 | lineCount++ |
| 156 | } | 156 | } |
| 157 | requestBody = body.toString() | 157 | requestBody = body.toString() |
| 158 | logger.info("Early read ${lineCount} lines, request body length: ${requestBody.length()}") | 158 | logger.debug("Early read ${lineCount} lines, request body length: ${requestBody.length()}") |
| 159 | } catch (Exception e) { | 159 | } catch (Exception e) { |
| 160 | logger.error("Failed to read request body early: ${e.message}") | 160 | logger.error("Failed to read request body early: ${e.message}") |
| 161 | } | 161 | } |
| ... | @@ -192,15 +192,15 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -192,15 +192,15 @@ class EnhancedMcpServlet extends HttpServlet { |
| 192 | // Route based on request method and path | 192 | // Route based on request method and path |
| 193 | String requestURI = request.getRequestURI() | 193 | String requestURI = request.getRequestURI() |
| 194 | String method = request.getMethod() | 194 | String method = request.getMethod() |
| 195 | logger.info("Enhanced MCP Request: ${method} ${requestURI} - Content-Length: ${request.getContentLength()}") | 195 | logger.debug("Enhanced MCP Request: ${method} ${requestURI} - Content-Length: ${request.getContentLength()}") |
| 196 | 196 | ||
| 197 | if ("GET".equals(method) && requestURI.endsWith("/sse")) { | 197 | if ("GET".equals(method) && requestURI.endsWith("/sse")) { |
| 198 | handleSseConnection(request, response, ec, webappName) | 198 | handleSseConnection(request, response, ec, webappName) |
| 199 | } else if ("POST".equals(method) && requestURI.endsWith("/message")) { | 199 | } else if ("POST".equals(method) && requestURI.endsWith("/message")) { |
| 200 | handleMessage(request, response, ec, requestBody) | 200 | handleMessage(request, response, ec, requestBody) |
| 201 | } else if ("POST".equals(method) && (requestURI.equals("/mcp") || requestURI.endsWith("/mcp"))) { | 201 | } else if ("POST".equals(method) && (requestURI.equals("/mcp") || requestURI.endsWith("/mcp"))) { |
| 202 | // Handle POST requests to /mcp for JSON-RPC | 202 | // Handle POST requests to /mcp for JSON-RPC |
| 203 | logger.info("About to call handleJsonRpc with visit: ${visit?.visitId}") | 203 | logger.debug("About to call handleJsonRpc with visit: ${visit?.visitId}") |
| 204 | handleJsonRpc(request, response, ec, webappName, requestBody, visit) | 204 | handleJsonRpc(request, response, ec, webappName, requestBody, visit) |
| 205 | } else if ("GET".equals(method) && (requestURI.equals("/mcp") || requestURI.endsWith("/mcp"))) { | 205 | } else if ("GET".equals(method) && (requestURI.equals("/mcp") || requestURI.endsWith("/mcp"))) { |
| 206 | // Handle GET requests to /mcp - maybe for server info or SSE fallback | 206 | // Handle GET requests to /mcp - maybe for server info or SSE fallback |
| ... | @@ -240,10 +240,10 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -240,10 +240,10 @@ class EnhancedMcpServlet extends HttpServlet { |
| 240 | } | 240 | } |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | private void handleSseConnection(HttpServletRequest request, HttpServletResponse response, ExecutionContextImpl ec, String webappName) | 243 | private void handleSseConnection(HttpServletRequest request, HttpServletResponse response, ExecutionContextImpl ec, String webappName) |
| 244 | throws IOException { | 244 | throws IOException { |
| 245 | 245 | ||
| 246 | logger.info("Handling Enhanced SSE connection from ${request.remoteAddr}") | 246 | logger.debug("Handling Enhanced SSE connection from ${request.remoteAddr}") |
| 247 | 247 | ||
| 248 | // Check for existing session ID first | 248 | // Check for existing session ID first |
| 249 | String sessionId = request.getHeader("Mcp-Session-Id") | 249 | String sessionId = request.getHeader("Mcp-Session-Id") |
| ... | @@ -332,10 +332,10 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -332,10 +332,10 @@ class EnhancedMcpServlet extends HttpServlet { |
| 332 | // Check if this is old HTTP+SSE transport (no session ID, no prior initialization) | 332 | // Check if this is old HTTP+SSE transport (no session ID, no prior initialization) |
| 333 | // Send endpoint event first for backwards compatibility | 333 | // Send endpoint event first for backwards compatibility |
| 334 | if (!request.getHeader("Mcp-Session-Id")) { | 334 | if (!request.getHeader("Mcp-Session-Id")) { |
| 335 | logger.info("No Mcp-Session-Id header detected, assuming old HTTP+SSE transport") | 335 | logger.debug("No Mcp-Session-Id header detected, assuming old HTTP+SSE transport") |
| 336 | sendSseEvent(response.writer, "endpoint", "/mcp", 0) | 336 | sendSseEvent(response.writer, "endpoint", "/mcp", 0) |
| 337 | } | 337 | } |
| 338 | 338 | ||
| 339 | // Send initial connection event for new transport | 339 | // Send initial connection event for new transport |
| 340 | def connectData = [ | 340 | def connectData = [ |
| 341 | version: "2.0.2", | 341 | version: "2.0.2", |
| ... | @@ -345,7 +345,7 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -345,7 +345,7 @@ class EnhancedMcpServlet extends HttpServlet { |
| 345 | 345 | ||
| 346 | // Set MCP session ID header per specification BEFORE sending any data | 346 | // Set MCP session ID header per specification BEFORE sending any data |
| 347 | response.setHeader("Mcp-Session-Id", visit.visitId.toString()) | 347 | response.setHeader("Mcp-Session-Id", visit.visitId.toString()) |
| 348 | logger.info("Set Mcp-Session-Id header to ${visit.visitId} for SSE connection") | 348 | logger.debug("Set Mcp-Session-Id header to ${visit.visitId} for SSE connection") |
| 349 | 349 | ||
| 350 | sendSseEvent(response.writer, "connect", JsonOutput.toJson(connectData), 1) | 350 | sendSseEvent(response.writer, "connect", JsonOutput.toJson(connectData), 1) |
| 351 | 351 | ||
| ... | @@ -414,7 +414,7 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -414,7 +414,7 @@ class EnhancedMcpServlet extends HttpServlet { |
| 414 | } | 414 | } |
| 415 | 415 | ||
| 416 | // Verify user has access to this Visit - rely on Moqui security | 416 | // Verify user has access to this Visit - rely on Moqui security |
| 417 | logger.info("Session validation: visit.userId=${visit.userId}, ec.user.userId=${ec.user.userId}, ec.user.username=${ec.user.username}") | 417 | logger.debug("Session validation: visit.userId=${visit.userId}, ec.user.userId=${ec.user.userId}, ec.user.username=${ec.user.username}") |
| 418 | if (visit.userId && ec.user.userId && visit.userId.toString() != ec.user.userId.toString()) { | 418 | if (visit.userId && ec.user.userId && visit.userId.toString() != ec.user.userId.toString()) { |
| 419 | logger.warn("Visit userId ${visit.userId} doesn't match current user userId ${ec.user.userId} - access denied") | 419 | logger.warn("Visit userId ${visit.userId} doesn't match current user userId ${ec.user.userId} - access denied") |
| 420 | response.setContentType("application/json") | 420 | response.setContentType("application/json") |
| ... | @@ -540,7 +540,7 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -540,7 +540,7 @@ class EnhancedMcpServlet extends HttpServlet { |
| 540 | String method = request.getMethod() | 540 | String method = request.getMethod() |
| 541 | String acceptHeader = request.getHeader("Accept") | 541 | String acceptHeader = request.getHeader("Accept") |
| 542 | 542 | ||
| 543 | logger.info("Enhanced MCP JSON-RPC Request: ${method} ${request.requestURI} - Accept: ${acceptHeader}") | 543 | logger.debug("Enhanced MCP JSON-RPC Request: ${method} ${request.requestURI} - Accept: ${acceptHeader}") |
| 544 | 544 | ||
| 545 | // Validate Accept header per MCP 2025-11-25 spec requirement #2 | 545 | // Validate Accept header per MCP 2025-11-25 spec requirement #2 |
| 546 | // Client MUST include Accept header with at least one of: application/json or text/event-stream | 546 | // Client MUST include Accept header with at least one of: application/json or text/event-stream |
| ... | @@ -565,10 +565,10 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -565,10 +565,10 @@ class EnhancedMcpServlet extends HttpServlet { |
| 565 | ])) | 565 | ])) |
| 566 | return | 566 | return |
| 567 | } | 567 | } |
| 568 | 568 | ||
| 569 | // Use pre-read request body | 569 | // Use pre-read request body |
| 570 | logger.info("Using pre-read request body, length: ${requestBody?.length()}") | 570 | logger.debug("Using pre-read request body, length: ${requestBody?.length()}") |
| 571 | 571 | ||
| 572 | if (!requestBody) { | 572 | if (!requestBody) { |
| 573 | response.setStatus(HttpServletResponse.SC_BAD_REQUEST) | 573 | response.setStatus(HttpServletResponse.SC_BAD_REQUEST) |
| 574 | response.setContentType("application/json") | 574 | response.setContentType("application/json") |
| ... | @@ -579,12 +579,12 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -579,12 +579,12 @@ class EnhancedMcpServlet extends HttpServlet { |
| 579 | ])) | 579 | ])) |
| 580 | return | 580 | return |
| 581 | } | 581 | } |
| 582 | 582 | ||
| 583 | // Log request body for debugging (be careful with this in production) | 583 | // Log request body for debugging (be careful with this in production) |
| 584 | if (requestBody.length() > 0) { | 584 | if (requestBody.length() > 0) { |
| 585 | logger.info("MCP JSON-RPC request body: ${requestBody}") | 585 | logger.trace("MCP JSON-RPC request body: ${requestBody}") |
| 586 | } | 586 | } |
| 587 | 587 | ||
| 588 | def rpcRequest | 588 | def rpcRequest |
| 589 | try { | 589 | try { |
| 590 | rpcRequest = jsonSlurper.parseText(requestBody) | 590 | rpcRequest = jsonSlurper.parseText(requestBody) |
| ... | @@ -626,15 +626,15 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -626,15 +626,15 @@ class EnhancedMcpServlet extends HttpServlet { |
| 626 | ])) | 626 | ])) |
| 627 | return | 627 | return |
| 628 | } | 628 | } |
| 629 | 629 | ||
| 630 | // Get session ID from Mcp-Session-Id header per MCP specification | 630 | // Get session ID from Mcp-Session-Id header per MCP specification |
| 631 | String sessionId = request.getHeader("Mcp-Session-Id") | 631 | String sessionId = request.getHeader("Mcp-Session-Id") |
| 632 | logger.info("Session ID from header: '${sessionId}', method: '${rpcRequest.method}'") | 632 | logger.debug("Session ID from header: '${sessionId}', method: '${rpcRequest.method}'") |
| 633 | 633 | ||
| 634 | // For initialize and notifications/initialized methods, use visit ID as session ID if no header | 634 | // For initialize and notifications/initialized methods, use visit ID as session ID if no header |
| 635 | if (!sessionId && ("initialize".equals(rpcRequest.method) || "notifications/initialized".equals(rpcRequest.method)) && visit) { | 635 | if (!sessionId && ("initialize".equals(rpcRequest.method) || "notifications/initialized".equals(rpcRequest.method)) && visit) { |
| 636 | sessionId = visit.visitId | 636 | sessionId = visit.visitId |
| 637 | logger.info("${rpcRequest.method} method: using visit ID as session ID: ${sessionId}") | 637 | logger.debug("${rpcRequest.method} method: using visit ID as session ID: ${sessionId}") |
| 638 | } | 638 | } |
| 639 | 639 | ||
| 640 | // Validate session ID for non-initialize requests per MCP spec | 640 | // Validate session ID for non-initialize requests per MCP spec |
| ... | @@ -681,11 +681,11 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -681,11 +681,11 @@ class EnhancedMcpServlet extends HttpServlet { |
| 681 | ])) | 681 | ])) |
| 682 | return | 682 | return |
| 683 | } | 683 | } |
| 684 | 684 | ||
| 685 | // Set visit ID in HTTP session so Moqui web facade initialization picks it up | 685 | // Set visit ID in HTTP session so Moqui web facade initialization picks it up |
| 686 | request.session.setAttribute("moqui.visitId", sessionId) | 686 | request.session.setAttribute("moqui.visitId", sessionId) |
| 687 | logger.info("Set existing Visit ${sessionId} in HTTP session for user ${ec.user.username}") | 687 | logger.debug("Set existing Visit ${sessionId} in HTTP session for user ${ec.user.username}") |
| 688 | 688 | ||
| 689 | } catch (Exception e) { | 689 | } catch (Exception e) { |
| 690 | logger.error("Error finding session ${sessionId}: ${e.message}") | 690 | logger.error("Error finding session ${sessionId}: ${e.message}") |
| 691 | response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR) | 691 | response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR) |
| ... | @@ -707,23 +707,23 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -707,23 +707,23 @@ class EnhancedMcpServlet extends HttpServlet { |
| 707 | if (isNotification) { | 707 | if (isNotification) { |
| 708 | // Special handling for notifications/initialized to transition session state | 708 | // Special handling for notifications/initialized to transition session state |
| 709 | if ("notifications/initialized".equals(rpcRequest.method)) { | 709 | if ("notifications/initialized".equals(rpcRequest.method)) { |
| 710 | logger.info("Processing notifications/initialized for sessionId: ${sessionId}") | 710 | logger.debug("Processing notifications/initialized for sessionId: ${sessionId}") |
| 711 | if (sessionId) { | 711 | if (sessionId) { |
| 712 | sessionStates.put(sessionId, STATE_INITIALIZED) | 712 | sessionStates.put(sessionId, STATE_INITIALIZED) |
| 713 | // Store user mapping in memory for fast validation | 713 | // Store user mapping in memory for fast validation |
| 714 | sessionUsers.put(sessionId, ec.user.userId.toString()) | 714 | sessionUsers.put(sessionId, ec.user.userId.toString()) |
| 715 | logger.info("Session ${sessionId} transitioned to INITIALIZED state for user ${ec.user.userId}") | 715 | logger.debug("Session ${sessionId} transitioned to INITIALIZED state for user ${ec.user.userId}") |
| 716 | } | 716 | } |
| 717 | 717 | ||
| 718 | // For notifications/initialized, return 202 Accepted per MCP HTTP Streaming spec | 718 | // For notifications/initialized, return 202 Accepted per MCP HTTP Streaming spec |
| 719 | if (sessionId) { | 719 | if (sessionId) { |
| 720 | response.setHeader("Mcp-Session-Id", sessionId.toString()) | 720 | response.setHeader("Mcp-Session-Id", sessionId.toString()) |
| 721 | } | 721 | } |
| 722 | response.setContentType("text/event-stream") | 722 | response.setContentType("text/event-stream") |
| 723 | response.setStatus(HttpServletResponse.SC_ACCEPTED) // 202 Accepted | 723 | response.setStatus(HttpServletResponse.SC_ACCEPTED) // 202 Accepted |
| 724 | logger.info("Sent 202 Accepted response for notifications/initialized") | 724 | logger.debug("Sent 202 Accepted response for notifications/initialized") |
| 725 | response.flushBuffer() // Commit the response immediately | 725 | response.flushBuffer() // Commit the response immediately |
| 726 | return | 726 | return |
| 727 | } | 727 | } |
| 728 | 728 | ||
| 729 | // For other notifications, set session header if needed but NO response per MCP spec | 729 | // For other notifications, set session header if needed but NO response per MCP spec |
| ... | @@ -757,12 +757,12 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -757,12 +757,12 @@ class EnhancedMcpServlet extends HttpServlet { |
| 757 | // For other methods, ensure we always return session ID from header | 757 | // For other methods, ensure we always return session ID from header |
| 758 | responseSessionId = sessionId.toString() | 758 | responseSessionId = sessionId.toString() |
| 759 | } | 759 | } |
| 760 | 760 | ||
| 761 | if (responseSessionId) { | 761 | if (responseSessionId) { |
| 762 | response.setHeader("Mcp-Session-Id", responseSessionId) | 762 | response.setHeader("Mcp-Session-Id", responseSessionId) |
| 763 | logger.info("Set Mcp-Session-Id header to ${responseSessionId} for method ${rpcRequest.method}") | 763 | logger.debug("Set Mcp-Session-Id header to ${responseSessionId} for method ${rpcRequest.method}") |
| 764 | } | 764 | } |
| 765 | 765 | ||
| 766 | // Build JSON-RPC response for regular requests | 766 | // Build JSON-RPC response for regular requests |
| 767 | // Extract the actual result from Moqui service response | 767 | // Extract the actual result from Moqui service response |
| 768 | def actualResult = result?.result ?: result | 768 | def actualResult = result?.result ?: result |
| ... | @@ -776,8 +776,8 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -776,8 +776,8 @@ class EnhancedMcpServlet extends HttpServlet { |
| 776 | if (sessionId && notificationQueues.containsKey(sessionId)) { | 776 | if (sessionId && notificationQueues.containsKey(sessionId)) { |
| 777 | def pendingNotifications = notificationQueues.get(sessionId) | 777 | def pendingNotifications = notificationQueues.get(sessionId) |
| 778 | if (pendingNotifications && !pendingNotifications.isEmpty()) { | 778 | if (pendingNotifications && !pendingNotifications.isEmpty()) { |
| 779 | logger.info("Adding ${pendingNotifications.size()} pending notifications to response content for session ${sessionId}") | 779 | logger.debug("Adding ${pendingNotifications.size()} pending notifications to response content for session ${sessionId}") |
| 780 | 780 | ||
| 781 | // Convert notifications to content items and add to result | 781 | // Convert notifications to content items and add to result |
| 782 | def notificationContent = [] | 782 | def notificationContent = [] |
| 783 | for (notification in pendingNotifications) { | 783 | for (notification in pendingNotifications) { |
| ... | @@ -793,7 +793,7 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -793,7 +793,7 @@ class EnhancedMcpServlet extends HttpServlet { |
| 793 | 793 | ||
| 794 | // Clear delivered notifications | 794 | // Clear delivered notifications |
| 795 | notificationQueues.put(sessionId, []) | 795 | notificationQueues.put(sessionId, []) |
| 796 | logger.info("Merged ${pendingNotifications.size()} notifications into response for session ${sessionId}") | 796 | logger.debug("Merged ${pendingNotifications.size()} notifications into response for session ${sessionId}") |
| 797 | } | 797 | } |
| 798 | } | 798 | } |
| 799 | 799 | ||
| ... | @@ -803,10 +803,10 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -803,10 +803,10 @@ class EnhancedMcpServlet extends HttpServlet { |
| 803 | // Send the main response | 803 | // Send the main response |
| 804 | response.writer.write(JsonOutput.toJson(rpcResponse)) | 804 | response.writer.write(JsonOutput.toJson(rpcResponse)) |
| 805 | } | 805 | } |
| 806 | 806 | ||
| 807 | private Map<String, Object> processMcpMethod(String method, Map params, ExecutionContextImpl ec, String sessionId, def visit) { | 807 | private Map<String, Object> processMcpMethod(String method, Map params, ExecutionContextImpl ec, String sessionId, def visit) { |
| 808 | logger.info("Enhanced METHOD: ${method} with sessionId: ${sessionId}") | 808 | logger.debug("Enhanced METHOD: ${method} with sessionId: ${sessionId}") |
| 809 | 809 | ||
| 810 | try { | 810 | try { |
| 811 | // Ensure params is not null | 811 | // Ensure params is not null |
| 812 | if (params == null) { | 812 | if (params == null) { |
| ... | @@ -835,19 +835,19 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -835,19 +835,19 @@ class EnhancedMcpServlet extends HttpServlet { |
| 835 | params.sessionId = visit.visitId | 835 | params.sessionId = visit.visitId |
| 836 | // Set session to initializing state using actual sessionId as key (for consistency) | 836 | // Set session to initializing state using actual sessionId as key (for consistency) |
| 837 | sessionStates.put(params.sessionId, STATE_INITIALIZING) | 837 | sessionStates.put(params.sessionId, STATE_INITIALIZING) |
| 838 | logger.info("Initialize - using visitId: ${visit.visitId}, set state ${params.sessionId} to INITIALIZING") | 838 | logger.debug("Initialize - using visitId: ${visit.visitId}, set state ${params.sessionId} to INITIALIZING") |
| 839 | } else { | 839 | } else { |
| 840 | logger.warn("Initialize - no visit available, using null sessionId") | 840 | logger.warn("Initialize - no visit available, using null sessionId") |
| 841 | } | 841 | } |
| 842 | params.actualUserId = ec.user.userId | 842 | params.actualUserId = ec.user.userId |
| 843 | logger.info("Initialize - actualUserId: ${params.actualUserId}, sessionId: ${params.sessionId}") | 843 | logger.debug("Initialize - actualUserId: ${params.actualUserId}, sessionId: ${params.sessionId}") |
| 844 | def serviceResult = callMcpService("mcp#Initialize", params, ec) | 844 | def serviceResult = callMcpService("mcp#Initialize", params, ec) |
| 845 | // Add sessionId to the response for mcp.sh compatibility | 845 | // Add sessionId to the response for mcp.sh compatibility |
| 846 | if (serviceResult && serviceResult.result) { | 846 | if (serviceResult && serviceResult.result) { |
| 847 | serviceResult.result.sessionId = params.sessionId | 847 | serviceResult.result.sessionId = params.sessionId |
| 848 | // Initialize successful - transition session to INITIALIZED state | 848 | // Initialize successful - transition session to INITIALIZED state |
| 849 | sessionStates.put(params.sessionId, STATE_INITIALIZED) | 849 | sessionStates.put(params.sessionId, STATE_INITIALIZED) |
| 850 | logger.info("Initialize - successful, set state ${params.sessionId} to INITIALIZED") | 850 | logger.debug("Initialize - successful, set state ${params.sessionId} to INITIALIZED") |
| 851 | } | 851 | } |
| 852 | return serviceResult | 852 | return serviceResult |
| 853 | case "ping": | 853 | case "ping": |
| ... | @@ -885,12 +885,12 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -885,12 +885,12 @@ class EnhancedMcpServlet extends HttpServlet { |
| 885 | // It will be processed by the notification handling logic above (lines 824-837) | 885 | // It will be processed by the notification handling logic above (lines 824-837) |
| 886 | case "notifications/tools/list_changed": | 886 | case "notifications/tools/list_changed": |
| 887 | // Handle tools list changed notification | 887 | // Handle tools list changed notification |
| 888 | logger.info("Tools list changed for sessionId: ${sessionId}") | 888 | logger.debug("Tools list changed for sessionId: ${sessionId}") |
| 889 | // Could trigger cache invalidation here if needed | 889 | // Could trigger cache invalidation here if needed |
| 890 | return null | 890 | return null |
| 891 | case "notifications/resources/list_changed": | 891 | case "notifications/resources/list_changed": |
| 892 | // Handle resources list changed notification | 892 | // Handle resources list changed notification |
| 893 | logger.info("Resources list changed for sessionId: ${sessionId}") | 893 | logger.debug("Resources list changed for sessionId: ${sessionId}") |
| 894 | // Could trigger cache invalidation here if needed | 894 | // Could trigger cache invalidation here if needed |
| 895 | return null | 895 | return null |
| 896 | case "notifications/send": | 896 | case "notifications/send": |
| ... | @@ -900,9 +900,9 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -900,9 +900,9 @@ class EnhancedMcpServlet extends HttpServlet { |
| 900 | if (!notificationMethod) { | 900 | if (!notificationMethod) { |
| 901 | throw new IllegalArgumentException("method is required for sending notification") | 901 | throw new IllegalArgumentException("method is required for sending notification") |
| 902 | } | 902 | } |
| 903 | 903 | ||
| 904 | logger.info("Sending notification ${notificationMethod} for sessionId: ${sessionId}") | 904 | logger.debug("Sending notification ${notificationMethod} for sessionId: ${sessionId}") |
| 905 | 905 | ||
| 906 | // Queue notification for delivery through SSE or polling | 906 | // Queue notification for delivery through SSE or polling |
| 907 | if (sessionId) { | 907 | if (sessionId) { |
| 908 | def notification = [ | 908 | def notification = [ |
| ... | @@ -915,10 +915,10 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -915,10 +915,10 @@ class EnhancedMcpServlet extends HttpServlet { |
| 915 | def queue = notificationQueues.get(sessionId) ?: [] | 915 | def queue = notificationQueues.get(sessionId) ?: [] |
| 916 | queue << notification | 916 | queue << notification |
| 917 | notificationQueues.put(sessionId, queue) | 917 | notificationQueues.put(sessionId, queue) |
| 918 | 918 | ||
| 919 | logger.info("Notification queued for session ${sessionId}: ${notificationMethod}") | 919 | logger.debug("Notification queued for session ${sessionId}: ${notificationMethod}") |
| 920 | } | 920 | } |
| 921 | 921 | ||
| 922 | return [sent: true, sessionId: sessionId, method: notificationMethod] | 922 | return [sent: true, sessionId: sessionId, method: notificationMethod] |
| 923 | case "notifications/subscribe": | 923 | case "notifications/subscribe": |
| 924 | // Handle notification subscription | 924 | // Handle notification subscription |
| ... | @@ -929,7 +929,7 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -929,7 +929,7 @@ class EnhancedMcpServlet extends HttpServlet { |
| 929 | def subscriptions = sessionSubscriptions.get(sessionId) ?: new HashSet<>() | 929 | def subscriptions = sessionSubscriptions.get(sessionId) ?: new HashSet<>() |
| 930 | subscriptions.add(subscriptionMethod) | 930 | subscriptions.add(subscriptionMethod) |
| 931 | sessionSubscriptions.put(sessionId, subscriptions) | 931 | sessionSubscriptions.put(sessionId, subscriptions) |
| 932 | logger.info("Session ${sessionId} subscribed to: ${subscriptionMethod}") | 932 | logger.debug("Session ${sessionId} subscribed to: ${subscriptionMethod}") |
| 933 | return [subscribed: true, sessionId: sessionId, method: subscriptionMethod] | 933 | return [subscribed: true, sessionId: sessionId, method: subscriptionMethod] |
| 934 | case "notifications/unsubscribe": | 934 | case "notifications/unsubscribe": |
| 935 | // Handle notification unsubscription | 935 | // Handle notification unsubscription |
| ... | @@ -945,7 +945,7 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -945,7 +945,7 @@ class EnhancedMcpServlet extends HttpServlet { |
| 945 | } else { | 945 | } else { |
| 946 | sessionSubscriptions.put(sessionId, subscriptions) | 946 | sessionSubscriptions.put(sessionId, subscriptions) |
| 947 | } | 947 | } |
| 948 | logger.info("Session ${sessionId} unsubscribed from: ${subscriptionMethod}") | 948 | logger.debug("Session ${sessionId} unsubscribed from: ${subscriptionMethod}") |
| 949 | } | 949 | } |
| 950 | return [unsubscribed: true, sessionId: sessionId, method: subscriptionMethod] | 950 | return [unsubscribed: true, sessionId: sessionId, method: subscriptionMethod] |
| 951 | case "notifications/progress": | 951 | case "notifications/progress": |
| ... | @@ -953,7 +953,7 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -953,7 +953,7 @@ class EnhancedMcpServlet extends HttpServlet { |
| 953 | def progressToken = params?.progressToken | 953 | def progressToken = params?.progressToken |
| 954 | def progressValue = params?.progress | 954 | def progressValue = params?.progress |
| 955 | def total = params?.total | 955 | def total = params?.total |
| 956 | logger.info("Progress notification for sessionId: ${sessionId}, token: ${progressToken}, progress: ${progressValue}/${total}") | 956 | logger.debug("Progress notification for sessionId: ${sessionId}, token: ${progressToken}, progress: ${progressValue}/${total}") |
| 957 | // Store progress for potential polling | 957 | // Store progress for potential polling |
| 958 | if (sessionId && progressToken) { | 958 | if (sessionId && progressToken) { |
| 959 | def progressKey = "${sessionId}_${progressToken}" | 959 | def progressKey = "${sessionId}_${progressToken}" |
| ... | @@ -963,12 +963,12 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -963,12 +963,12 @@ class EnhancedMcpServlet extends HttpServlet { |
| 963 | case "notifications/resources/updated": | 963 | case "notifications/resources/updated": |
| 964 | // Handle resource updated notification | 964 | // Handle resource updated notification |
| 965 | def uri = params?.uri | 965 | def uri = params?.uri |
| 966 | logger.info("Resource updated notification for sessionId: ${sessionId}, uri: ${uri}") | 966 | logger.debug("Resource updated notification for sessionId: ${sessionId}, uri: ${uri}") |
| 967 | // Could trigger resource cache invalidation here | 967 | // Could trigger resource cache invalidation here |
| 968 | return null | 968 | return null |
| 969 | case "notifications/prompts/list_changed": | 969 | case "notifications/prompts/list_changed": |
| 970 | // Handle prompts list changed notification | 970 | // Handle prompts list changed notification |
| 971 | logger.info("Prompts list changed for sessionId: ${sessionId}") | 971 | logger.debug("Prompts list changed for sessionId: ${sessionId}") |
| 972 | // Could trigger prompt cache invalidation here | 972 | // Could trigger prompt cache invalidation here |
| 973 | return null | 973 | return null |
| 974 | case "notifications/message": | 974 | case "notifications/message": |
| ... | @@ -976,7 +976,7 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -976,7 +976,7 @@ class EnhancedMcpServlet extends HttpServlet { |
| 976 | def level = params?.level ?: "info" | 976 | def level = params?.level ?: "info" |
| 977 | def message = params?.message | 977 | def message = params?.message |
| 978 | def data = params?.data | 978 | def data = params?.data |
| 979 | logger.info("Message notification for sessionId: ${sessionId}, level: ${level}, message: ${message}") | 979 | logger.debug("Message notification for sessionId: ${sessionId}, level: ${level}, message: ${message}") |
| 980 | // Store message for potential retrieval | 980 | // Store message for potential retrieval |
| 981 | if (sessionId) { | 981 | if (sessionId) { |
| 982 | def messages = sessionMessages.get(sessionId) ?: [] | 982 | def messages = sessionMessages.get(sessionId) ?: [] |
| ... | @@ -986,12 +986,12 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -986,12 +986,12 @@ class EnhancedMcpServlet extends HttpServlet { |
| 986 | return null | 986 | return null |
| 987 | case "notifications/roots/list_changed": | 987 | case "notifications/roots/list_changed": |
| 988 | // Handle roots list changed notification | 988 | // Handle roots list changed notification |
| 989 | logger.info("Roots list changed for sessionId: ${sessionId}") | 989 | logger.debug("Roots list changed for sessionId: ${sessionId}") |
| 990 | // Could trigger roots cache invalidation here | 990 | // Could trigger roots cache invalidation here |
| 991 | return null | 991 | return null |
| 992 | case "logging/setLevel": | 992 | case "logging/setLevel": |
| 993 | // Handle logging level change notification | 993 | // Handle logging level change notification |
| 994 | logger.info("Logging level change requested for sessionId: ${sessionId}") | 994 | logger.debug("Logging level change requested for sessionId: ${sessionId}") |
| 995 | return null | 995 | return null |
| 996 | default: | 996 | default: |
| 997 | throw new IllegalArgumentException("Method not found: ${method}") | 997 | throw new IllegalArgumentException("Method not found: ${method}") |
| ... | @@ -1073,14 +1073,14 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -1073,14 +1073,14 @@ class EnhancedMcpServlet extends HttpServlet { |
| 1073 | */ | 1073 | */ |
| 1074 | void queueNotification(String sessionId, Map notification) { | 1074 | void queueNotification(String sessionId, Map notification) { |
| 1075 | if (!sessionId || !notification) return | 1075 | if (!sessionId || !notification) return |
| 1076 | 1076 | ||
| 1077 | def queue = notificationQueues.computeIfAbsent(sessionId) { [] } | 1077 | def queue = notificationQueues.computeIfAbsent(sessionId) { [] } |
| 1078 | queue << notification | 1078 | queue << notification |
| 1079 | logger.info("Queued notification for session ${sessionId}: ${notification}") | 1079 | logger.info("Queued notification for session ${sessionId}: ${notification}") |
| 1080 | 1080 | ||
| 1081 | // Session activity updates handled at JSON-RPC level, not notification level | 1081 | // Session activity updates handled at JSON-RPC level, not notification level |
| 1082 | // This prevents excessive database updates during notification processing | 1082 | // This prevents excessive database updates during notification processing |
| 1083 | 1083 | ||
| 1084 | // Also try to send via SSE if active connection exists | 1084 | // Also try to send via SSE if active connection exists |
| 1085 | def writer = activeConnections.get(sessionId) | 1085 | def writer = activeConnections.get(sessionId) |
| 1086 | if (writer && !writer.checkError()) { | 1086 | if (writer && !writer.checkError()) { |
| ... | @@ -1092,7 +1092,7 @@ class EnhancedMcpServlet extends HttpServlet { | ... | @@ -1092,7 +1092,7 @@ class EnhancedMcpServlet extends HttpServlet { |
| 1092 | params: notification.params ?: notification | 1092 | params: notification.params ?: notification |
| 1093 | ] | 1093 | ] |
| 1094 | sendSseEvent(writer, "message", JsonOutput.toJson(notificationMessage), System.currentTimeMillis()) | 1094 | sendSseEvent(writer, "message", JsonOutput.toJson(notificationMessage), System.currentTimeMillis()) |
| 1095 | logger.info("Sent notification via SSE to session ${sessionId}") | 1095 | logger.debug("Sent notification via SSE to session ${sessionId}") |
| 1096 | } catch (Exception e) { | 1096 | } catch (Exception e) { |
| 1097 | logger.warn("Failed to send notification via SSE to session ${sessionId}: ${e.message}") | 1097 | logger.warn("Failed to send notification via SSE to session ${sessionId}: ${e.message}") |
| 1098 | } | 1098 | } | ... | ... |
| ... | @@ -190,27 +190,14 @@ class UiNarrativeBuilder { | ... | @@ -190,27 +190,14 @@ class UiNarrativeBuilder { |
| 190 | } | 190 | } |
| 191 | } | 191 | } |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | if (navigation.isEmpty()) { | ||
| 195 | def parentPath = getParentPath(currentPath) | ||
| 196 | if (parentPath) { | ||
| 197 | navigation << "To go back, call moqui_render_screen(path='${parentPath}')." | ||
| 198 | } | ||
| 199 | } | ||
| 200 | |||
| 201 | return navigation | ||
| 202 | } | ||
| 203 | } | ||
| 204 | } | ||
| 205 | } | ||
| 206 | |||
| 207 | if (navigation.isEmpty()) { | 194 | if (navigation.isEmpty()) { |
| 208 | def parentPath = getParentPath(currentPath) | 195 | def parentPath = getParentPath(currentPath) |
| 209 | if (parentPath) { | 196 | if (parentPath) { |
| 210 | navigation << "To go back, call moqui_browse_screens(path='${parentPath}')." | 197 | navigation << "To go back, call moqui_browse_screens(path='${parentPath}')." |
| 211 | } | 198 | } |
| 212 | } | 199 | } |
| 213 | 200 | ||
| 214 | return navigation | 201 | return navigation |
| 215 | } | 202 | } |
| 216 | 203 | ... | ... |
| ... | @@ -56,8 +56,8 @@ class VisitBasedMcpSession implements MoquiMcpTransport { | ... | @@ -56,8 +56,8 @@ class VisitBasedMcpSession implements MoquiMcpTransport { |
| 56 | metadata.mcpTransportType = "SSE" | 56 | metadata.mcpTransportType = "SSE" |
| 57 | metadata.mcpMessageCount = 0 | 57 | metadata.mcpMessageCount = 0 |
| 58 | saveSessionMetadata(metadata) | 58 | saveSessionMetadata(metadata) |
| 59 | 59 | ||
| 60 | logger.info("MCP Session initialized for Visit ${visit.visitId}") | 60 | logger.debug("MCP Session initialized for Visit ${visit.visitId}") |
| 61 | } | 61 | } |
| 62 | } catch (Exception e) { | 62 | } catch (Exception e) { |
| 63 | logger.warn("Failed to initialize MCP session for Visit ${visit.visitId}: ${e.message}") | 63 | logger.warn("Failed to initialize MCP session for Visit ${visit.visitId}: ${e.message}") |
| ... | @@ -90,10 +90,10 @@ class VisitBasedMcpSession implements MoquiMcpTransport { | ... | @@ -90,10 +90,10 @@ class VisitBasedMcpSession implements MoquiMcpTransport { |
| 90 | if (!active.compareAndSet(true, false)) { | 90 | if (!active.compareAndSet(true, false)) { |
| 91 | return // Already closed | 91 | return // Already closed |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | closing.set(true) | 94 | closing.set(true) |
| 95 | logger.info("Gracefully closing MCP session ${visit.visitId}") | 95 | logger.debug("Gracefully closing MCP session ${visit.visitId}") |
| 96 | 96 | ||
| 97 | try { | 97 | try { |
| 98 | // Send graceful shutdown notification | 98 | // Send graceful shutdown notification |
| 99 | def shutdownMessage = new JsonRpcNotification("shutdown", [ | 99 | def shutdownMessage = new JsonRpcNotification("shutdown", [ |
| ... | @@ -116,9 +116,9 @@ class VisitBasedMcpSession implements MoquiMcpTransport { | ... | @@ -116,9 +116,9 @@ class VisitBasedMcpSession implements MoquiMcpTransport { |
| 116 | if (!active.compareAndSet(true, false)) { | 116 | if (!active.compareAndSet(true, false)) { |
| 117 | return // Already closed | 117 | return // Already closed |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | logger.info("Closing MCP session ${visit.visitId} (messages sent: ${messageCount.get()})") | 120 | logger.debug("Closing MCP session ${visit.visitId} (messages sent: ${messageCount.get()})") |
| 121 | 121 | ||
| 122 | try { | 122 | try { |
| 123 | // Send final close event if writer is still available | 123 | // Send final close event if writer is still available |
| 124 | if (writer && !writer.checkError()) { | 124 | if (writer && !writer.checkError()) { | ... | ... |
-
Please register or sign in to post a comment