2
2
3
3
import static dev .openfeature .contrib .providers .flagd .resolver .process .model .FeatureFlag .EMPTY_TARGETING_STRING ;
4
4
5
+ import java .util .Map ;
6
+ import java .util .function .Consumer ;
7
+ import java .util .function .Supplier ;
8
+
5
9
import dev .openfeature .contrib .providers .flagd .FlagdOptions ;
6
10
import dev .openfeature .contrib .providers .flagd .resolver .Resolver ;
7
11
import dev .openfeature .contrib .providers .flagd .resolver .common .ConnectionEvent ;
@@ -37,8 +41,9 @@ public class InProcessResolver implements Resolver {
37
41
private final Consumer <ConnectionEvent > onConnectionEvent ;
38
42
private final Operator operator ;
39
43
private final long deadline ;
40
- private final ImmutableMetadata metadata ;
44
+ private final ImmutableMetadata fallBackMetadata ;
41
45
private final Supplier <Boolean > connectedSupplier ;
46
+ private final String scope ;
42
47
43
48
/**
44
49
* Resolves flag values using https://buf.build/open-feature/flagd/docs/main:flagd.sync.v1. Flags
@@ -48,20 +53,22 @@ public class InProcessResolver implements Resolver {
48
53
* @param connectedSupplier lambda providing current connection status from caller
49
54
* @param onConnectionEvent lambda which handles changes in the connection/stream
50
55
*/
51
- public InProcessResolver (
52
- FlagdOptions options ,
53
- final Supplier <Boolean > connectedSupplier ,
54
- Consumer <ConnectionEvent > onConnectionEvent ) {
56
+ public InProcessResolver (FlagdOptions options , final Supplier <Boolean > connectedSupplier ,
57
+ Consumer <ConnectionEvent > onConnectionEvent ) {
55
58
this .flagStore = new FlagStore (getConnector (options ));
56
59
this .deadline = options .getDeadline ();
57
60
this .onConnectionEvent = onConnectionEvent ;
58
61
this .operator = new Operator ();
59
62
this .connectedSupplier = connectedSupplier ;
60
- this .metadata = options .getSelector () == null
61
- ? null
62
- : ImmutableMetadata .builder ()
63
- .addString ("scope" , options .getSelector ())
64
- .build ();
63
+ if (options .getSelector () == null ) {
64
+ this .scope = null ;
65
+ this .fallBackMetadata = null ;
66
+ } else {
67
+ this .scope = options .getSelector ();
68
+ this .fallBackMetadata = ImmutableMetadata .builder ()
69
+ .addString ("scope" , this .scope )
70
+ .build ();
71
+ }
65
72
}
66
73
67
74
/** Initialize in-process resolver. */
@@ -109,8 +116,14 @@ public void shutdown() throws InterruptedException {
109
116
onConnectionEvent .accept (new ConnectionEvent (false ));
110
117
}
111
118
112
- /** Resolve a boolean flag. */
113
- public ProviderEvaluation <Boolean > booleanEvaluation (String key , Boolean defaultValue , EvaluationContext ctx ) {
119
+ /**
120
+ * Resolve a boolean flag.
121
+ */
122
+ public ProviderEvaluation <Boolean > booleanEvaluation (
123
+ String key ,
124
+ Boolean defaultValue ,
125
+ EvaluationContext ctx
126
+ ) {
114
127
return resolve (Boolean .class , key , ctx );
115
128
}
116
129
@@ -161,6 +174,7 @@ private <T> ProviderEvaluation<T> resolve(Class<T> type, String key, EvaluationC
161
174
return ProviderEvaluation .<T >builder ()
162
175
.errorMessage ("flag: " + key + " not found" )
163
176
.errorCode (ErrorCode .FLAG_NOT_FOUND )
177
+ .flagMetadata (fallBackMetadata )
164
178
.build ();
165
179
}
166
180
@@ -169,6 +183,7 @@ private <T> ProviderEvaluation<T> resolve(Class<T> type, String key, EvaluationC
169
183
return ProviderEvaluation .<T >builder ()
170
184
.errorMessage ("flag: " + key + " is disabled" )
171
185
.errorCode (ErrorCode .FLAG_NOT_FOUND )
186
+ .flagMetadata (getFlagMetadata (flag ))
172
187
.build ();
173
188
}
174
189
@@ -215,13 +230,51 @@ private <T> ProviderEvaluation<T> resolve(Class<T> type, String key, EvaluationC
215
230
throw new TypeMismatchError (message );
216
231
}
217
232
218
- final ProviderEvaluation . ProviderEvaluationBuilder < T > evaluationBuilder = ProviderEvaluation .<T >builder ()
233
+ return ProviderEvaluation .<T >builder ()
219
234
.value ((T ) value )
220
235
.variant (resolvedVariant )
221
- .reason (reason );
236
+ .reason (reason )
237
+ .flagMetadata (getFlagMetadata (flag ))
238
+ .build ();
239
+ }
240
+
241
+ private ImmutableMetadata getFlagMetadata (FeatureFlag flag ) {
242
+ if (flag == null ) {
243
+ return fallBackMetadata ;
244
+ }
245
+
246
+ ImmutableMetadata .ImmutableMetadataBuilder metadataBuilder = ImmutableMetadata .builder ();
247
+ if (scope != null ) {
248
+ metadataBuilder .addString ("scope" , scope );
249
+ }
250
+
251
+ for (Map .Entry <String , Object > entry : flag .getMetadata ().entrySet ()) {
252
+ Object value = entry .getValue ();
253
+ if (value instanceof Number ) {
254
+ if (value instanceof Long ) {
255
+ metadataBuilder .addLong (entry .getKey (), (Long ) value );
256
+ continue ;
257
+ } else if (value instanceof Double ) {
258
+ metadataBuilder .addDouble (entry .getKey (), (Double ) value );
259
+ continue ;
260
+ } else if (value instanceof Integer ) {
261
+ metadataBuilder .addInteger (entry .getKey (), (Integer ) value );
262
+ continue ;
263
+ } else if (value instanceof Float ) {
264
+ metadataBuilder .addFloat (entry .getKey (), (Float ) value );
265
+ continue ;
266
+ }
267
+ } else if (value instanceof Boolean ) {
268
+ metadataBuilder .addBoolean (entry .getKey (), (Boolean ) value );
269
+ continue ;
270
+ } else if (value instanceof String ) {
271
+ metadataBuilder .addString (entry .getKey (), (String ) value );
272
+ continue ;
273
+ }
274
+ throw new IllegalArgumentException ("The type of the Metadata entry with key " + entry .getKey ()
275
+ + " and value " + entry .getValue () + " is not supported" );
276
+ }
222
277
223
- return this .metadata == null
224
- ? evaluationBuilder .build ()
225
- : evaluationBuilder .flagMetadata (this .metadata ).build ();
278
+ return metadataBuilder .build ();
226
279
}
227
280
}
0 commit comments