8
8
import io .harness .cf .client .dto .Claim ;
9
9
import io .harness .cf .client .logger .LogUtil ;
10
10
import io .harness .cf .model .*;
11
- import java .lang . ref . WeakReference ;
11
+ import java .io . IOException ;
12
12
import java .nio .charset .StandardCharsets ;
13
13
import java .util .*;
14
14
import lombok .NonNull ;
15
15
import lombok .extern .slf4j .Slf4j ;
16
+ import okhttp3 .Interceptor ;
16
17
import okhttp3 .Request ;
17
18
import okhttp3 .Response ;
18
- import okhttp3 .internal .Util ;
19
19
import org .slf4j .MDC ;
20
20
21
21
@ Slf4j
@@ -25,8 +25,6 @@ public class HarnessConnector implements Connector, AutoCloseable {
25
25
private final MetricsApi metricsApi ;
26
26
private final String apiKey ;
27
27
private final HarnessConfig options ;
28
- private WeakReference <Response > responseReference ;
29
- private WeakReference <Response > metricsResponseReference ;
30
28
31
29
private String token ;
32
30
private String environment ;
@@ -48,12 +46,12 @@ public HarnessConnector(@NonNull String apiKey) {
48
46
public HarnessConnector (@ NonNull final String apiKey , @ NonNull final HarnessConfig options ) {
49
47
this .apiKey = apiKey ;
50
48
this .options = options ;
51
- this .api = new ClientApi (makeApiClient ());
52
- this .metricsApi = new MetricsApi (makeMetricsApiClient ());
49
+ this .api = new ClientApi (makeApiClient (2000 ));
50
+ this .metricsApi = new MetricsApi (makeMetricsApiClient (2000 ));
53
51
log .info ("Connector initialized, with options " + options );
54
52
}
55
53
56
- protected ApiClient makeApiClient () {
54
+ ApiClient makeApiClient (int retryBackOfDelay ) {
57
55
final ApiClient apiClient = new ApiClient ();
58
56
apiClient .setBasePath (options .getConfigUrl ());
59
57
apiClient .setConnectTimeout (options .getConnectionTimeout ());
@@ -66,45 +64,28 @@ protected ApiClient makeApiClient() {
66
64
apiClient
67
65
.getHttpClient ()
68
66
.newBuilder ()
69
- .addInterceptor (
70
- chain -> {
71
- final Request request =
72
- chain
73
- .request ()
74
- .newBuilder ()
75
- .addHeader ("X-Request-ID" , getRequestID ())
76
- .build ();
77
- log .info ("interceptor: requesting url {}" , request .url ().url ());
78
- Response response ;
79
- if (responseReference != null ) {
80
- response = responseReference .get ();
81
- if (response != null ) {
82
- if (response .isSuccessful ()) {
83
- log .debug (
84
- "interceptor: closing the response url={}" , response .request ().url ());
85
- } else {
86
- log .warn (
87
- "interceptor: closing the faulty response url={}" ,
88
- response .request ().url ());
89
- }
90
- Util .closeQuietly (response );
91
- }
92
- }
93
- response = chain .proceed (request );
94
- responseReference = new WeakReference <>(response );
95
- if (response .code () == 403 && onUnauthorized != null ) {
96
- onUnauthorized .run ();
97
- }
98
-
99
- return response ;
100
- })
101
- .addInterceptor (new RetryInterceptor (3 , 2000 ))
67
+ .addInterceptor (this ::interceptor )
68
+ .addInterceptor (new RetryInterceptor (3 , retryBackOfDelay ))
102
69
.build ());
103
70
log .info ("apiClient definition complete" );
104
71
return apiClient ;
105
72
}
106
73
107
- protected ApiClient makeMetricsApiClient () {
74
+ private Response interceptor (Interceptor .Chain chain ) throws IOException {
75
+ final Request request =
76
+ chain .request ().newBuilder ().addHeader ("X-Request-ID" , getRequestID ()).build ();
77
+ log .info ("interceptor: requesting url {}" , request .url ().url ());
78
+
79
+ Response response = chain .proceed (request );
80
+
81
+ if (response .code () == 403 && onUnauthorized != null ) {
82
+ onUnauthorized .run ();
83
+ }
84
+
85
+ return response ;
86
+ }
87
+
88
+ ApiClient makeMetricsApiClient (int retryBackoffDelay ) {
108
89
final int maxTimeout = 30 * 60 * 1000 ;
109
90
final ApiClient apiClient = new ApiClient ();
110
91
apiClient .setBasePath (options .getEventUrl ());
@@ -117,41 +98,21 @@ protected ApiClient makeMetricsApiClient() {
117
98
apiClient
118
99
.getHttpClient ()
119
100
.newBuilder ()
120
- .addInterceptor (
121
- chain -> {
122
- final Request request =
123
- chain
124
- .request ()
125
- .newBuilder ()
126
- .addHeader ("X-Request-ID" , getRequestID ())
127
- .build ();
128
- log .info ("metrics interceptor: requesting url {}" , request .url ().url ());
129
- Response response ;
130
- if (metricsResponseReference != null ) {
131
- response = metricsResponseReference .get ();
132
- if (response != null ) {
133
- if (response .isSuccessful ()) {
134
- log .debug (
135
- "metrics interceptor: closing the response url={}" ,
136
- response .request ().url ());
137
- } else {
138
- log .warn (
139
- "metrics interceptor: closing the faulty response url={}" ,
140
- response .request ().url ());
141
- }
142
- Util .closeQuietly (response );
143
- }
144
- }
145
- response = chain .proceed (request );
146
- metricsResponseReference = new WeakReference <>(response );
147
- return response ;
148
- })
149
- .addInterceptor (new RetryInterceptor (3 , 2000 ))
101
+ .addInterceptor (this ::metricsInterceptor )
102
+ .addInterceptor (new RetryInterceptor (3 , retryBackoffDelay ))
150
103
.build ());
151
104
log .info ("metricsApiClient definition complete" );
152
105
return apiClient ;
153
106
}
154
107
108
+ private Response metricsInterceptor (Interceptor .Chain chain ) throws IOException {
109
+ final Request request =
110
+ chain .request ().newBuilder ().addHeader ("X-Request-ID" , getRequestID ()).build ();
111
+ log .info ("metrics interceptor: requesting url {}" , request .url ().url ());
112
+
113
+ return chain .proceed (request );
114
+ }
115
+
155
116
protected String getRequestID () {
156
117
String requestId = MDC .get (REQUEST_ID_KEY );
157
118
if (requestId == null ) {
@@ -176,10 +137,11 @@ public String authenticate() throws ConnectorException {
176
137
if (apiException .getCode () == 401 || apiException .getCode () == 403 ) {
177
138
String errorMsg = String .format ("Invalid apiKey %s. SDK will serve default values" , apiKey );
178
139
log .error (errorMsg );
179
- throw new ConnectorException (errorMsg );
140
+ throw new ConnectorException (errorMsg , apiException . getCode (), apiException . getMessage () );
180
141
}
181
142
log .error ("Failed to get auth token" , apiException );
182
- throw new ConnectorException (apiException .getMessage ());
143
+ throw new ConnectorException (
144
+ apiException .getMessage (), apiException .getCode (), apiException .getMessage ());
183
145
} catch (Throwable ex ) {
184
146
log .error ("Unexpected exception" , ex );
185
147
throw ex ;
@@ -224,15 +186,17 @@ public List<FeatureConfig> getFlags() throws ConnectorException {
224
186
featureConfig .size (),
225
187
this .environment ,
226
188
this .cluster );
227
- log .info ("Got the following features: " + featureConfig );
189
+ if (log .isTraceEnabled ()) {
190
+ log .trace ("Got the following features: " + featureConfig );
191
+ }
228
192
return featureConfig ;
229
193
} catch (ApiException e ) {
230
194
log .error (
231
195
"Exception was raised while fetching the flags on env {} and cluster {}" ,
232
196
this .environment ,
233
197
this .cluster ,
234
198
e );
235
- throw new ConnectorException (e .getMessage ());
199
+ throw new ConnectorException (e .getMessage (), e . getCode (), e . getMessage () );
236
200
} finally {
237
201
MDC .remove (REQUEST_ID_KEY );
238
202
}
@@ -260,7 +224,7 @@ public FeatureConfig getFlag(@NonNull final String identifier) throws ConnectorE
260
224
this .environment ,
261
225
this .cluster ,
262
226
e );
263
- throw new ConnectorException (e .getMessage ());
227
+ throw new ConnectorException (e .getMessage (), e . getCode (), e . getMessage () );
264
228
} finally {
265
229
MDC .remove (REQUEST_ID_KEY );
266
230
}
@@ -283,11 +247,13 @@ public List<Segment> getSegments() throws ConnectorException {
283
247
return allSegments ;
284
248
} catch (ApiException e ) {
285
249
log .error (
286
- "Exception was raised while fetching the target groups on env {} and cluster {}" ,
250
+ "Exception was raised while fetching the target groups on env {} and cluster {} : httpCode={} message={} " ,
287
251
this .environment ,
288
252
this .cluster ,
253
+ e .getCode (),
254
+ e .getMessage (),
289
255
e );
290
- throw new ConnectorException (e .getMessage ());
256
+ throw new ConnectorException (e .getMessage (), e . getCode (), e . getMessage () );
291
257
} finally {
292
258
MDC .remove (REQUEST_ID_KEY );
293
259
}
@@ -317,7 +283,7 @@ public Segment getSegment(@NonNull final String identifier) throws ConnectorExce
317
283
this .environment ,
318
284
this .cluster ,
319
285
e );
320
- throw new ConnectorException (e .getMessage ());
286
+ throw new ConnectorException (e .getMessage (), e . getCode (), e . getMessage () );
321
287
} finally {
322
288
MDC .remove (REQUEST_ID_KEY );
323
289
}
@@ -340,7 +306,7 @@ public void postMetrics(@NonNull final Metrics metrics) throws ConnectorExceptio
340
306
this .environment ,
341
307
this .cluster ,
342
308
e );
343
- throw new ConnectorException (e .getMessage ());
309
+ throw new ConnectorException (e .getMessage (), e . getCode (), e . getMessage () );
344
310
} finally {
345
311
MDC .remove (REQUEST_ID_KEY );
346
312
}
@@ -365,28 +331,29 @@ public Service stream(@NonNull final Updater updater) {
365
331
366
332
@ Override
367
333
public void close () {
368
- log .info ("closing connector" );
369
- if (responseReference != null ) {
370
- final Response response = responseReference .get ();
371
- if (response != null ) {
372
- Util .closeQuietly (response );
373
- }
374
- responseReference = null ;
375
- }
376
- if (metricsResponseReference != null ) {
377
- final Response response = metricsResponseReference .get ();
378
- if (response != null ) {
379
- Util .closeQuietly (response );
380
- }
381
- metricsResponseReference = null ;
382
- }
334
+ log .debug ("closing connector" );
383
335
api .getApiClient ().getHttpClient ().connectionPool ().evictAll ();
384
- log .info ("All apiClient connections evicted" );
336
+ log .debug ("All apiClient connections evicted" );
385
337
metricsApi .getApiClient ().getHttpClient ().connectionPool ().evictAll ();
386
- log .info ("All metricsApiClient connections evicted" );
338
+ log .debug ("All metricsApiClient connections evicted" );
387
339
if (eventSource != null ) {
388
340
eventSource .close ();
389
341
}
390
- log .info ("connector closed!" );
342
+ log .debug ("connector closed!" );
343
+ }
344
+
345
+ /* package private - should not be used outside of tests */
346
+
347
+ HarnessConnector (
348
+ @ NonNull final String apiKey , @ NonNull final HarnessConfig options , int retryBackOffDelay ) {
349
+ this .apiKey = apiKey ;
350
+ this .options = options ;
351
+ this .api = new ClientApi (makeApiClient (retryBackOffDelay ));
352
+ this .metricsApi = new MetricsApi (makeMetricsApiClient (retryBackOffDelay ));
353
+ log .info (
354
+ "Connector initialized, with options "
355
+ + options
356
+ + " and retry backoff delay "
357
+ + retryBackOffDelay );
391
358
}
392
359
}
0 commit comments