4
4
import io .split .client .dtos .SegmentChange ;
5
5
import io .split .client .utils .Json ;
6
6
import io .split .client .utils .Utils ;
7
+ import io .split .engine .common .FetchOptions ;
7
8
import io .split .engine .metrics .Metrics ;
8
9
import io .split .engine .segments .SegmentChangeFetcher ;
10
+ import io .split .telemetry .domain .enums .HTTPLatenciesEnum ;
11
+ import io .split .telemetry .domain .enums .LastSynchronizationRecordsEnum ;
12
+ import io .split .telemetry .domain .enums .ResourceEnum ;
13
+ import io .split .telemetry .storage .TelemetryRuntimeProducer ;
9
14
import org .apache .hc .client5 .http .classic .methods .HttpGet ;
10
15
import org .apache .hc .client5 .http .impl .classic .CloseableHttpClient ;
11
16
import org .apache .hc .client5 .http .impl .classic .CloseableHttpResponse ;
17
+ import org .apache .hc .core5 .http .HttpStatus ;
18
+ import org .apache .hc .core5 .http .Header ;
12
19
import org .apache .hc .core5 .http .io .entity .EntityUtils ;
13
20
import org .apache .hc .core5 .net .URIBuilder ;
14
21
import org .slf4j .Logger ;
17
24
import java .net .URI ;
18
25
import java .net .URISyntaxException ;
19
26
import java .nio .charset .StandardCharsets ;
27
+ import java .util .Arrays ;
28
+ import java .util .stream .Collectors ;
20
29
21
30
import static com .google .common .base .Preconditions .checkNotNull ;
22
31
@@ -27,57 +36,72 @@ public final class HttpSegmentChangeFetcher implements SegmentChangeFetcher {
27
36
private static final Logger _log = LoggerFactory .getLogger (HttpSegmentChangeFetcher .class );
28
37
29
38
private static final String SINCE = "since" ;
39
+ private static final String TILL = "till" ;
30
40
private static final String PREFIX = "segmentChangeFetcher" ;
31
- private static final String NAME_CACHE = "Cache-Control" ;
32
- private static final String VALUE_CACHE = "no-cache" ;
41
+ private static final String CACHE_CONTROL_HEADER_NAME = "Cache-Control" ;
42
+ private static final String CACHE_CONTROL_HEADER_VALUE = "no-cache" ;
43
+
44
+ private static final String HEADER_FASTLY_DEBUG_NAME = "Fastly-Debug" ;
45
+ private static final String HEADER_FASTLY_DEBUG_VALUE = "1" ;
33
46
34
47
private final CloseableHttpClient _client ;
35
48
private final URI _target ;
36
- private final Metrics _metrics ;
37
-
38
- public static HttpSegmentChangeFetcher create (CloseableHttpClient client , URI root ) throws URISyntaxException {
39
- return create (client , root , new Metrics .NoopMetrics ());
40
- }
49
+ private final TelemetryRuntimeProducer _telemetryRuntimeProducer ;
41
50
42
- public static HttpSegmentChangeFetcher create (CloseableHttpClient client , URI root , Metrics metrics ) throws URISyntaxException {
43
- return new HttpSegmentChangeFetcher (client , Utils .appendPath (root , "api/segmentChanges" ), metrics );
51
+ public static HttpSegmentChangeFetcher create (CloseableHttpClient client , URI root , TelemetryRuntimeProducer telemetryRuntimeProducer ) throws URISyntaxException {
52
+ return new HttpSegmentChangeFetcher (client , Utils .appendPath (root , "api/segmentChanges" ), telemetryRuntimeProducer );
44
53
}
45
54
46
- private HttpSegmentChangeFetcher (CloseableHttpClient client , URI uri , Metrics metrics ) {
55
+ private HttpSegmentChangeFetcher (CloseableHttpClient client , URI uri , TelemetryRuntimeProducer telemetryRuntimeProducer ) {
47
56
_client = client ;
48
57
_target = uri ;
49
- _metrics = metrics ;
50
58
checkNotNull (_target );
59
+ _telemetryRuntimeProducer = checkNotNull (telemetryRuntimeProducer );
51
60
}
52
61
53
62
@ Override
54
- public SegmentChange fetch (String segmentName , long since , boolean addCacheHeader ) {
63
+ public SegmentChange fetch (String segmentName , long since , FetchOptions options ) {
55
64
long start = System .currentTimeMillis ();
56
65
57
66
CloseableHttpResponse response = null ;
58
67
59
68
try {
60
69
String path = _target .getPath () + "/" + segmentName ;
61
- URI uri = new URIBuilder (_target ).setPath (path ).addParameter (SINCE , "" + since ).build ();
70
+ URIBuilder uriBuilder = new URIBuilder (_target )
71
+ .setPath (path )
72
+ .addParameter (SINCE , "" + since );
73
+ if (options .hasCustomCN ()) {
74
+ uriBuilder .addParameter (TILL , "" + options .targetCN ());
75
+ }
76
+
77
+ URI uri = uriBuilder .build ();
62
78
HttpGet request = new HttpGet (uri );
63
- if (addCacheHeader ) {
64
- request .setHeader (NAME_CACHE , VALUE_CACHE );
79
+
80
+ if (options .cacheControlHeadersEnabled ()) {
81
+ request .setHeader (CACHE_CONTROL_HEADER_NAME , CACHE_CONTROL_HEADER_VALUE );
82
+ }
83
+
84
+ if (options .fastlyDebugHeaderEnabled ()) {
85
+ request .addHeader (HEADER_FASTLY_DEBUG_NAME , HEADER_FASTLY_DEBUG_VALUE );
65
86
}
87
+
66
88
response = _client .execute (request );
89
+ options .handleResponseHeaders (Arrays .stream (response .getHeaders ())
90
+ .collect (Collectors .toMap (Header ::getName , Header ::getValue )));
67
91
68
92
int statusCode = response .getCode ();
69
93
70
- if (statusCode < 200 || statusCode >= 300 ) {
94
+ if (statusCode < HttpStatus .SC_OK || statusCode >= HttpStatus .SC_MULTIPLE_CHOICES ) {
95
+ _telemetryRuntimeProducer .recordSyncError (ResourceEnum .SEGMENT_SYNC , statusCode );
71
96
_log .error ("Response status was: " + statusCode );
72
- if (statusCode == 403 ) {
97
+ if (statusCode == HttpStatus . SC_FORBIDDEN ) {
73
98
_log .error ("factory instantiation: you passed a browser type api_key, " +
74
99
"please grab an api key from the Split console that is of type sdk" );
75
100
}
76
- _metrics .count (PREFIX + ".status." + statusCode , 1 );
77
101
throw new IllegalStateException ("Could not retrieve segment changes for " + segmentName + "; http return code " + statusCode );
78
102
}
79
103
80
-
104
+ _telemetryRuntimeProducer . recordSuccessfulSync ( LastSynchronizationRecordsEnum . SEGMENTS , System . currentTimeMillis ());
81
105
82
106
String json = EntityUtils .toString (response .getEntity (), StandardCharsets .UTF_8 );
83
107
if (_log .isDebugEnabled ()) {
@@ -86,11 +110,10 @@ public SegmentChange fetch(String segmentName, long since, boolean addCacheHeade
86
110
87
111
return Json .fromJson (json , SegmentChange .class );
88
112
} catch (Throwable t ) {
89
- _metrics .count (PREFIX + ".exception" , 1 );
90
113
throw new IllegalStateException ("Problem fetching segmentChanges: " + t .getMessage (), t );
91
114
} finally {
115
+ _telemetryRuntimeProducer .recordSyncLatency (HTTPLatenciesEnum .SEGMENTS , System .currentTimeMillis ()-start );
92
116
Utils .forceClose (response );
93
- _metrics .time (PREFIX + ".time" , System .currentTimeMillis () - start );
94
117
}
95
118
96
119
0 commit comments