This plugin integrates openfeature with dropwizard and allows you to use
openfeature feature flags, provided by supported openfeature providers via a
managed OpenFeatureAPI instance.
It implements support for
- InMemoryProvider useful for testing
- flagd
- GO Feature Flag
- OpenFeature Remote Evaluation Protocol (OFREP) to support any providers implementing it
Currently only flagd and the SDKs InMemoryProvider providers are supported
io.github.sideshowcoder/dropwizard-openfeature
<dependency>
<groupId>io.github.sideshowcoder</groupId>
<artifactId>dropwizard-openfeature</artifactId>
<version>2.1.0</version>
</dependency>git clone https://github.com/sideshowcoder/dropwizard-openfeature
cd dropwizard-openfeature
./mvn install
After installing the plugin locally you can include it in your pom.xml
<dependency>
<groupId>io.github.sideshowcoder</groupId>
<artifactId>dropwizard-openfeature</artifactId>
<version>2.1.1-SNAPSHOT</version>
</dependency>Currently the following providers, implemented in the open-feature/java-sdk-contrib are supported, and their respective most used configuration options are mapped to yaml configuration. Addtional configuration can be set by accessing the underlying provider as needed.
- InMemoryProvider
- flagd
- GO Feature Flag
- OpenFeature Remote Evaluation Protocol (OFREP) to support any providers implementing it
For the configuration see the respective configuration classes.
The initialized OpenFeatureAPI is managed via the dropwizard lifecycle and
will be shutdown gracefully upon application shutdown, see
OpenFeatureAPIManager.
By default the bundle registers a healthcheck on the state of the provider
configured, this healthcheck can be further configured via the
OpenFeatureHealthCheckConfiguration.
Your Dropwizard application configuration class must implement OpenFeatureBundleConfiguration
For a full overview see OpenFeatureConfiguration,
OpenFeatureHealthCheckConfiguration, and the respective provider specific
configuration. A minimal configuration for flagd runnining locally on the port
8013 would look as follows.
openfeature:
provider: flagd
flagd:
host: localhost
port: 8013For the bundle to have access to the configuration, your application
configuration needs to implement OpenFeatureBundleConfiguration.
public class Config extends Configuration implements OpenFeatureBundleConfiguration {
@Valid
@NotNull
@JsonProperty
private OpenFeatureConfiguration openfeature;
@Override
public OpenFeatureConfiguration getOpenFeatureConfiguration() {
return openfeature;
}
}In your application's initialize method, call bootstrap.addBundle(new OpenFeatureBundle()):
public class App extends Application<Config> {
@Override
public void initialize(Bootstrap<MyConfiguration> bootstrap) {
bootstrap.addBundle(new OpenFeatureBundle());
}
@Override
public void run(Config config, Environment environment) throws Exception {
/* ... */
}
}OpenFeature configures a global OpenFeatureAPI which grants access to a
client, which can be injected as needed, it is common practise to provide a
domain as an identifier, this is however not required, unless multiple clients
are to be created.
public class App extends Application<Config> {
@Override
public void initialize(Bootstrap<MyConfiguration> bootstrap) {
bootstrap.addBundle(new OpenFeatureBundle());
}
@Override
public void run(Config config, Environment environment) throws Exception {
/* ... */
var client = OpenFeatureAPI.getInstance().getClient("my-application-domain");
var myResource = new MyResource(client);
environment.jersey().register(myResource);
var myOtherResource = new MyOtherResource(client);
environment.jersey().register(myResource);
/* ... */
}
}The bundle exposes access to the underlying feature provider. Useful for runtime
configuration and introspection of the provider. For example when using the
InMemoryProvider flags can be updated at runtime for example for testing.
public class App extends Application<Config> {
private OpenFeatureBundle bundle;
private InMemoryProvider provider;
@Override
public void initialize(Bootstrap<MyConfiguration> bootstrap) {
bundle = new OpenFeatureBundle();
bootstrap.addBundle(bundle);
}
@Override
public void run(Config config, Environment environment) throws Exception {
// ...
provider = (InMemoryProvider) bundle.getFeatureProvider();
provider.updateFlags(Map.of(/* ... */));
// ...
}
}