Class A2AServerRoutes

java.lang.Object
org.a2aproject.sdk.server.apps.quarkus.A2AServerRoutes

@Singleton public class A2AServerRoutes extends Object
Quarkus routing configuration for JSON-RPC A2A protocol requests.

This class defines Vert.x Web routes for handling JSON-RPC 2.0 requests over HTTP, processing them through the JSONRPCHandler, and returning responses in either standard JSON or Server-Sent Events (SSE) format for streaming operations.

Request Flow

HTTP POST / → invokeJSONRPCHandler()
    ↓
Parse JSON-RPC request body
    ↓
Route to handler method (blocking or streaming)
    ↓
JSONRPCHandler → RequestHandler → AgentExecutor
    ↓
Response (JSON or SSE stream)

Supported Operations

Non-Streaming (JSON responses):

  • sendMessage - Send message and wait for completion
  • getTask - Retrieve task by ID
  • cancelTask - Cancel task execution
  • listTasks - List tasks with filtering
  • setTaskPushNotificationConfig - Configure push notifications
  • getTaskPushNotificationConfig - Get push notification config
  • listTaskPushNotificationConfigs - List push notification configs
  • deleteTaskPushNotificationConfig - Delete push notification config
  • getExtendedAgentCard - Get extended agent capabilities

Streaming (SSE responses):

  • sendStreamingMessage - Send message with streaming response
  • subscribeToTask - Subscribe to task events

JSON-RPC Request Format

POST /
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "id": "req-123",
  "method": "sendMessage",
  "params": {
    "message": {
      "parts": [{"text": "Hello"}]
    }
  }
}

Error Handling

Errors are mapped to JSON-RPC 2.0 error responses:

CDI Integration

This class is a CDI @Singleton that automatically wires:

Multi-Tenancy Support

Tenant identification is extracted from the request path:

  • POST / → empty tenant
  • POST /tenant1 → tenant "tenant1"
  • POST /tenant1/ → tenant "tenant1" (trailing slash stripped)
See Also:
  • Constructor Details

    • A2AServerRoutes

      public A2AServerRoutes()
  • Method Details

    • invokeJSONRPCHandler

      public void invokeJSONRPCHandler(String body, io.vertx.ext.web.RoutingContext rc)
      Main entry point for all JSON-RPC requests.

      This route handler processes JSON-RPC 2.0 requests, dispatches them to the appropriate handler method based on the request type (streaming vs non-streaming), and returns either a JSON response or an SSE stream.

      Request Format:

      POST /[tenant]
      Content-Type: application/json
      
      {
        "jsonrpc": "2.0",
        "id": "req-123",
        "method": "sendMessage",
        "params": { ... }
      }
      

      Non-Streaming Response:

      HTTP/1.1 200 OK
      Content-Type: application/json
      
      {
        "jsonrpc": "2.0",
        "id": "req-123",
        "result": { ... }
      }
      

      Streaming Response (SSE):

      HTTP/1.1 200 OK
      Content-Type: text/event-stream
      
      id: 0
      data: {"jsonrpc":"2.0","id":"req-123","result":{...}}
      
      id: 1
      data: {"jsonrpc":"2.0","id":"req-123","result":{...}}
      

      Error Response:

      HTTP/1.1 200 OK
      Content-Type: application/json
      
      {
        "jsonrpc": "2.0",
        "id": "req-123",
        "error": {
          "code": -32602,
          "message": "Invalid params"
        }
      }
      

      Processing Flow:

      1. Parse JSON-RPC request body using JSONRPCUtils.parseRequestBody(String, String)
      2. Create ServerCallContext from routing context
      3. Route to streaming or non-streaming handler
      4. Handle errors with appropriate JSON-RPC error codes
      5. Return JSON response or start SSE stream
      Parameters:
      body - the raw JSON-RPC request body
      rc - the Vert.x routing context containing HTTP request/response
      Throws:
      A2AError - if request processing fails
    • getAgentCard

      public @Nullable String getAgentCard(io.vertx.ext.web.RoutingContext rc) throws JsonProcessingException
      Handles GET requests to the agent card endpoint.

      Returns the agent's capabilities and metadata in JSON format according to the A2A protocol specification. This endpoint is publicly accessible (no authentication).

      Includes HTTP caching headers per A2A specification section 8.6:

      • Cache-Control - with max-age directive
      • ETag - content hash for validation
      • Last-Modified - timestamp when agent card was initialized

      Request:

      GET /.well-known/agent-card.json
      

      Response:

      HTTP/1.1 200 OK
      Content-Type: application/json
      Cache-Control: public, max-age=3600
      ETag: "a1b2c3d4..."
      Last-Modified: Mon, 17 Mar 2025 10:00:00 GMT
      
      {
        "name": "My Agent",
        "description": "Agent description",
        "capabilities": {
          "streaming": true,
          "pushNotifications": false
        },
        ...
      }
      
      Parameters:
      rc - the Vert.x routing context
      Returns:
      the agent card as a JSON string
      Throws:
      JsonProcessingException - if serialization fails
      See Also:
    • getTenantAgentCard

      public @Nullable String getTenantAgentCard(io.vertx.ext.web.RoutingContext rc) throws JsonProcessingException
      Retrieves the public agent card for a specific tenant.
      Parameters:
      rc - the Vert.x routing context (must contain a tenant path parameter)
      Returns:
      the tenant-specific agent card as a JSON string
      Throws:
      IllegalArgumentException - if the tenant contains invalid characters
      JsonProcessingException - if serialization fails
    • setStreamingMultiSseSupportSubscribedRunnable

      public static void setStreamingMultiSseSupportSubscribedRunnable(Runnable runnable)
      Sets a callback to be invoked when SSE streaming subscription starts.

      This is a testing hook used to synchronize test execution with streaming setup. In production, this remains null.

      Parameters:
      runnable - the callback to invoke on subscription