Skip to content

Commit a686742

Browse files
Merge pull request #69 from sideshowcoder/sideshowcoder/45/ofrep-support
Sideshowcoder/45/ofrep support
2 parents 172fde7 + 674182f commit a686742

14 files changed

Lines changed: 300 additions & 46 deletions

README.md

Lines changed: 53 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
1-
[![Maven Central](https://maven-badges.sml.io/sonatype-central/io.github.sideshowcoder/dropwizard-openfeature/badge.svg?version=2.0.0)](https://maven-badges.sml.io/sonatype-central/io.github.sideshowcoder/dropwizard-openfeature) ![Maven Test & Build](https://github.com/sideshowcoder/dropwizard-openfeature/actions/workflows/maven-build.yml/badge.svg)
1+
[![Maven Central](https://maven-badges.sml.io/sonatype-central/io.github.sideshowcoder/dropwizard-openfeature/badge.svg?version=2.1.0)](https://maven-badges.sml.io/sonatype-central/io.github.sideshowcoder/dropwizard-openfeature) ![Maven Test & Build](https://github.com/sideshowcoder/dropwizard-openfeature/actions/workflows/maven-build.yml/badge.svg)
22

33
# Dropwizard Openfeature
44

5-
This plugin integrates [openfeature][1] with dropwizard and allows you to use openfeature feature
6-
flags, provided by supported openfeature providers via a managed `OpenFeatureAPI` instance.
5+
This plugin integrates [openfeature][1] with dropwizard and allows you to use
6+
openfeature feature flags, provided by supported openfeature providers via a
7+
managed `OpenFeatureAPI` instance.
78

8-
Currently only [flagd][2] and the SDKs [InMemoryProvider][3] providers are supported
9+
It implements support for
10+
- [InMemoryProvider][3] useful for testing
11+
- [flagd][2]
12+
- [GO Feature Flag][6]
13+
- [OpenFeature Remote Evaluation Protocol (OFREP)][8] to support any providers implementing it
14+
15+
Currently only [flagd][2] and the SDKs [InMemoryProvider][3] providers are
16+
supported
917

1018
## Installing the bundle
1119

@@ -17,7 +25,7 @@ Currently only [flagd][2] and the SDKs [InMemoryProvider][3] providers are suppo
1725
<dependency>
1826
<groupId>io.github.sideshowcoder</groupId>
1927
<artifactId>dropwizard-openfeature</artifactId>
20-
<version>2.0.0</version>
28+
<version>2.1.0</version>
2129
</dependency>
2230
```
2331

@@ -35,38 +43,49 @@ After installing the plugin locally you can include it in your `pom.xml`
3543
<dependency>
3644
<groupId>io.github.sideshowcoder</groupId>
3745
<artifactId>dropwizard-openfeature</artifactId>
38-
<version>2.0.1-SNAPSHOT</version>
46+
<version>2.1.1-SNAPSHOT</version>
3947
</dependency>
4048
```
4149

42-
43-
4450
## Included in the bundle
4551

4652
### Supported providers
4753

48-
The bundle currently supports both the SDK included `InMemoryProvider` as well as `flagd`, the provider can be selected
49-
via the configuration. For details on the configuration options see `FlagdConfiguration` as well the
50-
[flagd documentation][5].
54+
Currently the following providers, implemented in the
55+
[open-feature/java-sdk-contrib][11] are supported, and their respective most
56+
used configuration options are mapped to yaml configuration. Addtional
57+
configuration can be set by accessing the underlying provider as needed.
58+
59+
- [InMemoryProvider][3]
60+
- [flagd][9]
61+
- [GO Feature Flag][10]
62+
- [OpenFeature Remote Evaluation Protocol (OFREP)][7] to support any providers
63+
implementing it
64+
65+
For the configuration see the respective configuration classes.
5166

5267
### OpenFeatureAPI management
5368

54-
The initialized `OpenFeatureAPI` is managed via the dropwizard lifecycle and will be shutdown gracefully upon
55-
application shutdown, see `OpenFeatureAPIManager`.
69+
The initialized `OpenFeatureAPI` is managed via the dropwizard lifecycle and
70+
will be shutdown gracefully upon application shutdown, see
71+
`OpenFeatureAPIManager`.
5672

5773
### Healthcheck
5874

59-
By default the bundle registers a healthcheck on the state of the provider configured, this healthcheck can be further
60-
configured via the `OpenFeatureHealthCheckConfiguration`.
75+
By default the bundle registers a healthcheck on the state of the provider
76+
configured, this healthcheck can be further configured via the
77+
`OpenFeatureHealthCheckConfiguration`.
6178

6279
## Activating the bundle
6380

6481
Your Dropwizard application configuration class must implement `OpenFeatureBundleConfiguration`
6582

6683
### Configuring dropwizard-openfeature in the dropwizard config file
6784

68-
For a full overview see `OpenFeatureConfiguration`, `OpenFeatureHealthCheckConfiguration`, and `FlagdConfiguration` a
69-
minimal configuration for flagd runnining locally on the port 8013 would look as follows.
85+
For a full overview see `OpenFeatureConfiguration`,
86+
`OpenFeatureHealthCheckConfiguration`, and the respective provider specific
87+
configuration. A minimal configuration for flagd runnining locally on the port
88+
8013 would look as follows.
7089

7190
```yaml
7291
openfeature:
@@ -76,8 +95,8 @@ openfeature:
7695
port: 8013
7796
```
7897
79-
For the bundle to have access to the configuration, your application configuration needs to implement
80-
`OpenFeatureBundleConfiguration`.
98+
For the bundle to have access to the configuration, your application
99+
configuration needs to implement `OpenFeatureBundleConfiguration`.
81100

82101
```java
83102
public class Config extends Configuration implements OpenFeatureBundleConfiguration {
@@ -96,7 +115,8 @@ public class Config extends Configuration implements OpenFeatureBundleConfigurat
96115

97116
### Initialization
98117

99-
In your application's `initialize` method, call `bootstrap.addBundle(new OpenFeatureBundle())`:
118+
In your application's `initialize` method, call `bootstrap.addBundle(new
119+
OpenFeatureBundle())`:
100120

101121
```java
102122
public class App extends Application<Config> {
@@ -115,9 +135,10 @@ public class App extends Application<Config> {
115135

116136
### Using the client
117137

118-
OpenFeature configures a global `OpenFeatureAPI` which grants access to a client, which can be injected as needed, it is
119-
common practise to provide a domain as an identifier, this is however not required, unless multiple clients are to be
120-
created.
138+
OpenFeature configures a global `OpenFeatureAPI` which grants access to a
139+
client, which can be injected as needed, it is common practise to provide a
140+
domain as an identifier, this is however not required, unless multiple clients
141+
are to be created.
121142

122143
```java
123144
public class App extends Application<Config> {
@@ -144,8 +165,9 @@ public class App extends Application<Config> {
144165

145166
### Accessing the underlying feature provider
146167

147-
The bundle exposes access to the underlying feature provider. Useful for runtime configuration and introspection of the
148-
provider. For example when using the `InMemoryProvider` flags can be updated at runtime for example for testing.
168+
The bundle exposes access to the underlying feature provider. Useful for runtime
169+
configuration and introspection of the provider. For example when using the
170+
`InMemoryProvider` flags can be updated at runtime for example for testing.
149171

150172
```java
151173
public class App extends Application<Config> {
@@ -177,3 +199,9 @@ public class App extends Application<Config> {
177199
[3]: https://github.com/open-feature/java-sdk/blob/main/src/main/java/dev/openfeature/sdk/providers/memory/InMemoryProvider.java
178200
[4]: https://central.sonatype.com/artifact/io.github.sideshowcoder/dropwizard-openfeature
179201
[5]: https://flagd.dev/providers/java/
202+
[6]: https://gofeatureflag.org
203+
[7]: https://github.com/open-feature/java-sdk-contrib/tree/main/providers/ofrep
204+
[8]: https://openfeature.dev/docs/reference/other-technologies/ofrep/
205+
[9]: https://github.com/open-feature/java-sdk-contrib/tree/main/providers/flagd
206+
[10]: https://github.com/open-feature/java-sdk-contrib/tree/main/providers/go-feature-flag
207+
[11]: https://github.com/open-feature/java-sdk-contrib

compose.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
services:
2+
go-feature-flag:
3+
image: gofeatureflag/go-feature-flag:latest
4+
ports:
5+
- 1031:1031 # relay proxy port
6+
volumes:
7+
# relay proxy config
8+
- ./src/test/resources/goff-proxy.yaml:/goff/goff-proxy.yaml
9+
# flags to be served
10+
- ./src/test/resources/go-feature-flags-flags.yaml:/goff/flags.yaml
11+
flagd:
12+
image: ghcr.io/open-feature/flagd:latest
13+
command: start --uri file:/etc/flagd/flagd-test-flags.json
14+
ports:
15+
- 8013:8013 # standard port
16+
- 8016:8016 # ofrep port
17+
volumes:
18+
- ./src/test/resources:/etc/flagd

flag-provider-requests.restclient

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
### flagd ###
2+
POST http://localhost:8013/flagd.evaluation.v1.Service/ResolveString
3+
Content-Type: application/json
4+
5+
{
6+
"flagKey": "static-string-flag",
7+
"context": {}
8+
}
9+
10+
### ofrep ###
11+
12+
# flagd bulk
13+
POST http://localhost:8016/ofrep/v1/evaluate/flags
14+
15+
# flagd flag
16+
POST http://localhost:8016/ofrep/v1/evaluate/flags/static-string-flag
17+
18+
# go-feature-flag
19+
POST http://localhost:1031/ofrep/v1/evaluate/flags/staticstringflag
20+
Content-Type: application/json
21+
22+
{
23+
"context": {
24+
"targetingKey": "key"
25+
}
26+
}
27+
28+
# go-feature-flag bulk
29+
POST http://localhost:1031/ofrep/v1/evaluate/flags
30+
Content-Type: application/json
31+
32+
{
33+
"context": {
34+
"targetingKey": "key"
35+
}
36+
}

pom.xml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>io.github.sideshowcoder</groupId>
88
<artifactId>dropwizard-openfeature</artifactId>
9-
<version>2.0.1-SNAPSHOT</version>
9+
<version>2.1.0</version>
1010
<packaging>jar</packaging>
1111

1212
<name>dropwizard-openfeature</name>
@@ -23,6 +23,7 @@
2323
<openfeature-sdk.version>1.20.1</openfeature-sdk.version>
2424
<openfeature-contrib-providers-flagd.version>0.11.20</openfeature-contrib-providers-flagd.version>
2525
<openfeature-contrib-providers-go-feature-flag.version>1.1.1</openfeature-contrib-providers-go-feature-flag.version>
26+
<openfeature-contrib-providers-ofrep.version>0.0.1</openfeature-contrib-providers-ofrep.version>
2627
<jacoco-maven-plugin.version>0.8.14</jacoco-maven-plugin.version>
2728
<maven-compiler-plugin.version>3.15.0</maven-compiler-plugin.version>
2829
<maven-gpg-plugin.version>3.2.8</maven-gpg-plugin.version>
@@ -116,6 +117,7 @@
116117
<artifactId>sdk</artifactId>
117118
<version>${openfeature-sdk.version}</version>
118119
</dependency>
120+
119121
<dependency>
120122
<groupId>dev.openfeature.contrib.providers</groupId>
121123
<artifactId>flagd</artifactId>
@@ -126,6 +128,11 @@
126128
<artifactId>go-feature-flag</artifactId>
127129
<version>${openfeature-contrib-providers-go-feature-flag.version}</version>
128130
</dependency>
131+
<dependency>
132+
<groupId>dev.openfeature.contrib.providers</groupId>
133+
<artifactId>ofrep</artifactId>
134+
<version>${openfeature-contrib-providers-ofrep.version}</version>
135+
</dependency>
129136

130137
<dependency>
131138
<groupId>io.dropwizard</groupId>

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@
77
import dev.openfeature.contrib.providers.gofeatureflag.exception.InvalidOptions;
88
import jakarta.validation.constraints.NotNull;
99

10+
/**
11+
* Maps the {@link GoFeatureFlagConfiguration} confiuration in yaml to the actual {@link GoFeatureFlagProviderOptions }.
12+
*
13+
* Supported options
14+
*
15+
* Name | Type | example | required | description
16+
* endpoit | String | http://localhost:8016 | yes | endpoint to reach the GoFeatureFlag relay proxy
17+
*/
1018
public class GoFeatureFlagConfiguration {
1119

1220
@JsonProperty
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package io.github.sideshowcoder.dropwizard_openfeature;
2+
3+
import java.time.Duration;
4+
import java.util.concurrent.Executor;
5+
import java.util.concurrent.Executors;
6+
7+
import com.fasterxml.jackson.annotation.JsonProperty;
8+
9+
import dev.openfeature.contrib.providers.ofrep.OfrepProviderOptions;
10+
import jakarta.validation.constraints.NotNull;
11+
12+
/**
13+
* Maps the ofrep confiuration in yaml to the actual {@link OfrepProviderOptions}.
14+
*
15+
* Supported options
16+
*
17+
* Name | Type | example | required | description
18+
* baseurl | String | http://localhost:8016 | yes | baseurl for the ofrep protocol to use
19+
* timeout | long | 500 | no | request timeout in millis
20+
* threadcount | int | 5 | no | thread pool size for the http client
21+
*/
22+
public class OfrepConfiguration {
23+
24+
@JsonProperty
25+
@NotNull
26+
private String baseurl;
27+
28+
@JsonProperty
29+
private long timeout;
30+
31+
@JsonProperty
32+
private int threadcount;
33+
34+
public OfrepProviderOptions getOfrepProviderOptions() {
35+
OfrepProviderOptions.Builder builder = OfrepProviderOptions.builder().baseUrl(baseurl);
36+
37+
if (timeout != 0) {
38+
Duration requestTimeout = Duration.ofMillis(timeout);
39+
builder.requestTimeout(requestTimeout);
40+
}
41+
42+
if (threadcount != 0) {
43+
Executor executor = Executors.newFixedThreadPool(threadcount);
44+
builder.executor(executor);
45+
}
46+
47+
return builder.build();
48+
}
49+
}
50+

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
import dev.openfeature.contrib.providers.flagd.FlagdProvider;
44
import dev.openfeature.contrib.providers.gofeatureflag.GoFeatureFlagProvider;
5-
import dev.openfeature.contrib.providers.gofeatureflag.GoFeatureFlagProviderOptions;
65
import dev.openfeature.contrib.providers.gofeatureflag.exception.InvalidOptions;
6+
import dev.openfeature.contrib.providers.ofrep.OfrepProvider;
77
import dev.openfeature.sdk.Client;
88
import dev.openfeature.sdk.FeatureProvider;
99
import dev.openfeature.sdk.OpenFeatureAPI;
@@ -54,6 +54,9 @@ private synchronized void initializeFeatureProvider(OpenFeatureConfiguration con
5454
new RuntimeException(e);
5555
}
5656
break;
57+
case OFREP:
58+
featureProvider = OfrepProvider.constructProvider(config.getOfrep().getOfrepProviderOptions());
59+
break;
5760
}
5861
}
5962
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ public class OpenFeatureConfiguration {
1515
@JsonProperty
1616
private GoFeatureFlagConfiguration gofeatureflag = new GoFeatureFlagConfiguration();
1717

18+
@Valid
19+
@JsonProperty
20+
private OfrepConfiguration ofrep = new OfrepConfiguration();
21+
1822
@Valid
1923
@JsonProperty
2024
private OpenFeatureHealthCheckConfiguration healthcheck = new OpenFeatureHealthCheckConfiguration();
@@ -40,6 +44,14 @@ public void setGoFeatureFlag(GoFeatureFlagConfiguration gofeatureflag) {
4044
this.gofeatureflag = gofeatureflag;
4145
}
4246

47+
public OfrepConfiguration getOfrep() {
48+
return ofrep;
49+
}
50+
51+
public void setOfrep(OfrepConfiguration ofrep) {
52+
this.ofrep = ofrep;
53+
}
54+
4355
public OpenFeatureHealthCheckConfiguration getHealthcheck() {
4456
return healthcheck;
4557
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
public enum ProviderType {
44
FLAGD,
55
GOFEATUREFLAG,
6+
OFREP,
67
INMEMORY;
78
}

0 commit comments

Comments
 (0)