1- /*
2- * Copyright The WildFly Authors
3- * SPDX-License-Identifier: Apache-2.0
4- */
51package io .a2a .client .transport ;
62
73import static io .a2a .util .Assert .checkNotNullParam ;
139import io .a2a .client .ClientCallContext ;
1410import io .a2a .client .ClientCallInterceptor ;
1511import io .a2a .client .PayloadAndHeaders ;
12+ import io .a2a .client .sse .JSONRestSSEEventListener ;
1613import io .a2a .grpc .CancelTaskRequest ;
14+ import io .a2a .grpc .CreateTaskPushNotificationConfigRequest ;
15+ import io .a2a .grpc .GetTaskPushNotificationConfigRequest ;
1716import io .a2a .grpc .GetTaskRequest ;
1817import io .a2a .spec .TaskPushNotificationConfig ;
1918import io .a2a .http .A2AHttpClient ;
3130import io .a2a .spec .TaskIdParams ;
3231import io .a2a .spec .TaskQueryParams ;
3332import io .a2a .grpc .utils .ProtoUtils ;
33+ import io .a2a .spec .SendStreamingMessageRequest ;
34+ import io .a2a .spec .SetTaskPushNotificationConfigRequest ;
3435import java .io .IOException ;
3536import java .util .List ;
3637import java .util .Map ;
38+ import java .util .concurrent .CompletableFuture ;
39+ import java .util .concurrent .atomic .AtomicReference ;
3740import java .util .function .Consumer ;
3841
3942public class JSONRestTransport implements ClientTransport {
@@ -62,19 +65,11 @@ public JSONRestTransport(A2AHttpClient httpClient, AgentCard agentCard,
6265 @ Override
6366 public EventKind sendMessage (MessageSendParams messageSendParams , ClientCallContext context ) throws A2AClientException {
6467 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 ));
7369 PayloadAndHeaders payloadAndHeaders = applyInterceptors (io .a2a .spec .SendMessageRequest .METHOD , builder .getRequestOrBuilder (),
7470 agentCard , context );
7571 try {
7672 String httpResponseBody = sendPostRequest (agentUrl + "/v1/message:send" , payloadAndHeaders );
77- System .out .println ("Response " + httpResponseBody );
7873 io .a2a .grpc .SendMessageResponse .Builder responseBuilder = io .a2a .grpc .SendMessageResponse .newBuilder ();
7974 JsonFormat .parser ().merge (httpResponseBody , responseBuilder );
8075 if (responseBuilder .hasMsg ()) {
@@ -89,8 +84,28 @@ public EventKind sendMessage(MessageSendParams messageSendParams, ClientCallCont
8984 }
9085
9186 @ 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+ }
94109 }
95110
96111 @ Override
@@ -102,12 +117,11 @@ public Task getTask(TaskQueryParams taskQueryParams, ClientCallContext context)
102117 agentCard , context );
103118 try {
104119 String url ;
105- if (taskQueryParams .historyLength () != null ) {
120+ if (taskQueryParams .historyLength () != null ) {
106121 url = agentUrl + String .format ("/v1/tasks/%1s?historyLength=%2d" , taskQueryParams .id (), taskQueryParams .historyLength ());
107122 } else {
108123 url = agentUrl + String .format ("/v1/tasks/%1s" , taskQueryParams .id ());
109124 }
110- System .out .println ("Getting URL: " + url );
111125 A2AHttpClient .GetBuilder getBuilder = httpClient .createGet ().url (url );
112126 if (payloadAndHeaders .getHttpHeaders () != null ) {
113127 for (Map .Entry <String , String > entry : payloadAndHeaders .getHttpHeaders ().entrySet ()) {
@@ -120,7 +134,6 @@ public Task getTask(TaskQueryParams taskQueryParams, ClientCallContext context)
120134 throw new A2AClientException ("Failed to send message: " + e , e );
121135 }
122136 String httpResponseBody = response .body ();
123- System .out .println ("Response " + httpResponseBody );
124137 io .a2a .grpc .Task .Builder responseBuilder = io .a2a .grpc .Task .newBuilder ();
125138 JsonFormat .parser ().merge (httpResponseBody , responseBuilder );
126139 return ProtoUtils .FromProto .task (responseBuilder );
@@ -140,7 +153,6 @@ public Task cancelTask(TaskIdParams taskIdParams, ClientCallContext context) thr
140153 agentCard , context );
141154 try {
142155 String httpResponseBody = sendPostRequest (agentUrl + String .format ("/v1/tasks/%1s:cancel" , taskIdParams .id ()), payloadAndHeaders );
143- System .out .println ("Response " + httpResponseBody );
144156 io .a2a .grpc .Task .Builder responseBuilder = io .a2a .grpc .Task .newBuilder ();
145157 JsonFormat .parser ().merge (httpResponseBody , responseBuilder );
146158 return ProtoUtils .FromProto .task (responseBuilder );
@@ -153,12 +165,55 @@ public Task cancelTask(TaskIdParams taskIdParams, ClientCallContext context) thr
153165
154166 @ Override
155167 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+ }
157186 }
158187
159188 @ Override
160189 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+ }
162217 }
163218
164219 @ Override
@@ -173,7 +228,7 @@ public void deleteTaskPushNotificationConfigurations(DeleteTaskPushNotificationC
173228
174229 @ Override
175230 public void resubscribe (TaskIdParams request , Consumer <StreamingEventKind > eventConsumer ,
176- Consumer <Throwable > errorConsumer , ClientCallContext context ) throws A2AClientException {
231+ Consumer <Throwable > errorConsumer , ClientCallContext context ) throws A2AClientException {
177232 throw new UnsupportedOperationException ("Not supported yet." ); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
178233 }
179234
@@ -222,7 +277,6 @@ private A2AHttpClient.PostBuilder createPostBuilder(String url, PayloadAndHeader
222277 postBuilder .addHeader (entry .getKey (), entry .getValue ());
223278 }
224279 }
225-
226280 return postBuilder ;
227281 }
228282
0 commit comments