18
18
package org .apache .kyuubi .client ;
19
19
20
20
import java .net .URI ;
21
- import javax .net .ssl .SSLContext ;
21
+ import java .util .Arrays ;
22
+ import java .util .LinkedList ;
23
+ import java .util .List ;
22
24
import org .apache .commons .lang3 .StringUtils ;
23
- import org .apache .http .client .config .RequestConfig ;
24
- import org .apache .http .conn .ssl .NoopHostnameVerifier ;
25
- import org .apache .http .conn .ssl .SSLConnectionSocketFactory ;
26
- import org .apache .http .conn .ssl .TrustStrategy ;
27
- import org .apache .http .impl .client .CloseableHttpClient ;
28
- import org .apache .http .impl .client .HttpClientBuilder ;
29
- import org .apache .http .ssl .SSLContexts ;
30
25
import org .apache .kyuubi .client .auth .*;
31
- import org .slf4j .Logger ;
32
- import org .slf4j .LoggerFactory ;
33
26
34
27
public class KyuubiRestClient implements AutoCloseable {
35
28
36
- private static final Logger LOG = LoggerFactory .getLogger (KyuubiRestClient .class );
37
-
38
- private RestClient httpClient ;
29
+ private IRestClient httpClient ;
39
30
40
31
private AuthHeaderGenerator authHeaderGenerator ;
41
32
@@ -64,13 +55,21 @@ public void close() throws Exception {
64
55
private KyuubiRestClient () {}
65
56
66
57
private KyuubiRestClient (Builder builder ) {
67
- // Remove the trailing "/" from the hostUrl if present
68
- String hostUrl = builder .hostUrl .replaceAll ("/$" , "" );
69
- String baseUrl = String .format ("%s/%s" , hostUrl , builder .version .getApiNamespace ());
58
+ List <String > baseUrls = new LinkedList <>();
59
+ for (String hostUrl : builder .hostUrls ) {
60
+ // Remove the trailing "/" from the hostUrl if present
61
+ String baseUrl =
62
+ String .format ("%s/%s" , hostUrl .replaceAll ("/$" , "" ), builder .version .getApiNamespace ());
63
+ baseUrls .add (baseUrl );
64
+ }
70
65
71
- CloseableHttpClient httpclient = initHttpClient (builder );
66
+ RestClientConf conf = new RestClientConf ();
67
+ conf .setConnectTimeout (builder .connectTimeout );
68
+ conf .setSocketTimeout (builder .socketTimeout );
69
+ conf .setMaxAttempts (builder .maxAttempts );
70
+ conf .setAttemptWaitTime (builder .attemptWaitTime );
72
71
73
- this .httpClient = new RestClient ( baseUrl , httpclient );
72
+ this .httpClient = RetryableRestClient . getRestClient ( baseUrls , conf );
74
73
75
74
switch (builder .authHeaderMethod ) {
76
75
case BASIC :
@@ -94,42 +93,25 @@ public String getAuthHeader() {
94
93
return authHeaderGenerator .generateAuthHeader ();
95
94
}
96
95
97
- public RestClient getHttpClient () {
96
+ public IRestClient getHttpClient () {
98
97
return httpClient ;
99
98
}
100
99
101
- private CloseableHttpClient initHttpClient (Builder builder ) {
102
- RequestConfig requestConfig =
103
- RequestConfig .custom ()
104
- .setSocketTimeout (builder .socketTimeout )
105
- .setConnectTimeout (builder .connectTimeout )
106
- .build ();
107
- SSLConnectionSocketFactory sslSocketFactory ;
108
- try {
109
- TrustStrategy acceptingTrustStrategy = (cert , authType ) -> true ;
110
- SSLContext sslContext =
111
- SSLContexts .custom ().loadTrustMaterial (null , acceptingTrustStrategy ).build ();
112
- sslSocketFactory = new SSLConnectionSocketFactory (sslContext , NoopHostnameVerifier .INSTANCE );
113
- } catch (Exception e ) {
114
- LOG .error ("Error: " , e );
115
- throw new RuntimeException (e );
116
- }
117
-
118
- CloseableHttpClient httpclient =
119
- HttpClientBuilder .create ()
120
- .setDefaultRequestConfig (requestConfig )
121
- .setSSLSocketFactory (sslSocketFactory )
122
- .build ();
123
- return httpclient ;
124
- }
125
-
126
100
public static Builder builder (String hostUrl ) {
127
101
return new Builder (hostUrl );
128
102
}
129
103
104
+ public static Builder builder (String ... hostUrls ) {
105
+ return new Builder (Arrays .asList (hostUrls ));
106
+ }
107
+
108
+ public static Builder builder (List <String > hostUrls ) {
109
+ return new Builder (hostUrls );
110
+ }
111
+
130
112
public static class Builder {
131
113
132
- private String hostUrl ;
114
+ private List < String > hostUrls ;
133
115
134
116
private String spnegoHost ;
135
117
@@ -147,8 +129,23 @@ public static class Builder {
147
129
148
130
private int connectTimeout = 3000 ;
149
131
132
+ private int maxAttempts = 3 ;
133
+
134
+ private int attemptWaitTime = 3000 ;
135
+
150
136
public Builder (String hostUrl ) {
151
- this .hostUrl = hostUrl ;
137
+ if (StringUtils .isBlank (hostUrl )) {
138
+ throw new IllegalArgumentException ("hostUrl cannot be blank." );
139
+ }
140
+ this .hostUrls = new LinkedList <>();
141
+ this .hostUrls .add (hostUrl );
142
+ }
143
+
144
+ public Builder (List <String > hostUrls ) {
145
+ if (hostUrls .isEmpty ()) {
146
+ throw new IllegalArgumentException ("hostUrls cannot be blank." );
147
+ }
148
+ this .hostUrls = hostUrls ;
152
149
}
153
150
154
151
public Builder spnegoHost (String host ) {
@@ -193,16 +190,27 @@ public Builder connectionTimeout(int connectTimeout) {
193
190
return this ;
194
191
}
195
192
196
- public KyuubiRestClient build () {
197
- if (StringUtils .isBlank (hostUrl )) {
198
- throw new IllegalArgumentException ("hostUrl cannot be blank." );
199
- }
193
+ public Builder maxAttempts (int maxAttempts ) {
194
+ this .maxAttempts = maxAttempts ;
195
+ return this ;
196
+ }
197
+
198
+ public Builder attemptWaitTime (int attemptWaitTime ) {
199
+ this .attemptWaitTime = attemptWaitTime ;
200
+ return this ;
201
+ }
200
202
203
+ public KyuubiRestClient build () {
201
204
if (authHeaderMethod == AuthHeaderMethod .SPNEGO && StringUtils .isBlank (spnegoHost )) {
202
- try {
203
- this .spnegoHost = new URI (hostUrl ).getHost ();
204
- } catch (Exception e ) {
205
+ if (hostUrls .size () > 1 ) {
205
206
throw new IllegalArgumentException ("spnegoHost is invalid." );
207
+ } else {
208
+ // follow the behavior of curl, use host url by default
209
+ try {
210
+ this .spnegoHost = new URI (hostUrls .get (0 )).getHost ();
211
+ } catch (Exception e ) {
212
+ throw new IllegalArgumentException ("spnegoHost is invalid." , e );
213
+ }
206
214
}
207
215
}
208
216
return new KyuubiRestClient (this );
0 commit comments