Skip to content

Commit c233a4f

Browse files
Merge pull request #44 from sideshowcoder/sideshowcoder/22/support-go-feature-provider
feat: support for GoFeatureFlagProvider
2 parents f53edd5 + c20d433 commit c233a4f

File tree

10 files changed

+163
-6
lines changed

10 files changed

+163
-6
lines changed

pom.xml

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@
1515
<description>OpenFeature bundle for Dropwizard</description>
1616

1717
<properties>
18-
<!-- Support Java 8 as the same language level supported by the Openfeature SDK -->
19-
<java.version>8</java.version>
18+
<!-- Support Java 11 as the same language level supported by the Openfeature SDK -->
19+
<maven.compiler.release>11</maven.compiler.release>
2020
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
2121
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
2222
<dropwizard.version>5.0.0</dropwizard.version>
2323
<openfeature-sdk.version>1.18.2</openfeature-sdk.version>
2424
<openfeature-contrib-providers-flagd.version>0.11.17</openfeature-contrib-providers-flagd.version>
25+
<openfeature-contrib-providers-go-feature-flag.version>1.0.1</openfeature-contrib-providers-go-feature-flag.version>
2526
<jacoco-maven-plugin.version>0.8.14</jacoco-maven-plugin.version>
2627
<maven-compiler-plugin.version>3.14.1</maven-compiler-plugin.version>
2728
<maven-gpg-plugin.version>3.2.8</maven-gpg-plugin.version>
@@ -31,6 +32,7 @@
3132
<maven-surefire-plugin.version>3.5.4</maven-surefire-plugin.version>
3233
<maven-failsafe-plugin.version>3.5.4</maven-failsafe-plugin.version>
3334
<mockito.version>5.20.0</mockito.version>
35+
<testcontainers.version>1.21.3</testcontainers.version>
3436
<central-publishing-maven-plugin.version>0.9.0</central-publishing-maven-plugin.version>
3537
</properties>
3638

@@ -75,8 +77,15 @@
7577
<artifactId>mockito-bom</artifactId>
7678
<version>${mockito.version}</version>
7779
<type>pom</type>
78-
<scope>test</scope>
80+
<scope>import</scope>
7981
</dependency>
82+
<dependency>
83+
<groupId>org.testcontainers</groupId>
84+
<artifactId>testcontainers-bom</artifactId>
85+
<version>${testcontainers.version}</version>
86+
<type>pom</type>
87+
<scope>import</scope>
88+
</dependency>
8089
</dependencies>
8190
</dependencyManagement>
8291

@@ -112,6 +121,12 @@
112121
<artifactId>flagd</artifactId>
113122
<version>${openfeature-contrib-providers-flagd.version}</version>
114123
</dependency>
124+
<dependency>
125+
<groupId>dev.openfeature.contrib.providers</groupId>
126+
<artifactId>go-feature-flag</artifactId>
127+
<version>${openfeature-contrib-providers-go-feature-flag.version}</version>
128+
</dependency>
129+
115130
<dependency>
116131
<groupId>io.dropwizard</groupId>
117132
<artifactId>dropwizard-testing</artifactId>
@@ -127,6 +142,21 @@
127142
<artifactId>mockito-junit-jupiter</artifactId>
128143
<scope>test</scope>
129144
</dependency>
145+
<dependency>
146+
<groupId>org.junit.jupiter</groupId>
147+
<artifactId>junit-jupiter</artifactId>
148+
<scope>test</scope>
149+
</dependency>
150+
<dependency>
151+
<groupId>org.testcontainers</groupId>
152+
<artifactId>junit-jupiter</artifactId>
153+
<scope>test</scope>
154+
</dependency>
155+
<dependency>
156+
<groupId>org.testcontainers</groupId>
157+
<artifactId>testcontainers</artifactId>
158+
<scope>test</scope>
159+
</dependency>
130160
</dependencies>
131161

