Skip to content

Commit

Permalink
flagd utilize initialization context for evals
Browse files Browse the repository at this point in the history
Signed-off-by: Kavindu Dodanduwa <[email protected]>
  • Loading branch information
Kavindu-Dodan committed Nov 21, 2023
1 parent c765bee commit 8b00b0d
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ public class FlagdProvider extends EventProvider implements FeatureProvider {

private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Resolver flagResolver;

private ProviderState state = ProviderState.NOT_READY;

private EvaluationContext evaluationContext;

/**
* Create a new FlagdProvider instance with default options.
*/
Expand Down Expand Up @@ -60,6 +61,7 @@ public FlagdProvider(final FlagdOptions options) {

@Override
public void initialize(EvaluationContext evaluationContext) throws Exception {
this.evaluationContext = evaluationContext;
this.flagResolver.init();
}

Expand Down Expand Up @@ -91,27 +93,35 @@ public Metadata getMetadata() {

@Override
public ProviderEvaluation<Boolean> getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx) {
return this.flagResolver.booleanEvaluation(key, defaultValue, ctx);
return this.flagResolver.booleanEvaluation(key, defaultValue, mergeContext(ctx));
}

@Override
public ProviderEvaluation<String> getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) {
return this.flagResolver.stringEvaluation(key, defaultValue, ctx);
return this.flagResolver.stringEvaluation(key, defaultValue, mergeContext(ctx));
}

@Override
public ProviderEvaluation<Double> getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx) {
return this.flagResolver.doubleEvaluation(key, defaultValue, ctx);
return this.flagResolver.doubleEvaluation(key, defaultValue, mergeContext(ctx));
}

@Override
public ProviderEvaluation<Integer> getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) {
return this.flagResolver.integerEvaluation(key, defaultValue, ctx);
return this.flagResolver.integerEvaluation(key, defaultValue, mergeContext(ctx));
}

@Override
public ProviderEvaluation<Value> getObjectEvaluation(String key, Value defaultValue, EvaluationContext ctx) {
return this.flagResolver.objectEvaluation(key, defaultValue, ctx);
return this.flagResolver.objectEvaluation(key, defaultValue, mergeContext(ctx));
}

private EvaluationContext mergeContext(final EvaluationContext clientCallCtx) {
if (this.evaluationContext != null) {
return evaluationContext.merge(clientCallCtx);
}

return clientCallCtx;
}

private void setState(ProviderState newState) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package dev.openfeature.contrib.providers.flagd;

import com.google.protobuf.Struct;
import dev.openfeature.contrib.providers.flagd.resolver.grpc.cache.Cache;
import dev.openfeature.contrib.providers.flagd.resolver.grpc.cache.CacheType;
import dev.openfeature.contrib.providers.flagd.resolver.Resolver;
import dev.openfeature.contrib.providers.flagd.resolver.grpc.GrpcConnector;
import dev.openfeature.contrib.providers.flagd.resolver.grpc.GrpcResolver;
import dev.openfeature.contrib.providers.flagd.resolver.grpc.cache.Cache;
import dev.openfeature.contrib.providers.flagd.resolver.grpc.cache.CacheType;
import dev.openfeature.flagd.grpc.Schema.EventStreamResponse;
import dev.openfeature.flagd.grpc.Schema.ResolveBooleanRequest;
import dev.openfeature.flagd.grpc.Schema.ResolveBooleanResponse;
Expand All @@ -16,6 +17,7 @@
import dev.openfeature.flagd.grpc.ServiceGrpc.ServiceBlockingStub;
import dev.openfeature.flagd.grpc.ServiceGrpc.ServiceStub;
import dev.openfeature.sdk.FlagEvaluationDetails;
import dev.openfeature.sdk.ImmutableContext;
import dev.openfeature.sdk.ImmutableMetadata;
import dev.openfeature.sdk.MutableContext;
import dev.openfeature.sdk.MutableStructure;
Expand Down Expand Up @@ -48,6 +50,7 @@
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

class FlagdProviderTest {
Expand Down Expand Up @@ -763,6 +766,39 @@ void disabled_cache() {
assertEquals(STATIC_REASON, objectDetails.getReason());
}

@Test
void contextMerging() throws Exception {
// given
final FlagdProvider provider = new FlagdProvider();

final Resolver resolverMock = mock(Resolver.class);

Field flagResolver = FlagdProvider.class.getDeclaredField("flagResolver");
flagResolver.setAccessible(true);
flagResolver.set(provider, resolverMock);

final HashMap<String, Value> globalCtxMap = new HashMap<>();
globalCtxMap.put("id", new Value("GlobalID"));
globalCtxMap.put("env", new Value("A"));

final HashMap<String, Value> localCtxMap = new HashMap<>();
localCtxMap.put("id", new Value("localID"));
localCtxMap.put("client", new Value("999"));

final HashMap<String, Value> expectedCtx = new HashMap<>();
expectedCtx.put("id", new Value("localID"));
expectedCtx.put("env", new Value("A"));
localCtxMap.put("client", new Value("999"));

// when
provider.initialize(new ImmutableContext(globalCtxMap));
provider.getBooleanEvaluation("ket", false, new ImmutableContext(localCtxMap));

// then
verify(resolverMock).booleanEvaluation(any(), any(), argThat(
ctx -> ctx.asMap().entrySet().containsAll(expectedCtx.entrySet())));
}

// test utils

// create provider with given grpc connector
Expand Down

0 comments on commit 8b00b0d

Please sign in to comment.