1616
1717package io .serverlessworkflow .impl .executors .http .oauth ;
1818
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 ;
1924import io .serverlessworkflow .impl .TaskContext ;
2025import io .serverlessworkflow .impl .WorkflowApplication ;
2126import io .serverlessworkflow .impl .WorkflowContext ;
2227import io .serverlessworkflow .impl .WorkflowModel ;
2328import io .serverlessworkflow .impl .WorkflowUtils ;
2429import 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 ;
2537import java .net .URI ;
2638import java .net .URLEncoder ;
27- import java .net .http .HttpRequest ;
2839import java .nio .charset .StandardCharsets ;
29- import java .time .Duration ;
3040import java .util .HashMap ;
3141import java .util .Map ;
32- import java .util .Objects ;
33- import java .util .stream .Collectors ;
3442
35- public class HttpRequestBuilder {
43+ class HttpRequestBuilder {
3644
3745 private final Map <String , WorkflowValueResolver <String >> headers ;
3846
@@ -42,86 +50,99 @@ public class HttpRequestBuilder {
4250
4351 private URI uri ;
4452
45- private String method ;
53+ private OAuth2AutenthicationData .OAuth2AutenthicationDataGrant grantType ;
54+
55+ private Oauth2TokenRequestEncoding requestContentType = APPLICATION_X_WWW_FORM_URLENCODED ;
4656
47- public HttpRequestBuilder (WorkflowApplication app ) {
57+ HttpRequestBuilder (WorkflowApplication app ) {
4858 this .app = app ;
4959 headers = new HashMap <>();
5060 queryParams = new HashMap <>();
5161 }
5262
53- public HttpRequestBuilder addHeader (String key , String token ) {
63+ HttpRequestBuilder addHeader (String key , String token ) {
5464 headers .put (key , WorkflowUtils .buildStringFilter (app , token ));
5565 return this ;
5666 }
5767
58- public HttpRequestBuilder addQueryParam (String key , String token ) {
68+ HttpRequestBuilder addQueryParam (String key , String token ) {
5969 queryParams .put (key , WorkflowUtils .buildStringFilter (app , token ));
6070 return this ;
6171 }
6272
63- public HttpRequestBuilder withUri (URI uri ) {
73+ HttpRequestBuilder withUri (URI uri ) {
6474 this .uri = uri ;
6575 return this ;
6676 }
6777
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 ;
7088 return this ;
7189 }
7290
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" );
75103
76104 for (var entry : headers .entrySet ()) {
77105 String headerValue = entry .getValue ().apply (workflow , task , model );
78106 if (headerValue != null ) {
79- request = request .header (entry .getKey (), headerValue );
107+ builder .header (entry .getKey (), headerValue );
80108 }
81109 }
82110
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+ }
84135
136+ return new InvocationHolder (client , () -> builder .post (entity ));
137+ }
138+
139+ private void validate () {
85140 if (uri == null ) {
86141 throw new IllegalStateException ("URI must be set before building the request" );
87142 }
88143
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" );
123146 }
124- request .timeout (Duration .ofSeconds (15 ));
125- return request .build ();
126147 }
127148}
0 commit comments