contextCaptor = ArgumentCaptor.forClass(ServerCallContext.class);
@@ -286,8 +283,8 @@ public void testDeleteTaskPushNotificationConfiguration_MethodNameSetInContext()
routes.deleteTaskPushNotificationConfiguration(mockRoutingContext);
// Assert
- verify(mockRestHandler).deleteTaskPushNotificationConfiguration(eq("task123"), eq("config456"), anyString(),
- contextCaptor.capture());
+ verify(mockRestHandler).deleteTaskPushNotificationConfiguration(contextCaptor.capture(), anyString(), eq("task123"),
+ eq("config456"));
ServerCallContext capturedContext = contextCaptor.getValue();
assertNotNull(capturedContext);
assertEquals(DELETE_TASK_PUSH_NOTIFICATION_CONFIG_METHOD, capturedContext.getState().get(METHOD_NAME_KEY));
diff --git a/server-common/src/main/java/io/a2a/server/requesthandlers/DefaultRequestHandler.java b/server-common/src/main/java/io/a2a/server/requesthandlers/DefaultRequestHandler.java
index e1a16eb3c..27fb786a5 100644
--- a/server-common/src/main/java/io/a2a/server/requesthandlers/DefaultRequestHandler.java
+++ b/server-common/src/main/java/io/a2a/server/requesthandlers/DefaultRequestHandler.java
@@ -6,6 +6,7 @@
import static java.util.concurrent.TimeUnit.SECONDS;
import java.time.Instant;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -68,6 +69,7 @@
import io.a2a.spec.TaskState;
import io.a2a.spec.TaskStatusUpdateEvent;
import io.a2a.spec.UnsupportedOperationError;
+import java.util.Collections;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
diff --git a/spec/src/main/java/io/a2a/spec/A2AMethods.java b/spec/src/main/java/io/a2a/spec/A2AMethods.java
index e270a7d91..1731077fe 100644
--- a/spec/src/main/java/io/a2a/spec/A2AMethods.java
+++ b/spec/src/main/java/io/a2a/spec/A2AMethods.java
@@ -27,5 +27,6 @@ public interface A2AMethods {
String SET_TASK_PUSH_NOTIFICATION_CONFIG_METHOD = "CreateTaskPushNotificationConfig";
/** Method name for subscribing to task events. */
String SUBSCRIBE_TO_TASK_METHOD = "SubscribeToTask";
+
}
diff --git a/spec/src/main/java/io/a2a/spec/Message.java b/spec/src/main/java/io/a2a/spec/Message.java
index 4383b1e02..978af4c40 100644
--- a/spec/src/main/java/io/a2a/spec/Message.java
+++ b/spec/src/main/java/io/a2a/spec/Message.java
@@ -94,6 +94,11 @@ public static Builder builder(Message message) {
return new Builder(message);
}
+ @Override
+ public String toString() {
+ return "Message{" + "role=" + role + ", parts=" + parts + ", messageId=" + messageId + ", contextId=" + contextId + ", taskId=" + taskId + ", metadata=" + metadata + ", referenceTaskIds=" + referenceTaskIds + ", extensions=" + extensions + '}';
+ }
+
/**
* Defines the role of the message sender in the conversation.
*
diff --git a/spec/src/main/java/io/a2a/spec/Task.java b/spec/src/main/java/io/a2a/spec/Task.java
index 24336dcd9..b51db72ce 100644
--- a/spec/src/main/java/io/a2a/spec/Task.java
+++ b/spec/src/main/java/io/a2a/spec/Task.java
@@ -103,6 +103,11 @@ public static Builder builder(Task task) {
return new Builder(task);
}
+ @Override
+ public String toString() {
+ return "Task{" + "id=" + id + ", contextId=" + contextId + ", status=" + status + ", artifacts=" + artifacts + ", history=" + history + ", metadata=" + metadata + '}';
+ }
+
/**
* Builder for constructing immutable {@link Task} instances.
*
diff --git a/transport/grpc/src/main/java/io/a2a/transport/grpc/context/GrpcContextKeys.java b/transport/grpc/src/main/java/io/a2a/transport/grpc/context/GrpcContextKeys.java
index a025236f0..a1392f20a 100644
--- a/transport/grpc/src/main/java/io/a2a/transport/grpc/context/GrpcContextKeys.java
+++ b/transport/grpc/src/main/java/io/a2a/transport/grpc/context/GrpcContextKeys.java
@@ -1,16 +1,20 @@
package io.a2a.transport.grpc.context;
+
+import java.util.Map;
+
+import io.a2a.spec.A2AMethods;
import io.grpc.Context;
/**
* Shared gRPC context keys for A2A protocol data.
- *
+ *
* These keys provide access to gRPC context information similar to
* Python's grpc.aio.ServicerContext, enabling rich context access
* in service method implementations.
*/
public final class GrpcContextKeys {
-
+
/**
* Context key for storing the X-A2A-Version header value.
* Set by server interceptors and accessed by service handlers.
@@ -24,21 +28,28 @@ public final class GrpcContextKeys {
*/
public static final Context.Key EXTENSIONS_HEADER_KEY =
Context.key("x-a2a-extensions");
-
+
/**
* Context key for storing the complete gRPC Metadata object.
* Provides access to all request headers and metadata.
*/
public static final Context.Key METADATA_KEY =
Context.key("grpc-metadata");
-
+
/**
* Context key for storing the method name being called.
* Equivalent to Python's context.method() functionality.
*/
- public static final Context.Key METHOD_NAME_KEY =
+ public static final Context.Key GRPC_METHOD_NAME_KEY =
Context.key("grpc-method-name");
+ /**
+ * Context key for storing the method name being called.
+ * Equivalent to Python's context.method() functionality.
+ */
+ public static final Context.Key METHOD_NAME_KEY =
+ Context.key("method");
+
/**
* Context key for storing the peer information.
* Provides access to client connection details.
@@ -46,6 +57,18 @@ public final class GrpcContextKeys {
public static final Context.Key PEER_INFO_KEY =
Context.key("grpc-peer-info");
+ public static final Map METHOD_MAPPING = Map.of(
+ "SendMessage", A2AMethods.SEND_MESSAGE_METHOD,
+ "SendStreamingMessage", A2AMethods.SEND_STREAMING_MESSAGE_METHOD,
+ "GetTask", A2AMethods.GET_TASK_METHOD,
+ "ListTask", A2AMethods.LIST_TASK_METHOD,
+ "CancelTask", A2AMethods.CANCEL_TASK_METHOD,
+ "SubscribeToTask", A2AMethods.SUBSCRIBE_TO_TASK_METHOD,
+ "CreateTaskPushNotification", A2AMethods.SET_TASK_PUSH_NOTIFICATION_CONFIG_METHOD,
+ "GetTaskPushNotification", A2AMethods.GET_TASK_PUSH_NOTIFICATION_CONFIG_METHOD,
+ "ListTaskPushNotification", A2AMethods.LIST_TASK_PUSH_NOTIFICATION_CONFIG_METHOD,
+ "DeleteTaskPushNotification", A2AMethods.DELETE_TASK_PUSH_NOTIFICATION_CONFIG_METHOD);
+
private GrpcContextKeys() {
// Utility class
}
diff --git a/transport/grpc/src/main/java/io/a2a/transport/grpc/handler/GrpcHandler.java b/transport/grpc/src/main/java/io/a2a/transport/grpc/handler/GrpcHandler.java
index 376d9b11d..06f58e96e 100644
--- a/transport/grpc/src/main/java/io/a2a/transport/grpc/handler/GrpcHandler.java
+++ b/transport/grpc/src/main/java/io/a2a/transport/grpc/handler/GrpcHandler.java
@@ -57,15 +57,17 @@
import io.a2a.spec.VersionNotSupportedError;
import io.a2a.transport.grpc.context.GrpcContextKeys;
import io.grpc.Context;
+import io.grpc.Metadata;
import io.grpc.Status;
import io.grpc.stub.StreamObserver;
+import org.jspecify.annotations.Nullable;
@Vetoed
public abstract class GrpcHandler extends A2AServiceGrpc.A2AServiceImplBase {
// Hook so testing can wait until streaming subscriptions are established.
// Without this we get intermittent failures
- private static volatile Runnable streamingSubscribedRunnable;
+ private static volatile @Nullable Runnable streamingSubscribedRunnable;
private final AtomicBoolean initialised = new AtomicBoolean(false);
@@ -279,12 +281,14 @@ private void convertToStreamResponse(Flow.Publisher publishe
ServerCallContext context) {
CompletableFuture.runAsync(() -> {
publisher.subscribe(new Flow.Subscriber() {
- private Flow.Subscription subscription;
+ private Flow.@Nullable Subscription subscription;
@Override
public void onSubscribe(Flow.Subscription subscription) {
this.subscription = subscription;
- subscription.request(1);
+ if (this.subscription != null) {
+ this.subscription.request(1);
+ }
// Detect gRPC client disconnect and call EventConsumer.cancel() directly
// This stops the polling loop without relying on subscription cancellation propagation
@@ -312,14 +316,18 @@ public void onNext(StreamingEventKind event) {
if (response.hasStatusUpdate() && response.getStatusUpdate().getFinal()) {
responseObserver.onCompleted();
} else {
- subscription.request(1);
+ if (this.subscription != null) {
+ this.subscription.request(1);
+ }
}
}
@Override
public void onError(Throwable throwable) {
// Cancel upstream to stop EventConsumer when error occurs
- subscription.cancel();
+ if (this.subscription != null) {
+ subscription.cancel();
+ }
if (throwable instanceof A2AError jsonrpcError) {
handleError(responseObserver, jsonrpcError);
} else {
@@ -403,8 +411,12 @@ private ServerCallContext createCallContext(StreamObserver responseObserv
if (grpcMetadata != null) {
state.put("grpc_metadata", grpcMetadata);
}
-
- String methodName = GrpcContextKeys.METHOD_NAME_KEY.get(currentContext);
+ Map headers= new HashMap<>();
+ for(String key : grpcMetadata.keys()) {
+ headers.put(key, grpcMetadata.get(Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER)));
+ }
+ state.put("headers", headers);
+ String methodName = GrpcContextKeys.GRPC_METHOD_NAME_KEY.get(currentContext);
if (methodName != null) {
state.put("grpc_method_name", methodName);
}
@@ -573,7 +585,7 @@ public static void setStreamingSubscribedRunnable(Runnable runnable) {
*
* @return the version header value, or null if not available
*/
- private String getVersionFromContext() {
+ private @Nullable String getVersionFromContext() {
try {
return GrpcContextKeys.VERSION_HEADER_KEY.get();
} catch (Exception e) {
@@ -589,7 +601,7 @@ private String getVersionFromContext() {
*
* @return the extensions header value, or null if not available
*/
- private String getExtensionsFromContext() {
+ private @Nullable String getExtensionsFromContext() {
try {
return GrpcContextKeys.EXTENSIONS_HEADER_KEY.get();
} catch (Exception e) {
@@ -609,7 +621,7 @@ private String getExtensionsFromContext() {
* @param key the context key to retrieve
* @return the context value, or null if not available
*/
- private static T getFromContext(Context.Key key) {
+ private static @Nullable T getFromContext(Context.Key key) {
try {
return key.get();
} catch (Exception e) {
@@ -624,7 +636,7 @@ private static T getFromContext(Context.Key key) {
*
* @return the gRPC Metadata object, or null if not available
*/
- protected static io.grpc.Metadata getCurrentMetadata() {
+ protected static io.grpc.@Nullable Metadata getCurrentMetadata() {
return getFromContext(GrpcContextKeys.METADATA_KEY);
}
@@ -634,8 +646,8 @@ protected static io.grpc.Metadata getCurrentMetadata() {
*
* @return the method name, or null if not available
*/
- protected static String getCurrentMethodName() {
- return getFromContext(GrpcContextKeys.METHOD_NAME_KEY);
+ protected static @Nullable String getCurrentMethodName() {
+ return getFromContext(GrpcContextKeys.GRPC_METHOD_NAME_KEY);
}
/**
@@ -644,7 +656,7 @@ protected static String getCurrentMethodName() {
*
* @return the peer information, or null if not available
*/
- protected static String getCurrentPeerInfo() {
+ protected static @Nullable String getCurrentPeerInfo() {
return getFromContext(GrpcContextKeys.PEER_INFO_KEY);
}
}
diff --git a/transport/grpc/src/main/java/io/a2a/transport/grpc/handler/package-info.java b/transport/grpc/src/main/java/io/a2a/transport/grpc/handler/package-info.java
new file mode 100644
index 000000000..0cc667b2d
--- /dev/null
+++ b/transport/grpc/src/main/java/io/a2a/transport/grpc/handler/package-info.java
@@ -0,0 +1,9 @@
+/*
+ * Copyright The WildFly Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+@NullMarked
+package io.a2a.transport.grpc.handler;
+
+import org.jspecify.annotations.NullMarked;
+
diff --git a/transport/jsonrpc/src/main/java/io/a2a/transport/jsonrpc/handler/JSONRPCHandler.java b/transport/jsonrpc/src/main/java/io/a2a/transport/jsonrpc/handler/JSONRPCHandler.java
index a592bd55d..eeb7b9c93 100644
--- a/transport/jsonrpc/src/main/java/io/a2a/transport/jsonrpc/handler/JSONRPCHandler.java
+++ b/transport/jsonrpc/src/main/java/io/a2a/transport/jsonrpc/handler/JSONRPCHandler.java
@@ -110,7 +110,6 @@ public SendMessageResponse onMessageSend(SendMessageRequest request, ServerCallC
}
}
-
public Flow.Publisher onMessageSendStream(
SendStreamingMessageRequest request, ServerCallContext context) {
if (!agentCard.capabilities().streaming()) {
diff --git a/transport/rest/src/main/java/io/a2a/transport/rest/handler/RestHandler.java b/transport/rest/src/main/java/io/a2a/transport/rest/handler/RestHandler.java
index f4b594f6b..cf28a7d7c 100644
--- a/transport/rest/src/main/java/io/a2a/transport/rest/handler/RestHandler.java
+++ b/transport/rest/src/main/java/io/a2a/transport/rest/handler/RestHandler.java
@@ -108,7 +108,8 @@ public RestHandler(AgentCard agentCard, RequestHandler requestHandler, Executor
this.executor = executor;
}
- public HTTPRestResponse sendMessage(String body, String tenant, ServerCallContext context) {
+ public HTTPRestResponse sendMessage(ServerCallContext context, String tenant, String body) {
+
try {
A2AVersionValidator.validateProtocolVersion(agentCard, context);
A2AExtensions.validateRequiredExtensions(agentCard, context);
@@ -124,7 +125,7 @@ public HTTPRestResponse sendMessage(String body, String tenant, ServerCallContex
}
}
- public HTTPRestResponse sendStreamingMessage(String body, String tenant, ServerCallContext context) {
+ public HTTPRestResponse sendStreamingMessage(ServerCallContext context, String tenant, String body) {
try {
if (!agentCard.capabilities().streaming()) {
return createErrorResponse(new InvalidRequestError("Streaming is not supported by the agent"));
@@ -143,7 +144,7 @@ public HTTPRestResponse sendStreamingMessage(String body, String tenant, ServerC
}
}
- public HTTPRestResponse cancelTask(String taskId, String tenant, ServerCallContext context) {
+ public HTTPRestResponse cancelTask(ServerCallContext context, String tenant, String taskId) {
try {
if (taskId == null || taskId.isEmpty()) {
throw new InvalidParamsError();
@@ -161,7 +162,7 @@ public HTTPRestResponse cancelTask(String taskId, String tenant, ServerCallConte
}
}
- public HTTPRestResponse CreateTaskPushNotificationConfiguration(String taskId, String body, String tenant, ServerCallContext context) {
+ public HTTPRestResponse createTaskPushNotificationConfiguration(ServerCallContext context, String tenant, String body, String taskId) {
try {
if (!agentCard.capabilities().pushNotifications()) {
throw new PushNotificationNotSupportedError();
@@ -178,7 +179,7 @@ public HTTPRestResponse CreateTaskPushNotificationConfiguration(String taskId, S
}
}
- public HTTPRestResponse subscribeToTask(String taskId, String tenant, ServerCallContext context) {
+ public HTTPRestResponse subscribeToTask(ServerCallContext context, String tenant, String taskId) {
try {
if (!agentCard.capabilities().streaming()) {
return createErrorResponse(new InvalidRequestError("Streaming is not supported by the agent"));
@@ -193,7 +194,7 @@ public HTTPRestResponse subscribeToTask(String taskId, String tenant, ServerCall
}
}
- public HTTPRestResponse getTask(String taskId, @Nullable Integer historyLength, String tenant, ServerCallContext context) {
+ public HTTPRestResponse getTask(ServerCallContext context, String tenant, String taskId, @Nullable Integer historyLength) {
try {
TaskQueryParams params = new TaskQueryParams(taskId, historyLength, tenant);
Task task = requestHandler.onGetTask(params, context);
@@ -208,11 +209,11 @@ public HTTPRestResponse getTask(String taskId, @Nullable Integer historyLength,
}
}
- public HTTPRestResponse listTasks(@Nullable String contextId, @Nullable String status,
+ public HTTPRestResponse listTasks(ServerCallContext context, String tenant,
+ @Nullable String contextId, @Nullable String status,
@Nullable Integer pageSize, @Nullable String pageToken,
@Nullable Integer historyLength, @Nullable String statusTimestampAfter,
- @Nullable Boolean includeArtifacts, String tenant,
- ServerCallContext context) {
+ @Nullable Boolean includeArtifacts) {
try {
// Build params
ListTasksParams.Builder paramsBuilder = ListTasksParams.builder();
@@ -303,7 +304,7 @@ public HTTPRestResponse listTasks(@Nullable String contextId, @Nullable String s
}
}
- public HTTPRestResponse getTaskPushNotificationConfiguration(String taskId, @Nullable String configId, String tenant, ServerCallContext context) {
+ public HTTPRestResponse getTaskPushNotificationConfiguration(ServerCallContext context, String tenant, String taskId, @Nullable String configId) {
try {
if (!agentCard.capabilities().pushNotifications()) {
throw new PushNotificationNotSupportedError();
@@ -318,7 +319,7 @@ public HTTPRestResponse getTaskPushNotificationConfiguration(String taskId, @Nul
}
}
- public HTTPRestResponse listTaskPushNotificationConfigurations(String taskId, int pageSize, String pageToken, String tenant, ServerCallContext context) {
+ public HTTPRestResponse listTaskPushNotificationConfigurations(ServerCallContext context, String tenant, String taskId, int pageSize, String pageToken) {
try {
if (!agentCard.capabilities().pushNotifications()) {
throw new PushNotificationNotSupportedError();
@@ -333,7 +334,7 @@ public HTTPRestResponse listTaskPushNotificationConfigurations(String taskId, in
}
}
- public HTTPRestResponse deleteTaskPushNotificationConfiguration(String taskId, String configId, String tenant, ServerCallContext context) {
+ public HTTPRestResponse deleteTaskPushNotificationConfiguration(ServerCallContext context, String tenant, String taskId, String configId) {
try {
if (!agentCard.capabilities().pushNotifications()) {
throw new PushNotificationNotSupportedError();
@@ -491,7 +492,7 @@ private int mapErrorToHttpStatus(A2AError error) {
return 500;
}
- public HTTPRestResponse getExtendedAgentCard(String tenant) {
+ public HTTPRestResponse getExtendedAgentCard(ServerCallContext context, String tenant) {
try {
if (!agentCard.capabilities().extendedAgentCard() || extendedAgentCard == null || !extendedAgentCard.isResolvable()) {
throw new ExtendedAgentCardNotConfiguredError(null, "Extended Card not configured", null);
diff --git a/transport/rest/src/test/java/io/a2a/transport/rest/handler/RestHandlerTest.java b/transport/rest/src/test/java/io/a2a/transport/rest/handler/RestHandlerTest.java
index 48eaae912..595902509 100644
--- a/transport/rest/src/test/java/io/a2a/transport/rest/handler/RestHandlerTest.java
+++ b/transport/rest/src/test/java/io/a2a/transport/rest/handler/RestHandlerTest.java
@@ -34,13 +34,13 @@ public void testGetTaskSuccess() {
RestHandler handler = new RestHandler(CARD, requestHandler, internalExecutor);
taskStore.save(MINIMAL_TASK, false);
- RestHandler.HTTPRestResponse response = handler.getTask(MINIMAL_TASK.id(), 0, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.getTask(callContext, "", MINIMAL_TASK.id(), 0);
Assertions.assertEquals(200, response.getStatusCode());
Assertions.assertEquals("application/json", response.getContentType());
Assertions.assertTrue(response.getBody().contains(MINIMAL_TASK.id()));
- response = handler.getTask(MINIMAL_TASK.id(),2 , "",callContext);
+ response = handler.getTask(callContext, "", MINIMAL_TASK.id(), 2);
Assertions.assertEquals(200, response.getStatusCode());
Assertions.assertEquals("application/json", response.getContentType());
@@ -51,7 +51,7 @@ public void testGetTaskSuccess() {
public void testGetTaskNotFound() {
RestHandler handler = new RestHandler(CARD, requestHandler, internalExecutor);
- RestHandler.HTTPRestResponse response = handler.getTask("nonexistent", 0, "",callContext);
+ RestHandler.HTTPRestResponse response = handler.getTask(callContext, "", "nonexistent", 0);
Assertions.assertEquals(404, response.getStatusCode());
Assertions.assertEquals("application/json", response.getContentType());
@@ -63,8 +63,8 @@ public void testListTasksStatusWireString() {
RestHandler handler = new RestHandler(CARD, requestHandler, internalExecutor);
taskStore.save(MINIMAL_TASK, false);
- RestHandler.HTTPRestResponse response = handler.listTasks(null, "submitted", null, null,
- null, null, null, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.listTasks(callContext, "", null, "submitted", null, null,
+ null, null, null);
Assertions.assertEquals(200, response.getStatusCode());
Assertions.assertEquals("application/json", response.getContentType());
@@ -75,8 +75,8 @@ public void testListTasksStatusWireString() {
public void testListTasksInvalidStatus() {
RestHandler handler = new RestHandler(CARD, requestHandler, internalExecutor);
- RestHandler.HTTPRestResponse response = handler.listTasks(null, "not-a-status", null, null,
- null, null, null, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.listTasks(callContext, "", null, "not-a-status", null, null,
+ null, null, null);
Assertions.assertEquals(422, response.getStatusCode());
Assertions.assertEquals("application/json", response.getContentType());
@@ -108,7 +108,7 @@ public void testSendMessage() throws InvalidProtocolBufferException {
}
}""";
- RestHandler.HTTPRestResponse response = handler.sendMessage(requestBody, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.sendMessage(callContext, "", requestBody);
Assertions.assertEquals(200, response.getStatusCode(), response.toString());
Assertions.assertEquals("application/json", response.getContentType());
Assertions.assertNotNull(response.getBody());
@@ -119,7 +119,7 @@ public void testSendMessageInvalidBody() {
RestHandler handler = new RestHandler(CARD, requestHandler, internalExecutor);
String invalidBody = "invalid json";
- RestHandler.HTTPRestResponse response = handler.sendMessage(invalidBody, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.sendMessage(callContext, "", invalidBody);
Assertions.assertEquals(400, response.getStatusCode());
Assertions.assertEquals("application/json", response.getContentType());
@@ -143,7 +143,7 @@ public void testSendMessageWrongValueBody() {
}
}
}""";
- RestHandler.HTTPRestResponse response = handler.sendMessage(requestBody, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.sendMessage(callContext, "", requestBody);
Assertions.assertEquals(422, response.getStatusCode());
Assertions.assertEquals("application/json", response.getContentType());
@@ -154,7 +154,7 @@ public void testSendMessageWrongValueBody() {
public void testSendMessageEmptyBody() {
RestHandler handler = new RestHandler(CARD, requestHandler, internalExecutor);
- RestHandler.HTTPRestResponse response = handler.sendMessage("", "", callContext);
+ RestHandler.HTTPRestResponse response = handler.sendMessage(callContext, "", "");
Assertions.assertEquals(400, response.getStatusCode());
Assertions.assertEquals("application/json", response.getContentType());
@@ -175,7 +175,7 @@ public void testCancelTaskSuccess() {
taskUpdater.cancel();
};
- RestHandler.HTTPRestResponse response = handler.cancelTask(MINIMAL_TASK.id(), "", callContext);
+ RestHandler.HTTPRestResponse response = handler.cancelTask(callContext, "", MINIMAL_TASK.id());
Assertions.assertEquals(200, response.getStatusCode());
Assertions.assertEquals("application/json", response.getContentType());
@@ -186,7 +186,7 @@ public void testCancelTaskSuccess() {
public void testCancelTaskNotFound() {
RestHandler handler = new RestHandler(CARD, requestHandler, internalExecutor);
- RestHandler.HTTPRestResponse response = handler.cancelTask("nonexistent", "", callContext);
+ RestHandler.HTTPRestResponse response = handler.cancelTask(callContext, "", "nonexistent");
Assertions.assertEquals(404, response.getStatusCode());
Assertions.assertEquals("application/json", response.getContentType());
@@ -216,7 +216,7 @@ public void testSendStreamingMessageSuccess() {
}
}""";
- RestHandler.HTTPRestResponse response = handler.sendStreamingMessage(requestBody, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.sendStreamingMessage(callContext, "", requestBody);
Assertions.assertEquals(200, response.getStatusCode(), response.toString());
Assertions.assertInstanceOf(RestHandler.HTTPRestStreamingResponse.class, response);
RestHandler.HTTPRestStreamingResponse streamingResponse = (RestHandler.HTTPRestStreamingResponse) response;
@@ -239,7 +239,7 @@ public void testSendStreamingMessageNotSupported() {
}
""";
- RestHandler.HTTPRestResponse response = handler.sendStreamingMessage(requestBody, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.sendStreamingMessage(callContext, "", requestBody);
Assertions.assertEquals(400, response.getStatusCode());
Assertions.assertTrue(response.getBody().contains("InvalidRequestError"));
@@ -265,7 +265,7 @@ public void testPushNotificationConfigSuccess() {
}
}""".formatted(MINIMAL_TASK.id(), MINIMAL_TASK.id());
- RestHandler.HTTPRestResponse response = handler.CreateTaskPushNotificationConfiguration( MINIMAL_TASK.id(), requestBody, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.createTaskPushNotificationConfiguration(callContext, "", requestBody, MINIMAL_TASK.id());
Assertions.assertEquals(201, response.getStatusCode(), response.toString());
Assertions.assertEquals("application/json", response.getContentType());
@@ -286,7 +286,7 @@ public void testPushNotificationConfigNotSupported() {
}
""".formatted(MINIMAL_TASK.id());
- RestHandler.HTTPRestResponse response = handler.CreateTaskPushNotificationConfiguration(MINIMAL_TASK.id(), requestBody, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.createTaskPushNotificationConfiguration(callContext, "", requestBody, MINIMAL_TASK.id());
Assertions.assertEquals(501, response.getStatusCode());
Assertions.assertTrue(response.getBody().contains("PushNotificationNotSupportedError"));
@@ -312,11 +312,11 @@ public void testGetPushNotificationConfig() {
}
}
}""".formatted(MINIMAL_TASK.id(), MINIMAL_TASK.id());
- RestHandler.HTTPRestResponse response = handler.CreateTaskPushNotificationConfiguration(MINIMAL_TASK.id(), createRequestBody, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.createTaskPushNotificationConfiguration(callContext, "", createRequestBody, MINIMAL_TASK.id());
Assertions.assertEquals(201, response.getStatusCode(), response.toString());
Assertions.assertEquals("application/json", response.getContentType());
// Now get it
- response = handler.getTaskPushNotificationConfiguration(MINIMAL_TASK.id(), "default-config-id", "", callContext);
+ response = handler.getTaskPushNotificationConfiguration(callContext, "", MINIMAL_TASK.id(), "default-config-id");
Assertions.assertEquals(200, response.getStatusCode(), response.toString());
Assertions.assertEquals("application/json", response.getContentType());
}
@@ -325,7 +325,7 @@ public void testGetPushNotificationConfig() {
public void testDeletePushNotificationConfig() {
RestHandler handler = new RestHandler(CARD, requestHandler, internalExecutor);
taskStore.save(MINIMAL_TASK, false);
- RestHandler.HTTPRestResponse response = handler.deleteTaskPushNotificationConfiguration(MINIMAL_TASK.id(), "default-config-id", "", callContext);
+ RestHandler.HTTPRestResponse response = handler.deleteTaskPushNotificationConfiguration(callContext, "", MINIMAL_TASK.id(), "default-config-id");
Assertions.assertEquals(204, response.getStatusCode());
}
@@ -334,7 +334,7 @@ public void testListPushNotificationConfigs() {
RestHandler handler = new RestHandler(CARD, requestHandler, internalExecutor);
taskStore.save(MINIMAL_TASK, false);
- RestHandler.HTTPRestResponse response = handler.listTaskPushNotificationConfigurations(MINIMAL_TASK.id(), 0, "", "", callContext);
+ RestHandler.HTTPRestResponse response = handler.listTaskPushNotificationConfigurations(callContext, "", MINIMAL_TASK.id(), 0, "");
Assertions.assertEquals(200, response.getStatusCode());
Assertions.assertEquals("application/json", response.getContentType());
@@ -346,11 +346,11 @@ public void testHttpStatusCodeMapping() {
RestHandler handler = new RestHandler(CARD, requestHandler, internalExecutor);
// Test 400 for invalid request
- RestHandler.HTTPRestResponse response = handler.sendMessage("", "", callContext);
+ RestHandler.HTTPRestResponse response = handler.sendMessage(callContext, "", "");
Assertions.assertEquals(400, response.getStatusCode());
// Test 404 for not found
- response = handler.getTask("nonexistent", 0, "", callContext);
+ response = handler.getTask(callContext, "", "nonexistent", 0);
Assertions.assertEquals(404, response.getStatusCode());
}
@@ -390,7 +390,7 @@ public void testStreamingDoesNotBlockMainThread() throws Exception {
}""";
// Start streaming
- RestHandler.HTTPRestResponse response = handler.sendStreamingMessage(requestBody, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.sendStreamingMessage(callContext, "", requestBody);
Assertions.assertEquals(200, response.getStatusCode());
Assertions.assertInstanceOf(RestHandler.HTTPRestStreamingResponse.class, response);
@@ -479,7 +479,7 @@ public void testExtensionSupportRequiredErrorOnSendMessage() {
}
}""";
- RestHandler.HTTPRestResponse response = handler.sendMessage(requestBody, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.sendMessage(callContext, "", requestBody);
Assertions.assertEquals(400, response.getStatusCode());
Assertions.assertEquals("application/json", response.getContentType());
@@ -528,7 +528,7 @@ public void testExtensionSupportRequiredErrorOnSendStreamingMessage() {
}
}""";
- RestHandler.HTTPRestResponse response = handler.sendStreamingMessage(requestBody, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.sendStreamingMessage(callContext, "", requestBody);
// Streaming responses embed errors in the stream with status 200
Assertions.assertEquals(200, response.getStatusCode());
@@ -630,7 +630,7 @@ public void testRequiredExtensionProvidedSuccess() {
}
}""";
- RestHandler.HTTPRestResponse response = handler.sendMessage(requestBody, "", contextWithExtension);
+ RestHandler.HTTPRestResponse response = handler.sendMessage(contextWithExtension, "", requestBody);
// Should succeed without error
Assertions.assertEquals(200, response.getStatusCode());
@@ -681,7 +681,7 @@ public void testVersionNotSupportedErrorOnSendMessage() {
}
}""";
- RestHandler.HTTPRestResponse response = handler.sendMessage(requestBody, "", contextWithVersion);
+ RestHandler.HTTPRestResponse response = handler.sendMessage(contextWithVersion, "", requestBody);
Assertions.assertEquals(501, response.getStatusCode());
Assertions.assertEquals("application/json", response.getContentType());
@@ -731,7 +731,7 @@ public void testVersionNotSupportedErrorOnSendStreamingMessage() {
}
}""";
- RestHandler.HTTPRestResponse response = handler.sendStreamingMessage(requestBody, "", contextWithVersion);
+ RestHandler.HTTPRestResponse response = handler.sendStreamingMessage(contextWithVersion, "", requestBody);
// Streaming responses embed errors in the stream with status 200
Assertions.assertEquals(200, response.getStatusCode());
@@ -824,7 +824,7 @@ public void testCompatibleVersionSuccess() {
}
}""";
- RestHandler.HTTPRestResponse response = handler.sendMessage(requestBody, "", contextWithVersion);
+ RestHandler.HTTPRestResponse response = handler.sendMessage(contextWithVersion, "", requestBody);
// Should succeed without error
Assertions.assertEquals(200, response.getStatusCode());
@@ -872,7 +872,7 @@ public void testNoVersionDefaultsToCurrentVersionSuccess() {
}
}""";
- RestHandler.HTTPRestResponse response = handler.sendMessage(requestBody, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.sendMessage(callContext, "", requestBody);
// Should succeed without error (defaults to 1.0)
Assertions.assertEquals(200, response.getStatusCode());
@@ -885,8 +885,8 @@ public void testListTasksNegativeTimestampReturns422() {
RestHandler handler = new RestHandler(CARD, requestHandler, internalExecutor);
// Negative timestamp should return 422 (Invalid params)
- RestHandler.HTTPRestResponse response = handler.listTasks(null, null, null, null,
- null, "-1", null, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.listTasks(callContext, "", null, null, null, null,
+ null, "-1", null);
Assertions.assertEquals(422, response.getStatusCode());
Assertions.assertEquals("application/json", response.getContentType());
@@ -900,8 +900,8 @@ public void testListTasksUnixMillisecondsTimestamp() {
// Unix milliseconds timestamp should be accepted
String timestampMillis = String.valueOf(System.currentTimeMillis() - 10000);
- RestHandler.HTTPRestResponse response = handler.listTasks(null, null, null, null,
- null, timestampMillis, null, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.listTasks(callContext, "", null, null, null, null,
+ null, timestampMillis, null);
Assertions.assertEquals(200, response.getStatusCode());
Assertions.assertEquals("application/json", response.getContentType());
@@ -914,8 +914,8 @@ public void testListTasksProtobufEnumStatus() {
taskStore.save(MINIMAL_TASK, false);
// Protobuf enum format (TASK_STATE_SUBMITTED) should be accepted
- RestHandler.HTTPRestResponse response = handler.listTasks(null, "TASK_STATE_SUBMITTED", null, null,
- null, null, null, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.listTasks(callContext, "", null, "TASK_STATE_SUBMITTED", null, null,
+ null, null, null);
Assertions.assertEquals(200, response.getStatusCode());
Assertions.assertEquals("application/json", response.getContentType());
@@ -928,8 +928,8 @@ public void testListTasksEnumConstantStatus() {
taskStore.save(MINIMAL_TASK, false);
// Enum constant format (SUBMITTED) should be accepted
- RestHandler.HTTPRestResponse response = handler.listTasks(null, "SUBMITTED", null, null,
- null, null, null, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.listTasks(callContext, "", null, "SUBMITTED", null, null,
+ null, null, null);
Assertions.assertEquals(200, response.getStatusCode());
Assertions.assertEquals("application/json", response.getContentType());
@@ -941,8 +941,8 @@ public void testListTasksEmptyResultIncludesAllFields() {
RestHandler handler = new RestHandler(CARD, requestHandler, internalExecutor);
// Query for a context that doesn't exist - should return empty result with all fields
- RestHandler.HTTPRestResponse response = handler.listTasks("nonexistent-context-id", null, null, null,
- null, null, null, "", callContext);
+ RestHandler.HTTPRestResponse response = handler.listTasks(callContext, "", "nonexistent-context-id", null, null, null,
+ null, null, null);
Assertions.assertEquals(200, response.getStatusCode());
Assertions.assertEquals("application/json", response.getContentType());