Skip to content

Commit 6781691

Browse files
authored
Merge branch 'main' into release-please--branches--main--components--dev.openfeature.contrib.providers.flagd
2 parents b20d649 + b9f9ffd commit 6781691

File tree

8 files changed

+43
-5
lines changed

8 files changed

+43
-5
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
1818

1919
- name: Set up JDK 8
20-
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4
20+
uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4
2121
with:
2222
java-version: '8'
2323
distribution: 'temurin'

.github/workflows/release-please.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121

2222
- name: Set up JDK 8
2323
if: ${{ steps.release.outputs.releases_created }}
24-
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4
24+
uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4
2525
with:
2626
java-version: '8'
2727
distribution: 'temurin'

providers/flagd/README.md

+21-2
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,28 @@ Provider will attempt to detect file changes using polling.
6464
Polling happens at 5 second intervals and this is currently unconfigurable.
6565
This mode is useful for local development, tests and offline applications.
6666

67+
#### Custom Connector
68+
69+
You can include a custom connector as a configuration option to customize how the in-process resolver fetches flags.
70+
The custom connector must implement the [Connector interface](https://github.com/open-feature/java-sdk-contrib/blob/main/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/storage/connector/Connector.java).
71+
72+
```java
73+
Connector myCustomConnector = new MyCustomConnector();
74+
FlagdOptions options =
75+
FlagdOptions.builder()
76+
.resolverType(Config.Resolver.IN_PROCESS)
77+
.customConnector(myCustomConnector)
78+
.build();
79+
80+
FlagdProvider flagdProvider = new FlagdProvider(options);
81+
```
82+
6783
> [!IMPORTANT]
68-
> Note that you can only use a single flag source (either gRPC or offline file) for the in-process resolver.
69-
> If both sources are configured, offline mode will be selected.
84+
> Note that the in-process resolver can only use a single flag source.
85+
> If multiple sources are configured then only one would be selected based on the following order of preference:
86+
> 1. Custom Connector
87+
> 2. Offline file
88+
> 3. gRPC
7089
7190
### Configuration options
7291

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

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.openfeature.contrib.providers.flagd;
22

3+
import dev.openfeature.contrib.providers.flagd.resolver.process.storage.connector.Connector;
34
import io.opentelemetry.api.GlobalOpenTelemetry;
45
import io.opentelemetry.api.OpenTelemetry;
56
import lombok.Builder;
@@ -99,6 +100,11 @@ public class FlagdOptions {
99100
@Builder.Default
100101
private String offlineFlagSourcePath = fallBackToEnvOrDefault(Config.OFFLINE_SOURCE_PATH, null);
101102

103+
/**
104+
* Inject a Custom Connector for fetching flags.
105+
*/
106+
private Connector customConnector;
107+
102108
/**
103109
* Inject OpenTelemetry for the library runtime. Providing sdk will initiate
104110
* distributed tracing for flagd grpc

providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/InProcessResolver.java

+3
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ public ProviderEvaluation<Value> objectEvaluation(String key, Value defaultValue
152152
}
153153

154154
static Connector getConnector(final FlagdOptions options) {
155+
if (options.getCustomConnector() != null) {
156+
return options.getCustomConnector();
157+
}
155158
return options.getOfflineFlagSourcePath() != null && !options.getOfflineFlagSourcePath().isEmpty()
156159
? new FileConnector(options.getOfflineFlagSourcePath())
157160
: new GrpcStreamConnector(options);

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

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package dev.openfeature.contrib.providers.flagd;
22

3+
import dev.openfeature.contrib.providers.flagd.resolver.process.storage.MockConnector;
4+
import dev.openfeature.contrib.providers.flagd.resolver.process.storage.connector.Connector;
35
import io.opentelemetry.api.OpenTelemetry;
46
import org.junit.jupiter.api.Disabled;
57
import org.junit.jupiter.api.Test;
@@ -28,13 +30,15 @@ void TestDefaults() {
2830
assertEquals(DEFAULT_MAX_EVENT_STREAM_RETRIES, builder.getMaxEventStreamRetries());
2931
assertNull(builder.getSelector());
3032
assertNull(builder.getOpenTelemetry());
33+
assertNull(builder.getCustomConnector());
3134
assertNull(builder.getOfflineFlagSourcePath());
3235
assertEquals(Resolver.RPC, builder.getResolverType());
3336
}
3437

3538
@Test
3639
void TestBuilderOptions() {
3740
OpenTelemetry openTelemetry = Mockito.mock(OpenTelemetry.class);
41+
Connector connector = new MockConnector(null);
3842

3943
FlagdOptions flagdOptions = FlagdOptions.builder()
4044
.host("https://hosted-flagd")
@@ -47,6 +51,7 @@ void TestBuilderOptions() {
4751
.selector("app=weatherApp")
4852
.offlineFlagSourcePath("some-path")
4953
.openTelemetry(openTelemetry)
54+
.customConnector(connector)
5055
.resolverType(Resolver.IN_PROCESS)
5156
.build();
5257

@@ -60,6 +65,7 @@ void TestBuilderOptions() {
6065
assertEquals("app=weatherApp", flagdOptions.getSelector());
6166
assertEquals("some-path", flagdOptions.getOfflineFlagSourcePath());
6267
assertEquals(openTelemetry, flagdOptions.getOpenTelemetry());
68+
assertEquals(connector, flagdOptions.getCustomConnector());
6369
assertEquals(Resolver.IN_PROCESS, flagdOptions.getResolverType());
6470
}
6571

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

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import dev.openfeature.contrib.providers.flagd.Config;
44
import dev.openfeature.contrib.providers.flagd.FlagdOptions;
55
import dev.openfeature.contrib.providers.flagd.resolver.process.model.FeatureFlag;
6+
import dev.openfeature.contrib.providers.flagd.resolver.process.storage.MockConnector;
67
import dev.openfeature.contrib.providers.flagd.resolver.process.storage.StorageState;
78
import dev.openfeature.contrib.providers.flagd.resolver.process.storage.connector.file.FileConnector;
89
import dev.openfeature.contrib.providers.flagd.resolver.process.storage.connector.grpc.GrpcStreamConnector;
@@ -53,10 +54,13 @@ public void connectorSetup(){
5354
FlagdOptions.builder().resolverType(Config.Resolver.IN_PROCESS).host("localhost").port(8080).build();
5455
FlagdOptions forOfflineOptions =
5556
FlagdOptions.builder().resolverType(Config.Resolver.IN_PROCESS).offlineFlagSourcePath("path").build();
57+
FlagdOptions forCustomConnectorOptions =
58+
FlagdOptions.builder().resolverType(Config.Resolver.IN_PROCESS).customConnector(new MockConnector(null)).build();
5659

5760
// then
5861
assertInstanceOf(GrpcStreamConnector.class, InProcessResolver.getConnector(forGrpcOptions));
5962
assertInstanceOf(FileConnector.class, InProcessResolver.getConnector(forOfflineOptions));
63+
assertInstanceOf(MockConnector.class, InProcessResolver.getConnector(forCustomConnectorOptions));
6064
}
6165

6266
@Test

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public class MockConnector implements Connector {
1212

1313
private BlockingQueue<StreamPayload> mockQueue;
1414

15-
MockConnector(final BlockingQueue<StreamPayload> mockQueue) {
15+
public MockConnector(final BlockingQueue<StreamPayload> mockQueue) {
1616
this.mockQueue = mockQueue;
1717
}
1818

0 commit comments

Comments
 (0)