Java implementation of the OpenFeature SDK
Go to file
Todd Baert bad5b0a7f5
feat: events (#476)
* feat: events

Signed-off-by: Todd Baert <todd.baert@dynatrace.com>

* fixup: fix bad import, fix test

Signed-off-by: Todd Baert <todd.baert@dynatrace.com>

* fixup: add more coverage of internal

Signed-off-by: Todd Baert <todd.baert@dynatrace.com>

* fixup: remove unused imports

Signed-off-by: Todd Baert <todd.baert@dynatrace.com>

* fixup: unsed imports

Signed-off-by: Todd Baert <todd.baert@dynatrace.com>

* fixup: make inner static

Signed-off-by: Todd Baert <todd.baert@dynatrace.com>

* fixup: more tests, run ready immediately

Signed-off-by: Todd Baert <todd.baert@dynatrace.com>

* fixup: improve reliability of error tests

Signed-off-by: Todd Baert <todd.baert@dynatrace.com>

* Update src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java

Co-authored-by: Giovanni Liva <giovanni.liva@dynatrace.com>
Signed-off-by: Todd Baert <todd.baert@dynatrace.com>

* fixup: review feedback, add comments

Signed-off-by: Todd Baert <todd.baert@dynatrace.com>

* fixup: add provider repo tests, fitest warnings

Signed-off-by: Todd Baert <todd.baert@dynatrace.com>

* Update src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java

Co-authored-by: Kavindu Dodanduwa <Kavindu-Dodan@users.noreply.github.com>
Signed-off-by: Todd Baert <todd.baert@dynatrace.com>

* fixup: shorten javadoc links, shutdown tasks, use methods refs

Signed-off-by: Todd Baert <todd.baert@dynatrace.com>

* fixup: flaky test

Signed-off-by: Todd Baert <todd.baert@dynatrace.com>

* Update src/main/java/dev/openfeature/sdk/OpenFeatureClient.java

Co-authored-by: Justin Abrahms <jabrahms@ebay.com>
Signed-off-by: Todd Baert <todd.baert@dynatrace.com>

* fixup: feedback from justin

Signed-off-by: Todd Baert <todd.baert@dynatrace.com>

* fixup: improve javadoc

Signed-off-by: Todd Baert <todd.baert@dynatrace.com>

* fixup: test race condition fixes

Signed-off-by: Todd Baert <todd.baert@dynatrace.com>

---------

Signed-off-by: Todd Baert <todd.baert@dynatrace.com>
Co-authored-by: Giovanni Liva <giovanni.liva@dynatrace.com>
Co-authored-by: Kavindu Dodanduwa <Kavindu-Dodan@users.noreply.github.com>
Co-authored-by: Justin Abrahms <jabrahms@ebay.com>
2023-07-12 09:22:16 -07:00
.github/workflows chore(deps): update github/codeql-action digest to 12aa0a6 (#505) 2023-07-12 12:04:19 +00:00
docs chore: Add release plz (#66) 2022-09-13 11:36:42 -07:00
release Add release instructions & build caches 2022-06-24 00:04:35 -05:00
src feat: events (#476) 2023-07-12 09:22:16 -07:00
test-harness@2d4c63c800 chore: update cuke submodule, tests (#231) 2023-01-10 09:28:17 -08:00
.clomonitor.yml chore: Document where to find our SBOMs (#124) 2022-10-06 16:33:11 -04:00
.gitattributes Skeleton implementation of the java sdk 2022-04-20 21:12:09 -07:00
.gitignore Handle null provider, all author code in try/catch 2022-08-15 08:57:55 -04:00
.gitmodules chore: add integration tests (#77) 2022-09-20 09:48:34 -04:00
.release-please-manifest.json chore(main): release 1.3.1 (#331) 2023-03-28 13:33:51 -04:00
CHANGELOG.md chore(main): release 1.3.1 (#331) 2023-03-28 13:33:51 -04:00
CODEOWNERS chore: update CODEOWNERS 2023-03-23 15:24:11 -04:00
CONTRIBUTING.md chore: rename integration tests e2e (#417) 2023-05-03 04:36:22 +00:00
LICENSE Add Apache2.0 license 2022-04-29 15:21:59 -04:00
README.md chore: update copy and links on the readme (#488) 2023-06-23 15:23:58 -04:00
checkstyle-suppressions.xml chore: fix issues with compilation on later JDKs (#178) 2022-11-20 23:25:45 -08:00
checkstyle.xml chore: fix issues with compilation on later JDKs (#178) 2022-11-20 23:25:45 -08:00
pom.xml feat: events (#476) 2023-07-12 09:22:16 -07:00
release-please-config.json chore: add changelog sections (#320) 2023-03-08 12:33:13 -08:00
renovate.json chore: renovate regex manager to monitor test-harness version (#238) 2023-01-12 12:42:10 -05:00
spec_finder.py Keep tests in line with spec changes 2022-08-29 11:18:46 -07:00
spotbugs-exclusions.xml chore: fix issues with compilation on later JDKs (#178) 2022-11-20 23:25:45 -08:00
version.txt chore(main): release 1.3.1 (#331) 2023-03-28 13:33:51 -04:00

README.md

OpenFeature Logo

OpenFeature Java SDK

Specification Maven Central javadoc Project Status: Active – The project has reached a stable, usable state and is being actively developed. Known Vulnerabilities on-merge codecov CII Best Practices

👋 Hey there! Thanks for checking out the OpenFeature Java SDK

What is OpenFeature?

OpenFeature is an open standard that provides a vendor-agnostic, community-driven API for feature flagging that works with your favorite feature flag management tool.

Why standardize feature flags?

Standardizing feature flags unifies tools and vendors behind a common interface which avoids vendor lock-in at the code level. Additionally, it offers a framework for building extensions and integrations and allows providers to focus on their unique value proposition.

🔍 Requirements:

  • Java 8+ (compiler target is 1.8)

Note that this library is intended to be used in server-side contexts and has not been evaluated for use in mobile devices.

📦 Installation:

Maven

<dependency>
    <groupId>dev.openfeature</groupId>
    <artifactId>sdk</artifactId>
    <version>1.3.1</version>
</dependency>

If you would like snapshot builds, this is the relevant repository information:

<repositories>
    <repository>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
        <id>sonartype</id>
        <name>Sonartype Repository</name>
        <url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
    </repository>
</repositories>

Gradle

dependencies {
    implementation 'dev.openfeature:sdk:1.3.1'
}

Software Bill of Materials (SBOM)

We publish SBOMs with all of our releases as of 0.3.0. You can find them in Maven Central alongside the artifacts.

🌟 Features:

  • support for various backend providers
  • easy integration and extension via hooks
  • bool, string, numeric, and object flag types
  • context-aware evaluation

🚀 Usage:

Basics:

public void example(){

    // configure a provider
    OpenFeatureAPI api = OpenFeatureAPI.getInstance();
    api.setProvider(new MyProviderOfChoice());

    // create a client
    Client client = api.getClient();

    // get a bool flag value
    boolean flagValue = client.getBooleanValue("boolFlag", false);
}

Context-aware evaluation:

Sometimes the value of a flag must take into account some dynamic criteria about the application or user, such as the user location, IP, email address, or the location of the server. In OpenFeature, we refer to this as targeting. If the flag system you're using supports targeting, you can provide the input data using the EvaluationContext.

// global context for static data
OpenFeatureAPI api = OpenFeatureAPI.getInstance();
Map<String, Value> attributes = new HashMap<>();
attributes.put("appVersion", new Value(System.getEnv("APP_VERSION")));
EvaluationContext apiCtx = new ImmutableContext(attributes);
api.setEvaluationContext(apiCtx);

// request context
Map<String, Value> attributes = new HashMap<>();
attributes.put("email", new Value(session.getAttribute("email")));
attributes.put("product", new Value(productId));
String targetingKey = session.getId();
EvaluationContext reqCtx = new ImmutableContext(targetingKey, attributes);

// use merged contextual data to determine a flag value
boolean flagValue = client.getBooleanValue("some-flag", false, reqCtx);

Providers:

To develop a provider, you need to create a new project and include the OpenFeature SDK as a dependency. This can be a new repository or included in the existing contrib repository available under the OpenFeature organization. Finally, youll then need to write the provider itself. This can be accomplished by implementing the FeatureProvider interface exported by the OpenFeature SDK.

public class MyProvider implements FeatureProvider {
@Override
    public Metadata getMetadata() {
        return () -> "My Provider";
    }

    @Override
    public ProviderEvaluation<Boolean> getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx) {
        // resolve a boolean flag value
    }

    @Override
    public ProviderEvaluation<String> getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) {
        // resolve a string flag value
    }

    @Override
    public ProviderEvaluation<Integer> getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) {
        // resolve an int flag value
    }

    @Override
    public ProviderEvaluation<Double> getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx) {
        // resolve a double flag value
    }

    @Override
    public ProviderEvaluation<Value> getObjectEvaluation(String key, Value defaultValue, EvaluationContext ctx) {
        // resolve an object flag value
    }
}

See here for a catalog of available providers.

Hooks:

A hook is a mechanism that allows for adding arbitrary behavior at well-defined points of the flag evaluation life-cycle. Use cases include validating the resolved flag value, modifying or adding data to the evaluation context, logging, telemetry, and tracking.

public class MyHook implements Hook {
    /**
     *
     * @param ctx     Information about the particular flag evaluation
     * @param details Information about how the flag was resolved, including any resolved values.
     * @param hints   An immutable mapping of data for users to communicate to the hooks.
     */
    @Override
    public void after(HookContext ctx, FlagEvaluationDetails details, Map hints) {
        System.out.println("After evaluation!");
    }
}

See here for a catalog of available hooks.

Logging:

The Java SDK uses SLF4J. See the SLF4J manual for complete documentation.

Complete API documentation:

See here for the complete API documentation.

Support the project

🤝 Contributing

Interested in contributing? Great, we'd love your help! To get started, take a look at the CONTRIBUTING guide.

Thanks to everyone that has already contributed

Pictures of the folks who have contributed to the project

Made with contrib.rocks.

📜 License

Apache License 2.0