)]}'
{
  "commit": "2527428788cb8af6104db600dffea5746fb5479f",
  "tree": "3d145e3ce975f03682c89c44842c909d4672264c",
  "parents": [
    "7cfbeded744d3859030dd7285501e35ecdbd5b4d"
  ],
  "author": {
    "name": "Eason Chen",
    "email": "qqeasonchen@gmail.com",
    "time": "Mon Jun 29 09:10:32 2026 +0800"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Mon Jun 29 09:10:32 2026 +0800"
  },
  "message": "[ISSUE #5259] Add A2A Gateway: REST API, SSE streaming, Task lifecycle, Java SDK and tests (#5260)\n\n* [EVENTMESH-xxx] Add A2A Gateway: REST API, SSE streaming, Task lifecycle, Java SDK and tests\n\n## What\u0027s New\n\n### A2A Gateway Runtime (eventmesh-runtime)\n- A2AGatewayServer: standalone HTTP server entry point\n- A2AGatewayService: core gateway logic with task timeout, agent validation,\n  cancel notification, and concurrent-safe status subscribers\n- A2AGatewayHttpHandler: Netty-based REST handler with CORS, SSE streaming,\n  health check, task list pagination, and precise error codes\n- TaskRegistry: in-memory task lifecycle management with TTL cleanup,\n  CopyOnWriteArrayList for parent-child concurrency safety\n- InMemoryA2AMessageTransport: default transport implementation\n- A2ACardHttpHandler: enhanced with CORS headers\n\n### A2A Protocol Plugin (eventmesh-protocol-a2a)\n- A2AClient: typed Java SDK with sync/async task send, SSE streaming\n  (streamTaskStatus), agent discovery, heartbeat, and SSE-aware socket timeout\n- A2AMessageTransport: transport abstraction interface\n- A2ATopicFactory: A2A topic convention standardization\n- A2ATopicFactoryTest: unit tests\n\n### Examples\n- A2AGatewayDemo: end-to-end HTTP client demo\n\n### Tests (all passing)\n- A2AGatewayServiceTest: 15+ tests covering timeout, agent validation,\n  cancel, SSE, pagination\n- TaskRegistryTest: TTL, concurrent child creation, lifecycle transitions\n- A2AClientServerIntegrationTest: full client-server integration with\n  SSE streaming, CORS, health, heartbeat\n- A2AGatewayEndToEndTest: end-to-end pipeline verification\n- InMemoryA2AMessageTransportTest: transport unit tests\n\n### Documentation (7 files updated)\n- eventmesh-a2a-design.md, ARCHITECTURE.md, IMPLEMENTATION_SUMMARY.md,\n  IMPLEMENTATION_SUMMARY_EN.md, TEST_RESULTS.md, README.md, README_EN.md\n\n### Key Engineering Decisions\n- Task timeout: auto-fail non-terminal tasks after configurable threshold\n- SSE: heartbeat mechanism + socketTimeout(0) for long-lived connections\n- Concurrency: CopyOnWriteArrayList + ConcurrentHashMap throughout\n- CORS: Access-Control-Allow-Origin on all A2A endpoints\n- Agent validation: reject tasks for unregistered agents\n\n* fix: fix Javadoc bad use of \u0027\u003e\u0027 in A2AGatewayDemo flow diagram\n\nReplace \u0027--\u003e\u0027 arrow notation with HTML entity \u0027\u0026gt;\u0027 in Javadoc \u003cpre\u003e block\nto fix javadoc compilation error: \u0027bad use of \"\u003e\".\n\nThe \u0027\u003e\u0027 character inside \u003cpre\u003e blocks in Javadoc must be escaped as \u0027\u0026gt;\u0027\nwhen it appears after \u0027-\u0027 characters (forming \u0027--\u003e\u0027 which Java parser\nmisinterprets as an HTML comment end marker).\n\nFixes: CodeQL Analyze (java) and all Build CI failures in PR #5260.\n\n* fix: escape \u0027\u003e\u0027 in TaskRegistry Javadoc state machine diagram\n\nReplace \u0027-\u003e\u0027 with \u0027-\u0026gt;\u0027 in Javadoc \u003cpre\u003e block to avoid\njavadoc \u0027bad use of \u003e\u0027 compilation error. The Java parser\ninterprets \u0027\u003e\u0027 in \u003cpre\u003e blocks as HTML tag closers.\n\nFixes: remaining CI build failure in PR #5260 after first fix.\n\n* fix: resolve all checkstyle violations in A2A module\n\ncheckstyleMain (4 files, 8 violations):\n- Remove unused imports (ArrayList, Objects)\n- Fix import ordering per project convention: static first, then\n  org.apache.eventmesh, org.apache, java, io, org.junit, com\n- Replace Unicode escape (\\u00b0) with literal degree symbol\n- Add missing Javadoc for StatusSubscriber interface\n\ncheckstyleTest (5 files, 9 violations):\n- Move static imports to top (option\u003dtop in checkstyle config)\n- Fix import group ordering (io before org per groups config)\n- Remove unused import (assertNull)\n- Fix VariableDeclarationUsageDistance by moving declarations\n  closer to first usage\n\nFixes: third round of CI failures in PR #5260 after javadoc fixes.\n\n* fix: correct import group ordering in A2A module\n\ncheckstyle groups order: org.apache.eventmesh,org.apache,java,javax,org,io,net,junit,com,lombok\n\n- Move org.junit.jupiter.* (org group) before io.cloudevents.* (io group) in test files\n- Separate com.fasterxml and lombok into their own groups with blank lines in A2AGatewayService\n\nFixes: 4th round checkstyle violations in PR #5260\n\n* fix: stabilize flaky testHeartbeatRefreshesTtl test\n\nIncrease TTL from 200ms to 500ms and cleanup interval from 100ms to 250ms\nto prevent race condition on slow CI runners (macOS). Add assertion messages\nfor better debugging.\n\nThe test was flaky because Thread.sleep(100) could exceed 100ms on overloaded\nCI runners, causing the cleanup to expire the card before heartbeat check.\n\nFixes: 5th round CI failure on macOS in PR #5260\n\n* fix: resolve checkstyle violations in protocol-a2a module\n\n- A2AMessageTransport.java: add Javadoc for MessageCallback interface\n- A2AClient.java: remove unused java.util.function.Consumer import\n- A2AClient.java: fix import order (org.apache.eventmesh, org.apache,\n  java, org, io, com per checkstyle groups)\n- A2AClient.java: add Javadoc for RequestHandler interface\n\nFixes: 6th round CI failure (protocol-a2a checkstyle) in PR #5260\n\n* fix: static import ordering in A2ATopicFactoryTest\n\n- Move static imports to top (option\u003dtop in checkstyle)\n- Fix alphabetical order: assertFalse before assertNotNull\n\nFixes: 7th round CI failure (protocol-a2a checkstyleTest) in PR #5260",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "12c99a1cda097ede71c9d8fff558389c88586d05",
      "old_mode": 33188,
      "old_path": "docs/a2a-protocol/ARCHITECTURE.md",
      "new_id": "bcb485b107e3456868d60d43df95f9327c492b4b",
      "new_mode": 33188,
      "new_path": "docs/a2a-protocol/ARCHITECTURE.md"
    },
    {
      "type": "modify",
      "old_id": "de1e784cc551915ac149f417843b103c45af829b",
      "old_mode": 33188,
      "old_path": "docs/a2a-protocol/IMPLEMENTATION_SUMMARY.md",
      "new_id": "fd5081c6102218e551cd274465725305046e5411",
      "new_mode": 33188,
      "new_path": "docs/a2a-protocol/IMPLEMENTATION_SUMMARY.md"
    },
    {
      "type": "modify",
      "old_id": "33b9e191fbec878221a5c9e7d23378ee070d64b2",
      "old_mode": 33188,
      "old_path": "docs/a2a-protocol/IMPLEMENTATION_SUMMARY_EN.md",
      "new_id": "aec8aef9449b1ed483ee3fa37ae6834d736dfaa5",
      "new_mode": 33188,
      "new_path": "docs/a2a-protocol/IMPLEMENTATION_SUMMARY_EN.md"
    },
    {
      "type": "modify",
      "old_id": "b7cde31dd272d83121f0d426534a04a89ba1261e",
      "old_mode": 33188,
      "old_path": "docs/a2a-protocol/README.md",
      "new_id": "73247de79031f4d9f0bcf0a83e8efaaaade4de82",
      "new_mode": 33188,
      "new_path": "docs/a2a-protocol/README.md"
    },
    {
      "type": "modify",
      "old_id": "3f3f2b2127e4e7501fc3825eccf99e57ebec5d22",
      "old_mode": 33188,
      "old_path": "docs/a2a-protocol/README_EN.md",
      "new_id": "b7d8aa5fea465586bc256922fb13d7cb9ab8a2a4",
      "new_mode": 33188,
      "new_path": "docs/a2a-protocol/README_EN.md"
    },
    {
      "type": "modify",
      "old_id": "43c96e83077c52cbe36ee32ec5d2150b493598e6",
      "old_mode": 33188,
      "old_path": "docs/a2a-protocol/TEST_RESULTS.md",
      "new_id": "01a79014f4ea713afb81b010c836773d5235cd5f",
      "new_mode": 33188,
      "new_path": "docs/a2a-protocol/TEST_RESULTS.md"
    },
    {
      "type": "modify",
      "old_id": "11589f7548ece3c683c019df64f00ccc318e7c2f",
      "old_mode": 33188,
      "old_path": "docs/a2a-protocol/eventmesh-a2a-design.md",
      "new_id": "a3b2135fe4e74bf1f04c722ad85f95ad5f18e7be",
      "new_mode": 33188,
      "new_path": "docs/a2a-protocol/eventmesh-a2a-design.md"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "0e4ea34de35761fbd894b1a778acd04fa76217ad",
      "new_mode": 33188,
      "new_path": "eventmesh-examples/src/main/java/org/apache/eventmesh/a2a/demo/README.md"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "432a255a0318fd4ed39001b5f919a54b29af16a8",
      "new_mode": 33188,
      "new_path": "eventmesh-examples/src/main/java/org/apache/eventmesh/a2a/demo/gateway/A2AGatewayDemo.java"
    },
    {
      "type": "modify",
      "old_id": "440788eeaf639f64df91c77862eb68cad7a1a30a",
      "old_mode": 33188,
      "old_path": "eventmesh-protocol-plugin/eventmesh-protocol-a2a/build.gradle",
      "new_id": "4c2dd2f9640bb665def2888e165b5939370b8f21",
      "new_mode": 33188,
      "new_path": "eventmesh-protocol-plugin/eventmesh-protocol-a2a/build.gradle"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "b7d312e2c7cf9f846de222b503a9c3bb5d3d24a5",
      "new_mode": 33188,
      "new_path": "eventmesh-protocol-plugin/eventmesh-protocol-a2a/src/main/java/org/apache/eventmesh/protocol/a2a/A2AClient.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "5856df96174eb657c38d8910008c82ff0f22f842",
      "new_mode": 33188,
      "new_path": "eventmesh-protocol-plugin/eventmesh-protocol-a2a/src/main/java/org/apache/eventmesh/protocol/a2a/A2AMessageTransport.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "dbd299a1cfbbbbe31ffcae05698bca6376c28b09",
      "new_mode": 33188,
      "new_path": "eventmesh-protocol-plugin/eventmesh-protocol-a2a/src/main/java/org/apache/eventmesh/protocol/a2a/A2ATopicFactory.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "a29d322db4ce0f3b3522a0cb457ef40067d59b1a",
      "new_mode": 33188,
      "new_path": "eventmesh-protocol-plugin/eventmesh-protocol-a2a/src/test/java/org/apache/eventmesh/protocol/a2a/A2ATopicFactoryTest.java"
    },
    {
      "type": "modify",
      "old_id": "f905ee2b0396225c2b7663495c74b471dbcff292",
      "old_mode": 33188,
      "old_path": "eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/a2a/A2ACardHttpHandler.java",
      "new_id": "1e9f262c845fda67eb9b5ab321e4a5b8733b867c",
      "new_mode": 33188,
      "new_path": "eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/a2a/A2ACardHttpHandler.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "8c4722089ad93174246c6814f9d884308e909b1c",
      "new_mode": 33188,
      "new_path": "eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/a2a/A2AGatewayHttpHandler.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "8db1f400b606af02f6a33edbdbb4c47da54bfc5e",
      "new_mode": 33188,
      "new_path": "eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/a2a/A2AGatewayServer.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "ed1d8ffddf0c4291551731fd2b1f87c53d4eca64",
      "new_mode": 33188,
      "new_path": "eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/a2a/A2AGatewayService.java"
    },
    {
      "type": "modify",
      "old_id": "6dab3f54665c7be995bfa17f251c6b712390a748",
      "old_mode": 33188,
      "old_path": "eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/a2a/A2APublishSubscribeService.java",
      "new_id": "5171b0e2a91fc7addd8c62f339faa486f822a780",
      "new_mode": 33188,
      "new_path": "eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/a2a/A2APublishSubscribeService.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "d7f2f2ed4db137d47ac59a594c455094ee5051cd",
      "new_mode": 33188,
      "new_path": "eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/a2a/InMemoryA2AMessageTransport.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "549296447addf7ad6e228016a1c7d79b02ca12db",
      "new_mode": 33188,
      "new_path": "eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/a2a/TaskRegistry.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "f22d3b2e0bc1f40269428ad29abc89880c224b32",
      "new_mode": 33188,
      "new_path": "eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/a2a/A2AClientServerIntegrationTest.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "9f0c65213774c47914ea5db7aa7b4531eecc2933",
      "new_mode": 33188,
      "new_path": "eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/a2a/A2AGatewayEndToEndTest.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "42bf71df763f3260983a2500f66252ef21a096e4",
      "new_mode": 33188,
      "new_path": "eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/a2a/A2AGatewayServiceTest.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "5354d066809a8250343f11e78640c5ad3f78885f",
      "new_mode": 33188,
      "new_path": "eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/a2a/AgentCardTestUtils.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "0770a906fbeb2aa5066c970b935667a3090298c3",
      "new_mode": 33188,
      "new_path": "eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/a2a/InMemoryA2AMessageTransportTest.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "4bac7b52be6b3366cfc8b36893720d771741d33b",
      "new_mode": 33188,
      "new_path": "eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/a2a/TaskRegistryTest.java"
    }
  ]
}
