1515 */
1616package io .serverlessworkflow .impl .executors .grpc ;
1717
18- import com .fasterxml .jackson .core .JsonProcessingException ;
19- import com .fasterxml .jackson .databind .JsonNode ;
20- import com .google .protobuf .DescriptorProtos ;
21- import com .google .protobuf .Descriptors ;
22- import com .google .protobuf .DynamicMessage ;
23- import com .google .protobuf .InvalidProtocolBufferException ;
24- import com .google .protobuf .Message ;
25- import com .google .protobuf .util .JsonFormat ;
26- import io .grpc .MethodDescriptor ;
27- import io .grpc .Status ;
28- import io .grpc .stub .StreamObserver ;
29- import io .serverlessworkflow .api .WorkflowFormat ;
30- import io .serverlessworkflow .api .types .ExternalResource ;
3118import io .serverlessworkflow .impl .TaskContext ;
3219import io .serverlessworkflow .impl .WorkflowContext ;
3320import io .serverlessworkflow .impl .WorkflowModel ;
3421import io .serverlessworkflow .impl .executors .CallableTask ;
35- import java .io .IOException ;
36- import java .io .UncheckedIOException ;
37- import java .util .ArrayList ;
38- import java .util .List ;
39- import java .util .Map ;
4022import java .util .concurrent .CompletableFuture ;
41- import java .util .concurrent .CompletionException ;
42- import java .util .concurrent .ExecutionException ;
43- import java .util .concurrent .TimeUnit ;
44- import java .util .concurrent .TimeoutException ;
45- import org .slf4j .Logger ;
46- import org .slf4j .LoggerFactory ;
4723
4824public class GrpcExecutor implements CallableTask {
4925
50- private static final Logger LOGGER = LoggerFactory .getLogger (GrpcExecutor .class );
51-
5226 private final GrpcRequestContext requestContext ;
5327 private final GrpcCallExecutor grpcCallExecutor ;
5428 private final FileDescriptorContextSupplier fileDescriptorContextSupplier ;
5529
5630 public GrpcExecutor (
57- ExternalResource proto ,
5831 GrpcRequestContext builder ,
5932 GrpcCallExecutor grpcCallExecutor ,
6033 FileDescriptorContextSupplier fileDescriptorContextSupplier ) {
@@ -75,98 +48,4 @@ public CompletableFuture<WorkflowModel> apply(
7548 this .grpcCallExecutor .apply (
7649 fileDescriptorContext , this .requestContext , workflowContext , taskContext , input ));
7750 }
78-
79- public static Message .Builder buildMessage (Object object , Message .Builder builder )
80- throws InvalidProtocolBufferException , JsonProcessingException {
81- JsonFormat .parser ().merge (WorkflowFormat .JSON .mapper ().writeValueAsString (object ), builder );
82- return builder ;
83- }
84-
85- public static Message .Builder buildMessage (
86- Descriptors .MethodDescriptor methodDescriptor , Map <String , Object > parameters )
87- throws InvalidProtocolBufferException , JsonProcessingException {
88- DynamicMessage .Builder builder = DynamicMessage .newBuilder (methodDescriptor .getInputType ());
89- JsonFormat .parser ().merge (WorkflowFormat .JSON .mapper ().writeValueAsString (parameters ), builder );
90- return builder ;
91- }
92-
93- public static JsonNode convert (Message message ) {
94- StringBuilder str = new StringBuilder ();
95- try {
96- JsonFormat .printer ().appendTo (message , str );
97- return WorkflowFormat .JSON .mapper ().readTree (str .toString ());
98- } catch (IOException e ) {
99- throw new UncheckedIOException ("Error converting protobuf message to JSON" , e );
100- }
101- }
102-
103- public static MethodDescriptor .MethodType getMethodType (
104- com .google .protobuf .Descriptors .MethodDescriptor methodDesc ) {
105- DescriptorProtos .MethodDescriptorProto methodDescProto = methodDesc .toProto ();
106- if (methodDescProto .getClientStreaming ()) {
107- if (methodDescProto .getServerStreaming ()) {
108- return MethodDescriptor .MethodType .BIDI_STREAMING ;
109- }
110- return MethodDescriptor .MethodType .CLIENT_STREAMING ;
111- } else if (methodDescProto .getServerStreaming ()) {
112- return MethodDescriptor .MethodType .SERVER_STREAMING ;
113- } else {
114- return MethodDescriptor .MethodType .UNARY ;
115- }
116- }
117-
118- public static class WaitingStreamObserver implements StreamObserver <Message > {
119- List <Message > responses = new ArrayList <>();
120- CompletableFuture <List <Message >> responsesFuture = new CompletableFuture <>();
121- private final int timeout ;
122-
123- public WaitingStreamObserver (int timeout ) {
124- this .timeout = timeout ;
125- }
126-
127- @ Override
128- public void onNext (Message messageReply ) {
129- responses .add (messageReply );
130- }
131-
132- @ Override
133- public void onError (Throwable throwable ) {
134- responsesFuture .completeExceptionally (throwable );
135- }
136-
137- @ Override
138- public void onCompleted () {
139- responsesFuture .complete (responses );
140- }
141-
142- public List <Message > get () {
143- try {
144- return responsesFuture .get (timeout , TimeUnit .SECONDS );
145- } catch (InterruptedException e ) {
146- Thread .currentThread ().interrupt ();
147- throw new IllegalStateException (e );
148- } catch (TimeoutException e ) {
149- throw new IllegalStateException (
150- String .format ("gRPC call timed out after %d seconds" , timeout ), e );
151- } catch (ExecutionException e ) {
152- throw new IllegalStateException (getServerStreamErrorMessage (e .getCause ()), e .getCause ());
153- }
154- }
155-
156- public void checkForServerStreamErrors () {
157- if (responsesFuture .isCompletedExceptionally ()) {
158- try {
159- responsesFuture .join ();
160- } catch (CompletionException e ) {
161- throw new IllegalStateException (getServerStreamErrorMessage (e .getCause ()), e .getCause ());
162- }
163- }
164- }
165-
166- private String getServerStreamErrorMessage (Throwable throwable ) {
167- return String .format (
168- "Received an error through gRPC server stream with status: %s" ,
169- Status .fromThrowable (throwable ));
170- }
171- }
17251}
0 commit comments