diff --git a/providers/flagd/README.md b/providers/flagd/README.md index 7d28e4ef8..194da5ff6 100644 --- a/providers/flagd/README.md +++ b/providers/flagd/README.md @@ -77,20 +77,21 @@ variables. Given below are the supported configurations: -| Option name | Environment variable name | Type & Values | Default | Compatible resolver | -|-----------------------|--------------------------------|------------------------|-----------|---------------------| -| host | FLAGD_HOST | String | localhost | rpc & in-process | -| port | FLAGD_PORT | int | 8013 | rpc & in-process | -| tls | FLAGD_TLS | boolean | false | rpc & in-process | -| socketPath | FLAGD_SOCKET_PATH | String | null | rpc & in-process | -| certPath | FLAGD_SERVER_CERT_PATH | String | null | rpc & in-process | -| deadline | FLAGD_DEADLINE_MS | int | 500 | rpc & in-process | -| selector | FLAGD_SOURCE_SELECTOR | String | null | in-process | -| cache | FLAGD_CACHE | String - lru, disabled | lru | rpc | -| maxCacheSize | FLAGD_MAX_CACHE_SIZE | int | 1000 | rpc | -| maxEventStreamRetries | FLAGD_MAX_EVENT_STREAM_RETRIES | int | 5 | rpc | -| retryBackoffMs | FLAGD_RETRY_BACKOFF_MS | int | 1000 | rpc | -| offlineFlagSourcePath | FLAGD_OFFLINE_FLAG_SOURCE_PATH | String | null | in-process | +| Option name | Environment variable name | Type & Values | Default | Compatible resolver | +|-----------------------|--------------------------------|--------------------------|-----------|---------------------| +| resolver | FLAGD_RESOLVER | String - rpc, in-process | rpc | | +| host | FLAGD_HOST | String | localhost | rpc & in-process | +| port | FLAGD_PORT | int | 8013 | rpc & in-process | +| tls | FLAGD_TLS | boolean | false | rpc & in-process | +| socketPath | FLAGD_SOCKET_PATH | String | null | rpc & in-process | +| certPath | FLAGD_SERVER_CERT_PATH | String | null | rpc & in-process | +| deadline | FLAGD_DEADLINE_MS | int | 500 | rpc & in-process | +| selector | FLAGD_SOURCE_SELECTOR | String | null | in-process | +| cache | FLAGD_CACHE | String - lru, disabled | lru | rpc | +| maxCacheSize | FLAGD_MAX_CACHE_SIZE | int | 1000 | rpc | +| maxEventStreamRetries | FLAGD_MAX_EVENT_STREAM_RETRIES | int | 5 | rpc | +| retryBackoffMs | FLAGD_RETRY_BACKOFF_MS | int | 1000 | rpc | +| offlineFlagSourcePath | FLAGD_OFFLINE_FLAG_SOURCE_PATH | String | null | in-process | > [!NOTE] > Some configurations are only applicable for RPC resolver. diff --git a/providers/flagd/schemas b/providers/flagd/schemas index cc2f5a1b5..8c72c14ee 160000 --- a/providers/flagd/schemas +++ b/providers/flagd/schemas @@ -1 +1 @@ -Subproject commit cc2f5a1b506700eca1e56b462921573532f2b463 +Subproject commit 8c72c14eebff2a5b20fe2afb90c7ad44c1184ae8 diff --git a/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/Config.java b/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/Config.java index 68564c51b..5dfec4e13 100644 --- a/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/Config.java +++ b/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/Config.java @@ -1,10 +1,14 @@ package dev.openfeature.contrib.providers.flagd; import dev.openfeature.contrib.providers.flagd.resolver.grpc.cache.CacheType; +import lombok.extern.slf4j.Slf4j; + +import java.util.function.Function; /** * Helper class to hold configuration default values. */ +@Slf4j public final class Config { static final Evaluator DEFAULT_RESOLVER_TYPE = Evaluator.RPC; static final String DEFAULT_PORT = "8013"; @@ -14,6 +18,7 @@ public final class Config { static final int DEFAULT_DEADLINE = 500; static final int DEFAULT_MAX_CACHE_SIZE = 1000; + static final String RESOLVER_ENV_VAR = "FLAGD_RESOLVER"; static final String HOST_ENV_VAR_NAME = "FLAGD_HOST"; static final String PORT_ENV_VAR_NAME = "FLAGD_PORT"; static final String TLS_ENV_VAR_NAME = "FLAGD_TLS"; @@ -55,6 +60,23 @@ static int fallBackToEnvOrDefault(String key, int defaultValue) { } } + static Evaluator fromValueProvider(Function provider) { + final String resolverVar = provider.apply(RESOLVER_ENV_VAR); + if (resolverVar == null) { + return DEFAULT_RESOLVER_TYPE; + } + + switch (resolverVar.toLowerCase()) { + case "in-process": + return Evaluator.IN_PROCESS; + case "rpc": + return Evaluator.RPC; + default: + log.warn("Unsupported resolver variable: {}", resolverVar); + return DEFAULT_RESOLVER_TYPE; + } + } + /** * flagd evaluator type. */ diff --git a/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/FlagdOptions.java b/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/FlagdOptions.java index 32d2ae678..a51defe87 100644 --- a/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/FlagdOptions.java +++ b/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/FlagdOptions.java @@ -15,7 +15,6 @@ import static dev.openfeature.contrib.providers.flagd.Config.DEFAULT_MAX_CACHE_SIZE; import static dev.openfeature.contrib.providers.flagd.Config.DEFAULT_MAX_EVENT_STREAM_RETRIES; import static dev.openfeature.contrib.providers.flagd.Config.DEFAULT_PORT; -import static dev.openfeature.contrib.providers.flagd.Config.DEFAULT_RESOLVER_TYPE; import static dev.openfeature.contrib.providers.flagd.Config.DEFAULT_TLS; import static dev.openfeature.contrib.providers.flagd.Config.HOST_ENV_VAR_NAME; import static dev.openfeature.contrib.providers.flagd.Config.MAX_CACHE_SIZE_ENV_VAR_NAME; @@ -27,6 +26,7 @@ import static dev.openfeature.contrib.providers.flagd.Config.SOURCE_SELECTOR_ENV_VAR_NAME; import static dev.openfeature.contrib.providers.flagd.Config.TLS_ENV_VAR_NAME; import static dev.openfeature.contrib.providers.flagd.Config.fallBackToEnvOrDefault; +import static dev.openfeature.contrib.providers.flagd.Config.fromValueProvider; /** * FlagdOptions is a builder to build flagd provider options. @@ -40,7 +40,7 @@ public class FlagdOptions { * flagd resolving type. */ @Builder.Default - private Config.Evaluator resolverType = DEFAULT_RESOLVER_TYPE; + private Config.Evaluator resolverType = fromValueProvider(System::getenv); /** * flagd connection host. diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/FlagdOptionsTest.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/FlagdOptionsTest.java index a95b9f36f..db70a21b5 100644 --- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/FlagdOptionsTest.java +++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/FlagdOptionsTest.java @@ -4,6 +4,8 @@ import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import java.util.function.Function; + import static dev.openfeature.contrib.providers.flagd.Config.DEFAULT_CACHE; import static dev.openfeature.contrib.providers.flagd.Config.DEFAULT_HOST; import static dev.openfeature.contrib.providers.flagd.Config.DEFAULT_MAX_CACHE_SIZE; @@ -31,6 +33,7 @@ public void TestDefaults() { assertNull(builder.getSelector()); assertNull(builder.getOpenTelemetry()); assertNull(builder.getOfflineFlagSourcePath()); + assertEquals(Config.Evaluator.RPC, builder.getResolverType()); } @Test @@ -48,6 +51,7 @@ public void TestBuilderOptions() { .selector("app=weatherApp") .offlineFlagSourcePath("some-path") .openTelemetry(openTelemetry) + .resolverType(Config.Evaluator.IN_PROCESS) .build(); assertEquals("https://hosted-flagd", flagdOptions.getHost()); @@ -60,5 +64,32 @@ public void TestBuilderOptions() { assertEquals("app=weatherApp", flagdOptions.getSelector()); assertEquals("some-path", flagdOptions.getOfflineFlagSourcePath()); assertEquals(openTelemetry, flagdOptions.getOpenTelemetry()); + assertEquals(Config.Evaluator.IN_PROCESS, flagdOptions.getResolverType()); } + + + @Test + public void testValueProviderForEdgeCase_valid() { + Function valueProvider = s -> "in-process"; + assertEquals(Config.Evaluator.IN_PROCESS, Config.fromValueProvider(valueProvider)); + + valueProvider = s -> "IN-PROCESS"; + assertEquals(Config.Evaluator.IN_PROCESS, Config.fromValueProvider(valueProvider)); + + valueProvider = s -> "rpc"; + assertEquals(Config.Evaluator.RPC, Config.fromValueProvider(valueProvider)); + + valueProvider = s -> "RPC"; + assertEquals(Config.Evaluator.RPC, Config.fromValueProvider(valueProvider)); + } + + @Test + public void testValueProviderForEdgeCase_invalid() { + Function dummy = s -> "some-other"; + assertEquals(Config.DEFAULT_RESOLVER_TYPE, Config.fromValueProvider(dummy)); + + dummy = s -> null; + assertEquals(Config.DEFAULT_RESOLVER_TYPE, Config.fromValueProvider(dummy)); + } + }