47
47
import org .slf4j .LoggerFactory ;
48
48
import org .sourcelab .http .rest .configuration .Configuration ;
49
49
import org .sourcelab .http .rest .configuration .ProxyConfiguration ;
50
- import org .sourcelab .http .rest .configuration .RequestHeader ;
50
+ import org .sourcelab .http .rest .request .RequestHeader ;
51
51
import org .sourcelab .http .rest .exceptions .ConnectionException ;
52
52
import org .sourcelab .http .rest .exceptions .ResultParsingException ;
53
53
import org .sourcelab .http .rest .handlers .RestResponseHandler ;
54
+ import org .sourcelab .http .rest .interceptor .HeaderRequestInterceptor ;
54
55
import org .sourcelab .http .rest .interceptor .RequestContext ;
55
56
import org .sourcelab .http .rest .interceptor .RequestInterceptor ;
56
57
import org .sourcelab .http .rest .request .Request ;
57
58
import org .sourcelab .http .rest .request .RequestMethod ;
59
+ import org .sourcelab .http .rest .request .RequestParameter ;
60
+ import org .sourcelab .http .rest .request .body .RequestBodyContent ;
61
+ import org .sourcelab .http .rest .request .body .UrlEncodedFormBodyContent ;
58
62
59
63
import javax .net .ssl .SSLHandshakeException ;
60
64
import java .io .IOException ;
65
69
import java .net .URL ;
66
70
import java .nio .charset .StandardCharsets ;
67
71
import java .util .ArrayList ;
68
- import java .util .Collection ;
69
- import java .util .Collections ;
70
72
import java .util .List ;
71
- import java .util .Map ;
72
73
import java .util .concurrent .TimeUnit ;
73
74
74
75
/**
77
78
public class HttpClientRestClient implements RestClient {
78
79
private static final Logger logger = LoggerFactory .getLogger (HttpClientRestClient .class );
79
80
80
- /**
81
- * Default headers included with every request.
82
- */
83
- private Collection <RequestHeader > defaultHeaders = new ArrayList <>();
84
-
85
81
/**
86
82
* Save a copy of the configuration.
87
83
*/
@@ -97,8 +93,7 @@ public class HttpClientRestClient implements RestClient {
97
93
/**
98
94
* To allow for custom modifications to request prior to submitting it.
99
95
*/
100
- private RequestInterceptor requestInterceptor ;
101
-
96
+ private final List <RequestInterceptor > requestInterceptors = new ArrayList <>();
102
97
103
98
/**
104
99
* Constructor.
@@ -116,14 +111,17 @@ public void init(final Configuration configuration) {
116
111
// Save reference to configuration
117
112
this .configuration = configuration ;
118
113
119
- // Load RequestMutator instance from configuration.
120
- requestInterceptor = configuration .getRequestInterceptor ();
121
-
122
114
// Load default headers
123
- if (configuration .getRequestHeaders () != null ) {
124
- defaultHeaders = Collections .unmodifiableCollection (configuration .getRequestHeaders ());
115
+ if (configuration .getRequestHeaders () != null && !configuration .getRequestHeaders ().isEmpty ()) {
116
+ // Add interceptor to add headers to all requests.
117
+ requestInterceptors .add (
118
+ new HeaderRequestInterceptor (configuration .getRequestHeaders ())
119
+ );
125
120
}
126
121
122
+ // Load RequestMutator instance from configuration.
123
+ requestInterceptors .addAll (configuration .getRequestInterceptors ());
124
+
127
125
// Create https context builder utility.
128
126
final HttpsContextBuilder httpsContextBuilder = new HttpsContextBuilder (configuration );
129
127
@@ -245,7 +243,7 @@ public RestResponse submitRequest(final Request request) throws RestException {
245
243
try {
246
244
switch (request .getRequestMethod ()) {
247
245
case GET :
248
- return submitGetRequest (url , ( Map < String , String >) request .getRequestBody (), responseHandler );
246
+ return submitGetRequest (url , request .getRequestBody (), responseHandler );
249
247
case POST :
250
248
return submitPostRequest (url , request .getRequestBody (), responseHandler );
251
249
case PUT :
@@ -263,25 +261,33 @@ public RestResponse submitRequest(final Request request) throws RestException {
263
261
/**
264
262
* Internal GET method.
265
263
* @param url Url to GET to.
266
- * @param getParams GET parameters to include in the request
264
+ * @param requestBodyContent parameters to include in the request
267
265
* @param responseHandler The response Handler to use to parse the response
268
266
* @param <T> The type that ResponseHandler returns.
269
267
* @return Parsed response.
270
268
*/
271
- private <T > T submitGetRequest (final String url , final Map <String , String > getParams , final ResponseHandler <T > responseHandler ) throws IOException {
269
+ private <T > T submitGetRequest (
270
+ final String url ,
271
+ final RequestBodyContent requestBodyContent ,
272
+ final ResponseHandler <T > responseHandler
273
+ ) throws IOException {
272
274
final RequestContext requestContext = new RequestContext (url , RequestMethod .GET );
273
275
274
276
try {
275
- // Pass request parameters through interceptor.
276
- requestInterceptor .modifyRequestParameters (getParams , requestContext );
277
-
278
277
// Construct URI including our request parameters.
279
278
final URIBuilder uriBuilder = new URIBuilder (url )
280
279
.setCharset (StandardCharsets .UTF_8 );
281
280
282
- // Attach submitRequest params
283
- for (final Map .Entry <String , String > entry : getParams .entrySet ()) {
284
- uriBuilder .setParameter (entry .getKey (), entry .getValue ());
281
+ if (requestBodyContent instanceof UrlEncodedFormBodyContent ) {
282
+ final List <RequestParameter > requestParameters = processRequestParameters (
283
+ ((UrlEncodedFormBodyContent ) requestBodyContent ).getRequestParameters (),
284
+ requestContext
285
+ );
286
+
287
+ // Attach submitRequest params
288
+ for (final RequestParameter requestParameter : requestParameters ) {
289
+ uriBuilder .setParameter (requestParameter .getName (), requestParameter .getValue ());
290
+ }
285
291
}
286
292
287
293
// Build Get Request
@@ -306,12 +312,16 @@ private <T> T submitGetRequest(final String url, final Map<String, String> getPa
306
312
/**
307
313
* Internal POST method.
308
314
* @param url Url to POST to.
309
- * @param requestBody POST entity include in the request body
315
+ * @param requestBodyContent POST entity include in the request body
310
316
* @param responseHandler The response Handler to use to parse the response
311
317
* @param <T> The type that ResponseHandler returns.
312
318
* @return Parsed response.
313
319
*/
314
- private <T > T submitPostRequest (final String url , final Object requestBody , final ResponseHandler <T > responseHandler ) throws IOException {
320
+ private <T > T submitPostRequest (
321
+ final String url ,
322
+ final RequestBodyContent requestBodyContent ,
323
+ final ResponseHandler <T > responseHandler
324
+ ) throws IOException {
315
325
final RequestContext requestContext = new RequestContext (url , RequestMethod .POST );
316
326
317
327
try {
@@ -322,9 +332,9 @@ private <T> T submitPostRequest(final String url, final Object requestBody, fina
322
332
323
333
// Build request entity
324
334
post .setEntity (
325
- buildEntity (requestBody , requestContext )
335
+ buildEntity (requestBodyContent , requestContext )
326
336
);
327
- logger .debug ("Executing request {} with {}" , post .getRequestLine (), requestBody );
337
+ logger .debug ("Executing request {} with {}" , post .getRequestLine (), requestBodyContent );
328
338
329
339
// Execute and return
330
340
return httpClient .execute (post , responseHandler , httpClientContext );
@@ -340,12 +350,16 @@ private <T> T submitPostRequest(final String url, final Object requestBody, fina
340
350
/**
341
351
* Internal PUT method.
342
352
* @param url Url to POST to.
343
- * @param requestBody POST entity include in the request body
353
+ * @param requestBodyContent POST entity include in the request body
344
354
* @param responseHandler The response Handler to use to parse the response
345
355
* @param <T> The type that ResponseHandler returns.
346
356
* @return Parsed response.
347
357
*/
348
- private <T > T submitPutRequest (final String url , final Object requestBody , final ResponseHandler <T > responseHandler ) throws IOException {
358
+ private <T > T submitPutRequest (
359
+ final String url ,
360
+ final RequestBodyContent requestBodyContent ,
361
+ final ResponseHandler <T > responseHandler
362
+ ) throws IOException {
349
363
final RequestContext requestContext = new RequestContext (url , RequestMethod .PUT );
350
364
351
365
try {
@@ -356,9 +370,9 @@ private <T> T submitPutRequest(final String url, final Object requestBody, final
356
370
357
371
// Build request entity
358
372
put .setEntity (
359
- buildEntity (requestBody , requestContext )
373
+ buildEntity (requestBodyContent , requestContext )
360
374
);
361
- logger .debug ("Executing request {} with {}" , put .getRequestLine (), requestBody );
375
+ logger .debug ("Executing request {} with {}" , put .getRequestLine (), requestBodyContent );
362
376
363
377
// Execute and return
364
378
return httpClient .execute (put , responseHandler , httpClientContext );
@@ -410,33 +424,60 @@ private String constructApiUrl(final String endPoint) {
410
424
return configuration .getApiHost () + endPoint ;
411
425
}
412
426
413
- private HttpEntity buildEntity (final Object parameters , final RequestContext requestContext ) throws UnsupportedEncodingException {
414
- if (parameters instanceof Map ) {
415
- final Map <String , String > parametersMap = (Map <String , String >) parameters ;
416
-
417
- // Pass request parameters through interceptor.
418
- requestInterceptor .modifyRequestParameters (parametersMap , requestContext );
427
+ private HttpEntity buildEntity (final RequestBodyContent requestBodyContent , final RequestContext requestContext ) throws UnsupportedEncodingException {
428
+ if (requestBodyContent instanceof UrlEncodedFormBodyContent ) {
429
+ List <RequestParameter > requestParameters = processRequestParameters (
430
+ ((UrlEncodedFormBodyContent ) requestBodyContent ).getRequestParameters (), requestContext
431
+ );
419
432
420
- // Define required auth params
433
+ // Build Form parameters
421
434
final List <NameValuePair > params = new ArrayList <>();
422
435
423
436
// Attach submitRequest params
424
- for ( Map . Entry < String , String > entry : parametersMap . entrySet ()) {
425
- params .add (new BasicNameValuePair (entry . getKey (), entry .getValue ()));
426
- }
437
+ requestParameters
438
+ . forEach ( parameter -> params .add (new BasicNameValuePair (parameter . getName (), parameter .getValue ()))
439
+ );
427
440
return new UrlEncodedFormEntity (params );
428
441
} else {
429
- return new StringEntity (parameters .toString ());
442
+ return new StringEntity (requestBodyContent .toString ());
430
443
}
431
444
}
432
445
446
+ /**
447
+ * Process headers through requestInteceptor instances.
448
+ * @param requestBase The underlying request object.
449
+ * @param requestContext Contextual details about the request.
450
+ */
433
451
private void buildHeaders (final HttpRequestBase requestBase , final RequestContext requestContext ) {
434
452
// Pass headers through interceptor interface
435
- final List <RequestHeader > headers = new ArrayList <>(defaultHeaders );
436
- requestInterceptor .modifyHeaders (headers , requestContext );
453
+ List <RequestHeader > headers = new ArrayList <>();
454
+ for (final RequestInterceptor requestInterceptor : requestInterceptors ) {
455
+ headers = requestInterceptor .modifyHeaders (headers , requestContext );
456
+ }
457
+
458
+ // Add headers to the request instance.
437
459
headers
438
460
.stream ()
439
461
.map ((entry ) -> new BasicHeader (entry .getName (), entry .getValue ()))
440
462
.forEach (requestBase ::addHeader );
441
463
}
464
+
465
+ /**
466
+ * Process request parameters through request interceptors.
467
+ *
468
+ * @param incomingParameters The defined request parameters.
469
+ * @param requestContext Contextual details about the request.
470
+ * @return Modified request parameters.
471
+ */
472
+ private List <RequestParameter > processRequestParameters (final List <RequestParameter > incomingParameters , final RequestContext requestContext ) {
473
+ // Copy parameters
474
+ List <RequestParameter > requestParameters = new ArrayList <>(incomingParameters );
475
+
476
+ // Loop over each interceptor
477
+ for (final RequestInterceptor requestInterceptor : requestInterceptors ) {
478
+ // Pass in the parameters and get the returned list.
479
+ requestParameters = requestInterceptor .modifyRequestParameters (requestParameters , requestContext );
480
+ }
481
+ return requestParameters ;
482
+ }
442
483
}
0 commit comments