feat(a2a): wire A2A Gateway onto Runtime via TaskStore (issue #5302 Sub-PR D1) - #5313
Merged
Merged
Conversation
…5302 Sub-PR D1) Brings the A2A Gateway back into the Runtime, this time with the unified control-plane stores from apache#5301 Sub-PR A/C as the durable backend instead of the in-memory TaskRegistry that PR apache#5260 introduced. What lands ---------- * A2AGatewayService — task lifecycle controller. Replaces the in-memory TaskRegistry with TaskStore (Sub-PR A/C). A small runtime cache holds the two fields TaskStore does not model: parentTaskId (used to render child-task queries) and taskEpoch (the per-task counter the store requires for stale-write rejection on updateStatus). Both caches are rebuildable from the store on a fresh JVM; the cache keys are taskIds, so the cache size tracks active tasks only. * A2AGatewayHttpHandler — Netty HTTP handler for the REST + SSE API (/a2a/tasks, /a2a/tasks/{id}, /a2a/tasks/{id}/stream, /a2a/health). SSE registers a StatusSubscriber so intermediate PENDING -> RUNNING -> COMPLETED transitions stream to the client. * A2AGatewayServer — Netty HTTP bootstrap. Production wires EventMeshA2ATransport (Runtime-bridged) for the A2AMessageTransport dependency; tests pass an in-process transport. The weather-agent demo from PR apache#5260 is removed — the demo client (A2AGatewayDemo) and the Meta-ized AgentCard registry land in Sub-PR D2. * AgentCardRegistry + InMemoryAgentCardRegistry — minimal discovery surface (isAgentRegistered / registerCard / getCard). A Meta-backed implementation backed by SessionStore (Sub-PR A) lands in D2. Status mapping (PR apache#5260 -> Sub-PR A/C) --------------------------------------- SUBMITTED -> PENDING, WORKING -> RUNNING, CANCELLED -> CANCELED (one L) The legacy wire vocabulary stays available via A2AGatewayService.TaskState and the toLegacyState() helper. JSON response payloads still emit SUBMITTED/WORKING/CANCELLED so existing A2A clients do not break. Documentation ------------- * docs/a2a-protocol/README.md carries an EXPERIMENTAL banner that lists the three pieces still missing for production (TaskExpirer, Meta-ized AgentCard, Testcontainers E2E) — all scheduled for Sub-PR D2. Acceptance against issue apache#5302 ------------------------------ * "A2A transport over the Runtime delivery path" — A2AGatewayService takes an A2AMessageTransport; production wires EventMeshA2ATransport which already bridges A2A onto UniIngressService (issue apache#5301 Sub-PR A's runtime ingress). The parallel InMemoryA2AMessageTransport is no longer required by the gateway path. * "A2A tasks persist through TaskStore and recover across restarts" — createTask / updateStatus / getTask all go through the persistent store. On a fresh JVM, a gateway that had pending tasks sees them with their last persisted status; in-flight work that was awaiting a response will be picked up on the next status callback. Tests (7, all passing) ---------------------- * A2AGatewayServiceTest — 6 tests: create+complete, cancel, cancel-on- unknown, submit-to-unregistered, parent-child index, task-not-found. Uses an in-process TaskStore (mirrors Sub-PR A's test stub) and an in-process A2AMessageTransport that handles A2A's + single-segment wildcards. * A2AGatewaySmokeTest — Netty HTTP /a2a/health loopback check. Not in D1 (Sub-PR D2) --------------------- * TaskExpirer reaper (periodic TaskStore.expireStale sweep). * Meta-backed AgentCardRegistry (SessionStore). * Testcontainers fault-injection E2E.
…5313) A2AGatewayHttpHandler.java: - Remove unused imports (A2AProtocolConstants, A2ATopicFactory, TaskState) - Expand try-catch blocks for limit/offset parsing (EmptyCatchBlock, NeedBraces) - Expand handleList loop control flow (NeedBraces) - Collapse duplicate blank line between package and imports (EmptyLineSeparator) A2AGatewayServiceTest.java: - Expand single-line if-blocks in InProcessTaskStore.listByAgent - Expand if-block in InProcessTransport.matches - Expand if-blocks in tearDown - Move taskId declaration closer to its use (VariableDeclarationUsageDistance) A2AGatewaySmokeTest.java: - Rewrite StubTaskStore / NoopTransport with multi-line method bodies (LeftCurly, RightCurlyAlone, NeedBraces, EmptyLineSeparator) - Add missing static imports (assertEquals, assertNotNull) Build PR apache#5313 fix.
…owup) A2AGatewayServiceTest.java: - Fix ImportOrder: AgentCapabilities before AgentCard (alphabetical) - Fix VariableDeclarationUsageDistance for f: inline taskId into submitTask call so the declaration is closer to first use A2AGatewaySmokeTest.java: - Fix ImportOrder: static Assertions imports before non-static TaskStore import Build PR apache#5313 followup.
…ollowup) The previous fixup broke the test logic by calling TaskResult.getTaskId() which does not exist. Restore the original taskId declaration pattern while keeping the f declaration within 3 lines of its first use: - Declare taskId first - Declare f immediately after - Inline cancelTask result into the assertTrue (no intermediate boolean) - Move f.get() call right after the cancel assertion so f's first use is within 3 lines of its declaration Build PR apache#5313 followup.
Contributor
Author
CI build fix pushed
Verified locally:
No D1 code changes - all fixes are to satisfy Apache Checkstyle rules for the new files in D1. |
This was referenced Aug 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brings the A2A Gateway back into the Runtime, this time with the unified control-plane stores from #5301 Sub-PR A/C as the durable backend.
What lands
Status mapping (PR #5260 → Sub-PR A/C)
The legacy wire vocabulary stays available via A2AGatewayService.TaskState and the toLegacyState() helper. JSON response payloads still emit SUBMITTED/WORKING/CANCELLED so existing A2A clients do not break.
Acceptance against issue #5302
Tests (7, all passing locally)
Not in D1 (Sub-PR D2)
Fixes #5302 P1 acceptance criteria (partial: A2A-via-Runtime transport + TaskStore persistence + Experimental banner). Closes #5302 for the parts of the acceptance criteria that this PR delivers; the remaining D2 work will be tracked in a follow-up issue.
Co-authored-by: qqeasonchen qqeasonchen@gmail.com