Skip to content

Commit 618a64a

Browse files
feat: introduce Resolver as a drop in replacement for Evaluator (#793)
Signed-off-by: Kavindu Dodanduwa <kavindudodanduwa@gmail.com> Co-authored-by: Todd Baert <todd.baert@dynatrace.com>
1 parent 47224e5 commit 618a64a

File tree

10 files changed

+73
-28
lines changed

10 files changed

+73
-28
lines changed

providers/flagd/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Consider the following example to create a `FlagdProvider` with in-process evalu
4141
```java
4242
FlagdProvider flagdProvider = new FlagdProvider(
4343
FlagdOptions.builder()
44-
.resolverType(Config.Evaluator.IN_PROCESS)
44+
.resolverType(Config.Resolver.IN_PROCESS)
4545
.build());
4646
```
4747

@@ -55,7 +55,7 @@ To enable this mode, you should provide a valid flag configuration file with the
5555
```java
5656
FlagdProvider flagdProvider = new FlagdProvider(
5757
FlagdOptions.builder()
58-
.resolverType(Config.Evaluator.IN_PROCESS)
58+
.resolverType(Config.Resolver.IN_PROCESS)
5959
.offlineFlagSourcePath("PATH")
6060
.build());
6161
```

providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/Config.java

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*/
1111
@Slf4j
1212
public final class Config {
13-
static final Evaluator DEFAULT_RESOLVER_TYPE = Evaluator.RPC;
13+
static final Resolver DEFAULT_RESOLVER_TYPE = Resolver.RPC;
1414
static final String DEFAULT_PORT = "8013";
1515
static final String DEFAULT_TLS = "false";
1616
static final String DEFAULT_HOST = "localhost";
@@ -32,6 +32,9 @@ public final class Config {
3232
static final String SOURCE_SELECTOR_ENV_VAR_NAME = "FLAGD_SOURCE_SELECTOR";
3333
static final String OFFLINE_SOURCE_PATH = "FLAGD_OFFLINE_FLAG_SOURCE_PATH";
3434

35+
static final String RESOLVER_RPC = "rpc";
36+
static final String RESOLVER_IN_PROCESS = "in-process";
37+
3538
public static final String STATIC_REASON = "STATIC";
3639
public static final String CACHED_REASON = "CACHED";
3740

@@ -60,37 +63,79 @@ static int fallBackToEnvOrDefault(String key, int defaultValue) {
6063
}
6164
}
6265

63-
static Evaluator fromValueProvider(Function<String, String> provider) {
66+
static Resolver fromValueProvider(Function<String, String> provider) {
6467
final String resolverVar = provider.apply(RESOLVER_ENV_VAR);
6568
if (resolverVar == null) {
6669
return DEFAULT_RESOLVER_TYPE;
6770
}
6871

6972
switch (resolverVar.toLowerCase()) {
7073
case "in-process":
71-
return Evaluator.IN_PROCESS;
74+
return Resolver.IN_PROCESS;
7275
case "rpc":
73-
return Evaluator.RPC;
76+
return Resolver.RPC;
7477
default:
7578
log.warn("Unsupported resolver variable: {}", resolverVar);
7679
return DEFAULT_RESOLVER_TYPE;
7780
}
7881
}
7982

83+
// intermediate interface to unify deprecated Evaluator & new Resolver
84+
interface EvaluatorType {
85+
String asString();
86+
}
87+
8088
/**
8189
* flagd evaluator type.
90+
* Deprecated : Please use {@code Config.Resolver}, which is a drop-in replacement of this.
91+
*/
92+
@Deprecated
93+
public enum Evaluator implements EvaluatorType {
94+
/**
95+
* This is the default resolver type, which connects to flagd instance with flag evaluation gRPC contract.
96+
* Evaluations are performed remotely.
97+
*/
98+
RPC {
99+
public String asString() {
100+
return RESOLVER_RPC;
101+
}
102+
},
103+
/**
104+
* This is the in-process resolving type, where flags are fetched with flag sync gRPC contract and stored
105+
* locally for in-process evaluation.
106+
* Evaluations are preformed in-process.
107+
*/
108+
IN_PROCESS {
109+
public String asString() {
110+
return RESOLVER_IN_PROCESS;
111+
}
112+
}
113+
114+
}
115+
116+
117+
/**
118+
* flagd Resolver type.
82119
*/
83-
public enum Evaluator {
120+
public enum Resolver implements EvaluatorType {
84121
/**
85122
* This is the default resolver type, which connects to flagd instance with flag evaluation gRPC contract.
86123
* Evaluations are performed remotely.
87124
*/
88-
RPC,
125+
RPC {
126+
public String asString() {
127+
return RESOLVER_RPC;
128+
}
129+
},
89130
/**
90131
* This is the in-process resolving type, where flags are fetched with flag sync gRPC contract and stored
91132
* locally for in-process evaluation.
92133
* Evaluations are preformed in-process.
93134
*/
94-
IN_PROCESS
135+
IN_PROCESS {
136+
public String asString() {
137+
return RESOLVER_IN_PROCESS;
138+
}
139+
}
95140
}
96141
}

providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/FlagdOptions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public class FlagdOptions {
4040
* flagd resolving type.
4141
*/
4242
@Builder.Default
43-
private Config.Evaluator resolverType = fromValueProvider(System::getenv);
43+
private Config.EvaluatorType resolverType = fromValueProvider(System::getenv);
4444

4545
/**
4646
* flagd connection host.

providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/FlagdProvider.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@ public FlagdProvider() {
5050
* @param options {@link FlagdOptions} with
5151
*/
5252
public FlagdProvider(final FlagdOptions options) {
53-
switch (options.getResolverType()) {
54-
case IN_PROCESS:
53+
switch (options.getResolverType().asString()) {
54+
case Config.RESOLVER_IN_PROCESS:
5555
this.flagResolver = new InProcessResolver(options, this::setState);
5656
break;
57-
case RPC:
57+
case Config.RESOLVER_RPC:
5858
this.flagResolver =
5959
new GrpcResolver(options,
6060
new Cache(options.getCacheType(), options.getMaxCacheSize()),

providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/FlagdOptionsTest.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public void TestDefaults() {
3333
assertNull(builder.getSelector());
3434
assertNull(builder.getOpenTelemetry());
3535
assertNull(builder.getOfflineFlagSourcePath());
36-
assertEquals(Config.Evaluator.RPC, builder.getResolverType());
36+
assertEquals(Config.Resolver.RPC, builder.getResolverType());
3737
}
3838

3939
@Test
@@ -51,7 +51,7 @@ public void TestBuilderOptions() {
5151
.selector("app=weatherApp")
5252
.offlineFlagSourcePath("some-path")
5353
.openTelemetry(openTelemetry)
54-
.resolverType(Config.Evaluator.IN_PROCESS)
54+
.resolverType(Config.Resolver.IN_PROCESS)
5555
.build();
5656

5757
assertEquals("https://hosted-flagd", flagdOptions.getHost());
@@ -64,23 +64,23 @@ public void TestBuilderOptions() {
6464
assertEquals("app=weatherApp", flagdOptions.getSelector());
6565
assertEquals("some-path", flagdOptions.getOfflineFlagSourcePath());
6666
assertEquals(openTelemetry, flagdOptions.getOpenTelemetry());
67-
assertEquals(Config.Evaluator.IN_PROCESS, flagdOptions.getResolverType());
67+
assertEquals(Config.Resolver.IN_PROCESS, flagdOptions.getResolverType());
6868
}
6969

7070

7171
@Test
7272
public void testValueProviderForEdgeCase_valid() {
7373
Function<String, String> valueProvider = s -> "in-process";
74-
assertEquals(Config.Evaluator.IN_PROCESS, Config.fromValueProvider(valueProvider));
74+
assertEquals(Config.Resolver.IN_PROCESS, Config.fromValueProvider(valueProvider));
7575

7676
valueProvider = s -> "IN-PROCESS";
77-
assertEquals(Config.Evaluator.IN_PROCESS, Config.fromValueProvider(valueProvider));
77+
assertEquals(Config.Resolver.IN_PROCESS, Config.fromValueProvider(valueProvider));
7878

7979
valueProvider = s -> "rpc";
80-
assertEquals(Config.Evaluator.RPC, Config.fromValueProvider(valueProvider));
80+
assertEquals(Config.Resolver.RPC, Config.fromValueProvider(valueProvider));
8181

8282
valueProvider = s -> "RPC";
83-
assertEquals(Config.Evaluator.RPC, Config.fromValueProvider(valueProvider));
83+
assertEquals(Config.Resolver.RPC, Config.fromValueProvider(valueProvider));
8484
}
8585

8686
@Test

providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/process/FlagdInProcessSetup.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class FlagdInProcessSetup {
1919
@BeforeAll()
2020
public static void setup() throws InterruptedException {
2121
FlagdInProcessSetup.provider = new FlagdProvider(FlagdOptions.builder()
22-
.resolverType(Config.Evaluator.IN_PROCESS)
22+
.resolverType(Config.Resolver.IN_PROCESS)
2323
.deadline(3000)
2424
.port(9090)
2525
.build());

providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/reconnect/process/FlagdInProcessSetup.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ public class FlagdInProcessSetup {
1717
@BeforeAll()
1818
public static void setup() throws InterruptedException {
1919
FeatureProvider workingProvider = new FlagdProvider(FlagdOptions.builder()
20-
.resolverType(Config.Evaluator.IN_PROCESS)
20+
.resolverType(Config.Resolver.IN_PROCESS)
2121
.deadline(3000)
2222
.port(9091)
2323
.build());
2424
StepDefinitions.setUnstableProvider(workingProvider);
2525

2626
FeatureProvider unavailableProvider = new FlagdProvider(FlagdOptions.builder()
27-
.resolverType(Config.Evaluator.IN_PROCESS)
27+
.resolverType(Config.Resolver.IN_PROCESS)
2828
.deadline(100)
2929
.port(9092) // this port isn't serving anything, error expected
3030
.build());

providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/reconnect/rpc/FlagdRpcSetup.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public class FlagdRpcSetup {
1818
@BeforeAll()
1919
public static void setup() throws InterruptedException {
2020
FeatureProvider workingProvider = new FlagdProvider(FlagdOptions.builder()
21-
.resolverType(Config.Evaluator.RPC)
21+
.resolverType(Config.Resolver.RPC)
2222
.port(8014)
2323
// set a generous deadline, to prevent timeouts in actions
2424
.deadline(3000)
@@ -27,7 +27,7 @@ public static void setup() throws InterruptedException {
2727
StepDefinitions.setUnstableProvider(workingProvider);
2828

2929
FeatureProvider unavailableProvider = new FlagdProvider(FlagdOptions.builder()
30-
.resolverType(Config.Evaluator.RPC)
30+
.resolverType(Config.Resolver.RPC)
3131
.port(8015) // this port isn't serving anything, error expected
3232
// set a generous deadline, to prevent timeouts in actions
3333
.deadline(100)

providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/rpc/FlagdRpcSetup.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class FlagdRpcSetup {
2020
@BeforeAll()
2121
public static void setup() {
2222
FlagdRpcSetup.provider = new FlagdProvider(FlagdOptions.builder()
23-
.resolverType(Config.Evaluator.RPC)
23+
.resolverType(Config.Resolver.RPC)
2424
// set a generous deadline, to prevent timeouts in actions
2525
.deadline(3000)
2626
.cacheType(CacheType.DISABLED.getValue())

providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/InProcessResolverTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ class InProcessResolverTest {
5050
public void connectorSetup(){
5151
// given
5252
FlagdOptions forGrpcOptions =
53-
FlagdOptions.builder().resolverType(Config.Evaluator.IN_PROCESS).host("localhost").port(8080).build();
53+
FlagdOptions.builder().resolverType(Config.Resolver.IN_PROCESS).host("localhost").port(8080).build();
5454
FlagdOptions forOfflineOptions =
55-
FlagdOptions.builder().resolverType(Config.Evaluator.IN_PROCESS).offlineFlagSourcePath("path").build();
55+
FlagdOptions.builder().resolverType(Config.Resolver.IN_PROCESS).offlineFlagSourcePath("path").build();
5656

5757
// then
5858
assertInstanceOf(GrpcStreamConnector.class, InProcessResolver.getConnector(forGrpcOptions));

0 commit comments

Comments
 (0)