Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Flag metadata #223

Merged
merged 34 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5b5f9a3
Add FlagMetadata class to OpenFeature.Model
askpt Jan 23, 2024
be07fd0
Update FlagEvaluationDetails and ResolutionDetails classes with FlagM…
askpt Jan 23, 2024
454a277
chore: SourceLink is built-in for .NET SDK 8.0.100+ (#198)
austindrenski Jan 23, 2024
fc817a6
chore: Sync release.yml with ci.yml following #173 (#195)
austindrenski Jan 23, 2024
ace936e
build: Update OpenFeature.sln (#202)
askpt Jan 23, 2024
bd4a48a
chore(deps): update actions/upload-artifact action to v4.3.0 (#203)
renovate[bot] Jan 24, 2024
adb57ab
Adding a GetValue.
askpt Jan 24, 2024
0034d51
Adding more Get methods.
askpt Jan 24, 2024
d8956cd
Adding empty constructor.
askpt Jan 24, 2024
a8978a0
Adding top level namespace.
askpt Jan 24, 2024
f40ce57
docs: update the feature table key
beeme1mr Jan 24, 2024
824ffc2
chore: Enable Central Package Management (CPM) (#178)
austindrenski Jan 26, 2024
f70fc61
chore(deps): update codecov/codecov-action action to v3.1.5 (#209)
renovate[bot] Jan 26, 2024
58bd313
chore: More sln cleanup (#206)
austindrenski Jan 26, 2024
48b9e6c
chore: Sync ci.yml with contrib repo (#196)
austindrenski Jan 27, 2024
0325083
fix: Fix NU1009 reference assembly warning (#222)
austindrenski Jan 29, 2024
d7ba40f
Refactor FlagMetadata class to use ImmutableDictionary
askpt Jan 30, 2024
b04f01c
Adding initial tests.
askpt Jan 30, 2024
0fb919c
Moved code and fixed code smells.
askpt Jan 30, 2024
4ad9ca5
Fix code. Added unit tests.
askpt Jan 30, 2024
9813d3c
Change namespace scope. Added nullable check.
askpt Jan 30, 2024
a33db20
Merge branch 'main' into askpt/192-feature-implement-flag-metadata
askpt Jan 30, 2024
cc91037
Refactor FlagMetadata class to inherit from BaseMetadata
askpt Jan 31, 2024
8a6859e
Adding documentation.
askpt Jan 31, 2024
5a2dcc9
Adding reference.
askpt Feb 2, 2024
e4fbad0
Merge branch 'main' into askpt/192-feature-implement-flag-metadata
askpt Feb 2, 2024
c59c30e
Adding reference to the spec.
askpt Feb 2, 2024
cdb8a86
Small fix.
askpt Feb 2, 2024
c1ae332
Added some conditions.
askpt Feb 2, 2024
c14361f
Adding more specs.
askpt Feb 2, 2024
2b2a64f
Fixing unit tests.
askpt Feb 2, 2024
adf885a
Merge branch 'main' into askpt/192-feature-implement-flag-metadata
toddbaert Feb 10, 2024
2761bff
Remove default constructor from BaseMetadata class
askpt Feb 12, 2024
03db18a
Merge branch 'main' into askpt/192-feature-implement-flag-metadata
askpt Feb 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions src/OpenFeature/Model/BaseMetadata.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;

#nullable enable
namespace OpenFeature.Model;

/// <summary>
/// Represents the base class for metadata objects.
/// </summary>
public abstract class BaseMetadata
{
private readonly ImmutableDictionary<string, object> _metadata;

internal BaseMetadata(Dictionary<string, object> metadata)
{
this._metadata = metadata.ToImmutableDictionary();
}

/// <summary>
/// Gets the boolean value associated with the specified key.
/// </summary>
/// <param name="key">The key of the value to retrieve.</param>
/// <returns>The boolean value associated with the key, or null if the key is not found.</returns>
public virtual bool? GetBool(string key)
{
return this.GetValue<bool>(key);
}

/// <summary>
/// Gets the integer value associated with the specified key.
/// </summary>
/// <param name="key">The key of the value to retrieve.</param>
/// <returns>The integer value associated with the key, or null if the key is not found.</returns>
public virtual int? GetInt(string key)
{
return this.GetValue<int>(key);
}

/// <summary>
/// Gets the double value associated with the specified key.
/// </summary>
/// <param name="key">The key of the value to retrieve.</param>
/// <returns>The double value associated with the key, or null if the key is not found.</returns>
public virtual double? GetDouble(string key)
{
return this.GetValue<double>(key);
}

/// <summary>
/// Gets the string value associated with the specified key.
/// </summary>
/// <param name="key">The key of the value to retrieve.</param>
/// <returns>The string value associated with the key, or null if the key is not found.</returns>
public virtual string? GetString(string key)
{
var hasValue = this._metadata.TryGetValue(key, out var value);
if (!hasValue)
{
return null;
}

return value as string ?? null;
}

private T? GetValue<T>(string key) where T : struct
{
var hasValue = this._metadata.TryGetValue(key, out var value);
if (!hasValue)
{
return null;
}

return value is T tValue ? tValue : null;
}
}
11 changes: 9 additions & 2 deletions src/OpenFeature/Model/FlagEvaluationDetails.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace OpenFeature.Model
/// The contract returned to the caller that describes the result of the flag evaluation process.
/// </summary>
/// <typeparam name="T">Flag value type</typeparam>
/// <seealso href="https://github.com/open-feature/spec/blob/v0.5.2/specification/types.md#evaluation-details"/>
/// <seealso href="https://github.com/open-feature/spec/blob/v0.7.0/specification/types.md#evaluation-details"/>
public sealed class FlagEvaluationDetails<T>
{
/// <summary>
Expand Down Expand Up @@ -45,6 +45,11 @@ public sealed class FlagEvaluationDetails<T>
/// </summary>
public string Variant { get; }

/// <summary>
/// A structure which supports definition of arbitrary properties, with keys of type string, and values of type boolean, string, or number.
/// </summary>
public FlagMetadata FlagMetadata { get; }

/// <summary>
/// Initializes a new instance of the <see cref="FlagEvaluationDetails{T}"/> class.
/// </summary>
Expand All @@ -54,15 +59,17 @@ public sealed class FlagEvaluationDetails<T>
/// <param name="reason">Reason</param>
/// <param name="variant">Variant</param>
/// <param name="errorMessage">Error message</param>
/// <param name="flagMetadata">Flag metadata</param>
public FlagEvaluationDetails(string flagKey, T value, ErrorType errorType, string reason, string variant,
string errorMessage = null)
string errorMessage = null, FlagMetadata flagMetadata = null)
{
this.Value = value;
this.FlagKey = flagKey;
this.ErrorType = errorType;
this.Reason = reason;
this.Variant = variant;
this.ErrorMessage = errorMessage;
this.FlagMetadata = flagMetadata;
}
}
}
28 changes: 28 additions & 0 deletions src/OpenFeature/Model/FlagMetadata.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;

#nullable enable
namespace OpenFeature.Model;

/// <summary>
/// Represents the metadata associated with a feature flag.
/// </summary>
/// <seealso href="https://github.com/open-feature/spec/blob/v0.7.0/specification/types.md#flag-metadata"/>
public sealed class FlagMetadata : BaseMetadata
{
/// <summary>
/// Constructor for the <see cref="BaseMetadata"/> class.
/// </summary>
public FlagMetadata() : this([])
{
}

/// <summary>
/// Constructor for the <see cref="BaseMetadata"/> class.
/// </summary>
/// <param name="metadata">The dictionary containing the metadata.</param>
public FlagMetadata(Dictionary<string, object> metadata) : base(metadata)
{
}
}
1 change: 1 addition & 0 deletions src/OpenFeature/Model/ProviderEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class ProviderEventPayload
/// <summary>
/// Metadata information for the event.
/// </summary>
// TODO: This needs to be changed to a EventMetadata object
askpt marked this conversation as resolved.
Show resolved Hide resolved
public Dictionary<string, object> EventMetadata { get; set; }
}
}
11 changes: 9 additions & 2 deletions src/OpenFeature/Model/ResolutionDetails.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace OpenFeature.Model
/// Describes the details of the feature flag being evaluated
/// </summary>
/// <typeparam name="T">Flag value type</typeparam>
/// <seealso href="https://github.com/open-feature/spec/blob/v0.5.2/specification/types.md#resolution-details"/>
/// <seealso href="https://github.com/open-feature/spec/blob/v0.7.0/specification/types.md#resolution-details"/>
public sealed class ResolutionDetails<T>
{
/// <summary>
Expand Down Expand Up @@ -44,6 +44,11 @@ public sealed class ResolutionDetails<T>
/// </summary>
public string Variant { get; }

/// <summary>
/// A structure which supports definition of arbitrary properties, with keys of type string, and values of type boolean, string, or number.
/// </summary>
public FlagMetadata FlagMetadata { get; }

/// <summary>
/// Initializes a new instance of the <see cref="ResolutionDetails{T}"/> class.
/// </summary>
Expand All @@ -53,15 +58,17 @@ public sealed class ResolutionDetails<T>
/// <param name="reason">Reason</param>
/// <param name="variant">Variant</param>
/// <param name="errorMessage">Error message</param>
/// <param name="flagMetadata">Flag metadata</param>
public ResolutionDetails(string flagKey, T value, ErrorType errorType = ErrorType.None, string reason = null,
string variant = null, string errorMessage = null)
string variant = null, string errorMessage = null, FlagMetadata flagMetadata = null)
{
this.Value = value;
this.FlagKey = flagKey;
this.ErrorType = errorType;
this.Reason = reason;
this.Variant = variant;
this.ErrorMessage = errorMessage;
this.FlagMetadata = flagMetadata;
}
}
}
Loading
Loading