Skip to content

Commit

Permalink
feat: add Unleash provider (#424)
Browse files Browse the repository at this point in the history
Signed-off-by: liran2000 <liran2000@gmail.com>
Co-authored-by: Todd Baert <todd.baert@dynatrace.com>
Co-authored-by: Ivar Conradi Østhus <ivarconr@gmail.com>
  • Loading branch information
3 people authored Sep 28, 2023
1 parent 269d284 commit ec6b3c9
Show file tree
Hide file tree
Showing 16 changed files with 979 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .github/component_owners.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ components:
- thomaspoignant
providers/jsonlogic-eval-provider:
- justinabrahms
providers/unleash:
- liran2000
- sighphyre

ignored-authors:
- renovate-bot
3 changes: 2 additions & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"providers/go-feature-flag": "0.2.13",
"providers/flagsmith": "0.0.8",
"providers/env-var": "0.0.4",
"providers/jsonlogic-eval-provider": "1.0.0"
"providers/jsonlogic-eval-provider": "1.0.0",
"providers/unleash": "0.0.1-alpha"
}
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<module>providers/go-feature-flag</module>
<module>providers/jsonlogic-eval-provider</module>
<module>providers/env-var</module>
<module>providers/unleash</module>
</modules>

<scm>
Expand Down
Empty file added providers/unleash/CHANGELOG.md
Empty file.
62 changes: 62 additions & 0 deletions providers/unleash/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Unofficial Unleash OpenFeature Provider for Java

[Unleash](https://getunleash.io) OpenFeature Provider can provide usage for Unleash via OpenFeature Java SDK.

## Installation

<!-- x-release-please-start-version -->

```xml

<dependency>
<groupId>dev.openfeature.contrib.providers</groupId>
<artifactId>unleash</artifactId>
<version>0.0.1-alpha</version>
</dependency>
```

<!-- x-release-please-end-version -->

## Concepts
* Boolean evaluation gets feature enabled status.
* String evaluation gets feature variant value.

## Usage
Unleash OpenFeature Provider is using Unleash Java SDK.

### Usage Example

```
FeatureProvider unleashProvider = new UnleashProvider(unleashProviderConfig);
OpenFeatureAPI.getInstance().setProviderAndWait(unleashProvider);
boolean featureEnabled = client.getBooleanValue(FLAG_NAME, false);
// Context parameters are optional, not mandatory to fill all parameters
MutableContext evaluationContext = new MutableContext();
evaluationContext.add("userId", userIdValue);
evaluationContext.add("currentTime", String.valueOf(currentTimeValue));
evaluationContext.add("sessionId", sessionIdValue);
evaluationContext.add("remoteAddress", remoteAddressValue);
evaluationContext.add("environment", environmentValue);
evaluationContext.add("appName", appNameValue);
evaluationContext.add(customPropertyKey, customPropertyValue);
featureEnabled = client.getBooleanValue(FLAG_NAME, false, evaluationContext);
String variantValue = client.getStringValue(FLAG_NAME, "");
```

See [UnleashProviderTest.java](./src/test/java/dev/openfeature/contrib/providers/unleash/UnleashProviderTest.java) for more information.

### Additional Usage Details

* When default value is used and returned, default variant is not used and variant name is not set.
* json/csv payloads are evaluated via object evaluation as what returned from Unleash - string, wrapped with Value.
* Additional evaluation data can be received via flag metadata, such as:
* *enabled* - boolean
* *variant-stickiness* - string
* *payload-type* - string, optional

## Unleash Provider Tests Strategies

Unit test based on Unleash instance with Unleash features schema file, with WireMock for API mocking.
See [UnleashProviderTest.java](./src/test/java/dev/openfeature/contrib/providers/unleash/UnleashProviderTest.java) for more information.
5 changes: 5 additions & 0 deletions providers/unleash/lombok.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# This file is needed to avoid errors throw by findbugs when working with lombok.
lombok.addSuppressWarnings = true
lombok.addLombokGeneratedAnnotation = true
config.stopBubbling = true
lombok.extern.findbugs.addSuppressFBWarnings = true
47 changes: 47 additions & 0 deletions providers/unleash/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>dev.openfeature.contrib</groupId>
<artifactId>parent</artifactId>
<version>0.1.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<groupId>dev.openfeature.contrib.providers</groupId>
<artifactId>unleash</artifactId>
<version>0.0.1-alpha</version> <!--x-release-please-version -->

<name>unleash</name>
<description>unleash provider for Java</description>
<url>https://www.getunleash.io/</url>

<dependencies>
<dependency>
<groupId>io.getunleash</groupId>
<artifactId>unleash-client-java</artifactId>
<version>8.3.1</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>

<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8</artifactId>
<version>2.35.1</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<version>2.20.0</version>
<scope>test</scope>
</dependency>

</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package dev.openfeature.contrib.providers.unleash;

import dev.openfeature.sdk.EvaluationContext;
import io.getunleash.UnleashContext;

import java.time.ZonedDateTime;

/**
* Transformer from Unleash context to OpenFeature context and vice versa.
*/
public class ContextTransformer {

public static final String CONTEXT_APP_NAME = "appName";
public static final String CONTEXT_USER_ID = "userId";
public static final String CONTEXT_ENVIRONMENT = "environment";
public static final String CONTEXT_REMOTE_ADDRESS = "remoteAddress";
public static final String CONTEXT_SESSION_ID = "sessionId";
public static final String CONTEXT_CURRENT_TIME = "currentTime";

protected static UnleashContext transform(EvaluationContext ctx) {
UnleashContext.Builder unleashContextBuilder = new UnleashContext.Builder();
ctx.asObjectMap().forEach((k, v) -> {
switch (k) {
case CONTEXT_APP_NAME:
unleashContextBuilder.appName(String.valueOf(v));
break;
case CONTEXT_USER_ID:
unleashContextBuilder.userId(String.valueOf(v));
break;
case CONTEXT_ENVIRONMENT:
unleashContextBuilder.environment(String.valueOf(v));
break;
case CONTEXT_REMOTE_ADDRESS:
unleashContextBuilder.remoteAddress(String.valueOf(v));
break;
case CONTEXT_SESSION_ID:
unleashContextBuilder.sessionId(String.valueOf(v));
break;
case CONTEXT_CURRENT_TIME:
unleashContextBuilder.currentTime(ZonedDateTime.parse(String.valueOf(v)));
break;
default:
unleashContextBuilder.addProperty(k, String.valueOf(v));
break;
}
});
return unleashContextBuilder.build();
}

}
Loading

0 comments on commit ec6b3c9

Please sign in to comment.