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 31a1a6670..2e310ccf0 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;
@@ -66,6 +67,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 979bb5ef4..7a312a5d0 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
@@ -318,17 +322,23 @@ public void onNext(StreamingEventKind event) {
if (isFinal) {
responseObserver.onCompleted();
} else {
- subscription.request(1);
+ if (this.subscription != null) {
+ subscription.request(1);
+ }
}
} 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 {
@@ -412,8 +422,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);
}
@@ -582,7 +596,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) {
@@ -598,7 +612,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) {
@@ -618,7 +632,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) {
@@ -633,7 +647,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);
}
@@ -643,8 +657,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);
}
/**
@@ -653,7 +667,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 da22cf592..aa5ad4493 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 ada8e8170..96ef35bda 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 2d1c19b84..45c7a35cc 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
@@ -35,13 +35,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());
@@ -52,7 +52,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());
@@ -64,8 +64,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());
@@ -76,8 +76,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());
@@ -109,7 +109,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());
@@ -120,7 +120,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());
@@ -144,7 +144,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());
@@ -155,7 +155,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());
@@ -176,7 +176,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());
@@ -187,7 +187,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());
@@ -217,7 +217,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;
@@ -240,7 +240,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"));
@@ -263,7 +263,7 @@ public void testPushNotificationConfigSuccess() {
}
}""".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(201, response.getStatusCode(), response.toString());
Assertions.assertEquals("application/json", response.getContentType());
@@ -284,7 +284,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"));
@@ -307,11 +307,11 @@ public void testGetPushNotificationConfig() {
}
}
}""".formatted(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());
}
@@ -320,7 +320,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());
}
@@ -329,7 +329,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());
@@ -341,11 +341,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());
}
@@ -385,7 +385,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);
@@ -473,7 +473,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());
@@ -521,7 +521,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());
@@ -622,7 +622,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());
@@ -673,7 +673,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());
@@ -723,7 +723,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());
@@ -816,7 +816,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());
@@ -864,7 +864,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());
@@ -877,8 +877,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());
@@ -892,8 +892,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());
@@ -906,8 +906,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());
@@ -920,8 +920,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());
@@ -933,8 +933,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());