24
24
import io .serverlessworkflow .impl .TaskContext ;
25
25
import io .serverlessworkflow .impl .WorkflowApplication ;
26
26
import io .serverlessworkflow .impl .WorkflowContext ;
27
+ import io .serverlessworkflow .impl .WorkflowError ;
28
+ import io .serverlessworkflow .impl .WorkflowException ;
27
29
import io .serverlessworkflow .impl .WorkflowModel ;
28
30
import io .serverlessworkflow .impl .resources .ResourceLoader ;
29
31
import io .swagger .v3 .oas .models .OpenAPI ;
30
32
import io .swagger .v3 .parser .OpenAPIV3Parser ;
33
+ import jakarta .ws .rs .WebApplicationException ;
31
34
import jakarta .ws .rs .client .Client ;
32
35
import jakarta .ws .rs .client .ClientBuilder ;
33
36
import jakarta .ws .rs .client .Invocation ;
34
37
import jakarta .ws .rs .client .WebTarget ;
35
38
import jakarta .ws .rs .core .MultivaluedMap ;
39
+ import jakarta .ws .rs .core .Response ;
36
40
import java .net .URI ;
41
+ import java .util .List ;
42
+ import java .util .Map ;
43
+ import java .util .Optional ;
37
44
import java .util .concurrent .CompletableFuture ;
38
- import java .util .concurrent .atomic .AtomicReference ;
39
45
40
46
public class OpenAPIExecutor implements CallableTask <CallOpenAPI > {
41
47
42
48
private static final Client client = ClientBuilder .newClient ();
43
49
private WebTargetSupplier webTargetSupplier ;
44
50
private RequestSupplier requestSupplier ;
45
- private final OpenAPIModelConverter converter = new OpenAPIModelConverter () {};
51
+ private OpenAPIModelConverter converter = new OpenAPIModelConverter () {};
46
52
47
53
@ FunctionalInterface
48
54
private interface WebTargetSupplier {
@@ -59,7 +65,6 @@ WorkflowModel apply(
59
65
public void init (
60
66
CallOpenAPI task , Workflow workflow , WorkflowApplication application , ResourceLoader loader ) {
61
67
OpenAPIArguments args = task .getWith ();
62
- WithOpenAPIParameters withParams = args .getParameters ();
63
68
64
69
URI uri = getOpenAPIDocumentURI (args .getDocument ().getEndpoint ().getUriTemplate ());
65
70
@@ -69,33 +74,75 @@ public void init(
69
74
70
75
OpenAPIOperationContext ctx = generateContext (openAPI , args , uri );
71
76
72
- this .webTargetSupplier =
73
- () -> {
74
- final AtomicReference <WebTarget > webTarget =
75
- new AtomicReference <>(
76
- client
77
- .target (openAPI .getServers ().get (0 ).getUrl ())
78
- .path (ctx .buildPath (withParams .getAdditionalProperties ())));
79
-
80
- MultivaluedMap <String , Object > queryParams =
81
- ctx .buildQueryParams (withParams .getAdditionalProperties ());
82
- queryParams .forEach (
83
- (key , value ) -> {
84
- for (Object o : value ) {
85
- webTarget .set (webTarget .get ().queryParam (key , o ));
86
- }
87
- });
88
-
89
- return webTarget .get ();
90
- };
77
+ WithOpenAPIParameters withParams =
78
+ Optional .ofNullable (args .getParameters ()).orElse (new WithOpenAPIParameters ());
79
+
80
+ this .webTargetSupplier = getTargetSupplier (openAPI , ctx , withParams );
91
81
92
82
this .requestSupplier =
93
83
(request , w , taskContext , node ) -> {
94
- Object response = request .method (ctx .httpMethodName (), node .objectClass ());
95
- return converter .toModel (application .modelFactory (), node , response );
84
+ try {
85
+ Response response = request .method (ctx .httpMethodName (), Response .class );
86
+
87
+ if (!args .isRedirect () && !is2xx (response )) {
88
+ throw new WorkflowException (
89
+ WorkflowError .communication (
90
+ response .getStatus (),
91
+ taskContext ,
92
+ "Received a non-2xx nor 3xx response but redirects are enabled" )
93
+ .build ());
94
+ }
95
+
96
+ if (args .isRedirect () && isNot2xxNor3xx (response )) {
97
+ throw new WorkflowException (
98
+ WorkflowError .communication (
99
+ response .getStatus (),
100
+ taskContext ,
101
+ "Received a non-2xx nor 3xx response but redirects are enabled" )
102
+ .build ());
103
+ }
104
+
105
+ return converter .toModel (
106
+ application .modelFactory (), node , response .readEntity (node .objectClass ()));
107
+ } catch (WebApplicationException exception ) {
108
+ throw new WorkflowException (
109
+ WorkflowError .communication (
110
+ exception .getResponse ().getStatus (), taskContext , exception )
111
+ .build ());
112
+ }
96
113
};
97
114
}
98
115
116
+ private static WebTargetSupplier getTargetSupplier (
117
+ OpenAPI openAPI , OpenAPIOperationContext ctx , WithOpenAPIParameters withParams ) {
118
+ return () -> {
119
+ WebTarget webTarget =
120
+ client
121
+ .target (openAPI .getServers ().get (0 ).getUrl ())
122
+ .path (ctx .buildPath (withParams .getAdditionalProperties ()));
123
+
124
+ MultivaluedMap <String , Object > queryParams =
125
+ ctx .buildQueryParams (withParams .getAdditionalProperties ());
126
+
127
+ for (Map .Entry <String , List <Object >> queryParam : queryParams .entrySet ()) {
128
+ for (Object value : queryParam .getValue ()) {
129
+ webTarget = webTarget .queryParam (queryParam .getKey (), value );
130
+ }
131
+ }
132
+
133
+ return webTarget ;
134
+ };
135
+ }
136
+
137
+ private static boolean is2xx (Response response ) {
138
+ return response .getStatusInfo ().getFamily ().equals (Response .Status .Family .SUCCESSFUL );
139
+ }
140
+
141
+ private static boolean isNot2xxNor3xx (Response response ) {
142
+ return !(response .getStatusInfo ().getFamily ().equals (Response .Status .Family .SUCCESSFUL )
143
+ || response .getStatusInfo ().getFamily ().equals (Response .Status .Family .REDIRECTION ));
144
+ }
145
+
99
146
private static OpenAPIOperationContext generateContext (
100
147
OpenAPI openAPI , OpenAPIArguments args , URI uri ) {
101
148
return openAPI .getPaths ().entrySet ().stream ()
@@ -142,7 +189,6 @@ private static URI getOpenAPIDocumentURI(UriTemplate template) {
142
189
if (template .getLiteralUri () != null ) {
143
190
return template .getLiteralUri ();
144
191
} else if (template .getLiteralUriTemplate () != null ) {
145
- // TODO: Support
146
192
// https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#uri-template
147
193
throw new UnsupportedOperationException (
148
194
"URI templates with parameters are not supported yet" );
0 commit comments