Skip to content

Commit 2ee4196

Browse files
authored
fix(grpc): allow omitted push config ids (a2aproject#1163)
Signed-off-by: wj56 <823072490@qq.com>
1 parent 1ffc02c commit 2ee4196

4 files changed

Lines changed: 154 additions & 3 deletions

File tree

‎client/transport/grpc/pom.xml‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@
5151
<artifactId>junit-jupiter-api</artifactId>
5252
<scope>test</scope>
5353
</dependency>
54+
<dependency>
55+
<groupId>io.grpc</groupId>
56+
<artifactId>grpc-inprocess</artifactId>
57+
<scope>test</scope>
58+
</dependency>
5459

5560
<dependency>
5661
<groupId>org.mock-server</groupId>
@@ -59,4 +64,4 @@
5964
</dependency>
6065
</dependencies>
6166

62-
</project>
67+
</project>

‎client/transport/grpc/src/main/java/org/a2aproject/sdk/client/transport/grpc/GrpcTransport.java‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,12 +256,12 @@ public TaskPushNotificationConfig getTaskPushNotificationConfiguration(GetTaskPu
256256
@Nullable ClientCallContext context) throws A2AClientException {
257257
checkNotNullParam("request", request);
258258
checkNotNullParam("taskId", request.taskId());
259-
checkNotNullParam("id", request.id());
259+
String configId = request.id();
260260

261261
org.a2aproject.sdk.grpc.GetTaskPushNotificationConfigRequest grpcRequest = org.a2aproject.sdk.grpc.GetTaskPushNotificationConfigRequest.newBuilder()
262262
.setTaskId(request.taskId())
263263
.setTenant(resolveTenant(request.tenant()))
264-
.setId(request.id())
264+
.setId(configId == null ? "" : configId)
265265
.build();
266266
PayloadAndHeaders payloadAndHeaders = applyInterceptors(GET_TASK_PUSH_NOTIFICATION_CONFIG_METHOD, grpcRequest, agentCard, context);
267267

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package org.a2aproject.sdk.client.transport.grpc;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertNotNull;
5+
6+
import java.util.List;
7+
import java.util.concurrent.TimeUnit;
8+
import java.util.concurrent.atomic.AtomicReference;
9+
10+
import io.grpc.ManagedChannel;
11+
import io.grpc.Server;
12+
import io.grpc.inprocess.InProcessChannelBuilder;
13+
import io.grpc.inprocess.InProcessServerBuilder;
14+
import io.grpc.stub.StreamObserver;
15+
import org.a2aproject.sdk.grpc.A2AServiceGrpc;
16+
import org.a2aproject.sdk.grpc.GetTaskPushNotificationConfigRequest;
17+
import org.a2aproject.sdk.spec.AgentCapabilities;
18+
import org.a2aproject.sdk.spec.AgentCard;
19+
import org.a2aproject.sdk.spec.AgentInterface;
20+
import org.a2aproject.sdk.spec.GetTaskPushNotificationConfigParams;
21+
import org.a2aproject.sdk.spec.TaskPushNotificationConfig;
22+
import org.jspecify.annotations.Nullable;
23+
import org.junit.jupiter.api.AfterEach;
24+
import org.junit.jupiter.api.BeforeEach;
25+
import org.junit.jupiter.api.Test;
26+
import org.junit.jupiter.api.Timeout;
27+
28+
@Timeout(5)
29+
class GrpcTransportTest {
30+
31+
private static final String TASK_ID = "task-1";
32+
private static final String CALLBACK_URL = "https://example.com/callback";
33+
private static final AgentCard CARD = AgentCard.builder()
34+
.name("Test Agent")
35+
.description("Agent for gRPC transport tests")
36+
.version("1.0.0")
37+
.supportedInterfaces(List.of(new AgentInterface("GRPC", "http://localhost")))
38+
.capabilities(AgentCapabilities.builder().pushNotifications(true).build())
39+
.defaultInputModes(List.of("text"))
40+
.defaultOutputModes(List.of("text"))
41+
.skills(List.of())
42+
.build();
43+
44+
private final AtomicReference<GetTaskPushNotificationConfigRequest> receivedRequest = new AtomicReference<>();
45+
private Server server;
46+
private ManagedChannel channel;
47+
48+
@BeforeEach
49+
void setUp() throws Exception {
50+
String serverName = InProcessServerBuilder.generateName();
51+
server = InProcessServerBuilder.forName(serverName)
52+
.directExecutor()
53+
.addService(new A2AServiceGrpc.A2AServiceImplBase() {
54+
@Override
55+
public void getTaskPushNotificationConfig(GetTaskPushNotificationConfigRequest request,
56+
StreamObserver<org.a2aproject.sdk.grpc.TaskPushNotificationConfig> responseObserver) {
57+
receivedRequest.set(request);
58+
responseObserver.onNext(org.a2aproject.sdk.grpc.TaskPushNotificationConfig.newBuilder()
59+
.setTaskId(request.getTaskId())
60+
.setId(request.getId().isEmpty() ? request.getTaskId() : request.getId())
61+
.setUrl(CALLBACK_URL)
62+
.build());
63+
responseObserver.onCompleted();
64+
}
65+
})
66+
.build()
67+
.start();
68+
channel = InProcessChannelBuilder.forName(serverName).directExecutor().build();
69+
}
70+
71+
@AfterEach
72+
void tearDown() throws InterruptedException {
73+
channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS);
74+
server.shutdownNow().awaitTermination(5, TimeUnit.SECONDS);
75+
}
76+
77+
@Test
78+
void testGetPushNotificationConfigWithOmittedId() throws Exception {
79+
assertGetPushNotificationConfig(new GetTaskPushNotificationConfigParams(TASK_ID), null, "", "");
80+
}
81+
82+
@Test
83+
void testGetPushNotificationConfigWithOmittedIdViaBuilder() throws Exception {
84+
assertGetPushNotificationConfig(GetTaskPushNotificationConfigParams.builder().taskId(TASK_ID).build(),
85+
null, "", "");
86+
}
87+
88+
@Test
89+
void testGetPushNotificationConfigWithEmptyId() throws Exception {
90+
assertGetPushNotificationConfig(new GetTaskPushNotificationConfigParams(TASK_ID, ""), null, "", "");
91+
}
92+
93+
@Test
94+
void testGetPushNotificationConfigWithExplicitIdAndDefaultTenant() throws Exception {
95+
assertGetPushNotificationConfig(new GetTaskPushNotificationConfigParams(TASK_ID, "config-1"),
96+
"default-tenant", "config-1", "default-tenant");
97+
}
98+
99+
@Test
100+
void testGetPushNotificationConfigWithOmittedIdAndRequestTenant() throws Exception {
101+
assertGetPushNotificationConfig(new GetTaskPushNotificationConfigParams(TASK_ID, null, "request-tenant"),
102+
"default-tenant", "", "request-tenant");
103+
}
104+
105+
private void assertGetPushNotificationConfig(GetTaskPushNotificationConfigParams params,
106+
@Nullable String defaultTenant, String expectedId, String expectedTenant) throws Exception {
107+
GrpcTransport transport = new GrpcTransport(channel, CARD, defaultTenant, null);
108+
TaskPushNotificationConfig result = transport.getTaskPushNotificationConfiguration(params, null);
109+
110+
GetTaskPushNotificationConfigRequest request = receivedRequest.get();
111+
assertNotNull(request);
112+
assertEquals(TASK_ID, request.getTaskId());
113+
assertEquals(expectedId, request.getId());
114+
assertEquals(expectedTenant, request.getTenant());
115+
assertEquals(expectedId.isEmpty() ? TASK_ID : expectedId, result.id());
116+
assertEquals(TASK_ID, result.taskId());
117+
assertEquals(CALLBACK_URL, result.url());
118+
}
119+
}

‎client/transport/rest/src/test/java/org/a2aproject/sdk/client/transport/rest/RestTransportTest.java‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,33 @@ public void testGetTaskPushNotificationConfiguration() throws Exception {
340340
assertEquals("jwt", authenticationInfo.scheme());
341341
}
342342

343+
@Test
344+
public void testGetTaskPushNotificationConfigurationWithOmittedId() throws Exception {
345+
assertGetTaskPushNotificationConfigurationWithDefaultId(
346+
new GetTaskPushNotificationConfigParams("de38c76d-d54c-436c-8b9f-4c2703648d64"));
347+
}
348+
349+
@Test
350+
public void testGetTaskPushNotificationConfigurationWithEmptyId() throws Exception {
351+
assertGetTaskPushNotificationConfigurationWithDefaultId(
352+
new GetTaskPushNotificationConfigParams("de38c76d-d54c-436c-8b9f-4c2703648d64", ""));
353+
}
354+
355+
private void assertGetTaskPushNotificationConfigurationWithDefaultId(
356+
GetTaskPushNotificationConfigParams params) throws Exception {
357+
this.server.when(request()
358+
.withMethod("GET")
359+
.withPath("/tasks/de38c76d-d54c-436c-8b9f-4c2703648d64/pushNotificationConfigs/"))
360+
.respond(response()
361+
.withStatusCode(200)
362+
.withBody(GET_TASK_PUSH_NOTIFICATION_CONFIG_TEST_RESPONSE));
363+
364+
RestTransport client = new RestTransport(CARD);
365+
TaskPushNotificationConfig config = client.getTaskPushNotificationConfiguration(params, null);
366+
367+
assertEquals("https://example.com/callback", config.url());
368+
}
369+
343370
/**
344371
* Test of listTaskPushNotificationConfigurations method, of class JSONRestTransport.
345372
*/

0 commit comments

Comments
 (0)