blob: aec8aef9449b1ed483ee3fa37ae6834d736dfaa5 [file] [view]
# Implementation Summary: EventMesh A2A Protocol v2.0 (MCP Edition)
## Key Achievements
The A2A protocol has been successfully refactored to adopt the **MCP (Model Context Protocol)** architecture, positioning EventMesh as a modern **Agent Collaboration Bus**.
### 1. Core Protocol Refactoring (`EnhancedA2AProtocolAdaptor`)
- **Hybrid Engine (JSON-RPC & CloudEvents)**: Implemented a smart parsing engine that supports:
- **MCP/JSON-RPC 2.0**: For LLM-friendly, low-code integration.
- **Native CloudEvents**: For advanced, protocol-compliant integration.
- The adaptor automatically delegates processing based on the payload content (`jsonrpc` detection).
- **Async RPC Mapping**: Established a bridge between synchronous RPC semantics and asynchronous Event-Driven Architecture (EDA).
- **Requests** map to `*.req` events with `mcptype=request`.
- **Responses** map to `*.resp` events with `mcptype=response`.
- **Correlation** is handled by mapping JSON-RPC `id` to CloudEvent `collaborationid`.
- **Routing Optimization**: Implemented "Deep Body Routing" extraction:
- `params._agentId` -> CloudEvent Extension `targetagent` (P2P).
- `params._topic` -> CloudEvent Subject (Pub/Sub).
### 2. Native Pub/Sub & Streaming
- **Pub/Sub**: Added support for O(1) broadcast complexity by mapping `_topic` to CloudEvent Subject.
- **Streaming**: Added support for `message/sendStream` operation, mapping to `.stream` event type and preserving sequence via `_seq` -> `seq` extension.
### 3. Standardization & Compatibility
- **Models**: Defined `JsonRpcRequest`, `JsonRpcResponse`, `JsonRpcError` POJOs compliant with JSON-RPC 2.0 spec.
- **Methods**: Introduced `McpMethods` constants for standard operations like `tools/call`, `resources/read`.
- **AgentCard Models**: Implemented `AgentCard`, `AgentSkill`, `AgentInterface`, `AgentCapabilities` for complete agent capability description.
### 4. Gateway Runtime Architecture (`eventmesh-runtime`)
A standalone HTTP Gateway service bridging external clients to the A2A event bus.
#### Core Components
| Component | Responsibility |
| :--- | :--- |
| `A2AGatewayServer` | Netty HTTP server entry point, pre-registers mock agents, wires all components |
| `A2AGatewayHttpHandler` | HTTP request router, supports SSE streaming responses |
| `A2AGatewayService` | Core orchestration: task submission, response handling, status subscription, SSE push |
| `TaskRegistry` | In-memory task state machine + TTL auto-cleanup |
| `A2APublishSubscribeService` | AgentCard registration, discovery, heartbeat management |
| `InMemoryA2AMessageTransport` | In-memory pub/sub (replaceable by EventMesh broker) |
| `A2ACardHttpHandler` | AgentCard CRUD REST endpoints |
| `A2AClient` | Java SDK with typed API |
#### REST API
| Method | Path | Description |
| :--- | :--- | :--- |
| `POST` | `/a2a/tasks?mode=sync` | Submit task synchronously |
| `POST` | `/a2a/tasks?mode=async` | Submit task asynchronously |
| `GET` | `/a2a/tasks/{taskId}` | Get task status |
| `DELETE` | `/a2a/tasks/{taskId}` | Cancel a task |
| `GET` | `/a2a/tasks/{taskId}/wait` | Long-poll wait for result |
| `GET` | `/a2a/tasks/{taskId}/stream` | SSE stream of task status updates |
| `GET` | `/a2a/agents` | List registered agents |
| `POST` | `/a2a/heartbeat` | Agent heartbeat |
| `GET` | `/a2a/cards/list` | List all AgentCards |
| `POST` | `/a2a/cards/card/{org}/{unit}/{agent}` | Register an AgentCard |
### 5. Key Improvements
#### 5.1 TaskRegistry TTL Auto-Cleanup
- **Problem**: Terminal-state tasks (COMPLETED/FAILED/CANCELLED) accumulate indefinitely, causing memory leaks.
- **Solution**: A daemon `ScheduledExecutorService` runs every 60 seconds, removing terminal-state tasks older than the TTL (default: 5 minutes).
- **Configuration**: `TaskRegistry(taskTtlMs, cleanupIntervalMs)` constructor allows custom tuning.
#### 5.2 Race Condition Fix
- **Problem**: `InMemoryTransport` delivers messages synchronously. If `transport.publish()` executes before `pendingTasks.put()`, `handleResponse()` runs before `put()` and the future never completes.
- **Solution**: Ensure `pendingTasks.put(taskId, future)` is called **before** `transport.publish()`, with comments documenting the ordering importance.
#### 5.3 A2AClient Typed Returns
- **Improvement**: `getTaskStatus()` returns `TaskResult` object (instead of raw JSON string), `listAgents()` returns `List<String>` (instead of raw JSON).
- **Compatibility**: `TaskResult.data` field uses `@JsonAlias("result")` annotation to handle the server's `result` field name.
#### 5.4 SSE Streaming Response
- **Endpoint**: `GET /a2a/tasks/{taskId}/stream`
- **Implementation**: Handler writes `DefaultHttpContent` chunks directly to the Netty channel, returning `null` to skip the standard `FullHttpResponse` path. Uses `StatusSubscriber` callbacks for real-time state push.
#### 5.5 Usage Documentation
- Created `eventmesh-examples/.../demo/README.md` with architecture diagram, API table, curl examples, SDK usage, and run instructions.
### 6. Testing & Quality
- **Protocol Unit Tests**: `EnhancedA2AProtocolAdaptorTest` covers Request/Response cycles, Error handling, Notifications, and Batching.
- **Topic Utility Tests**: `A2ATopicFactoryTest` covers topic generation and parsing.
- **Gateway Runtime Tests**:
- `TaskRegistryTest` — Task state machine + TTL cleanup verification
- `InMemoryA2AMessageTransportTest` — In-memory transport delivery
- `A2AGatewayServiceTest` — Gateway service layer
- `A2AGatewayEndToEndTest` — In-process end-to-end flow
- `A2AClientServerIntegrationTest` — Real HTTP client-server integration test
- **Integration Demos**: `McpIntegrationDemoTest`, `McpPatternsIntegrationTest`, `McpComprehensiveDemoTest`, `CloudEventsComprehensiveDemoTest`
- **Total**: 73 test scenarios, all passing.
## Next Steps
1. **EventMesh Broker Integration**: Replace `InMemoryA2AMessageTransport` with the real EventMesh broker for production deployment.
2. **Router Integration**: Update EventMesh Runtime Router to leverage `targetagent` and `a2amethod` extension attributes for advanced routing rules.
3. **Schema Registry**: Implement a "Registry Agent" that allows agents to publish their MCP capabilities (`methods/list`) dynamically.
4. **Sidecar Support**: Expose the A2A adaptor logic in the Sidecar proxy to allow non-Java agents (Python, Node.js) to interact via simple HTTP/JSON.
5. **WebSocket Streaming**: Extend SSE to bidirectional WebSocket for real-time agent dialogue.
6. **Task Persistence**: Persist `TaskRegistry` state to a durable store (Redis/DB) for crash recovery.
7. **Authentication**: Add API key / JWT authentication to the Gateway REST API.