-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Introduce flipt provider for dotnet (#285)
Signed-off-by: Andrei de la Cruz <[email protected]>
- Loading branch information
1 parent
cbe61a9
commit 5cc83a1
Showing
21 changed files
with
3,513 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
src/OpenFeature.Contrib.Providers.Flipt/ClientWrapper/FliptClientWrapper.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
using System; | ||
using System.Net.Http; | ||
using System.Threading.Tasks; | ||
using Flipt.Rest; | ||
|
||
namespace OpenFeature.Contrib.Providers.Flipt.ClientWrapper; | ||
|
||
/// <summary> | ||
/// Wrapper for Flipt server sdk client for .net | ||
/// </summary> | ||
public class FliptClientWrapper : IFliptClientWrapper | ||
{ | ||
private readonly FliptRestClient _fliptRestClient; | ||
|
||
/// <summary> | ||
/// </summary> | ||
/// <param name="fliptUrl">Url of flipt instance</param> | ||
/// <param name="clientToken">Authentication access token</param> | ||
/// <param name="timeoutInSeconds">Timeout when calling flipt endpoints in seconds</param> | ||
public FliptClientWrapper(string fliptUrl, | ||
string clientToken = "", | ||
int timeoutInSeconds = 30) | ||
{ | ||
_fliptRestClient = BuildClient(fliptUrl, clientToken, timeoutInSeconds); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public async Task<VariantEvaluationResponse> EvaluateVariantAsync(EvaluationRequest evaluationRequest) | ||
{ | ||
return await _fliptRestClient.EvaluateV1VariantAsync(evaluationRequest); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public async Task<BooleanEvaluationResponse> EvaluateBooleanAsync(EvaluationRequest evaluationRequest) | ||
{ | ||
return await _fliptRestClient.EvaluateV1BooleanAsync(evaluationRequest); | ||
} | ||
|
||
private static FliptRestClient BuildClient(string fliptUrl, string clientToken, int timeoutInSeconds = 30) | ||
{ | ||
var httpClient = new HttpClient | ||
{ | ||
BaseAddress = new Uri(fliptUrl), | ||
Timeout = TimeSpan.FromSeconds(timeoutInSeconds), | ||
DefaultRequestHeaders = { { "Authorization", $"Bearer {clientToken}" } } | ||
}; | ||
return new FliptRestClient(httpClient); | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
src/OpenFeature.Contrib.Providers.Flipt/ClientWrapper/IFliptClientWrapper.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
using System.Threading.Tasks; | ||
using Flipt.Rest; | ||
|
||
namespace OpenFeature.Contrib.Providers.Flipt.ClientWrapper; | ||
|
||
/// <summary> | ||
/// </summary> | ||
public interface IFliptClientWrapper | ||
{ | ||
/// <summary> | ||
/// Wrapper to Flipt.io/EvaluateVariantAsync method | ||
/// </summary> | ||
/// <param name="evaluationRequest"></param> | ||
/// <returns></returns> | ||
Task<VariantEvaluationResponse> EvaluateVariantAsync(EvaluationRequest evaluationRequest); | ||
|
||
/// <summary> | ||
/// Wrapper to Flipt.io/EvaluateBooleanAsync method | ||
/// </summary> | ||
/// <param name="evaluationRequest"></param> | ||
/// <returns></returns> | ||
Task<BooleanEvaluationResponse> EvaluateBooleanAsync(EvaluationRequest evaluationRequest); | ||
} |
23 changes: 23 additions & 0 deletions
23
src/OpenFeature.Contrib.Providers.Flipt/Converters/JsonConverterExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
using System.Text.Json; | ||
|
||
namespace OpenFeature.Contrib.Providers.Flipt.Converters; | ||
|
||
/// <summary> | ||
/// Extensions for default JsonConverter behavior | ||
/// </summary> | ||
public static class JsonConverterExtensions | ||
{ | ||
/// <summary> | ||
/// JsonConverter serializer settings for Flipt to OpenFeature model deserialization | ||
/// </summary> | ||
public static readonly JsonSerializerOptions DefaultSerializerSettings = new() | ||
{ | ||
WriteIndented = true, | ||
AllowTrailingCommas = true, | ||
Converters = | ||
{ | ||
new OpenFeatureStructureConverter(), | ||
new OpenFeatureValueConverter() | ||
} | ||
}; | ||
} |
30 changes: 30 additions & 0 deletions
30
src/OpenFeature.Contrib.Providers.Flipt/Converters/OpenFeatureStructureConverter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text.Json; | ||
using System.Text.Json.Serialization; | ||
using OpenFeature.Model; | ||
|
||
namespace OpenFeature.Contrib.Providers.Flipt.Converters; | ||
|
||
/// <summary> | ||
/// JsonConverter for OpenFeature Structure type | ||
/// </summary> | ||
public class OpenFeatureStructureConverter : JsonConverter<Structure> | ||
{ | ||
/// <inheritdoc /> | ||
public override void Write(Utf8JsonWriter writer, Structure value, JsonSerializerOptions options) | ||
{ | ||
var jsonDoc = JsonDocument.Parse(JsonSerializer.Serialize(value.AsDictionary(), | ||
JsonConverterExtensions.DefaultSerializerSettings)); | ||
jsonDoc.WriteTo(writer); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public override Structure Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | ||
{ | ||
using var jsonDocument = JsonDocument.ParseValue(ref reader); | ||
var jsonText = jsonDocument.RootElement.GetRawText(); | ||
return new Structure(JsonSerializer.Deserialize<Dictionary<string, Value>>(jsonText, | ||
JsonConverterExtensions.DefaultSerializerSettings)); | ||
} | ||
} |
102 changes: 102 additions & 0 deletions
102
src/OpenFeature.Contrib.Providers.Flipt/Converters/OpenFeatureValueConverter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text.Json; | ||
using System.Text.Json.Serialization; | ||
using OpenFeature.Model; | ||
|
||
namespace OpenFeature.Contrib.Providers.Flipt.Converters; | ||
|
||
/// <summary> | ||
/// OpenFeature Value type converter | ||
/// </summary> | ||
public class OpenFeatureValueConverter : JsonConverter<Value> | ||
{ | ||
/// <inheritdoc /> | ||
public override Value Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | ||
{ | ||
var value = new Value(); | ||
switch (reader.TokenType) | ||
{ | ||
case JsonTokenType.String: | ||
return reader.TryGetDateTime(out var dateTimeValue) | ||
? new Value(dateTimeValue) | ||
: new Value(reader.GetString() ?? string.Empty); | ||
case JsonTokenType.True: | ||
case JsonTokenType.False: | ||
return new Value(reader.GetBoolean()); | ||
case JsonTokenType.Number: | ||
if (reader.TryGetInt32(out var intValue)) return new Value(intValue); | ||
if (reader.TryGetDouble(out var dblValue)) return new Value(dblValue); | ||
break; | ||
case JsonTokenType.StartArray: | ||
return new Value(GenerateValueArray(ref reader, typeToConvert, options)); | ||
case JsonTokenType.StartObject: | ||
return new Value(GetStructure(ref reader, typeToConvert, options)); | ||
} | ||
|
||
return value; | ||
} | ||
|
||
private Structure GetStructure(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | ||
{ | ||
var startDepth = reader.CurrentDepth; | ||
var structureDictionary = new Dictionary<string, Value>(); | ||
while (reader.Read()) | ||
{ | ||
if (reader.TokenType == JsonTokenType.PropertyName) | ||
{ | ||
var key = reader.GetString(); | ||
reader.Read(); | ||
var val = Read(ref reader, typeToConvert, options); | ||
structureDictionary[key ?? string.Empty] = val; | ||
} | ||
|
||
if (reader.TokenType == JsonTokenType.EndObject && reader.CurrentDepth == startDepth) break; | ||
} | ||
|
||
return new Structure(structureDictionary); | ||
} | ||
|
||
|
||
private IList<Value> GenerateValueArray(ref Utf8JsonReader reader, Type typeToConvert, | ||
JsonSerializerOptions options) | ||
{ | ||
var valuesArray = new List<Value>(); | ||
var startDepth = reader.CurrentDepth; | ||
|
||
while (reader.Read()) | ||
switch (reader.TokenType) | ||
{ | ||
case JsonTokenType.EndArray when reader.CurrentDepth == startDepth: | ||
return valuesArray; | ||
default: | ||
valuesArray.Add(Read(ref reader, typeToConvert, options)); | ||
break; | ||
} | ||
|
||
return valuesArray; | ||
} | ||
|
||
/// <inheritdoc /> | ||
public override void Write(Utf8JsonWriter writer, Value value, JsonSerializerOptions options) | ||
{ | ||
if (value.IsList) | ||
{ | ||
writer.WriteStartArray(); | ||
foreach (var val in value.AsList!) | ||
{ | ||
var jsonDoc = JsonDocument.Parse(JsonSerializer.Serialize(val.AsObject, | ||
JsonConverterExtensions.DefaultSerializerSettings)); | ||
jsonDoc.WriteTo(writer); | ||
} | ||
|
||
writer.WriteEndArray(); | ||
} | ||
else | ||
{ | ||
var jsonDoc = JsonDocument.Parse(JsonSerializer.Serialize(value.AsObject, | ||
JsonConverterExtensions.DefaultSerializerSettings)); | ||
jsonDoc.WriteTo(writer); | ||
} | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
src/OpenFeature.Contrib.Providers.Flipt/FliptExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text.Json; | ||
using OpenFeature.Contrib.Providers.Flipt.Converters; | ||
using OpenFeature.Model; | ||
|
||
namespace OpenFeature.Contrib.Providers.Flipt; | ||
|
||
/// <summary> | ||
/// Extension helper methods | ||
/// </summary> | ||
public static class FliptExtensions | ||
{ | ||
/// <summary> | ||
/// Transforms openFeature EvaluationContext to a mutable Dictionary that flipt sdk accepts | ||
/// </summary> | ||
/// <param name="evaluationContext">OpenFeature EvaluationContext</param> | ||
/// <returns></returns> | ||
public static Dictionary<string, string> ToStringDictionary(this EvaluationContext evaluationContext) | ||
{ | ||
return evaluationContext?.AsDictionary() | ||
.ToDictionary(k => k.Key, | ||
v => JsonSerializer.Serialize(v.Value.AsObject, | ||
JsonConverterExtensions.DefaultSerializerSettings)) ?? | ||
[]; | ||
} | ||
} |
Oops, something went wrong.