132162
<build>
@@ -165,8 +195,7 @@
165195
<artifactId>maven-compiler-plugin</artifactId>
166196
<version>${maven-compiler-plugin.version}</version>
167197
<configuration>
168-
<source>${java.version}</source>
169-
<target>${java.version}</target>
198+
<release>${maven.compiler.release}</release>
170199
</configuration>
171200
</plugin>
172201
<plugin>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package io.github.sideshowcoder.dropwizard_openfeature;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
import dev.openfeature.contrib.providers.gofeatureflag.GoFeatureFlagProviderOptions;
6+
import dev.openfeature.contrib.providers.gofeatureflag.GoFeatureFlagProviderOptions.GoFeatureFlagProviderOptionsBuilder;
7+
import dev.openfeature.contrib.providers.gofeatureflag.exception.InvalidOptions;
8+
import jakarta.validation.constraints.NotNull;
9+
10+
public class GoFeatureFlagConfiguration {
11+
12+
@JsonProperty
13+
@NotNull
14+
private String endpoint;
15+
16+
public GoFeatureFlagProviderOptions getGoFeatureFlagProviderOptions() throws InvalidOptions {
17+
GoFeatureFlagProviderOptionsBuilder builder = GoFeatureFlagProviderOptions.builder();
18+
19+
builder.endpoint(endpoint);
20+
21+
GoFeatureFlagProviderOptions options = builder.build();
22+
options.validate();
23+
return options;
24+
}
25+
26+
}

src/main/java/io/github/sideshowcoder/dropwizard_openfeature/OpenFeatureBundle.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package io.github.sideshowcoder.dropwizard_openfeature;
22

33
import dev.openfeature.contrib.providers.flagd.FlagdProvider;
4+
import dev.openfeature.contrib.providers.gofeatureflag.GoFeatureFlagProvider;
5+
import dev.openfeature.contrib.providers.gofeatureflag.GoFeatureFlagProviderOptions;
6+
import dev.openfeature.contrib.providers.gofeatureflag.exception.InvalidOptions;
47
import dev.openfeature.sdk.Client;
58
import dev.openfeature.sdk.FeatureProvider;
69
import dev.openfeature.sdk.OpenFeatureAPI;
@@ -44,6 +47,13 @@ private synchronized void initializeFeatureProvider(OpenFeatureConfiguration con
4447
case FLAGD:
4548
featureProvider = new FlagdProvider(config.getFlagd().getFlagdOptions());
4649
break;
50+
case GOFEATUREFLAG:
51+
try {
52+
featureProvider = new GoFeatureFlagProvider(config.getGoFeatureFlag().getGoFeatureFlagProviderOptions());
53+
} catch(InvalidOptions e) {
54+
new RuntimeException(e);
55+
}
56+
break;
4757
}
4858
}
4959
}

