1
1
package com .coveo .pushapiclient ;
2
2
3
+ import io .github .resilience4j .core .IntervalFunction ;
4
+ import io .github .resilience4j .retry .Retry ;
5
+ import io .github .resilience4j .retry .RetryConfig ;
3
6
import java .io .IOException ;
4
7
import java .net .URI ;
5
8
import java .net .http .HttpClient ;
6
9
import java .net .http .HttpRequest ;
7
10
import java .net .http .HttpRequest .BodyPublisher ;
8
11
import java .net .http .HttpResponse ;
12
+ import java .util .function .Function ;
9
13
import org .apache .logging .log4j .LogManager ;
10
14
import org .apache .logging .log4j .Logger ;
11
15
12
- // TODO: LENS-934 - Support throttling
13
16
class ApiCore {
14
17
private final HttpClient httpClient ;
15
18
private final Logger logger ;
19
+ private final BackoffOptions options ;
16
20
17
21
public ApiCore () {
18
- this .httpClient = HttpClient .newHttpClient ();
19
- this .logger = LogManager .getLogger (ApiCore .class );
22
+ this (HttpClient .newHttpClient (), LogManager .getLogger (ApiCore .class ));
20
23
}
21
24
22
25
public ApiCore (HttpClient httpClient , Logger logger ) {
26
+ this (httpClient , logger , new BackoffOptionsBuilder ().build ());
27
+ }
28
+
29
+ public ApiCore (HttpClient httpClient , Logger logger , BackoffOptions options ) {
23
30
this .httpClient = httpClient ;
24
31
this .logger = logger ;
32
+ this .options = options ;
33
+ }
34
+
35
+ public HttpResponse <String > callApiWithRetries (HttpRequest request )
36
+ throws IOException , InterruptedException {
37
+ IntervalFunction intervalFn =
38
+ IntervalFunction .ofExponentialRandomBackoff (
39
+ this .options .getRetryAfter (), this .options .getTimeMultiple ());
40
+
41
+ RetryConfig retryConfig =
42
+ RetryConfig .<HttpResponse <String >>custom ()
43
+ .maxAttempts (this .options .getMaxRetries ())
44
+ .intervalFunction (intervalFn )
45
+ .retryOnResult (response -> response != null && response .statusCode () == 429 )
46
+ .build ();
47
+
48
+ Retry retry = Retry .of ("platformRequest" , retryConfig );
49
+
50
+ Function <HttpRequest , HttpResponse <String >> retryRequestFn =
51
+ Retry .decorateFunction (retry , req -> sendRequest (req ));
52
+
53
+ return retryRequestFn .apply (request );
54
+ }
55
+
56
+ public HttpResponse <String > sendRequest (HttpRequest request ) {
57
+ String uri = request .uri ().toString ();
58
+ String reqMethod = request .method ();
59
+ this .logger .debug (reqMethod + " " + uri );
60
+ try {
61
+ HttpResponse <String > response =
62
+ this .httpClient .send (request , HttpResponse .BodyHandlers .ofString ());
63
+ this .logResponse (response );
64
+ return response ;
65
+ } catch (IOException | InterruptedException e ) {
66
+ throw new Error (e .getMessage ());
67
+ }
25
68
}
26
69
27
70
public HttpResponse <String > post (URI uri , String [] headers )
@@ -31,42 +74,30 @@ public HttpResponse<String> post(URI uri, String[] headers)
31
74
32
75
public HttpResponse <String > post (URI uri , String [] headers , BodyPublisher body )
33
76
throws IOException , InterruptedException {
34
- this .logger .debug ("POST " + uri );
35
77
HttpRequest request = HttpRequest .newBuilder ().headers (headers ).uri (uri ).POST (body ).build ();
36
- HttpResponse <String > response =
37
- this .httpClient .send (request , HttpResponse .BodyHandlers .ofString ());
38
- this .logResponse (response );
78
+ HttpResponse <String > response = this .callApiWithRetries (request );
39
79
return response ;
40
80
}
41
81
42
82
public HttpResponse <String > put (URI uri , String [] headers , BodyPublisher body )
43
83
throws IOException , InterruptedException {
44
- this .logger .debug ("PUT " + uri );
45
84
HttpRequest request = HttpRequest .newBuilder ().headers (headers ).uri (uri ).PUT (body ).build ();
46
- HttpResponse <String > response =
47
- this .httpClient .send (request , HttpResponse .BodyHandlers .ofString ());
48
- this .logResponse (response );
85
+ HttpResponse <String > response = this .callApiWithRetries (request );
49
86
return response ;
50
87
}
51
88
52
89
public HttpResponse <String > delete (URI uri , String [] headers )
53
90
throws IOException , InterruptedException {
54
- this .logger .debug ("DELETE " + uri );
55
91
HttpRequest request = HttpRequest .newBuilder ().headers (headers ).uri (uri ).DELETE ().build ();
56
- HttpResponse <String > response =
57
- this .httpClient .send (request , HttpResponse .BodyHandlers .ofString ());
58
- this .logResponse (response );
92
+ HttpResponse <String > response = this .callApiWithRetries (request );
59
93
return response ;
60
94
}
61
95
62
96
public HttpResponse <String > delete (URI uri , String [] headers , BodyPublisher body )
63
97
throws IOException , InterruptedException {
64
- this .logger .debug ("DELETE " + uri );
65
98
HttpRequest request =
66
99
HttpRequest .newBuilder ().headers (headers ).uri (uri ).method ("DELETE" , body ).build ();
67
- HttpResponse <String > response =
68
- this .httpClient .send (request , HttpResponse .BodyHandlers .ofString ());
69
- this .logResponse (response );
100
+ HttpResponse <String > response = this .callApiWithRetries (request );
70
101
return response ;
71
102
}
72
103
0 commit comments