Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions client/base/src/main/java/io/a2a/client/AbstractClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import io.a2a.spec.DeleteTaskPushNotificationConfigParams;
import io.a2a.spec.GetTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigResult;
import io.a2a.spec.ListTasksParams;
import io.a2a.spec.ListTasksResult;
import io.a2a.spec.Message;
Expand Down Expand Up @@ -271,26 +272,26 @@ public abstract TaskPushNotificationConfig getTaskPushNotificationConfiguration(
@Nullable ClientCallContext context) throws A2AClientException;

/**
* Retrieve the list of push notification configurations for a specific task.
* Retrieve the list of push notification configurations for a specific task with pagination support.
*
* @param request the parameters specifying which task's notification configs to retrieve
* @return the list of task push notification configs
* @return the result containing the list of task push notification configs and pagination information
* @throws A2AClientException if getting the task push notification configs fails for any reason
*/
public List<TaskPushNotificationConfig> listTaskPushNotificationConfigurations(
public ListTaskPushNotificationConfigResult listTaskPushNotificationConfigurations(
ListTaskPushNotificationConfigParams request) throws A2AClientException {
return listTaskPushNotificationConfigurations(request, null);
}

/**
* Retrieve the list of push notification configurations for a specific task.
* Retrieve the list of push notification configurations for a specific task with pagination support.
*
* @param request the parameters specifying which task's notification configs to retrieve
* @param context optional client call context for the request (may be {@code null})
* @return the list of task push notification configs
* @return the result containing the list of task push notification configs and pagination information
* @throws A2AClientException if getting the task push notification configs fails for any reason
*/
public abstract List<TaskPushNotificationConfig> listTaskPushNotificationConfigurations(
public abstract ListTaskPushNotificationConfigResult listTaskPushNotificationConfigurations(
ListTaskPushNotificationConfigParams request,
@Nullable ClientCallContext context) throws A2AClientException;

Expand Down
3 changes: 2 additions & 1 deletion client/base/src/main/java/io/a2a/client/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import io.a2a.spec.EventKind;
import io.a2a.spec.GetTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigResult;
import io.a2a.spec.ListTasksParams;
import io.a2a.spec.ListTasksResult;
import io.a2a.spec.Message;
Expand Down Expand Up @@ -108,7 +109,7 @@ public TaskPushNotificationConfig getTaskPushNotificationConfiguration(
}

@Override
public List<TaskPushNotificationConfig> listTaskPushNotificationConfigurations(
public ListTaskPushNotificationConfigResult listTaskPushNotificationConfigurations(
ListTaskPushNotificationConfigParams request, @Nullable ClientCallContext context) throws A2AClientException {
return clientTransport.listTaskPushNotificationConfigurations(request, context);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import io.a2a.spec.GetTaskRequest;
import io.a2a.spec.ListTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigRequest;
import io.a2a.spec.ListTaskPushNotificationConfigResult;
import io.a2a.spec.ListTasksParams;
import io.a2a.spec.ListTasksRequest;
import io.a2a.spec.ListTasksResult;
Expand Down Expand Up @@ -265,23 +266,24 @@ public TaskPushNotificationConfig getTaskPushNotificationConfiguration(
}

@Override
public List<TaskPushNotificationConfig> listTaskPushNotificationConfigurations(
public ListTaskPushNotificationConfigResult listTaskPushNotificationConfigurations(
ListTaskPushNotificationConfigParams request,
@Nullable ClientCallContext context) throws A2AClientException {
checkNotNullParam("request", request);

io.a2a.grpc.ListTaskPushNotificationConfigRequest grpcRequest = io.a2a.grpc.ListTaskPushNotificationConfigRequest.newBuilder()
.setParent("tasks/" + request.id())
.setTenant(resolveTenant(request.tenant()))
.setPageSize(request.pageSize())
.setPageToken(request.pageToken())
.build();
PayloadAndHeaders payloadAndHeaders = applyInterceptors(ListTaskPushNotificationConfigRequest.METHOD,
grpcRequest, agentCard, context);

try {
A2AServiceBlockingV2Stub stubWithMetadata = createBlockingStubWithMetadata(context, payloadAndHeaders);
return stubWithMetadata.listTaskPushNotificationConfig(grpcRequest).getConfigsList().stream()
.map(FromProto::taskPushNotificationConfig)
.collect(Collectors.toList());
io.a2a.grpc.ListTaskPushNotificationConfigResponse grpcResponse = stubWithMetadata.listTaskPushNotificationConfig(grpcRequest);
return FromProto.listTaskPushNotificationConfigResult(grpcResponse);
} catch (StatusRuntimeException | StatusException e) {
throw GrpcErrorMapper.mapGrpcError(e, "Failed to list task push notification config: ");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import io.a2a.spec.ListTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigRequest;
import io.a2a.spec.ListTaskPushNotificationConfigResponse;
import io.a2a.spec.ListTaskPushNotificationConfigResult;
import io.a2a.spec.ListTasksParams;
import io.a2a.spec.ListTasksRequest;
import io.a2a.spec.ListTasksResponse;
Expand Down Expand Up @@ -222,7 +223,7 @@ public TaskPushNotificationConfig getTaskPushNotificationConfiguration(GetTaskPu
}

@Override
public List<TaskPushNotificationConfig> listTaskPushNotificationConfigurations(
public ListTaskPushNotificationConfigResult listTaskPushNotificationConfigurations(
ListTaskPushNotificationConfigParams request,
@Nullable ClientCallContext context) throws A2AClientException {
checkNotNullParam("request", request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import io.a2a.spec.GetTaskRequest;
import io.a2a.spec.ListTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigRequest;
import io.a2a.spec.ListTaskPushNotificationConfigResult;
import io.a2a.spec.ListTasksParams;
import io.a2a.spec.ListTasksRequest;
import io.a2a.spec.ListTasksResult;
Expand Down Expand Up @@ -334,7 +335,7 @@ public TaskPushNotificationConfig getTaskPushNotificationConfiguration(GetTaskPu
}

@Override
public List<TaskPushNotificationConfig> listTaskPushNotificationConfigurations(ListTaskPushNotificationConfigParams request, @Nullable ClientCallContext context) throws A2AClientException {
public ListTaskPushNotificationConfigResult listTaskPushNotificationConfigurations(ListTaskPushNotificationConfigParams request, @Nullable ClientCallContext context) throws A2AClientException {
checkNotNullParam("request", request);
io.a2a.grpc.ListTaskPushNotificationConfigRequest.Builder builder
= io.a2a.grpc.ListTaskPushNotificationConfigRequest.newBuilder();
Expand All @@ -356,7 +357,7 @@ public List<TaskPushNotificationConfig> listTaskPushNotificationConfigurations(L
String httpResponseBody = response.body();
io.a2a.grpc.ListTaskPushNotificationConfigResponse.Builder responseBuilder = io.a2a.grpc.ListTaskPushNotificationConfigResponse.newBuilder();
JsonFormat.parser().merge(httpResponseBody, responseBuilder);
return ProtoUtils.FromProto.listTaskPushNotificationConfigParams(responseBuilder);
return ProtoUtils.FromProto.listTaskPushNotificationConfigResult(responseBuilder);
} catch (A2AClientException e) {
throw e;
} catch (IOException | InterruptedException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import io.a2a.spec.FileWithUri;
import io.a2a.spec.GetTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigResult;
import io.a2a.spec.Message;
import io.a2a.spec.MessageSendConfiguration;
import io.a2a.spec.MessageSendParams;
Expand Down Expand Up @@ -361,18 +362,18 @@ public void testListTaskPushNotificationConfigurations() throws Exception {
);

RestTransport client = new RestTransport(CARD);
List<TaskPushNotificationConfig> taskPushNotificationConfigs = client.listTaskPushNotificationConfigurations(
ListTaskPushNotificationConfigResult result = client.listTaskPushNotificationConfigurations(
new ListTaskPushNotificationConfigParams("de38c76d-d54c-436c-8b9f-4c2703648d64"), null);
assertEquals(2, taskPushNotificationConfigs.size());
PushNotificationConfig pushNotificationConfig = taskPushNotificationConfigs.get(0).pushNotificationConfig();
assertEquals(2, result.configs().size());
PushNotificationConfig pushNotificationConfig = result.configs().get(0).pushNotificationConfig();
assertNotNull(pushNotificationConfig);
assertEquals("https://example.com/callback", pushNotificationConfig.url());
assertEquals("10", pushNotificationConfig.id());
AuthenticationInfo authenticationInfo = pushNotificationConfig.authentication();
assertTrue(authenticationInfo.schemes().size() == 1);
assertEquals("jwt", authenticationInfo.schemes().get(0));
assertEquals("", authenticationInfo.credentials());
pushNotificationConfig = taskPushNotificationConfigs.get(1).pushNotificationConfig();
pushNotificationConfig = result.configs().get(1).pushNotificationConfig();
assertNotNull(pushNotificationConfig);
assertEquals("https://test.com/callback", pushNotificationConfig.url());
assertEquals("5", pushNotificationConfig.id());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import io.a2a.spec.EventKind;
import io.a2a.spec.GetTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigResult;
import io.a2a.spec.ListTasksParams;
import io.a2a.spec.ListTasksResult;
import io.a2a.spec.MessageSendParams;
Expand Down Expand Up @@ -102,14 +103,14 @@ TaskPushNotificationConfig getTaskPushNotificationConfiguration(
@Nullable ClientCallContext context) throws A2AClientException;

/**
* Retrieve the list of push notification configurations for a specific task.
* Retrieve the list of push notification configurations for a specific task with pagination support.
*
* @param request the parameters specifying which task's notification configs to retrieve
* @param context optional client call context for the request (may be {@code null})
* @return the list of task push notification configs
* @return the result containing the list of task push notification configs and pagination information
* @throws A2AClientException if getting the task push notification configs fails for any reason
*/
List<TaskPushNotificationConfig> listTaskPushNotificationConfigurations(
ListTaskPushNotificationConfigResult listTaskPushNotificationConfigurations(
ListTaskPushNotificationConfigParams request,
@Nullable ClientCallContext context) throws A2AClientException;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.a2a.extras.pushnotificationconfigstore.database.jpa;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import jakarta.annotation.Priority;
Expand All @@ -11,7 +13,10 @@

import io.a2a.json.JsonProcessingException;
import io.a2a.server.tasks.PushNotificationConfigStore;
import io.a2a.spec.ListTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigResult;
import io.a2a.spec.PushNotificationConfig;
import io.a2a.spec.TaskPushNotificationConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -65,7 +70,8 @@ public PushNotificationConfig setInfo(String taskId, PushNotificationConfig noti

@Transactional
@Override
public List<PushNotificationConfig> getInfo(String taskId) {
public ListTaskPushNotificationConfigResult getInfo(ListTaskPushNotificationConfigParams params) {
String taskId = params.id();
LOGGER.debug("Retrieving PushNotificationConfigs for Task '{}'", taskId);
try {
List<JpaPushNotificationConfig> jpaConfigs = em.createQuery(
Expand All @@ -88,13 +94,58 @@ public List<PushNotificationConfig> getInfo(String taskId) {
.toList();

LOGGER.debug("Successfully retrieved {} PushNotificationConfigs for Task '{}'", configs.size(), taskId);
return configs;

// Handle pagination
if (configs.isEmpty()) {
return new ListTaskPushNotificationConfigResult(Collections.emptyList());
}

if (params.pageSize() <= 0) {
return new ListTaskPushNotificationConfigResult(convertPushNotificationConfig(configs, params), null);
}

// Apply pageToken filtering if provided
List<PushNotificationConfig> paginatedConfigs = configs;
if (params.pageToken() != null && !params.pageToken().isBlank()) {
int index = findFirstIndex(configs, params.pageToken());
if (index < configs.size()) {
paginatedConfigs = configs.subList(index, configs.size());
}
}

// Apply page size limit
if (paginatedConfigs.size() <= params.pageSize()) {
return new ListTaskPushNotificationConfigResult(convertPushNotificationConfig(paginatedConfigs, params), null);
}

String nextToken = paginatedConfigs.get(params.pageSize()).token();
return new ListTaskPushNotificationConfigResult(
convertPushNotificationConfig(paginatedConfigs.subList(0, params.pageSize()), params),
nextToken);
} catch (Exception e) {
LOGGER.error("Failed to retrieve PushNotificationConfigs for Task '{}'", taskId, e);
throw e;
}
}

private int findFirstIndex(List<PushNotificationConfig> configs, String token) {
for (int i = 0; i < configs.size(); i++) {
if (token.equals(configs.get(i).token())) {
return i;
}
}
return configs.size();
}

private List<TaskPushNotificationConfig> convertPushNotificationConfig(List<PushNotificationConfig> pushNotificationConfigList, ListTaskPushNotificationConfigParams params) {
List<TaskPushNotificationConfig> taskPushNotificationConfigList = new ArrayList<>(pushNotificationConfigList.size());
for (PushNotificationConfig pushNotificationConfig : pushNotificationConfigList) {
TaskPushNotificationConfig taskPushNotificationConfig = new TaskPushNotificationConfig(params.id(), pushNotificationConfig, params.tenant());
taskPushNotificationConfigList.add(taskPushNotificationConfig);
}
return taskPushNotificationConfigList;
}

@Transactional
@Override
public void deleteInfo(String taskId, String configId) {
Expand Down
Loading