16
16
17
17
package io .serverlessworkflow .impl .executors .http .oauth ;
18
18
19
+ import static io .serverlessworkflow .api .types .OAuth2TokenRequest .Oauth2TokenRequestEncoding ;
20
+ import static io .serverlessworkflow .api .types .OAuth2TokenRequest .Oauth2TokenRequestEncoding .APPLICATION_X_WWW_FORM_URLENCODED ;
21
+
22
+ import io .serverlessworkflow .api .types .OAuth2AutenthicationData ;
23
+ import io .serverlessworkflow .api .types .OAuth2TokenRequest ;
19
24
import io .serverlessworkflow .impl .TaskContext ;
20
25
import io .serverlessworkflow .impl .WorkflowApplication ;
21
26
import io .serverlessworkflow .impl .WorkflowContext ;
22
27
import io .serverlessworkflow .impl .WorkflowModel ;
23
28
import io .serverlessworkflow .impl .WorkflowUtils ;
24
29
import io .serverlessworkflow .impl .WorkflowValueResolver ;
30
+ import jakarta .ws .rs .client .Client ;
31
+ import jakarta .ws .rs .client .ClientBuilder ;
32
+ import jakarta .ws .rs .client .Entity ;
33
+ import jakarta .ws .rs .client .Invocation ;
34
+ import jakarta .ws .rs .client .WebTarget ;
35
+ import jakarta .ws .rs .core .Form ;
36
+ import jakarta .ws .rs .core .MediaType ;
25
37
import java .net .URI ;
26
38
import java .net .URLEncoder ;
27
- import java .net .http .HttpRequest ;
28
39
import java .nio .charset .StandardCharsets ;
29
- import java .time .Duration ;
30
40
import java .util .HashMap ;
31
41
import java .util .Map ;
32
- import java .util .Objects ;
33
- import java .util .stream .Collectors ;
34
42
35
- public class HttpRequestBuilder {
43
+ class HttpRequestBuilder {
36
44
37
45
private final Map <String , WorkflowValueResolver <String >> headers ;
38
46
@@ -42,86 +50,99 @@ public class HttpRequestBuilder {
42
50
43
51
private URI uri ;
44
52
45
- private String method ;
53
+ private OAuth2AutenthicationData .OAuth2AutenthicationDataGrant grantType ;
54
+
55
+ private Oauth2TokenRequestEncoding requestContentType = APPLICATION_X_WWW_FORM_URLENCODED ;
46
56
47
- public HttpRequestBuilder (WorkflowApplication app ) {
57
+ HttpRequestBuilder (WorkflowApplication app ) {
48
58
this .app = app ;
49
59
headers = new HashMap <>();
50
60
queryParams = new HashMap <>();
51
61
}
52
62
53
- public HttpRequestBuilder addHeader (String key , String token ) {
63
+ HttpRequestBuilder addHeader (String key , String token ) {
54
64
headers .put (key , WorkflowUtils .buildStringFilter (app , token ));
55
65
return this ;
56
66
}
57
67
58
- public HttpRequestBuilder addQueryParam (String key , String token ) {
68
+ HttpRequestBuilder addQueryParam (String key , String token ) {
59
69
queryParams .put (key , WorkflowUtils .buildStringFilter (app , token ));
60
70
return this ;
61
71
}
62
72
63
- public HttpRequestBuilder withUri (URI uri ) {
73
+ HttpRequestBuilder withUri (URI uri ) {
64
74
this .uri = uri ;
65
75
return this ;
66
76
}
67
77
68
- public HttpRequestBuilder withMethod (String method ) {
69
- this .method = method ;
78
+ HttpRequestBuilder withRequestContentType (OAuth2TokenRequest oAuth2TokenRequest ) {
79
+ if (oAuth2TokenRequest != null ) {
80
+ this .requestContentType = oAuth2TokenRequest .getEncoding ();
81
+ }
82
+ return this ;
83
+ }
84
+
85
+ HttpRequestBuilder withGrantType (
86
+ OAuth2AutenthicationData .OAuth2AutenthicationDataGrant grantType ) {
87
+ this .grantType = grantType ;
70
88
return this ;
71
89
}
72
90
73
- public HttpRequest build (WorkflowContext workflow , TaskContext task , WorkflowModel model ) {
74
- HttpRequest .Builder request = HttpRequest .newBuilder ();
91
+ InvocationHolder build (WorkflowContext workflow , TaskContext task , WorkflowModel model ) {
92
+ validate ();
93
+
94
+ Client client = ClientBuilder .newClient ();
95
+ WebTarget target = client .target (uri );
96
+
97
+ Invocation .Builder builder = target .request (MediaType .APPLICATION_JSON );
98
+
99
+ builder .header ("grant_type" , grantType .name ().toLowerCase ());
100
+ builder .header ("User-Agent" , "OAuth2-Client-Credentials/1.0" );
101
+ builder .header ("Accept" , MediaType .APPLICATION_JSON );
102
+ builder .header ("Cache-Control" , "no-cache" );
75
103
76
104
for (var entry : headers .entrySet ()) {
77
105
String headerValue = entry .getValue ().apply (workflow , task , model );
78
106
if (headerValue != null ) {
79
- request = request .header (entry .getKey (), headerValue );
107
+ builder .header (entry .getKey (), headerValue );
80
108
}
81
109
}
82
110
83
- request .header ("Accept" , "application/json" );
111
+ Entity <?> entity ;
112
+ if (requestContentType .equals (APPLICATION_X_WWW_FORM_URLENCODED )) {
113
+ Form form = new Form ();
114
+ form .param ("grant_type" , grantType .value ());
115
+ queryParams .forEach (
116
+ (key , value ) -> {
117
+ String v = value .apply (workflow , task , model );
118
+ String encodedKey = URLEncoder .encode (key , StandardCharsets .UTF_8 );
119
+ String encodedValue = URLEncoder .encode (v , StandardCharsets .UTF_8 );
120
+ form .param (encodedKey , encodedValue );
121
+ });
122
+ entity = Entity .entity (form , MediaType .APPLICATION_FORM_URLENCODED );
123
+ } else {
124
+ Map <String , Object > jsonData = new HashMap <>();
125
+ jsonData .put ("grant_type" , grantType .value ());
126
+ queryParams .forEach (
127
+ (key , value ) -> {
128
+ String v = value .apply (workflow , task , model );
129
+ String encodedKey = URLEncoder .encode (key , StandardCharsets .UTF_8 );
130
+ String encodedValue = URLEncoder .encode (v , StandardCharsets .UTF_8 );
131
+ jsonData .put (encodedKey , encodedValue );
132
+ });
133
+ entity = Entity .entity (jsonData , MediaType .APPLICATION_JSON );
134
+ }
84
135
136
+ return new InvocationHolder (client , () -> builder .post (entity ));
137
+ }
138
+
139
+ private void validate () {
85
140
if (uri == null ) {
86
141
throw new IllegalStateException ("URI must be set before building the request" );
87
142
}
88
143
89
- String encoded =
90
- queryParams .entrySet ().stream ()
91
- .map (
92
- e -> {
93
- String v = e .getValue ().apply (workflow , task , model );
94
- if (v == null ) return null ;
95
- return URLEncoder .encode (e .getKey (), StandardCharsets .UTF_8 )
96
- + "="
97
- + URLEncoder .encode (v , StandardCharsets .UTF_8 );
98
- })
99
- .filter (Objects ::nonNull )
100
- .collect (Collectors .joining ("&" ));
101
-
102
- if (method != null ) {
103
- switch (method .toUpperCase ()) {
104
- case "GET" -> {
105
- if (!encoded .isEmpty ()) {
106
- String sep = (uri .getQuery () == null || uri .getQuery ().isEmpty ()) ? "?" : "&" ;
107
- uri = URI .create (uri .toString () + sep + encoded );
108
- }
109
- request .uri (uri ).GET ();
110
- }
111
- case "POST" -> {
112
- request .uri (uri );
113
- HttpRequest .BodyPublisher body =
114
- encoded .isEmpty ()
115
- ? HttpRequest .BodyPublishers .noBody ()
116
- : HttpRequest .BodyPublishers .ofString (encoded );
117
- request .POST (body );
118
- }
119
- default -> throw new IllegalArgumentException ("Unsupported HTTP method: " + method );
120
- }
121
- } else {
122
- throw new IllegalStateException ("HTTP method must be set before building the request" );
144
+ if (grantType == null ) {
145
+ throw new IllegalStateException ("Grant type must be set before building the request" );
123
146
}
124
- request .timeout (Duration .ofSeconds (15 ));
125
- return request .build ();
126
147
}
127
148
}
0 commit comments