diff --git a/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcTransport.java b/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcTransport.java index 7824e83c0..ca849d99c 100644 --- a/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcTransport.java +++ b/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcTransport.java @@ -233,7 +233,7 @@ public TaskPushNotificationConfig createTaskPushNotificationConfiguration(TaskPu @Nullable ClientCallContext context) throws A2AClientException { checkNotNullParam("request", request); - String configId = request.pushNotificationConfig().id(); + String configId = request.config().id(); io.a2a.grpc.CreateTaskPushNotificationConfigRequest grpcRequest = io.a2a.grpc.CreateTaskPushNotificationConfigRequest.newBuilder() .setTaskId(request.taskId()) .setConfig(ToProto.taskPushNotificationConfig(request).getPushNotificationConfig()) @@ -254,15 +254,15 @@ public TaskPushNotificationConfig createTaskPushNotificationConfiguration(TaskPu public TaskPushNotificationConfig getTaskPushNotificationConfiguration(GetTaskPushNotificationConfigParams request, @Nullable ClientCallContext context) throws A2AClientException { checkNotNullParam("request", request); - checkNotNullParam("taskId", request.id()); - if(request.pushNotificationConfigId() == null) { + checkNotNullParam("taskId", request.taskId()); + if(request.id() == null) { throw new IllegalArgumentException("Id must not be null"); } io.a2a.grpc.GetTaskPushNotificationConfigRequest grpcRequest = io.a2a.grpc.GetTaskPushNotificationConfigRequest.newBuilder() - .setTaskId(request.id()) + .setTaskId(request.taskId()) .setTenant(resolveTenant(request.tenant())) - .setId(request.pushNotificationConfigId()) + .setId(request.id()) .build(); PayloadAndHeaders payloadAndHeaders = applyInterceptors(GET_TASK_PUSH_NOTIFICATION_CONFIG_METHOD, grpcRequest, agentCard, context); @@ -304,8 +304,8 @@ public void deleteTaskPushNotificationConfigurations(DeleteTaskPushNotificationC checkNotNullParam("request", request); io.a2a.grpc.DeleteTaskPushNotificationConfigRequest grpcRequest = io.a2a.grpc.DeleteTaskPushNotificationConfigRequest.newBuilder() - .setTaskId(request.id()) - .setId(request.pushNotificationConfigId()) + .setTaskId(request.taskId()) + .setId(request.id()) .setTenant(resolveTenant(request.tenant())) .build(); PayloadAndHeaders payloadAndHeaders = applyInterceptors(DELETE_TASK_PUSH_NOTIFICATION_CONFIG_METHOD, grpcRequest, agentCard, context); diff --git a/client/transport/jsonrpc/src/test/java/io/a2a/client/transport/jsonrpc/JSONRPCTransportTest.java b/client/transport/jsonrpc/src/test/java/io/a2a/client/transport/jsonrpc/JSONRPCTransportTest.java index f6677ff13..255ce5fc8 100644 --- a/client/transport/jsonrpc/src/test/java/io/a2a/client/transport/jsonrpc/JSONRPCTransportTest.java +++ b/client/transport/jsonrpc/src/test/java/io/a2a/client/transport/jsonrpc/JSONRPCTransportTest.java @@ -309,7 +309,7 @@ public void testA2AClientGetTaskPushNotificationConfig() throws Exception { JSONRPCTransport client = new JSONRPCTransport("http://localhost:4001"); TaskPushNotificationConfig taskPushNotificationConfig = client.getTaskPushNotificationConfiguration( new GetTaskPushNotificationConfigParams("de38c76d-d54c-436c-8b9f-4c2703648d64", "c295ea44-7543-4f78-b524-7a38915ad6e4"), null); - PushNotificationConfig pushNotificationConfig = taskPushNotificationConfig.pushNotificationConfig(); + PushNotificationConfig pushNotificationConfig = taskPushNotificationConfig.config(); assertNotNull(pushNotificationConfig); assertEquals("https://example.com/callback", pushNotificationConfig.url()); AuthenticationInfo authenticationInfo = pushNotificationConfig.authentication(); @@ -339,7 +339,7 @@ public void testA2AClientCreateTaskPushNotificationConfig() throws Exception { .url("https://example.com/callback") .authentication(new AuthenticationInfo("jwt", null)) .build(), ""), null); - PushNotificationConfig pushNotificationConfig = taskPushNotificationConfig.pushNotificationConfig(); + PushNotificationConfig pushNotificationConfig = taskPushNotificationConfig.config(); assertNotNull(pushNotificationConfig); assertEquals("https://example.com/callback", pushNotificationConfig.url()); AuthenticationInfo authenticationInfo = pushNotificationConfig.authentication(); diff --git a/client/transport/rest/src/main/java/io/a2a/client/transport/rest/RestTransport.java b/client/transport/rest/src/main/java/io/a2a/client/transport/rest/RestTransport.java index 61fb29428..27137c24f 100644 --- a/client/transport/rest/src/main/java/io/a2a/client/transport/rest/RestTransport.java +++ b/client/transport/rest/src/main/java/io/a2a/client/transport/rest/RestTransport.java @@ -274,8 +274,8 @@ public TaskPushNotificationConfig createTaskPushNotificationConfiguration(TaskPu = io.a2a.grpc.CreateTaskPushNotificationConfigRequest.newBuilder(); builder.setConfig(ProtoUtils.ToProto.taskPushNotificationConfig(request).getPushNotificationConfig()) .setTaskId(request.taskId()); - if (request.pushNotificationConfig().id() != null) { - builder.setConfigId(request.pushNotificationConfig().id()); + if (request.config().id() != null) { + builder.setConfigId(request.config().id()); } PayloadAndHeaders payloadAndHeaders = applyInterceptors(SET_TASK_PUSH_NOTIFICATION_CONFIG_METHOD, builder, agentCard, context); try { @@ -296,14 +296,14 @@ public TaskPushNotificationConfig getTaskPushNotificationConfiguration(GetTaskPu io.a2a.grpc.GetTaskPushNotificationConfigRequest.Builder builder = io.a2a.grpc.GetTaskPushNotificationConfigRequest.newBuilder(); StringBuilder url = new StringBuilder(Utils.buildBaseUrl(agentInterface, request.tenant())); - String configId = request.pushNotificationConfigId(); + String configId = request.id(); if (configId != null && !configId.isEmpty()) { - builder.setId(configId).setTaskId(request.id()); - url.append(String.format("/tasks/%1s/pushNotificationConfigs/%2s", request.id(), configId)); + builder.setId(configId).setTaskId(request.taskId()); + url.append(String.format("/tasks/%1s/pushNotificationConfigs/%2s", request.taskId(), configId)); } else { // Use trailing slash to distinguish GET from LIST - builder.setTaskId(request.id()); - url.append(String.format("/tasks/%1s/pushNotificationConfigs/", request.id())); + builder.setTaskId(request.taskId()); + url.append(String.format("/tasks/%1s/pushNotificationConfigs/", request.taskId())); } PayloadAndHeaders payloadAndHeaders = applyInterceptors(GET_TASK_PUSH_NOTIFICATION_CONFIG_METHOD, builder, agentCard, context); @@ -367,7 +367,7 @@ public void deleteTaskPushNotificationConfigurations(DeleteTaskPushNotificationC PayloadAndHeaders payloadAndHeaders = applyInterceptors(DELETE_TASK_PUSH_NOTIFICATION_CONFIG_METHOD, builder, agentCard, context); try { - String url = Utils.buildBaseUrl(agentInterface, request.tenant()) + String.format("/tasks/%1s/pushNotificationConfigs/%2s", request.id(), request.pushNotificationConfigId()); + String url = Utils.buildBaseUrl(agentInterface, request.tenant()) + String.format("/tasks/%1s/pushNotificationConfigs/%2s", request.taskId(), request.id()); A2AHttpClient.DeleteBuilder deleteBuilder = httpClient.createDelete().url(url); if (payloadAndHeaders.getHeaders() != null) { for (Map.Entry entry : payloadAndHeaders.getHeaders().entrySet()) { diff --git a/client/transport/rest/src/test/java/io/a2a/client/transport/rest/RestTransportTest.java b/client/transport/rest/src/test/java/io/a2a/client/transport/rest/RestTransportTest.java index 476a93ba2..6fc0fa600 100644 --- a/client/transport/rest/src/test/java/io/a2a/client/transport/rest/RestTransportTest.java +++ b/client/transport/rest/src/test/java/io/a2a/client/transport/rest/RestTransportTest.java @@ -310,7 +310,7 @@ public void testCreateTaskPushNotificationConfiguration() throws Exception { new AuthenticationInfo("jwt", null)) .build(), "tenant"); TaskPushNotificationConfig taskPushNotificationConfig = client.createTaskPushNotificationConfiguration(pushedConfig, null); - PushNotificationConfig pushNotificationConfig = taskPushNotificationConfig.pushNotificationConfig(); + PushNotificationConfig pushNotificationConfig = taskPushNotificationConfig.config(); assertNotNull(pushNotificationConfig); assertEquals("https://example.com/callback", pushNotificationConfig.url()); AuthenticationInfo authenticationInfo = pushNotificationConfig.authentication(); @@ -336,7 +336,7 @@ public void testGetTaskPushNotificationConfiguration() throws Exception { RestTransport client = new RestTransport(CARD); TaskPushNotificationConfig taskPushNotificationConfig = client.getTaskPushNotificationConfiguration( new GetTaskPushNotificationConfigParams("de38c76d-d54c-436c-8b9f-4c2703648d64", "10"), null); - PushNotificationConfig pushNotificationConfig = taskPushNotificationConfig.pushNotificationConfig(); + PushNotificationConfig pushNotificationConfig = taskPushNotificationConfig.config(); assertNotNull(pushNotificationConfig); assertEquals("https://example.com/callback", pushNotificationConfig.url()); AuthenticationInfo authenticationInfo = pushNotificationConfig.authentication(); @@ -363,14 +363,14 @@ public void testListTaskPushNotificationConfigurations() throws Exception { ListTaskPushNotificationConfigResult result = client.listTaskPushNotificationConfigurations( new ListTaskPushNotificationConfigParams("de38c76d-d54c-436c-8b9f-4c2703648d64"), null); assertEquals(2, result.configs().size()); - PushNotificationConfig pushNotificationConfig = result.configs().get(0).pushNotificationConfig(); + PushNotificationConfig pushNotificationConfig = result.configs().get(0).config(); assertNotNull(pushNotificationConfig); assertEquals("https://example.com/callback", pushNotificationConfig.url()); assertEquals("10", pushNotificationConfig.id()); AuthenticationInfo authenticationInfo = pushNotificationConfig.authentication(); assertEquals("jwt", authenticationInfo.scheme()); assertEquals("", authenticationInfo.credentials()); - pushNotificationConfig = result.configs().get(1).pushNotificationConfig(); + pushNotificationConfig = result.configs().get(1).config(); assertNotNull(pushNotificationConfig); assertEquals("https://test.com/callback", pushNotificationConfig.url()); assertEquals("5", pushNotificationConfig.id()); diff --git a/extras/opentelemetry/client/src/main/java/io/a2a/extras/opentelemetry/client/OpenTelemetryClientTransport.java b/extras/opentelemetry/client/src/main/java/io/a2a/extras/opentelemetry/client/OpenTelemetryClientTransport.java index ed0db190d..640fb757d 100644 --- a/extras/opentelemetry/client/src/main/java/io/a2a/extras/opentelemetry/client/OpenTelemetryClientTransport.java +++ b/extras/opentelemetry/client/src/main/java/io/a2a/extras/opentelemetry/client/OpenTelemetryClientTransport.java @@ -246,8 +246,8 @@ public TaskPushNotificationConfig createTaskPushNotificationConfiguration(TaskPu if (request.taskId() != null) { spanBuilder.setAttribute(GENAI_TASK_ID, request.taskId()); } - if (request.pushNotificationConfig() != null && request.pushNotificationConfig().id() != null) { - spanBuilder.setAttribute(GENAI_CONFIG_ID, request.pushNotificationConfig().id()); + if (request.config() != null && request.config().id() != null) { + spanBuilder.setAttribute(GENAI_CONFIG_ID, request.config().id()); } if (extractRequest()) { spanBuilder.setAttribute(GENAI_REQUEST, request.toString()); @@ -276,11 +276,11 @@ public TaskPushNotificationConfig getTaskPushNotificationConfiguration(GetTaskPu ClientCallContext clientContext = createContext(context); SpanBuilder spanBuilder = tracer.spanBuilder(A2AMethods.GET_TASK_PUSH_NOTIFICATION_CONFIG_METHOD).setSpanKind(SpanKind.CLIENT); spanBuilder.setAttribute(GENAI_OPERATION_NAME, A2AMethods.GET_TASK_PUSH_NOTIFICATION_CONFIG_METHOD); - if (request.id() != null) { - spanBuilder.setAttribute(GENAI_TASK_ID, request.id()); + if (request.taskId() != null) { + spanBuilder.setAttribute(GENAI_TASK_ID, request.taskId()); } - if (request.pushNotificationConfigId() != null) { - spanBuilder.setAttribute(GENAI_CONFIG_ID, request.pushNotificationConfigId()); + if (request.id() != null) { + spanBuilder.setAttribute(GENAI_CONFIG_ID, request.id()); } if (extractRequest()) { spanBuilder.setAttribute(GENAI_REQUEST, request.toString()); @@ -345,11 +345,11 @@ public void deleteTaskPushNotificationConfigurations(DeleteTaskPushNotificationC if (extractRequest()) { spanBuilder.setAttribute(GENAI_REQUEST, request.toString()); } - if (request.id() != null) { - spanBuilder.setAttribute(GENAI_TASK_ID, request.id()); + if (request.taskId() != null) { + spanBuilder.setAttribute(GENAI_TASK_ID, request.taskId()); } - if (request.pushNotificationConfigId() != null) { - spanBuilder.setAttribute(GENAI_CONFIG_ID, request.pushNotificationConfigId()); + if (request.id() != null) { + spanBuilder.setAttribute(GENAI_CONFIG_ID, request.id()); } Span span = spanBuilder.startSpan(); try (Scope scope = span.makeCurrent()) { diff --git a/extras/opentelemetry/server/src/main/java/io/a2a/extras/opentelemetry/OpenTelemetryRequestHandlerDecorator.java b/extras/opentelemetry/server/src/main/java/io/a2a/extras/opentelemetry/OpenTelemetryRequestHandlerDecorator.java index f8bbf0745..b1bf3d680 100644 --- a/extras/opentelemetry/server/src/main/java/io/a2a/extras/opentelemetry/OpenTelemetryRequestHandlerDecorator.java +++ b/extras/opentelemetry/server/src/main/java/io/a2a/extras/opentelemetry/OpenTelemetryRequestHandlerDecorator.java @@ -298,8 +298,8 @@ public TaskPushNotificationConfig onCreateTaskPushNotificationConfig(TaskPushNot if (params.taskId() != null) { spanBuilder.setAttribute(GENAI_TASK_ID, params.taskId()); } - if (params.pushNotificationConfig() != null && params.pushNotificationConfig().id() != null) { - spanBuilder.setAttribute(GENAI_CONFIG_ID, params.pushNotificationConfig().id()); + if (params.config() != null && params.config().id() != null) { + spanBuilder.setAttribute(GENAI_CONFIG_ID, params.config().id()); } if (extractRequest()) { spanBuilder.setAttribute(GENAI_REQUEST, params.toString()); @@ -331,11 +331,11 @@ public TaskPushNotificationConfig onGetTaskPushNotificationConfig(GetTaskPushNot .setSpanKind(SpanKind.SERVER) .setAttribute(GENAI_OPERATION_NAME, A2AMethods.GET_TASK_PUSH_NOTIFICATION_CONFIG_METHOD); - if (params.id() != null) { - spanBuilder.setAttribute(GENAI_TASK_ID, params.id()); + if (params.taskId() != null) { + spanBuilder.setAttribute(GENAI_TASK_ID, params.taskId()); } - if (params.pushNotificationConfigId() != null) { - spanBuilder.setAttribute(GENAI_CONFIG_ID, params.pushNotificationConfigId()); + if (params.id() != null) { + spanBuilder.setAttribute(GENAI_CONFIG_ID, params.id()); } if (extractRequest()) { spanBuilder.setAttribute(GENAI_REQUEST, params.toString()); @@ -436,8 +436,8 @@ public void onDeleteTaskPushNotificationConfig(DeleteTaskPushNotificationConfigP if (extractRequest()) { spanBuilder.setAttribute(GENAI_REQUEST, params.toString()); } - if (params.id() != null) { - spanBuilder.setAttribute(GENAI_TASK_ID, params.id()); + if (params.taskId() != null) { + spanBuilder.setAttribute(GENAI_TASK_ID, params.taskId()); } Span span = spanBuilder.startSpan(); diff --git a/extras/push-notification-config-store-database-jpa/src/test/java/io/a2a/extras/pushnotificationconfigstore/database/jpa/JpaDatabasePushNotificationConfigStoreIntegrationTest.java b/extras/push-notification-config-store-database-jpa/src/test/java/io/a2a/extras/pushnotificationconfigstore/database/jpa/JpaDatabasePushNotificationConfigStoreIntegrationTest.java index 96f8f3adc..3e7a43d0e 100644 --- a/extras/push-notification-config-store-database-jpa/src/test/java/io/a2a/extras/pushnotificationconfigstore/database/jpa/JpaDatabasePushNotificationConfigStoreIntegrationTest.java +++ b/extras/push-notification-config-store-database-jpa/src/test/java/io/a2a/extras/pushnotificationconfigstore/database/jpa/JpaDatabasePushNotificationConfigStoreIntegrationTest.java @@ -133,9 +133,9 @@ public void testJpaDatabasePushNotificationConfigStoreIntegration() throws Excep assertNotNull(storedConfig); assertEquals(taskId, storedConfig.taskId()); - assertEquals("test-config-1", storedConfig.pushNotificationConfig().id()); - assertEquals("http://localhost:9999/mock-endpoint", storedConfig.pushNotificationConfig().url()); - assertEquals("test-token-123", storedConfig.pushNotificationConfig().token()); + assertEquals("test-config-1", storedConfig.config().id()); + assertEquals("http://localhost:9999/mock-endpoint", storedConfig.config().url()); + assertEquals("test-token-123", storedConfig.config().token()); // Step 4: Update the task to trigger the notification Message updateMessage = Message.builder() @@ -239,10 +239,10 @@ public void testPaginationWithPageToken() { // Verify NO overlap between pages - collect all IDs from both pages List firstPageIds = firstPage.configs().stream() - .map(c -> c.pushNotificationConfig().id()) + .map(c -> c.config().id()) .toList(); List secondPageIds = secondPage.configs().stream() - .map(c -> c.pushNotificationConfig().id()) + .map(c -> c.config().id()) .toList(); // Check that no ID from first page appears in second page @@ -471,10 +471,10 @@ public void testMultipleTasksDoNotInterfere() { assertEquals(2, result2.configs().size(), "Task2 should have 2 configs"); List task1Ids = result1.configs().stream() - .map(c -> taskId1 + c.pushNotificationConfig().id()) + .map(c -> taskId1 + c.config().id()) .toList(); List task2Ids = result2.configs().stream() - .map(c -> taskId2 + c.pushNotificationConfig().id()) + .map(c -> taskId2 + c.config().id()) .toList(); for (String id : task1Ids) { @@ -535,7 +535,7 @@ public void testPaginationOrderingConsistency() { ListTaskPushNotificationConfigResult result = pushNotificationConfigStore.getInfo(params); result.configs().forEach(c -> - allConfigIds.add(c.pushNotificationConfig().id())); + allConfigIds.add(c.config().id())); pageToken = result.nextPageToken(); pageCount++; diff --git a/extras/push-notification-config-store-database-jpa/src/test/java/io/a2a/extras/pushnotificationconfigstore/database/jpa/JpaPushNotificationConfigStoreTest.java b/extras/push-notification-config-store-database-jpa/src/test/java/io/a2a/extras/pushnotificationconfigstore/database/jpa/JpaPushNotificationConfigStoreTest.java index 6ecf045eb..81c3582d5 100644 --- a/extras/push-notification-config-store-database-jpa/src/test/java/io/a2a/extras/pushnotificationconfigstore/database/jpa/JpaPushNotificationConfigStoreTest.java +++ b/extras/push-notification-config-store-database-jpa/src/test/java/io/a2a/extras/pushnotificationconfigstore/database/jpa/JpaPushNotificationConfigStoreTest.java @@ -94,8 +94,8 @@ public void testSetInfoAddsNewConfig() { ListTaskPushNotificationConfigResult configResult = configStore.getInfo(new ListTaskPushNotificationConfigParams(taskId)); assertNotNull(configResult); assertEquals(1, configResult.configs().size()); - assertEquals(config.url(), configResult.configs().get(0).pushNotificationConfig().url()); - assertEquals(config.id(), configResult.configs().get(0).pushNotificationConfig().id()); + assertEquals(config.url(), configResult.configs().get(0).config().url()); + assertEquals(config.id(), configResult.configs().get(0).config().id()); } @Test @@ -116,7 +116,7 @@ public void testSetInfoAppendsToExistingConfig() { // Find the configs by ID since order might vary List configs = configResult.configs().stream() - .map(TaskPushNotificationConfig::pushNotificationConfig) + .map(TaskPushNotificationConfig::config) .toList(); PushNotificationConfig foundInitial = configs.stream() .filter(c -> "cfg_initial".equals(c.id())) @@ -146,7 +146,7 @@ public void testSetInfoWithoutConfigId() { ListTaskPushNotificationConfigResult configResult = configStore.getInfo(new ListTaskPushNotificationConfigParams(taskId)); assertEquals(1, configResult.configs().size()); - assertEquals(taskId, configResult.configs().get(0).pushNotificationConfig().id()); + assertEquals(taskId, configResult.configs().get(0).config().id()); PushNotificationConfig updatedConfig = PushNotificationConfig.builder() .url("http://initial.url/callback_new") @@ -157,7 +157,7 @@ public void testSetInfoWithoutConfigId() { configResult = configStore.getInfo(new ListTaskPushNotificationConfigParams(taskId)); assertEquals(1, configResult.configs().size(), "Should replace existing config with same ID rather than adding new one"); - assertEquals(updatedConfig.url(), configResult.configs().get(0).pushNotificationConfig().url()); + assertEquals(updatedConfig.url(), configResult.configs().get(0).config().url()); } @Test @@ -170,8 +170,8 @@ public void testGetInfoExistingConfig() { ListTaskPushNotificationConfigResult configResult = configStore.getInfo(new ListTaskPushNotificationConfigParams(taskId)); assertNotNull(configResult); assertEquals(1, configResult.configs().size()); - assertEquals(config.url(), configResult.configs().get(0).pushNotificationConfig().url()); - assertEquals(config.id(), configResult.configs().get(0).pushNotificationConfig().id()); + assertEquals(config.url(), configResult.configs().get(0).config().url()); + assertEquals(config.id(), configResult.configs().get(0).config().id()); } @Test @@ -326,7 +326,7 @@ public void testMultipleConfigsForSameTask() { // Verify both configs are present List configs = configResult.configs().stream() - .map(TaskPushNotificationConfig::pushNotificationConfig) + .map(TaskPushNotificationConfig::config) .toList(); assertTrue(configs.stream().anyMatch(c -> "cfg1".equals(c.id()))); assertTrue(configs.stream().anyMatch(c -> "cfg2".equals(c.id()))); @@ -348,7 +348,7 @@ public void testDeleteSpecificConfigFromMultiple() { ListTaskPushNotificationConfigResult configResult = configStore.getInfo(new ListTaskPushNotificationConfigParams(taskId)); assertNotNull(configResult); assertEquals(1, configResult.configs().size()); - assertEquals("cfg2", configResult.configs().get(0).pushNotificationConfig().id()); + assertEquals("cfg2", configResult.configs().get(0).config().id()); } @Test @@ -364,7 +364,7 @@ public void testConfigStoreIntegration() { ListTaskPushNotificationConfigResult configResult = configStore.getInfo(new ListTaskPushNotificationConfigParams(taskId)); assertEquals(1, configResult.configs().size()); - assertEquals(config.url(), configResult.configs().get(0).pushNotificationConfig().url()); + assertEquals(config.url(), configResult.configs().get(0).config().url()); // Test deletion configStore.deleteInfo(taskId, storedConfig.id()); 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 5fd8836dc..db96df3f2 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,7 +6,6 @@ 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,7 +67,6 @@ 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; @@ -765,7 +763,7 @@ public TaskPushNotificationConfig onCreateTaskPushNotificationConfig( throw new TaskNotFoundError(); } - PushNotificationConfig pushNotificationConfig = pushConfigStore.setInfo(params.taskId(), params.pushNotificationConfig()); + PushNotificationConfig pushNotificationConfig = pushConfigStore.setInfo(params.taskId(), params.config()); return new TaskPushNotificationConfig(params.taskId(), pushNotificationConfig, params.tenant()); } @@ -775,30 +773,28 @@ public TaskPushNotificationConfig onGetTaskPushNotificationConfig( if (pushConfigStore == null) { throw new UnsupportedOperationError(); } - Task task = taskStore.get(params.id()); + Task task = taskStore.get(params.taskId()); if (task == null) { throw new TaskNotFoundError(); } - ListTaskPushNotificationConfigResult listTaskPushNotificationConfigResult = pushConfigStore.getInfo(new ListTaskPushNotificationConfigParams(params.id())); + ListTaskPushNotificationConfigResult listTaskPushNotificationConfigResult = pushConfigStore.getInfo(new ListTaskPushNotificationConfigParams(params.taskId())); if (listTaskPushNotificationConfigResult == null || listTaskPushNotificationConfigResult.isEmpty()) { throw new InternalError("No push notification config found"); } - @Nullable String configId = params.pushNotificationConfigId(); - return new TaskPushNotificationConfig(params.id(), getPushNotificationConfig(listTaskPushNotificationConfigResult, configId), params.tenant()); + String configId = params.id(); + return new TaskPushNotificationConfig(params.taskId(), getPushNotificationConfig(listTaskPushNotificationConfigResult, configId), params.tenant()); } private PushNotificationConfig getPushNotificationConfig(ListTaskPushNotificationConfigResult notificationConfigList, - @Nullable String configId) { - if (configId != null) { + String configId) { for (TaskPushNotificationConfig notificationConfig : notificationConfigList.configs()) { - if (configId.equals(notificationConfig.pushNotificationConfig().id())) { - return notificationConfig.pushNotificationConfig(); - } + if (configId.equals(notificationConfig.config().id())) { + return notificationConfig.config(); } } - return notificationConfigList.configs().get(0).pushNotificationConfig(); + return notificationConfigList.configs().get(0).config(); } @Override @@ -859,12 +855,12 @@ public void onDeleteTaskPushNotificationConfig( throw new UnsupportedOperationError(); } - Task task = taskStore.get(params.id()); + Task task = taskStore.get(params.taskId()); if (task == null) { throw new TaskNotFoundError(); } - pushConfigStore.deleteInfo(params.id(), params.pushNotificationConfigId()); + pushConfigStore.deleteInfo(params.taskId(), params.id()); } private boolean shouldAddPushInfo(MessageSendParams params) { diff --git a/server-common/src/main/java/io/a2a/server/tasks/BasePushNotificationSender.java b/server-common/src/main/java/io/a2a/server/tasks/BasePushNotificationSender.java index a9b8093bf..0d6bdcf3b 100644 --- a/server-common/src/main/java/io/a2a/server/tasks/BasePushNotificationSender.java +++ b/server-common/src/main/java/io/a2a/server/tasks/BasePushNotificationSender.java @@ -87,7 +87,7 @@ public void sendNotification(StreamingEventKind event) { List> dispatchResults = configs .stream() - .map(pushConfig -> dispatch(event, pushConfig.pushNotificationConfig())) + .map(pushConfig -> dispatch(event, pushConfig.config())) .toList(); CompletableFuture allFutures = CompletableFuture.allOf(dispatchResults.toArray(new CompletableFuture[0])); CompletableFuture dispatchResult = allFutures.thenApply(v -> dispatchResults.stream() diff --git a/server-common/src/test/java/io/a2a/server/tasks/InMemoryPushNotificationConfigStoreTest.java b/server-common/src/test/java/io/a2a/server/tasks/InMemoryPushNotificationConfigStoreTest.java index c8ccd669f..09e261670 100644 --- a/server-common/src/test/java/io/a2a/server/tasks/InMemoryPushNotificationConfigStoreTest.java +++ b/server-common/src/test/java/io/a2a/server/tasks/InMemoryPushNotificationConfigStoreTest.java @@ -104,8 +104,8 @@ public void testSetInfoAddsNewConfig() { ListTaskPushNotificationConfigResult configResult = configStore.getInfo(new ListTaskPushNotificationConfigParams(taskId)); assertNotNull(configResult); assertEquals(1, configResult.configs().size()); - assertEquals(config.url(), configResult.configs().get(0).pushNotificationConfig().url()); - assertEquals(config.id(), configResult.configs().get(0).pushNotificationConfig().id()); + assertEquals(config.url(), configResult.configs().get(0).config().url()); + assertEquals(config.id(), configResult.configs().get(0).config().id()); } @Test @@ -125,7 +125,7 @@ public void testSetInfoAppendsToExistingConfig() { // Find the configs by ID since order might vary List configs = configResult.configs().stream() - .map(TaskPushNotificationConfig::pushNotificationConfig) + .map(TaskPushNotificationConfig::config) .toList(); PushNotificationConfig foundInitial = configs.stream() .filter(c -> "cfg_initial".equals(c.id())) @@ -154,7 +154,7 @@ public void testSetInfoWithoutConfigId() { ListTaskPushNotificationConfigResult configResult = configStore.getInfo(new ListTaskPushNotificationConfigParams(taskId)); assertEquals(1, configResult.configs().size()); - assertEquals(taskId, configResult.configs().get(0).pushNotificationConfig().id()); + assertEquals(taskId, configResult.configs().get(0).config().id()); PushNotificationConfig updatedConfig = PushNotificationConfig.builder() .url("http://initial.url/callback_new") @@ -165,7 +165,7 @@ public void testSetInfoWithoutConfigId() { configResult = configStore.getInfo(new ListTaskPushNotificationConfigParams(taskId)); assertEquals(1, configResult.configs().size(), "Should replace existing config with same ID rather than adding new one"); - assertEquals(updatedConfig.url(), configResult.configs().get(0).pushNotificationConfig().url()); + assertEquals(updatedConfig.url(), configResult.configs().get(0).config().url()); } @Test @@ -177,8 +177,8 @@ public void testGetInfoExistingConfig() { ListTaskPushNotificationConfigResult configResult = configStore.getInfo(new ListTaskPushNotificationConfigParams(taskId)); assertNotNull(configResult); assertEquals(1, configResult.configs().size()); - assertEquals(config.url(), configResult.configs().get(0).pushNotificationConfig().url()); - assertEquals(config.id(), configResult.configs().get(0).pushNotificationConfig().id()); + assertEquals(config.url(), configResult.configs().get(0).config().url()); + assertEquals(config.id(), configResult.configs().get(0).config().id()); } @Test @@ -340,7 +340,7 @@ public void testMultipleConfigsForSameTask() { // Verify both configs are present List configs = configResult.configs().stream() - .map(TaskPushNotificationConfig::pushNotificationConfig) + .map(TaskPushNotificationConfig::config) .toList(); assertTrue(configs.stream().anyMatch(c -> "cfg1".equals(c.id()))); assertTrue(configs.stream().anyMatch(c -> "cfg2".equals(c.id()))); @@ -361,7 +361,7 @@ public void testDeleteSpecificConfigFromMultiple() { ListTaskPushNotificationConfigResult configResult = configStore.getInfo(new ListTaskPushNotificationConfigParams(taskId)); assertNotNull(configResult); assertEquals(1, configResult.configs().size()); - assertEquals("cfg2", configResult.configs().get(0).pushNotificationConfig().id()); + assertEquals("cfg2", configResult.configs().get(0).config().id()); } @Test @@ -376,7 +376,7 @@ public void testConfigStoreIntegration() { ListTaskPushNotificationConfigResult configResult = configStore.getInfo(new ListTaskPushNotificationConfigParams(taskId)); assertEquals(1, configResult.configs().size()); - assertEquals(config.url(), configResult.configs().get(0).pushNotificationConfig().url()); + assertEquals(config.url(), configResult.configs().get(0).config().url()); // Test deletion configStore.deleteInfo(taskId, storedConfig.id()); @@ -430,10 +430,10 @@ public void testPaginationWithPageToken() { // Verify NO overlap between pages - collect all IDs from both pages List firstPageIds = firstPage.configs().stream() - .map(c -> c.pushNotificationConfig().id()) + .map(c -> c.config().id()) .toList(); List secondPageIds = secondPage.configs().stream() - .map(c -> c.pushNotificationConfig().id()) + .map(c -> c.config().id()) .toList(); // Check that no ID from first page appears in second page diff --git a/spec-grpc/src/main/java/io/a2a/grpc/mapper/CreateTaskPushNotificationConfigMapper.java b/spec-grpc/src/main/java/io/a2a/grpc/mapper/CreateTaskPushNotificationConfigMapper.java index ed15e7500..d33c04711 100644 --- a/spec-grpc/src/main/java/io/a2a/grpc/mapper/CreateTaskPushNotificationConfigMapper.java +++ b/spec-grpc/src/main/java/io/a2a/grpc/mapper/CreateTaskPushNotificationConfigMapper.java @@ -20,9 +20,7 @@ public interface CreateTaskPushNotificationConfigMapper { * @param request the protobuf CreateTaskPushNotificationConfigRequest * @return domain TaskPushNotificationConfig */ - @Mapping(target = "taskId", source = "taskId") - @Mapping(target = "pushNotificationConfig", expression = "java(mapPushNotificationConfigWithId(request))") - @Mapping(target = "tenant", source = "tenant") + @Mapping(target = "config", expression = "java(mapPushNotificationConfigWithId(request))") TaskPushNotificationConfig fromProto(CreateTaskPushNotificationConfigRequest request); /** @@ -31,10 +29,7 @@ public interface CreateTaskPushNotificationConfigMapper { * @param config the domain TaskPushNotificationConfig * @return proto CreateTaskPushNotificationConfigRequest */ - @Mapping(target = "taskId", source = "taskId") @Mapping(target = "configId", expression = "java(extractConfigId(config))") - @Mapping(target = "config", source = "pushNotificationConfig") - @Mapping(target = "tenant", source = "tenant") CreateTaskPushNotificationConfigRequest toProto(TaskPushNotificationConfig config); /** @@ -44,7 +39,7 @@ public interface CreateTaskPushNotificationConfigMapper { * @return the extracted config ID */ default String extractConfigId(TaskPushNotificationConfig config) { - return config.pushNotificationConfig() != null ? config.pushNotificationConfig().id() : null; + return config.config() != null ? config.config().id() : null; } /** diff --git a/spec-grpc/src/main/java/io/a2a/grpc/mapper/DeleteTaskPushNotificationConfigParamsMapper.java b/spec-grpc/src/main/java/io/a2a/grpc/mapper/DeleteTaskPushNotificationConfigParamsMapper.java index f7ddd3ce4..6e30f6eb9 100644 --- a/spec-grpc/src/main/java/io/a2a/grpc/mapper/DeleteTaskPushNotificationConfigParamsMapper.java +++ b/spec-grpc/src/main/java/io/a2a/grpc/mapper/DeleteTaskPushNotificationConfigParamsMapper.java @@ -18,16 +18,16 @@ public interface DeleteTaskPushNotificationConfigParamsMapper { * Converts proto DeleteTaskPushNotificationConfigRequest to domain DeleteTaskPushNotificationConfigParams. */ @BeanMapping(builder = @Builder(buildMethod = "build")) - @Mapping(target = "id", source = "taskId") - @Mapping(target = "pushNotificationConfigId", source = "id") + @Mapping(target = "taskId", source = "taskId") + @Mapping(target = "id", source = "id") @Mapping(target = "tenant", source = "tenant") DeleteTaskPushNotificationConfigParams fromProto(io.a2a.grpc.DeleteTaskPushNotificationConfigRequest proto); /** * Converts domain DeleteTaskPushNotificationConfigParams to proto DeleteTaskPushNotificationConfigRequest. */ - @Mapping(target = "taskId", source = "id") - @Mapping(target = "id", source = "pushNotificationConfigId") + @Mapping(target = "taskId", source = "taskId") + @Mapping(target = "id", source = "id") @Mapping(target = "tenant", source = "tenant") io.a2a.grpc.DeleteTaskPushNotificationConfigRequest toProto(DeleteTaskPushNotificationConfigParams domain); } diff --git a/spec-grpc/src/main/java/io/a2a/grpc/mapper/GetTaskPushNotificationConfigParamsMapper.java b/spec-grpc/src/main/java/io/a2a/grpc/mapper/GetTaskPushNotificationConfigParamsMapper.java index 5a74ac2cc..b9a8cad1b 100644 --- a/spec-grpc/src/main/java/io/a2a/grpc/mapper/GetTaskPushNotificationConfigParamsMapper.java +++ b/spec-grpc/src/main/java/io/a2a/grpc/mapper/GetTaskPushNotificationConfigParamsMapper.java @@ -18,16 +18,16 @@ public interface GetTaskPushNotificationConfigParamsMapper { * Converts proto GetTaskPushNotificationConfigRequest to domain GetTaskPushNotificationConfigParams. */ @BeanMapping(builder = @Builder(buildMethod = "build")) - @Mapping(target = "id", source = "taskId") - @Mapping(target = "pushNotificationConfigId", source = "id") + @Mapping(target = "taskId", source = "taskId") + @Mapping(target = "id", source = "id") @Mapping(target = "tenant", source = "tenant") GetTaskPushNotificationConfigParams fromProto(io.a2a.grpc.GetTaskPushNotificationConfigRequest proto); /** * Converts domain GetTaskPushNotificationConfigParams to proto GetTaskPushNotificationConfigRequest. */ - @Mapping(target = "taskId", source = "id") - @Mapping(target = "id", source = "pushNotificationConfigId", conditionExpression = "java(domain.pushNotificationConfigId() != null)") + @Mapping(target = "taskId", source = "taskId") + @Mapping(target = "id", source = "id", conditionExpression = "java(domain.id() != null)") @Mapping(target = "tenant", source = "tenant") io.a2a.grpc.GetTaskPushNotificationConfigRequest toProto(GetTaskPushNotificationConfigParams domain); } diff --git a/spec-grpc/src/main/java/io/a2a/grpc/mapper/TaskPushNotificationConfigMapper.java b/spec-grpc/src/main/java/io/a2a/grpc/mapper/TaskPushNotificationConfigMapper.java index 996bda0ac..5e3a6e669 100644 --- a/spec-grpc/src/main/java/io/a2a/grpc/mapper/TaskPushNotificationConfigMapper.java +++ b/spec-grpc/src/main/java/io/a2a/grpc/mapper/TaskPushNotificationConfigMapper.java @@ -19,14 +19,14 @@ public interface TaskPushNotificationConfigMapper { /** * Converts domain TaskPushNotificationConfig to protobuf TaskPushNotificationConfig. * - * @param config the domain TaskPushNotificationConfig + * @param domain the domain TaskPushNotificationConfig * @return protobuf TaskPushNotificationConfig */ - @Mapping(target = "id", expression = "java(extractId(config))") + @Mapping(target = "id", expression = "java(extractId(domain))") @Mapping(target = "taskId", source = "taskId") - @Mapping(target = "pushNotificationConfig", source = "pushNotificationConfig") - @Mapping(target = "tenant", source = "tenant", conditionExpression = "java(config.tenant() != null)") - io.a2a.grpc.TaskPushNotificationConfig toProto(TaskPushNotificationConfig config); + @Mapping(target = "pushNotificationConfig", source = "config") + @Mapping(target = "tenant", source = "tenant", conditionExpression = "java(domain.tenant() != null)") + io.a2a.grpc.TaskPushNotificationConfig toProto(TaskPushNotificationConfig domain); /** * Converts protobuf TaskPushNotificationConfig to domain TaskPushNotificationConfig. @@ -35,7 +35,7 @@ public interface TaskPushNotificationConfigMapper { * @return domain TaskPushNotificationConfig */ @Mapping(target = "taskId", source = "taskId") - @Mapping(target = "pushNotificationConfig", expression = "java(mapPushNotificationConfigWithId(proto))") + @Mapping(target = "config", expression = "java(mapPushNotificationConfigWithId(proto))") @Mapping(target = "tenant", expression = "java(proto.getTenant().isEmpty() ? null : proto.getTenant())") TaskPushNotificationConfig fromProto(io.a2a.grpc.TaskPushNotificationConfig proto); @@ -46,7 +46,7 @@ public interface TaskPushNotificationConfigMapper { * @return the config ID */ default String extractId(TaskPushNotificationConfig config) { - return config.pushNotificationConfig() != null ? config.pushNotificationConfig().id() : null; + return config.config()!= null ? config.config().id() : null; } /** diff --git a/spec-grpc/src/test/java/io/a2a/grpc/utils/JSONRPCUtilsTest.java b/spec-grpc/src/test/java/io/a2a/grpc/utils/JSONRPCUtilsTest.java index e5f75c78a..ecfab4beb 100644 --- a/spec-grpc/src/test/java/io/a2a/grpc/utils/JSONRPCUtilsTest.java +++ b/spec-grpc/src/test/java/io/a2a/grpc/utils/JSONRPCUtilsTest.java @@ -59,8 +59,8 @@ public void testParseCreateTaskPushNotificationConfigRequest_ValidProtoFormat() TaskPushNotificationConfig config = setRequest.getParams(); assertNotNull(config); assertEquals("task-123", config.taskId()); - assertNotNull(config.pushNotificationConfig()); - assertEquals("https://example.com/callback", config.pushNotificationConfig().url()); + assertNotNull(config.config()); + assertEquals("https://example.com/callback", config.config().url()); } @Test @@ -86,7 +86,7 @@ public void testParseGetTaskPushNotificationConfigRequest_ValidProtoFormat() thr assertEquals(2, getRequest.getId()); assertEquals("GetTaskPushNotificationConfig", getRequest.getMethod()); assertNotNull(getRequest.getParams()); - assertEquals("task-123", getRequest.getParams().id()); + assertEquals("task-123", getRequest.getParams().taskId()); } @Test @@ -329,7 +329,7 @@ public void testGenerateCreateTaskPushNotificationConfigResponse_Success() throw assertEquals(1, response.getId()); assertNotNull(response.getResult()); assertEquals("task-123", response.getResult().taskId()); - assertEquals("https://example.com/callback", response.getResult().pushNotificationConfig().url()); + assertEquals("https://example.com/callback", response.getResult().config().url()); } @Test @@ -356,7 +356,7 @@ public void testGenerateGetTaskPushNotificationConfigResponse_Success() throws E assertEquals(2, response.getId()); assertNotNull(response.getResult()); assertEquals("task-123", response.getResult().taskId()); - assertEquals("https://example.com/callback", response.getResult().pushNotificationConfig().url()); + assertEquals("https://example.com/callback", response.getResult().config().url()); } @Test diff --git a/spec-grpc/src/test/java/io/a2a/grpc/utils/ToProtoTest.java b/spec-grpc/src/test/java/io/a2a/grpc/utils/ToProtoTest.java index 4a3b1e2c6..a0a236b60 100644 --- a/spec-grpc/src/test/java/io/a2a/grpc/utils/ToProtoTest.java +++ b/spec-grpc/src/test/java/io/a2a/grpc/utils/ToProtoTest.java @@ -319,8 +319,8 @@ public void convertDeleteTaskPushNotificationConfigRequest() { // Test round-trip conversion DeleteTaskPushNotificationConfigParams convertedBack = ProtoUtils.FromProto.deleteTaskPushNotificationConfigParams(result); - assertEquals("task-123", convertedBack.id()); - assertEquals("config-456", convertedBack.pushNotificationConfigId()); + assertEquals("task-123", convertedBack.taskId()); + assertEquals("config-456", convertedBack.id()); } @Test diff --git a/spec/src/main/java/io/a2a/spec/DeleteTaskPushNotificationConfigParams.java b/spec/src/main/java/io/a2a/spec/DeleteTaskPushNotificationConfigParams.java index 28f438dfb..3a4a99b06 100644 --- a/spec/src/main/java/io/a2a/spec/DeleteTaskPushNotificationConfigParams.java +++ b/spec/src/main/java/io/a2a/spec/DeleteTaskPushNotificationConfigParams.java @@ -11,36 +11,36 @@ * This record specifies which task and which specific push notification configuration * to remove, allowing cleanup of notification endpoints that are no longer needed. * - * @param id the task identifier (required) - * @param pushNotificationConfigId the specific configuration ID to delete (required) + * @param taskId the task identifier (required) + * @param id the specific configuration ID to delete (required) * @param tenant optional tenant, provided as a path parameter. * @see A2A Protocol Specification */ -public record DeleteTaskPushNotificationConfigParams(String id, String pushNotificationConfigId, String tenant) { +public record DeleteTaskPushNotificationConfigParams(String taskId, String id, String tenant) { /** * Compact constructor that validates required fields. * + * @param taskId the taskId parameter (see class-level JavaDoc) * @param id the id parameter (see class-level JavaDoc) - * @param pushNotificationConfigId the pushNotificationConfigId parameter (see class-level JavaDoc) * @param tenant the tenant parameter (see class-level JavaDoc) - * @throws IllegalArgumentException if id or pushNotificationConfigId is null + * @throws IllegalArgumentException if taskId or id is null */ public DeleteTaskPushNotificationConfigParams { + Assert.checkNotNullParam("taskId", taskId); Assert.checkNotNullParam("id", id); - Assert.checkNotNullParam("pushNotificationConfigId", pushNotificationConfigId); Assert.checkNotNullParam("tenant", tenant); } /** * Creates parameters without optional metadata. * - * @param id the task identifier (required) - * @param pushNotificationConfigId the configuration ID to delete (required) - * @throws IllegalArgumentException if id or pushNotificationConfigId is null + * @param taskId the task identifier (required) + * @param id the configuration ID to delete (required) + * @throws IllegalArgumentException if taskId or id is null */ - public DeleteTaskPushNotificationConfigParams(String id, String pushNotificationConfigId) { - this(id, pushNotificationConfigId, ""); + public DeleteTaskPushNotificationConfigParams(String taskId, String id) { + this(taskId, id, ""); } /** @@ -58,8 +58,8 @@ public static Builder builder() { * Provides a fluent API for setting parameters with optional metadata. */ public static class Builder { + @Nullable String taskId; @Nullable String id; - @Nullable String pushNotificationConfigId; @Nullable String tenant; /** @@ -71,22 +71,22 @@ private Builder() { /** * Sets the task identifier. * - * @param id the task ID (required) + * @param taskId the task ID (required) * @return this builder for method chaining */ - public Builder id(String id) { - this.id = id; + public Builder taskId(String taskId) { + this.taskId = taskId; return this; } /** * Sets the push notification configuration ID to delete. * - * @param pushNotificationConfigId the configuration ID (required) + * @param id the configuration ID (required) * @return this builder for method chaining */ - public Builder pushNotificationConfigId(String pushNotificationConfigId) { - this.pushNotificationConfigId = pushNotificationConfigId; + public Builder id(String id) { + this.id = id; return this; } @@ -105,12 +105,12 @@ public Builder tenant(String tenant) { * Builds a new {@link DeleteTaskPushNotificationConfigParams} from the current builder state. * * @return a new DeleteTaskPushNotificationConfigParams instance - * @throws IllegalArgumentException if id or pushNotificationConfigId is null + * @throws IllegalArgumentException if taskId or id is null */ public DeleteTaskPushNotificationConfigParams build() { return new DeleteTaskPushNotificationConfigParams( + Assert.checkNotNullParam("taskId", taskId), Assert.checkNotNullParam("id", id), - Assert.checkNotNullParam("pushNotificationConfigId", pushNotificationConfigId), Assert.checkNotNullParam("tenant", tenant)); } } diff --git a/spec/src/main/java/io/a2a/spec/GetTaskPushNotificationConfigParams.java b/spec/src/main/java/io/a2a/spec/GetTaskPushNotificationConfigParams.java index 070042e40..c30aa9db8 100644 --- a/spec/src/main/java/io/a2a/spec/GetTaskPushNotificationConfigParams.java +++ b/spec/src/main/java/io/a2a/spec/GetTaskPushNotificationConfigParams.java @@ -11,36 +11,36 @@ * This record specifies which task's push notification configuration to retrieve, with * an optional filter by configuration ID if multiple configurations exist for the task. * - * @param id the task identifier (required) - * @param pushNotificationConfigId optional specific configuration ID to retrieve + * @param taskId the task identifier (required) + * @param id optional specific configuration ID to retrieve * @param tenant optional tenant, provided as a path parameter. * @see TaskPushNotificationConfig for the returned configuration structure * @see A2A Protocol Specification */ -public record GetTaskPushNotificationConfigParams(String id, String pushNotificationConfigId, String tenant) { +public record GetTaskPushNotificationConfigParams(String taskId, String id, String tenant) { /** * Compact constructor that validates required fields. * + * @param taskId the taskId parameter (see class-level JavaDoc) * @param id the id parameter (see class-level JavaDoc) - * @param pushNotificationConfigId the pushNotificationConfigId parameter (see class-level JavaDoc) * @param tenant the tenant parameter (see class-level JavaDoc) - * @throws IllegalArgumentException if id or tenant is null + * @throws IllegalArgumentException if taskId or tenant is null */ public GetTaskPushNotificationConfigParams { + Assert.checkNotNullParam("taskId", taskId); Assert.checkNotNullParam("id", id); - Assert.checkNotNullParam("pushNotificationConfigId", pushNotificationConfigId); Assert.checkNotNullParam("tenant", tenant); } /** * Convenience constructor for creating parameters without tenant. * - * @param id the task identifier (required) - * @param pushNotificationConfigId optional configuration ID to retrieve + * @param taskId the task identifier (required) + * @param id optional configuration ID to retrieve */ - public GetTaskPushNotificationConfigParams(String id, String pushNotificationConfigId) { - this(id, pushNotificationConfigId, ""); + public GetTaskPushNotificationConfigParams(String taskId, String id) { + this(taskId, id, ""); } /** @@ -56,8 +56,8 @@ public static Builder builder() { * Builder for constructing GetTaskPushNotificationConfigParams instances. */ public static class Builder { + @Nullable String taskId; @Nullable String id; - @Nullable String pushNotificationConfigId; @Nullable String tenant; /** @@ -69,22 +69,22 @@ private Builder() { /** * Sets the task ID. * - * @param id the task ID + * @param taskId the task ID * @return this builder for method chaining */ - public Builder id(String id) { - this.id = id; + public Builder taskId(String taskId) { + this.taskId = taskId; return this; } /** * Sets the push notification configuration ID. * - * @param pushNotificationConfigId the configuration ID + * @param id the configuration ID * @return this builder for method chaining */ - public Builder pushNotificationConfigId(String pushNotificationConfigId) { - this.pushNotificationConfigId = pushNotificationConfigId; + public Builder id(String id) { + this.id = id; return this; } @@ -106,8 +106,8 @@ public Builder tenant(String tenant) { */ public GetTaskPushNotificationConfigParams build() { return new GetTaskPushNotificationConfigParams( + Assert.checkNotNullParam("taskId", taskId), Assert.checkNotNullParam("id", id), - Assert.checkNotNullParam("pushNotificationConfigId", pushNotificationConfigId), Assert.checkNotNullParam("tenant", tenant)); } } diff --git a/spec/src/main/java/io/a2a/spec/TaskPushNotificationConfig.java b/spec/src/main/java/io/a2a/spec/TaskPushNotificationConfig.java index cf57a6f3c..9f973e897 100644 --- a/spec/src/main/java/io/a2a/spec/TaskPushNotificationConfig.java +++ b/spec/src/main/java/io/a2a/spec/TaskPushNotificationConfig.java @@ -15,23 +15,24 @@ * management methods ({@code tasks/pushNotificationConfig/set}, {@code tasks/pushNotificationConfig/get}, etc.). * * @param taskId the unique identifier of the task to receive push notifications for (required) - * @param pushNotificationConfig the push notification endpoint and authentication configuration (required) + * @param config the push notification endpoint and authentication configuration (required) + * @param tenant optional tenant identifier, provided as a path parameter * @see PushNotificationConfig for notification endpoint details * @see A2A Protocol Specification */ -public record TaskPushNotificationConfig(String taskId, PushNotificationConfig pushNotificationConfig, @Nullable String tenant) { +public record TaskPushNotificationConfig(String taskId, PushNotificationConfig config, @Nullable String tenant) { /** * Compact constructor for validation. * Validates that required parameters are not null. * * @param taskId the task identifier - * @param pushNotificationConfig the push notification configuration + * @param config the push notification configuration * @param tenant the tenant identifier */ public TaskPushNotificationConfig { Assert.checkNotNullParam("taskId", taskId); - Assert.checkNotNullParam("pushNotificationConfig", pushNotificationConfig); - Assert.checkNotNullParam("configId", pushNotificationConfig.id()); + Assert.checkNotNullParam("config", config); + Assert.checkNotNullParam("configId", config.id()); } } diff --git a/spec/src/main/java/io/a2a/spec/TaskStatus.java b/spec/src/main/java/io/a2a/spec/TaskStatus.java index 87055f236..95e70da0d 100644 --- a/spec/src/main/java/io/a2a/spec/TaskStatus.java +++ b/spec/src/main/java/io/a2a/spec/TaskStatus.java @@ -54,6 +54,11 @@ public TaskStatus(TaskState state, @Nullable Message message, @Nullable OffsetDa this.message = message; } + /** + * Returns the timestamp when this status was created. + * + * @return the UTC timestamp of the status + */ public OffsetDateTime timestamp() { return timestamp; } diff --git a/spec/src/main/java/io/a2a/util/Utils.java b/spec/src/main/java/io/a2a/util/Utils.java index 44d713f75..68fe2bef7 100644 --- a/spec/src/main/java/io/a2a/util/Utils.java +++ b/spec/src/main/java/io/a2a/util/Utils.java @@ -40,6 +40,13 @@ public class Utils { private static final Logger log = Logger.getLogger(Utils.class.getName()); + /** + * Private constructor to prevent instantiation of this utility class. + */ + private Utils() { + // Utility class - no instances + } + /** * Returns the provided value if non-null, otherwise returns the default value. *

diff --git a/tests/server-common/src/test/java/io/a2a/server/apps/common/AbstractA2AServerTest.java b/tests/server-common/src/test/java/io/a2a/server/apps/common/AbstractA2AServerTest.java index 1c6dcdde4..4646aac57 100644 --- a/tests/server-common/src/test/java/io/a2a/server/apps/common/AbstractA2AServerTest.java +++ b/tests/server-common/src/test/java/io/a2a/server/apps/common/AbstractA2AServerTest.java @@ -554,8 +554,8 @@ public void testSetPushNotificationSuccess() throws Exception { MINIMAL_TASK.id(), PushNotificationConfig.builder().id("c295ea44-7543-4f78-b524-7a38915ad6e4").url("http://example.com").build(), ""); TaskPushNotificationConfig config = getClient().createTaskPushNotificationConfiguration(taskPushConfig); assertEquals(MINIMAL_TASK.id(), config.taskId()); - assertEquals("http://example.com", config.pushNotificationConfig().url()); - assertEquals("c295ea44-7543-4f78-b524-7a38915ad6e4", config.pushNotificationConfig().id()); + assertEquals("http://example.com", config.config().url()); + assertEquals("c295ea44-7543-4f78-b524-7a38915ad6e4", config.config().id()); } catch (A2AClientException e) { fail("Unexpected exception during set push notification test: " + e.getMessage(), e); } finally { @@ -578,7 +578,7 @@ public void testGetPushNotificationSuccess() throws Exception { TaskPushNotificationConfig config = getClient().getTaskPushNotificationConfiguration( new GetTaskPushNotificationConfigParams(MINIMAL_TASK.id(), "c295ea44-7543-4f78-b524-7a38915ad6e4")); assertEquals(MINIMAL_TASK.id(), config.taskId()); - assertEquals("http://example.com", config.pushNotificationConfig().url()); + assertEquals("http://example.com", config.config().url()); } catch (A2AClientException e) { fail("Unexpected exception during get push notification test: " + e.getMessage(), e); } finally {