1
- /*
2
- * Copyright The WildFly Authors
3
- * SPDX-License-Identifier: Apache-2.0
4
- */
5
1
package io .a2a .client .transport ;
6
2
7
3
import static io .a2a .util .Assert .checkNotNullParam ;
13
9
import io .a2a .client .ClientCallContext ;
14
10
import io .a2a .client .ClientCallInterceptor ;
15
11
import io .a2a .client .PayloadAndHeaders ;
12
+ import io .a2a .client .sse .JSONRestSSEEventListener ;
16
13
import io .a2a .grpc .CancelTaskRequest ;
14
+ import io .a2a .grpc .CreateTaskPushNotificationConfigRequest ;
15
+ import io .a2a .grpc .GetTaskPushNotificationConfigRequest ;
17
16
import io .a2a .grpc .GetTaskRequest ;
18
17
import io .a2a .spec .TaskPushNotificationConfig ;
19
18
import io .a2a .http .A2AHttpClient ;
31
30
import io .a2a .spec .TaskIdParams ;
32
31
import io .a2a .spec .TaskQueryParams ;
33
32
import io .a2a .grpc .utils .ProtoUtils ;
33
+ import io .a2a .spec .SendStreamingMessageRequest ;
34
+ import io .a2a .spec .SetTaskPushNotificationConfigRequest ;
34
35
import java .io .IOException ;
35
36
import java .util .List ;
36
37
import java .util .Map ;
38
+ import java .util .concurrent .CompletableFuture ;
39
+ import java .util .concurrent .atomic .AtomicReference ;
37
40
import java .util .function .Consumer ;
38
41
39
42
public class JSONRestTransport implements ClientTransport {
@@ -62,19 +65,11 @@ public JSONRestTransport(A2AHttpClient httpClient, AgentCard agentCard,
62
65
@ Override
63
66
public EventKind sendMessage (MessageSendParams messageSendParams , ClientCallContext context ) throws A2AClientException {
64
67
checkNotNullParam ("messageSendParams" , messageSendParams );
65
- io .a2a .grpc .SendMessageRequest .Builder builder = io .a2a .grpc .SendMessageRequest .newBuilder ();
66
- builder .setRequest (ProtoUtils .ToProto .message (messageSendParams .message ()));
67
- if (messageSendParams .configuration () != null ) {
68
- builder .setConfiguration (ProtoUtils .ToProto .messageSendConfiguration (messageSendParams .configuration ()));
69
- }
70
- if (messageSendParams .metadata () != null ) {
71
- builder .setMetadata (ProtoUtils .ToProto .struct (messageSendParams .metadata ()));
72
- }
68
+ io .a2a .grpc .SendMessageRequest .Builder builder = io .a2a .grpc .SendMessageRequest .newBuilder (ProtoUtils .ToProto .sendMessageRequest (messageSendParams ));
73
69
PayloadAndHeaders payloadAndHeaders = applyInterceptors (io .a2a .spec .SendMessageRequest .METHOD , builder .getRequestOrBuilder (),
74
70
agentCard , context );
75
71
try {
76
72
String httpResponseBody = sendPostRequest (agentUrl + "/v1/message:send" , payloadAndHeaders );
77
- System .out .println ("Response " + httpResponseBody );
78
73
io .a2a .grpc .SendMessageResponse .Builder responseBuilder = io .a2a .grpc .SendMessageResponse .newBuilder ();
79
74
JsonFormat .parser ().merge (httpResponseBody , responseBuilder );
80
75
if (responseBuilder .hasMsg ()) {
@@ -89,8 +84,28 @@ public EventKind sendMessage(MessageSendParams messageSendParams, ClientCallCont
89
84
}
90
85
91
86
@ Override
92
- public void sendMessageStreaming (MessageSendParams request , Consumer <StreamingEventKind > eventConsumer , Consumer <Throwable > errorConsumer , ClientCallContext context ) throws A2AClientException {
93
- throw new UnsupportedOperationException ("Not supported yet." ); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
87
+ public void sendMessageStreaming (MessageSendParams messageSendParams , Consumer <StreamingEventKind > eventConsumer , Consumer <Throwable > errorConsumer , ClientCallContext context ) throws A2AClientException {
88
+ checkNotNullParam ("request" , messageSendParams );
89
+ checkNotNullParam ("eventConsumer" , eventConsumer );
90
+ checkNotNullParam ("messageSendParams" , messageSendParams );
91
+ io .a2a .grpc .SendMessageRequest .Builder builder = io .a2a .grpc .SendMessageRequest .newBuilder (ProtoUtils .ToProto .sendMessageRequest (messageSendParams ));
92
+ PayloadAndHeaders payloadAndHeaders = applyInterceptors (SendStreamingMessageRequest .METHOD ,
93
+ builder , agentCard , context );
94
+ AtomicReference <CompletableFuture <Void >> ref = new AtomicReference <>();
95
+ JSONRestSSEEventListener sseEventListener = new JSONRestSSEEventListener (eventConsumer , errorConsumer );
96
+ try {
97
+ A2AHttpClient .PostBuilder postBuilder = createPostBuilder (agentUrl + "/v1/message:stream" , payloadAndHeaders );
98
+ ref .set (postBuilder .postAsyncSSE (
99
+ msg -> sseEventListener .onMessage (msg , ref .get ()),
100
+ throwable -> sseEventListener .onError (throwable , ref .get ()),
101
+ () -> {
102
+ // We don't need to do anything special on completion
103
+ }));
104
+ } catch (IOException e ) {
105
+ throw new A2AClientException ("Failed to send streaming message request: " + e , e );
106
+ } catch (InterruptedException e ) {
107
+ throw new A2AClientException ("Send streaming message request timed out: " + e , e );
108
+ }
94
109
}
95
110
96
111
@ Override
@@ -102,12 +117,11 @@ public Task getTask(TaskQueryParams taskQueryParams, ClientCallContext context)
102
117
agentCard , context );
103
118
try {
104
119
String url ;
105
- if (taskQueryParams .historyLength () != null ) {
120
+ if (taskQueryParams .historyLength () != null ) {
106
121
url = agentUrl + String .format ("/v1/tasks/%1s?historyLength=%2d" , taskQueryParams .id (), taskQueryParams .historyLength ());
107
122
} else {
108
123
url = agentUrl + String .format ("/v1/tasks/%1s" , taskQueryParams .id ());
109
124
}
110
- System .out .println ("Getting URL: " + url );
111
125
A2AHttpClient .GetBuilder getBuilder = httpClient .createGet ().url (url );
112
126
if (payloadAndHeaders .getHttpHeaders () != null ) {
113
127
for (Map .Entry <String , String > entry : payloadAndHeaders .getHttpHeaders ().entrySet ()) {
@@ -120,7 +134,6 @@ public Task getTask(TaskQueryParams taskQueryParams, ClientCallContext context)
120
134
throw new A2AClientException ("Failed to send message: " + e , e );
121
135
}
122
136
String httpResponseBody = response .body ();
123
- System .out .println ("Response " + httpResponseBody );
124
137
io .a2a .grpc .Task .Builder responseBuilder = io .a2a .grpc .Task .newBuilder ();
125
138
JsonFormat .parser ().merge (httpResponseBody , responseBuilder );
126
139
return ProtoUtils .FromProto .task (responseBuilder );
@@ -140,7 +153,6 @@ public Task cancelTask(TaskIdParams taskIdParams, ClientCallContext context) thr
140
153
agentCard , context );
141
154
try {
142
155
String httpResponseBody = sendPostRequest (agentUrl + String .format ("/v1/tasks/%1s:cancel" , taskIdParams .id ()), payloadAndHeaders );
143
- System .out .println ("Response " + httpResponseBody );
144
156
io .a2a .grpc .Task .Builder responseBuilder = io .a2a .grpc .Task .newBuilder ();
145
157
JsonFormat .parser ().merge (httpResponseBody , responseBuilder );
146
158
return ProtoUtils .FromProto .task (responseBuilder );
@@ -153,12 +165,55 @@ public Task cancelTask(TaskIdParams taskIdParams, ClientCallContext context) thr
153
165
154
166
@ Override
155
167
public TaskPushNotificationConfig setTaskPushNotificationConfiguration (TaskPushNotificationConfig request , ClientCallContext context ) throws A2AClientException {
156
- throw new UnsupportedOperationException ("Not supported yet." ); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
168
+ checkNotNullParam ("request" , request );
169
+ CreateTaskPushNotificationConfigRequest .Builder builder = CreateTaskPushNotificationConfigRequest .newBuilder ();
170
+ builder .setConfig (ProtoUtils .ToProto .taskPushNotificationConfig (request ))
171
+ .setParent ("tasks/" + request .taskId ());
172
+ if (request .pushNotificationConfig ().id () != null ) {
173
+ builder .setConfigId (request .pushNotificationConfig ().id ());
174
+ }
175
+ PayloadAndHeaders payloadAndHeaders = applyInterceptors (SetTaskPushNotificationConfigRequest .METHOD , builder , agentCard , context );
176
+ try {
177
+ String httpResponseBody = sendPostRequest (agentUrl + String .format ("/v1/tasks/%1s/pushNotificationConfigs" , request .taskId ()), payloadAndHeaders );
178
+ io .a2a .grpc .TaskPushNotificationConfig .Builder reponseBuilder = io .a2a .grpc .TaskPushNotificationConfig .newBuilder ();
179
+ JsonFormat .parser ().merge (httpResponseBody , reponseBuilder );
180
+ return ProtoUtils .FromProto .taskPushNotificationConfig (reponseBuilder );
181
+ } catch (A2AClientException e ) {
182
+ throw e ;
183
+ } catch (IOException | InterruptedException e ) {
184
+ throw new A2AClientException ("Failed to set task push notification config: " + e , e );
185
+ }
157
186
}
158
187
159
188
@ Override
160
189
public TaskPushNotificationConfig getTaskPushNotificationConfiguration (GetTaskPushNotificationConfigParams request , ClientCallContext context ) throws A2AClientException {
161
- throw new UnsupportedOperationException ("Not supported yet." ); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
190
+ checkNotNullParam ("request" , request );
191
+ GetTaskPushNotificationConfigRequest .Builder builder = GetTaskPushNotificationConfigRequest .newBuilder ();
192
+ builder .setName (String .format ("/tasks/%1s/pushNotificationConfigs/%2s" , request .id (), request .pushNotificationConfigId ()));
193
+ PayloadAndHeaders payloadAndHeaders = applyInterceptors (io .a2a .spec .SendMessageRequest .METHOD , builder ,
194
+ agentCard , context );
195
+ try {
196
+ String url = agentUrl + String .format ("/v1/tasks/%1s/pushNotificationConfigs/%2s" , request .id (), request .pushNotificationConfigId ());
197
+ A2AHttpClient .GetBuilder getBuilder = httpClient .createGet ().url (url );
198
+ if (payloadAndHeaders .getHttpHeaders () != null ) {
199
+ for (Map .Entry <String , String > entry : payloadAndHeaders .getHttpHeaders ().entrySet ()) {
200
+ getBuilder .addHeader (entry .getKey (), entry .getValue ());
201
+ }
202
+ }
203
+ A2AHttpResponse response = getBuilder .get ();
204
+ if (!response .success ()) {
205
+ IOException e = new IOException ("Request failed " + response .status ());
206
+ throw new A2AClientException ("Failed to send message: " + e , e );
207
+ }
208
+ String httpResponseBody = response .body ();
209
+ io .a2a .grpc .TaskPushNotificationConfig .Builder reponseBuilder = io .a2a .grpc .TaskPushNotificationConfig .newBuilder ();
210
+ JsonFormat .parser ().merge (httpResponseBody , reponseBuilder );
211
+ return ProtoUtils .FromProto .taskPushNotificationConfig (reponseBuilder );
212
+ } catch (A2AClientException e ) {
213
+ throw e ;
214
+ } catch (IOException | InterruptedException e ) {
215
+ throw new A2AClientException ("Failed to send message: " + e , e );
216
+ }
162
217
}
163
218
164
219
@ Override
@@ -173,7 +228,7 @@ public void deleteTaskPushNotificationConfigurations(DeleteTaskPushNotificationC
173
228
174
229
@ Override
175
230
public void resubscribe (TaskIdParams request , Consumer <StreamingEventKind > eventConsumer ,
176
- Consumer <Throwable > errorConsumer , ClientCallContext context ) throws A2AClientException {
231
+ Consumer <Throwable > errorConsumer , ClientCallContext context ) throws A2AClientException {
177
232
throw new UnsupportedOperationException ("Not supported yet." ); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
178
233
}
179
234
@@ -222,7 +277,6 @@ private A2AHttpClient.PostBuilder createPostBuilder(String url, PayloadAndHeader
222
277
postBuilder .addHeader (entry .getKey (), entry .getValue ());
223
278
}
224
279
}
225
-
226
280
return postBuilder ;
227
281
}
228
282
0 commit comments