39
39
40
40
import static java .net .HttpURLConnection .HTTP_BAD_REQUEST ;
41
41
42
+ /**
43
+ * GoFeatureFlagProvider is the JAVA provider implementation for the feature flag solution GO Feature Flag.
44
+ */
42
45
public class GoFeatureFlagProvider implements FeatureProvider {
43
46
private static final String NAME = "GO Feature Flag Provider" ;
44
47
private static final ObjectMapper requestMapper = new ObjectMapper ();
@@ -48,7 +51,8 @@ public class GoFeatureFlagProvider implements FeatureProvider {
48
51
private OkHttpClient httpClient ;
49
52
50
53
/**
51
- * Constructor of the provider
54
+ * Constructor of the provider.
55
+ *
52
56
* @param options - options to configure the provider
53
57
* @throws InvalidOptions - if options are invalid
54
58
*/
@@ -77,7 +81,7 @@ private void validateInputOptions(GoFeatureFlagProviderOptions options) throws I
77
81
}
78
82
79
83
/**
80
- * initializeProvider is initializing the different class element used by the provider
84
+ * initializeProvider is initializing the different class element used by the provider.
81
85
*
82
86
* @param options - Options used while creating the provider
83
87
*/
@@ -113,32 +117,42 @@ public List<Hook> getProviderHooks() {
113
117
114
118
115
119
@ Override
116
- public ProviderEvaluation <Boolean > getBooleanEvaluation (String key , Boolean defaultValue , EvaluationContext evaluationContext ) {
120
+ public ProviderEvaluation <Boolean > getBooleanEvaluation (
121
+ String key , Boolean defaultValue , EvaluationContext evaluationContext
122
+ ) {
117
123
return resolveEvaluationGoFeatureFlagProxy (key , defaultValue , evaluationContext , Boolean .class );
118
124
}
119
125
120
126
@ Override
121
- public ProviderEvaluation <String > getStringEvaluation (String key , String defaultValue , EvaluationContext evaluationContext ) {
127
+ public ProviderEvaluation <String > getStringEvaluation (
128
+ String key , String defaultValue , EvaluationContext evaluationContext
129
+ ) {
122
130
return resolveEvaluationGoFeatureFlagProxy (key , defaultValue , evaluationContext , String .class );
123
131
}
124
132
125
133
@ Override
126
- public ProviderEvaluation <Integer > getIntegerEvaluation (String key , Integer defaultValue , EvaluationContext evaluationContext ) {
134
+ public ProviderEvaluation <Integer > getIntegerEvaluation (
135
+ String key , Integer defaultValue , EvaluationContext evaluationContext
136
+ ) {
127
137
return resolveEvaluationGoFeatureFlagProxy (key , defaultValue , evaluationContext , Integer .class );
128
138
}
129
139
130
140
@ Override
131
- public ProviderEvaluation <Double > getDoubleEvaluation (String key , Double defaultValue , EvaluationContext evaluationContext ) {
141
+ public ProviderEvaluation <Double > getDoubleEvaluation (
142
+ String key , Double defaultValue , EvaluationContext evaluationContext
143
+ ) {
132
144
return resolveEvaluationGoFeatureFlagProxy (key , defaultValue , evaluationContext , Double .class );
133
145
}
134
146
135
147
@ Override
136
- public ProviderEvaluation <Value > getObjectEvaluation (String key , Value defaultValue , EvaluationContext evaluationContext ) {
148
+ public ProviderEvaluation <Value > getObjectEvaluation (
149
+ String key , Value defaultValue , EvaluationContext evaluationContext
150
+ ) {
137
151
return resolveEvaluationGoFeatureFlagProxy (key , defaultValue , evaluationContext , Value .class );
138
152
}
139
153
140
154
/**
141
- * resolveEvaluationGoFeatureFlagProxy is calling the GO Feature Flag API to retrieve the flag value
155
+ * resolveEvaluationGoFeatureFlagProxy is calling the GO Feature Flag API to retrieve the flag value.
142
156
*
143
157
* @param key - name of the feature flag
144
158
* @param defaultValue - value used if something is not working as expected
@@ -147,7 +161,9 @@ public ProviderEvaluation<Value> getObjectEvaluation(String key, Value defaultVa
147
161
* @return a ProviderEvaluation that contains the open-feature response
148
162
* @throws OpenFeatureError - if an error happen
149
163
*/
150
- private <T > ProviderEvaluation <T > resolveEvaluationGoFeatureFlagProxy (String key , T defaultValue , EvaluationContext ctx , Class <? extends Object > expectedType ) throws OpenFeatureError {
164
+ private <T > ProviderEvaluation <T > resolveEvaluationGoFeatureFlagProxy (
165
+ String key , T defaultValue , EvaluationContext ctx , Class <? extends Object > expectedType )
166
+ throws OpenFeatureError {
151
167
try {
152
168
GoFeatureFlagUser user = GoFeatureFlagUser .fromEvaluationContext (ctx );
153
169
GoFeatureFlagRequest <T > goffRequest = new GoFeatureFlagRequest <T >(user , defaultValue );
@@ -162,14 +178,17 @@ private <T> ProviderEvaluation<T> resolveEvaluationGoFeatureFlagProxy(String key
162
178
Request request = new Request .Builder ()
163
179
.url (url )
164
180
.addHeader ("Content-Type" , "application/json" )
165
- .post (RequestBody .create (requestMapper .writeValueAsBytes (goffRequest ), MediaType .get ("application/json; charset=utf-8" )))
181
+ .post (RequestBody .create (
182
+ requestMapper .writeValueAsBytes (goffRequest ),
183
+ MediaType .get ("application/json; charset=utf-8" )))
166
184
.build ();
167
185
168
186
try (Response response = this .httpClient .newCall (request ).execute ()) {
169
187
if (response .code () >= HTTP_BAD_REQUEST ) {
170
188
throw new GeneralError ("impossible to contact GO Feature Flag relay proxy instance" );
171
189
}
172
- GoFeatureFlagResponse <T > goffResp = responseMapper .readValue (response .body ().string (), GoFeatureFlagResponse .class );
190
+ GoFeatureFlagResponse <T > goffResp =
191
+ responseMapper .readValue (response .body ().string (), GoFeatureFlagResponse .class );
173
192
174
193
if (Reason .DISABLED .name ().equalsIgnoreCase (goffResp .getReason ())) {
175
194
// we don't set a variant since we are using the default value, and we are not able to know
@@ -181,17 +200,18 @@ private <T> ProviderEvaluation<T> resolveEvaluationGoFeatureFlagProxy(String key
181
200
throw new FlagNotFoundError ("Flag " + key + " was not found in your configuration" );
182
201
}
183
202
184
- boolean isPrimitive = expectedType == Boolean .class ||
185
- expectedType == String .class ||
186
- expectedType == Integer .class ||
187
- expectedType == Double .class ;
203
+ boolean isPrimitive = expectedType == Boolean .class
204
+ || expectedType == String .class
205
+ || expectedType == Integer .class
206
+ || expectedType == Double .class ;
188
207
189
208
// Convert the value received from the API.
190
209
T flagValue = isPrimitive
191
210
? goffResp .getValue () : (T ) objectToValue (goffResp .getValue ());
192
211
193
212
if (flagValue .getClass () != expectedType ) {
194
- throw new TypeMismatchError ("Flag value " + key + " had unexpected type " + flagValue .getClass () + ", expected " + expectedType + "." );
213
+ throw new TypeMismatchError ("Flag value " + key + " had unexpected type "
214
+ + flagValue .getClass () + ", expected " + expectedType + "." );
195
215
}
196
216
197
217
return ProviderEvaluation .<T >builder ()
@@ -209,8 +229,7 @@ private <T> ProviderEvaluation<T> resolveEvaluationGoFeatureFlagProxy(String key
209
229
210
230
211
231
/**
212
- * mapReason is mapping the reason in string received by the API
213
- * to our internal SDK reason enum.
232
+ * mapReason is mapping the reason in string received by the API to our internal SDK reason enum.
214
233
*
215
234
* @param reason - string of the reason received from the API
216
235
* @return an item from the enum
@@ -258,13 +277,15 @@ private Value objectToValue(Object object) {
258
277
}
259
278
260
279
/**
261
- * mapToStructure transform a map coming from a JSON Object to a Structure type
280
+ * mapToStructure transform a map coming from a JSON Object to a Structure type.
262
281
*
263
282
* @param map - JSON object return by the API
264
283
* @return a Structure object in the SDK format
265
284
*/
266
285
private Structure mapToStructure (Map <String , Object > map ) {
267
286
return new Structure (
268
- map .entrySet ().stream ().filter (e -> e .getValue () != null ).collect (Collectors .toMap (Map .Entry ::getKey , e -> objectToValue (e .getValue ()))));
287
+ map .entrySet ().stream ()
288
+ .filter (e -> e .getValue () != null )
289
+ .collect (Collectors .toMap (Map .Entry ::getKey , e -> objectToValue (e .getValue ()))));
269
290
}
270
291
}
0 commit comments