Skip to content

Commit

Permalink
refactor(flipt): upgrade Flipt provider to use latest 1.0.0 Flipt SDK (
Browse files Browse the repository at this point in the history
…#638)

Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
  • Loading branch information
markphelps authored Jan 26, 2024
1 parent 4a5cac2 commit 42738b8
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 74 deletions.
16 changes: 12 additions & 4 deletions providers/flipt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,34 @@
<!-- x-release-please-start-version -->

```xml

<dependency>
<groupId>dev.openfeature.contrib.providers</groupId>
<artifactId>flipt</artifactId>
<version>0.0.2</version>
<version>0.1.0</version>
</dependency>
```

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

## Concepts

* Boolean evaluation gets feature boolean evaluation / enabled status.
* Non-boolean evaluation gets feature variant key.

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

Flipt OpenFeature Provider uses Flipt's [Server Java SDK](https://github.com/flipt-io/flipt-server-sdks/tree/main/flipt-java).

### Usage Example

```
```java
// create a Flipt client and provider
FliptClientBuilder fliptClientBuilder = FliptClient.builder().url(apiUrl);
FliptProviderConfig fliptProviderConfig = FliptProviderConfig.builder()
.fliptClientBuilder(fliptClientBuilder)
.build();

// create OpenFeature provider
FeatureProvider featureProvider = new FliptProvider(fliptProviderConfig);
OpenFeatureAPI.getInstance().setProviderAndWait("sync", fliptProvider);
client = OpenFeatureAPI.getInstance().getClient("sync");
Expand Down
26 changes: 23 additions & 3 deletions providers/flipt/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</parent>
<groupId>dev.openfeature.contrib.providers</groupId>
<artifactId>flipt</artifactId>
<version>0.0.2</version> <!--x-release-please-version -->
<version>0.1.0</version> <!--x-release-please-version -->

<name>flipt</name>
<description>Flipt provider for Java</description>
Expand All @@ -24,7 +24,7 @@
<dependency>
<groupId>io.flipt</groupId>
<artifactId>flipt-java</artifactId>
<version>0.2.15</version>
<version>1.0.1</version>
</dependency>

<dependency>
Expand All @@ -40,12 +40,32 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.16.1</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.16.1</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.16.1</version>
<scope>test</scope>
</dependency>

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

</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package dev.openfeature.contrib.providers.flipt;

import com.flipt.api.FliptApiClient;
import com.flipt.api.resources.evaluation.types.BooleanEvaluationResponse;
import com.flipt.api.resources.evaluation.types.EvaluationRequest;
import com.flipt.api.resources.evaluation.types.VariantEvaluationResponse;
import dev.openfeature.sdk.EvaluationContext;
import dev.openfeature.sdk.EventProvider;
import dev.openfeature.sdk.ImmutableMetadata;
Expand All @@ -14,6 +10,10 @@
import dev.openfeature.sdk.Value;
import dev.openfeature.sdk.exceptions.GeneralError;
import dev.openfeature.sdk.exceptions.ProviderNotReadyError;
import io.flipt.api.FliptClient;
import io.flipt.api.evaluation.models.BooleanEvaluationResponse;
import io.flipt.api.evaluation.models.EvaluationRequest;
import io.flipt.api.evaluation.models.VariantEvaluationResponse;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
Expand Down Expand Up @@ -41,7 +41,7 @@ public class FliptProvider extends EventProvider {

@Setter(AccessLevel.PROTECTED)
@Getter
private FliptApiClient fliptApiClient;
private FliptClient fliptClient;

@Setter(AccessLevel.PROTECTED)
@Getter
Expand All @@ -51,6 +51,7 @@ public class FliptProvider extends EventProvider {

/**
* Constructor.
*
* @param fliptProviderConfig FliptProviderConfig
*/
public FliptProvider(FliptProviderConfig fliptProviderConfig) {
Expand All @@ -59,6 +60,7 @@ public FliptProvider(FliptProviderConfig fliptProviderConfig) {

/**
* Initialize the provider.
*
* @param evaluationContext evaluation context
* @throws Exception on error
*/
Expand All @@ -69,7 +71,7 @@ public void initialize(EvaluationContext evaluationContext) throws Exception {
throw new GeneralError("already initialized");
}
super.initialize(evaluationContext);
fliptApiClient = fliptProviderConfig.getFliptApiClientBuilder().build();
fliptClient = fliptProviderConfig.getFliptClientBuilder().build();

state = ProviderState.READY;
log.info("finished initializing provider, state: {}", state);
Expand Down Expand Up @@ -103,45 +105,45 @@ public ProviderEvaluation<Boolean> getBooleanEvaluation(String key, Boolean defa

Map<String, String> contextMap = ContextTransformer.transform(ctx);
EvaluationRequest request = EvaluationRequest.builder().namespaceKey(fliptProviderConfig.getNamespace())
.flagKey(key).entityId(ctx.getTargetingKey()).context(contextMap).build();
.flagKey(key).entityId(ctx.getTargetingKey()).context(contextMap).build();

BooleanEvaluationResponse response = null;
try {
response = fliptApiClient.evaluation().boolean_(request);
response = fliptClient.evaluation().evaluateBoolean(request);
} catch (Exception e) {
log.error("Error evaluating boolean", e);
throw new GeneralError(e.getMessage());
}

return ProviderEvaluation.<Boolean>builder()
.value(response.getEnabled())
.reason(response.getReason().toString())
.build();
.value(response.isEnabled())
.reason(response.getReason().toString())
.build();
}

@Override
public ProviderEvaluation<String> getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) {
ProviderEvaluation<Value> valueProviderEvaluation = getObjectEvaluation(key, new Value(defaultValue), ctx);
return ProviderEvaluation.<String>builder()
.value(valueProviderEvaluation.getValue().asString())
.variant(valueProviderEvaluation.getVariant())
.value(valueProviderEvaluation.getValue().asString())
.variant(valueProviderEvaluation.getVariant())
.errorCode(valueProviderEvaluation.getErrorCode())
.reason(valueProviderEvaluation.getReason())
.flagMetadata(valueProviderEvaluation.getFlagMetadata())
.build();
.build();
}

@Override
public ProviderEvaluation<Integer> getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) {
ProviderEvaluation<Value> valueProviderEvaluation = getObjectEvaluation(key, new Value(defaultValue), ctx);
Integer value = getIntegerValue(valueProviderEvaluation, defaultValue);
return ProviderEvaluation.<Integer>builder()
.value(value)
.variant(valueProviderEvaluation.getVariant())
.errorCode(valueProviderEvaluation.getErrorCode())
.reason(valueProviderEvaluation.getReason())
.flagMetadata(valueProviderEvaluation.getFlagMetadata())
.build();
.value(value)
.variant(valueProviderEvaluation.getVariant())
.errorCode(valueProviderEvaluation.getErrorCode())
.reason(valueProviderEvaluation.getReason())
.flagMetadata(valueProviderEvaluation.getFlagMetadata())
.build();
}

private static Integer getIntegerValue(ProviderEvaluation<Value> valueProviderEvaluation, Integer defaultValue) {
Expand All @@ -158,12 +160,12 @@ public ProviderEvaluation<Double> getDoubleEvaluation(String key, Double default
ProviderEvaluation<Value> valueProviderEvaluation = getObjectEvaluation(key, new Value(defaultValue), ctx);
Double value = getDoubleValue(valueProviderEvaluation, defaultValue);
return ProviderEvaluation.<Double>builder()
.value(value)
.variant(valueProviderEvaluation.getVariant())
.errorCode(valueProviderEvaluation.getErrorCode())
.reason(valueProviderEvaluation.getReason())
.flagMetadata(valueProviderEvaluation.getFlagMetadata())
.build();
.value(value)
.variant(valueProviderEvaluation.getVariant())
.errorCode(valueProviderEvaluation.getErrorCode())
.reason(valueProviderEvaluation.getReason())
.flagMetadata(valueProviderEvaluation.getFlagMetadata())
.build();
}

private static Double getDoubleValue(ProviderEvaluation<Value> valueProviderEvaluation, Double defaultValue) {
Expand All @@ -185,22 +187,22 @@ public ProviderEvaluation<Value> getObjectEvaluation(String key, Value defaultVa
}
Map<String, String> contextMap = ContextTransformer.transform(ctx);
EvaluationRequest request = EvaluationRequest.builder().namespaceKey(fliptProviderConfig.getNamespace())
.flagKey(key).entityId(ctx.getTargetingKey()).context(contextMap).build();
.flagKey(key).entityId(ctx.getTargetingKey()).context(contextMap).build();

VariantEvaluationResponse response;
try {
response = fliptApiClient.evaluation().variant(request);
response = fliptClient.evaluation().evaluateVariant(request);
} catch (Exception e) {
log.error("Error evaluating variant", e);
throw new GeneralError(e.getMessage());
}

if (!response.getMatch()) {
if (!response.isMatch()) {
log.debug("non matching variant for {} : {}", key, response.getReason());
return ProviderEvaluation.<Value>builder()
.value(defaultValue)
.reason(DEFAULT.name())
.build();
.value(defaultValue)
.reason(DEFAULT.name())
.build();
}

ImmutableMetadata.ImmutableMetadataBuilder flagMetadataBuilder = ImmutableMetadata.builder();
Expand All @@ -209,11 +211,11 @@ public ProviderEvaluation<Value> getObjectEvaluation(String key, Value defaultVa
}

return ProviderEvaluation.<Value>builder()
.value(new Value(response.getVariantKey()))
.variant(response.getVariantKey())
.reason(TARGETING_MATCH.name())
.flagMetadata(flagMetadataBuilder.build())
.build();
.value(new Value(response.getVariantKey()))
.variant(response.getVariantKey())
.reason(TARGETING_MATCH.name())
.flagMetadata(flagMetadataBuilder.build())
.build();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
package dev.openfeature.contrib.providers.flipt;

import com.flipt.api.FliptApiClientBuilder;
import io.flipt.api.FliptClient.FliptClientBuilder;
import lombok.Builder;
import lombok.Getter;


/**
* FliptProvider config.
*/
@Getter
@Builder
public class FliptProviderConfig {
private FliptApiClientBuilder fliptApiClientBuilder;
private FliptClientBuilder fliptClientBuilder;

@Builder.Default
private String namespace = "default";
Expand Down
Loading

0 comments on commit 42738b8

Please sign in to comment.