Class ChatHandler

java.lang.Object
org.codelibs.fess.api.v2.handlers.ChatHandler

public class ChatHandler extends Object
Handles POST /api/v2/chat — non-streaming RAG chat.

Thin adapter: parses the v2 JSON body, validates the message length, then delegates to ChatClient.chat(java.lang.String, java.lang.String, java.lang.String). The response is wrapped in the v2 envelope as {response: {status:0, session_id, content, sources}}.

Session clearing has been moved to the dedicated DELETE endpoint /api/v2/chat/sessions/{session_id} handled by ChatSessionClearHandler.

Anonymous users are supported the same way v1 supports them — the user is identified by UserInfoHelper#getUserCode() when no logged-in bean is present. See §Risks (3) in the plan for the auth-posture rationale.

  • Constructor Summary

    Constructors
    Constructor
    Description
    Default constructor used by the DI container.
  • Method Summary

    Modifier and Type
    Method
    Description
    protected ChatClient
    Resolves the RAG ChatClient.
    protected String
    getRateLimitKey(jakarta.servlet.http.HttpServletRequest req)
    Resolves the chat rate-limit key (server-validated username for authenticated callers, else the proxy-aware client IP).
    protected String
    getUserId(jakarta.servlet.http.HttpServletRequest req)
    Resolves the effective chat user id.
    void
    handle(jakarta.servlet.http.HttpServletRequest req, jakarta.servlet.http.HttpServletResponse res)
    Processes one POST /api/v2/chat request.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • ChatHandler

      public ChatHandler()
      Default constructor used by the DI container. The handler holds no per-request state and is safe to share across concurrent requests.
  • Method Details

    • handle

      public void handle(jakarta.servlet.http.HttpServletRequest req, jakarta.servlet.http.HttpServletResponse res) throws IOException
      Processes one POST /api/v2/chat request.

      Rejects non-POST methods with V2ErrorCode.METHOD_NOT_ALLOWED. Validates the feature flag, parses the JSON body, enforces per-user chat rate limiting, then delegates to ChatClient.chat(java.lang.String, java.lang.String, java.lang.String) and writes the result as a v2 success envelope. Pre-call failures (parse errors, gate failures, DI lookup failures) are reported as structured error envelopes.

      Parameters:
      req - the incoming HTTP request
      res - the HTTP response to write to
      Throws:
      IOException - if writing the envelope or reading the body fails
    • getUserId

      protected String getUserId(jakarta.servlet.http.HttpServletRequest req)
      Resolves the effective chat user id. Exposed as a seam so unit tests can override the user identity directly. SystemHelper/UserInfoHelper are smart-deploy components, so stubbing them via ComponentUtil.register is not reliable once the shared test container has resolved the real ones; overriding this method avoids that fragility.
      Parameters:
      req - the incoming HTTP request
      Returns:
      the user identifier (never null)
    • getRateLimitKey

      protected String getRateLimitKey(jakarta.servlet.http.HttpServletRequest req)
      Resolves the chat rate-limit key (server-validated username for authenticated callers, else the proxy-aware client IP). Exposed as a seam so unit tests can pin the throttle key deterministically; the underlying SystemHelper/RateLimitHelper are smart-deploy components that are unreliable to stub via ComponentUtil.register once the shared test container has resolved the real ones (same rationale as getUserId(jakarta.servlet.http.HttpServletRequest)).
      Parameters:
      req - the incoming HTTP request
      Returns:
      the rate-limit key (never null/blank)
    • getChatClient

      protected ChatClient getChatClient()
      Resolves the RAG ChatClient. Exposed as a seam so unit tests can substitute a stub by overriding this method rather than registering into the DI container — chatClient is a named/smart-deploy component whose ComponentUtil.register fallback is order-sensitive across the shared test container (same rationale as getUserId(jakarta.servlet.http.HttpServletRequest)).
      Returns:
      the chat client component (never null in production)