11package com .postmarkapp .postmark .client ;
22
3- import org .glassfish .jersey .client .ClientConfig ;
4- import org .glassfish .jersey .client .ClientProperties ;
5- import org .glassfish .jersey .client .HttpUrlConnectorProvider ;
6-
7- import javax .ws .rs .client .Client ;
8- import javax .ws .rs .client .ClientBuilder ;
9- import javax .ws .rs .client .Entity ;
10- import javax .ws .rs .client .Invocation .Builder ;
11- import javax .ws .rs .core .Response ;
3+ import org .apache .hc .client5 .http .config .RequestConfig ;
4+ import org .apache .hc .client5 .http .impl .classic .CloseableHttpClient ;
5+ import org .apache .hc .client5 .http .impl .classic .HttpClientBuilder ;
6+ import org .apache .hc .client5 .http .impl .classic .HttpClients ;
7+ import org .apache .hc .core5 .http .ClassicHttpRequest ;
8+ import org .apache .hc .core5 .http .io .entity .EntityUtils ;
9+ import org .apache .hc .core5 .http .io .support .ClassicRequestBuilder ;
10+ import org .apache .hc .core5 .util .Timeout ;
11+
12+ import java .io .IOException ;
1213import java .util .Map ;
1314
1415/**
@@ -30,21 +31,35 @@ public enum DEFAULTS {
3031 }
3132
3233 private final Map <String ,Object > headers ;
33- private final Client client ;
34+ private CloseableHttpClient client ;
3435
3536 private boolean secureConnection = true ;
37+ private int connectTimeoutSeconds = DEFAULTS .CONNECT_TIMEOUT_SECONDS .value ;
38+ private int readTimeoutSeconds = DEFAULTS .READ_TIMEOUT_SECONDS .value ;
3639
3740 public HttpClient (Map <String ,Object > headers , int connectTimeoutSeconds , int readTimeoutSeconds ) {
38- this (headers );
39- setConnectTimeoutSeconds (connectTimeoutSeconds );
40- setReadTimeoutSeconds (readTimeoutSeconds );
41+ this .headers = headers ;
42+ this .connectTimeoutSeconds = connectTimeoutSeconds ;
43+ this .readTimeoutSeconds = readTimeoutSeconds ;
44+ buildClientWithCustomConfig ();
4145 }
4246
4347 public HttpClient (Map <String ,Object > headers ) {
4448 this .headers = headers ;
45- this .client = buildClient ();
46- setReadTimeoutSeconds (DEFAULTS .READ_TIMEOUT_SECONDS .value );
47- setConnectTimeoutSeconds (DEFAULTS .CONNECT_TIMEOUT_SECONDS .value );
49+ buildClientWithCustomConfig ();
50+ }
51+
52+ /**
53+ * Overload method for executing requests, which doesn't contain data
54+ *
55+ * @param request_type type of HTTP request
56+ * @param url request URL
57+ * @return simplified HTTP request response (status and response text)
58+ *
59+ * @see #execute(REQUEST_TYPES, String, String) for details
60+ */
61+ public ClientResponse execute (REQUEST_TYPES request_type , String url ) throws IOException {
62+ return execute (request_type , url , null );
4863 }
4964
5065 /**
@@ -56,57 +71,50 @@ public HttpClient(Map<String,Object> headers) {
5671 * @param data data sent for POST/PUT requests
5772 * @return response from HTTP request
5873 */
59- public ClientResponse execute (REQUEST_TYPES requestType , String url , String data ) {
60- Response response ;
61- final Builder requestBuilder = clientRequestBuilder ((url ));
74+ public ClientResponse execute (REQUEST_TYPES requestType , String url , String data ) throws IOException {
75+ ClassicHttpRequest request ;
6276
6377 switch (requestType ) {
6478 case POST :
65- response = requestBuilder .post (Entity . json (data ), Response . class );
79+ request = ClassicRequestBuilder .post (getHttpUrl ( url )). setEntity (data ). build ( );
6680 break ;
6781
6882 case PUT :
69- response = requestBuilder .put (Entity . json (data ), Response . class );
83+ request = ClassicRequestBuilder .put (getHttpUrl ( url )). setEntity (data ). build ( );
7084 break ;
7185
7286 case PATCH :
73- response = requestBuilder . method ( "PATCH" , Entity . json (data ), Response . class );
87+ request = ClassicRequestBuilder . patch ( getHttpUrl ( url )). setEntity (data ). build ( );
7488 break ;
7589
7690 case DELETE :
77- response = requestBuilder .delete (Response . class );
91+ request = ClassicRequestBuilder .delete (getHttpUrl ( url )). build ( );
7892 break ;
7993
8094 default :
81- response = requestBuilder .get (Response . class );
95+ request = ClassicRequestBuilder .get (getHttpUrl ( url )). build ( );
8296 break ;
83-
8497 }
8598
86- return transformResponse (response );
87- }
99+ for (Map .Entry <String , Object > header : headers .entrySet ()) {
100+ request .setHeader (header .getKey (), header .getValue ().toString ());
101+ }
88102
89- /**
90- * Overload method for executing requests, which doesn't contain data
91- *
92- * @param request_type type of HTTP request
93- * @param url request URL
94- * @return simplified HTTP request response (status and response text)
95- *
96- * @see #execute(REQUEST_TYPES, String, String) for details
97- */
98- public ClientResponse execute (REQUEST_TYPES request_type , String url ) {
99- return execute (request_type , url , null );
103+ return client .execute (
104+ request ,
105+ response -> new ClientResponse (response .getCode (), EntityUtils .toString (response .getEntity ())));
100106 }
101107
102108 // Setters and Getters
103109
104110 public void setConnectTimeoutSeconds (int connectTimeoutSeconds ) {
105- client .property (ClientProperties .CONNECT_TIMEOUT , connectTimeoutSeconds * 1000 );
111+ this .connectTimeoutSeconds = connectTimeoutSeconds ;
112+ buildClientWithCustomConfig ();
106113 }
107114
108115 public void setReadTimeoutSeconds (int readTimeoutSeconds ) {
109- client .property (ClientProperties .READ_TIMEOUT , readTimeoutSeconds * 1000 );
116+ this .readTimeoutSeconds = readTimeoutSeconds ;
117+ buildClientWithCustomConfig ();
110118 }
111119
112120 public void setSecureConnection (boolean secureConnection ) {
@@ -123,59 +131,32 @@ private String getHttpUrl(String url) {
123131 *
124132 * @return original HTTP client
125133 */
126- public Client getClient () {
134+ public CloseableHttpClient getClient () {
127135 return client ;
128136 }
129137
130138 /**
131139 * Build default HTTP client used for requests
132140 *
133- * Jersey client uses HttpUrlConnection by default which doesn't have PATCH method:
134- * https://docs.oracle.com/javase/8/docs/api/java/net/HttpURLConnection.html#setRequestMethod-java.lang.String-
135- * https://github.com/eclipse-ee4j/jersey/issues/4825
136- *
137- * Workaround for being able to do PATCH requests is by using reflection, which would work up to Java 16.
138- * https://stackoverflow.com/questions/55778145/how-to-use-patch-method-with-jersey-invocation-builder
139- *
140141 * @return initialized HTTP client
141142 */
142- private Client buildClient () {
143- Client client = ClientBuilder .newClient ();
144- // this allows calls to PATCH by using reflection
145- client .property (HttpUrlConnectorProvider .SET_METHOD_WORKAROUND , true );
146- return client ;
147- }
148-
149- private Builder clientRequestBuilder (String url ) {
150- Builder requestBuilder = client .target (getHttpUrl (url )).request ();
151-
152- for (Map .Entry <String , Object > header : headers .entrySet ()) {
153- requestBuilder .header (header .getKey (), header .getValue ());
154- }
155-
156- return requestBuilder ;
157- }
158-
159- /**
160- * Build HTTP client with custom config used for requests
161- * like:
162- *
163- * ClientConfig clientConfig = new ClientConfig();
164- * clientConfig.connectorProvider(new GrizzlyConnectorProvider());
165- * clientConfig.connectorProvider(new HttpUrlConnectorProvider().useSetMethodWorkaround());
166- */
167- private Client buildClient (ClientConfig config ) {
168- return ClientBuilder .newClient (config );
143+ private CloseableHttpClient buildClient () {
144+ return HttpClients .createDefault ();
169145 }
170146
171147 /**
172- * Gets simplified HTTP request response that will contain only response and status.
148+ * Build HTTP client used for requests with custom config settings
173149 *
174- * @param response HTTP request response result
175- * @return simplified HTTP request response
150+ * @return initialized HTTP client
176151 */
177- private ClientResponse transformResponse (Response response ) {
178- return new ClientResponse (response .getStatus (), response .readEntity (String .class ));
152+ private void buildClientWithCustomConfig () {
153+ RequestConfig requestConfig = RequestConfig
154+ .custom ()
155+ .setConnectTimeout (Timeout .ofSeconds (connectTimeoutSeconds ))
156+ .setResponseTimeout (Timeout .ofSeconds (readTimeoutSeconds ))
157+ .build ();
158+
159+ this .client = HttpClientBuilder .create ().setDefaultRequestConfig (requestConfig ).build ();
179160 }
180161
181162 /**
0 commit comments