-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathOctopusClient.java
More file actions
95 lines (86 loc) · 4.06 KB
/
OctopusClient.java
File metadata and controls
95 lines (86 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package com.octopus.openfeature.provider;
import com.fasterxml.jackson.core.type.TypeReference;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Optional;
class OctopusClient {
private final OctopusConfiguration config;
private static final System.Logger logger = System.getLogger(OctopusClient.class.getName());
private static final int StatusCodeNotFound = 404;
OctopusClient(OctopusConfiguration config){
this.config = config;
}
Boolean haveFeatureTogglesChanged(byte[] contentHash)
{
if (contentHash.length == 0) { return true; }
URI checkURI = getCheckURI();
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.GET()
.uri(checkURI)
.header("Authorization", String.format("Bearer %s", config.getClientIdentifier()))
.build();
try {
HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
FeatureToggleCheckResponse checkResponse = OctopusObjectMapper.INSTANCE.readValue(httpResponse.body(), FeatureToggleCheckResponse.class);
return !Arrays.equals(checkResponse.contentHash, contentHash);
} catch (Exception e) {
logger.log(System.Logger.Level.WARNING, String.format("Unable to query Octopus Feature Toggle service. URI: %s", checkURI.toString()), e);
// Use cached toggles
return false;
}
}
FeatureToggles getFeatureToggleEvaluationManifest()
{
URI manifestURI = getManifestURI();
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.GET()
.uri(manifestURI)
.header("Authorization", String.format("Bearer %s", config.getClientIdentifier()))
.build();
try {
HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
if (httpResponse.statusCode() == StatusCodeNotFound) {
logger.log(System.Logger.Level.WARNING,String.format("Failed to retrieve feature toggles for client identifier %s from %s", config.getClientIdentifier(), manifestURI.toString()));
return null;
}
Optional<String> contentHashHeader = httpResponse.headers().firstValue("ContentHash");
if (contentHashHeader.isEmpty()) {
logger.log(System.Logger.Level.WARNING,String.format("Feature toggle response from %s did not contain expected ContentHash header", manifestURI.toString()));
return null;
}
var evaluations = OctopusObjectMapper.INSTANCE.readValue(httpResponse.body(), new TypeReference<List<FeatureToggleEvaluation>>(){});
return new FeatureToggles(evaluations, Base64.getDecoder().decode(contentHashHeader.get()));
} catch (Exception e) {
logger.log(System.Logger.Level.WARNING, "Unable to query Octopus Feature Toggle service", e);
return null;
}
}
private URI getCheckURI() {
try {
return new URL(config.getServerUri().toURL(), "/api/featuretoggles/check/v3/").toURI();
} catch (MalformedURLException | URISyntaxException ignored) // we know this URL is well-formed
{ }
return null;
}
private URI getManifestURI() {
try {
return new URL(config.getServerUri().toURL(), "/api/toggles/evaluations/v3/").toURI();
} catch (MalformedURLException | URISyntaxException ignored) // we know this URL is well-formed
{ }
return null;
}
// This class needs to be static to allow deserialization
private static class FeatureToggleCheckResponse {
public byte[] contentHash;
}
}