88import io .harness .cf .client .dto .Claim ;
99import io .harness .cf .client .logger .LogUtil ;
1010import io .harness .cf .model .*;
11- import java .lang . ref . WeakReference ;
11+ import java .io . IOException ;
1212import java .nio .charset .StandardCharsets ;
1313import java .util .*;
1414import lombok .NonNull ;
1515import lombok .extern .slf4j .Slf4j ;
16+ import okhttp3 .Interceptor ;
1617import okhttp3 .Request ;
1718import okhttp3 .Response ;
18- import okhttp3 .internal .Util ;
1919import org .slf4j .MDC ;
2020
2121@ Slf4j
@@ -25,8 +25,6 @@ public class HarnessConnector implements Connector, AutoCloseable {
2525 private final MetricsApi metricsApi ;
2626 private final String apiKey ;
2727 private final HarnessConfig options ;
28- private WeakReference <Response > responseReference ;
29- private WeakReference <Response > metricsResponseReference ;
3028
3129 private String token ;
3230 private String environment ;
@@ -48,12 +46,12 @@ public HarnessConnector(@NonNull String apiKey) {
4846 public HarnessConnector (@ NonNull final String apiKey , @ NonNull final HarnessConfig options ) {
4947 this .apiKey = apiKey ;
5048 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 ));
5351 log .info ("Connector initialized, with options " + options );
5452 }
5553
56- protected ApiClient makeApiClient () {
54+ ApiClient makeApiClient (int retryBackOfDelay ) {
5755 final ApiClient apiClient = new ApiClient ();
5856 apiClient .setBasePath (options .getConfigUrl ());
5957 apiClient .setConnectTimeout (options .getConnectionTimeout ());
@@ -66,45 +64,28 @@ protected ApiClient makeApiClient() {
6664 apiClient
6765 .getHttpClient ()
6866 .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 ))
10269 .build ());
10370 log .info ("apiClient definition complete" );
10471 return apiClient ;
10572 }
10673
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 ) {
10889 final int maxTimeout = 30 * 60 * 1000 ;
10990 final ApiClient apiClient = new ApiClient ();
11091 apiClient .setBasePath (options .getEventUrl ());
@@ -117,41 +98,21 @@ protected ApiClient makeMetricsApiClient() {
11798 apiClient
11899 .getHttpClient ()
119100 .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 ))
150103 .build ());
151104 log .info ("metricsApiClient definition complete" );
152105 return apiClient ;
153106 }
154107
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+
155116 protected String getRequestID () {
156117 String requestId = MDC .get (REQUEST_ID_KEY );
157118 if (requestId == null ) {
@@ -176,10 +137,11 @@ public String authenticate() throws ConnectorException {
176137 if (apiException .getCode () == 401 || apiException .getCode () == 403 ) {
177138 String errorMsg = String .format ("Invalid apiKey %s. SDK will serve default values" , apiKey );
178139 log .error (errorMsg );
179- throw new ConnectorException (errorMsg );
140+ throw new ConnectorException (errorMsg , apiException . getCode (), apiException . getMessage () );
180141 }
181142 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 ());
183145 } catch (Throwable ex ) {
184146 log .error ("Unexpected exception" , ex );
185147 throw ex ;
@@ -224,15 +186,17 @@ public List<FeatureConfig> getFlags() throws ConnectorException {
224186 featureConfig .size (),
225187 this .environment ,
226188 this .cluster );
227- log .info ("Got the following features: " + featureConfig );
189+ if (log .isTraceEnabled ()) {
190+ log .trace ("Got the following features: " + featureConfig );
191+ }
228192 return featureConfig ;
229193 } catch (ApiException e ) {
230194 log .error (
231195 "Exception was raised while fetching the flags on env {} and cluster {}" ,
232196 this .environment ,
233197 this .cluster ,
234198 e );
235- throw new ConnectorException (e .getMessage ());
199+ throw new ConnectorException (e .getMessage (), e . getCode (), e . getMessage () );
236200 } finally {
237201 MDC .remove (REQUEST_ID_KEY );
238202 }
@@ -260,7 +224,7 @@ public FeatureConfig getFlag(@NonNull final String identifier) throws ConnectorE
260224 this .environment ,
261225 this .cluster ,
262226 e );
263- throw new ConnectorException (e .getMessage ());
227+ throw new ConnectorException (e .getMessage (), e . getCode (), e . getMessage () );
264228 } finally {
265229 MDC .remove (REQUEST_ID_KEY );
266230 }
@@ -283,11 +247,13 @@ public List<Segment> getSegments() throws ConnectorException {
283247 return allSegments ;
284248 } catch (ApiException e ) {
285249 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={} " ,
287251 this .environment ,
288252 this .cluster ,
253+ e .getCode (),
254+ e .getMessage (),
289255 e );
290- throw new ConnectorException (e .getMessage ());
256+ throw new ConnectorException (e .getMessage (), e . getCode (), e . getMessage () );
291257 } finally {
292258 MDC .remove (REQUEST_ID_KEY );
293259 }
@@ -317,7 +283,7 @@ public Segment getSegment(@NonNull final String identifier) throws ConnectorExce
317283 this .environment ,
318284 this .cluster ,
319285 e );
320- throw new ConnectorException (e .getMessage ());
286+ throw new ConnectorException (e .getMessage (), e . getCode (), e . getMessage () );
321287 } finally {
322288 MDC .remove (REQUEST_ID_KEY );
323289 }
@@ -340,7 +306,7 @@ public void postMetrics(@NonNull final Metrics metrics) throws ConnectorExceptio
340306 this .environment ,
341307 this .cluster ,
342308 e );
343- throw new ConnectorException (e .getMessage ());
309+ throw new ConnectorException (e .getMessage (), e . getCode (), e . getMessage () );
344310 } finally {
345311 MDC .remove (REQUEST_ID_KEY );
346312 }
@@ -365,28 +331,29 @@ public Service stream(@NonNull final Updater updater) {
365331
366332 @ Override
367333 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" );
383335 api .getApiClient ().getHttpClient ().connectionPool ().evictAll ();
384- log .info ("All apiClient connections evicted" );
336+ log .debug ("All apiClient connections evicted" );
385337 metricsApi .getApiClient ().getHttpClient ().connectionPool ().evictAll ();
386- log .info ("All metricsApiClient connections evicted" );
338+ log .debug ("All metricsApiClient connections evicted" );
387339 if (eventSource != null ) {
388340 eventSource .close ();
389341 }
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 );
391358 }
392359}
0 commit comments