src/main/java/io/github/sideshowcoder/dropwizard_openfeature/OpenFeatureConfiguration.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ public class OpenFeatureConfiguration {
1111
@JsonProperty
1212
private FlagdConfiguration flagd = new FlagdConfiguration();
1313

14+
@Valid
15+
@JsonProperty
16+
private GoFeatureFlagConfiguration gofeatureflag = new GoFeatureFlagConfiguration();
17+
1418
@Valid
1519
@JsonProperty
1620
private OpenFeatureHealthCheckConfiguration healthcheck = new OpenFeatureHealthCheckConfiguration();
@@ -28,6 +32,14 @@ public void setFlagd(FlagdConfiguration flagd) {
2832
this.flagd = flagd;
2933
}
3034

35+
public GoFeatureFlagConfiguration getGoFeatureFlag() {
36+
return gofeatureflag;
37+
}
38+
39+
public void setGoFeatureFlag(GoFeatureFlagConfiguration gofeatureflag) {
40+
this.gofeatureflag = gofeatureflag;
41+
}
42+
3143
public OpenFeatureHealthCheckConfiguration getHealthcheck() {
3244
return healthcheck;
3345
}

src/main/java/io/github/sideshowcoder/dropwizard_openfeature/ProviderType.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22

33
public enum ProviderType {
44
FLAGD,
5+
GOFEATUREFLAG,
56
INMEMORY;
67
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package io.github.sideshowcoder.dropwizard_openfeature;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertTrue;
5+
6+
import java.util.List;
7+
8+
import org.junit.jupiter.api.Test;
9+
import org.junit.jupiter.api.extension.ExtendWith;
10+
import org.testcontainers.containers.GenericContainer;
11+
import org.testcontainers.containers.wait.strategy.Wait;
12+
import org.testcontainers.junit.jupiter.Container;
13+
import org.testcontainers.junit.jupiter.Testcontainers;
14+
import org.testcontainers.utility.DockerImageName;
15+
import org.testcontainers.utility.MountableFile;
16+
17+
import com.codahale.metrics.health.HealthCheck;
18+
19+
import dev.openfeature.sdk.Client;
20+
import dev.openfeature.sdk.EvaluationContext;
21+
import dev.openfeature.sdk.ImmutableContext;
22+
import dev.openfeature.sdk.OpenFeatureAPI;
23+
import io.dropwizard.testing.ResourceHelpers;
24+
import io.dropwizard.testing.junit5.DropwizardAppExtension;
25+
import io.dropwizard.testing.junit5.DropwizardExtensionsSupport;
26+
import io.github.sideshowcoder.dropwizard_openfeature.helpers.App;
27+
import io.github.sideshowcoder.dropwizard_openfeature.helpers.Config;
28+
29+
@Testcontainers
30+
@ExtendWith(DropwizardExtensionsSupport.class)
31+
public class OpenFeatureBundleGoFeatureFlagProviderTest {
32+
33+
@Container
34+
private static GenericContainer<?> goFeatureFlagRelay = createGoFeatureFlagContainer();
35+
36+
private static GenericContainer<?> createGoFeatureFlagContainer() {
37+
GenericContainer<?> container = new GenericContainer<>(DockerImageName.parse("gofeatureflag/go-feature-flag:latest"))
38+
.withCopyFileToContainer(MountableFile.forClasspathResource("goff-proxy.yaml"), "/goff/goff-proxy.yaml")
39+
.withCopyFileToContainer(MountableFile.forClasspathResource("go-feature-flags-flags.yaml"), "/goff/flags.yaml");
40+
41+
container.setPortBindings(List.of("1031:1031"));
42+
container.waitingFor(Wait.forHttp("/health"));
43+
44+
return container;
45+
}
46+
47+
private static final DropwizardAppExtension<Config> APP = new DropwizardAppExtension<>(
48+
App.class,
49+
ResourceHelpers.resourceFilePath("go-feature-flag-provider-config.yml")
50+
);
51+
52+
@Test
53+
public void initializesHealthCheck() throws Exception {
54+
HealthCheck.Result healthcheckResult = APP.getEnvironment().healthChecks().runHealthCheck("openfeature-health-check");
55+
assertTrue(healthcheckResult.isHealthy());
56+
}
57+
58+
@Test
59+
public void providesFeatureFlagsViaInMemoryProvider() throws Exception {
60+
Client client = OpenFeatureAPI.getInstance().getClient("go-feature-flag-client");
61+
// GoFeatureFlags requires a target key for all queries!
62+
EvaluationContext ctx = new ImmutableContext("target");
63+
assertEquals("red", client.getStringValue("staticstringflag", "not-expected-value", ctx));
64+
}
65+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
host: flagd
22
port: 8082
33
resolver: rpc
4-
cacheType: disabled
4+
cacheType: disabled
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
openfeature:
2+
provider: gofeatureflag
3+
gofeatureflag:
4+
endpoint: "http://localhost:1031/"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
staticstringflag:
2+
variations:
3+
red: "red"
4+
green: "green"
5+
blue: "blue"
6+
defaultRule:
7+
variation: red

src/test/resources/goff-proxy.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
retrievers:
2+
- kind: file
3+
path: /goff/flags.yaml

0 commit comments

Comments
 (0)