Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
126 changes: 126 additions & 0 deletions DevCycle.SDK.Server.Common/Model/EvalReason.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using System;
using System.Runtime.Serialization;
using System.Text;
using Newtonsoft.Json;

namespace DevCycle.SDK.Server.Common.Model
{
[DataContract]
public class EvalReason : IEquatable<EvalReason>
{
/// <summary>
/// Initializes a new instance of the <see cref="EvalReason" /> class.
/// </summary>
/// <param name="reason">The evaluation reason (required).</param>
/// <param name="details">Additional details about the evaluation.</param>
/// <param name="targetId">Target identifier for the evaluation.</param>
public EvalReason(string reason = default, string details = default, string targetId = default)
{
Reason = reason ?? throw new ArgumentException("reason is a required property for EvalReason and cannot be null");
Details = details;
TargetId = targetId;
}

/// <summary>
/// The evaluation reason
/// </summary>
/// <value>The evaluation reason</value>
[DataMember(Name = "reason", EmitDefaultValue = false)]
[JsonProperty("reason")]
public string Reason { get; set; }

/// <summary>
/// Additional details about the evaluation
/// </summary>
/// <value>Additional details about the evaluation</value>
[DataMember(Name = "details", EmitDefaultValue = false)]
[JsonProperty("details")]
public string Details { get; set; }

/// <summary>
/// Target identifier for the evaluation
/// </summary>
/// <value>Target identifier for the evaluation</value>
[DataMember(Name = "targetId", EmitDefaultValue = false)]
[JsonProperty("targetId")]
public string TargetId { get; set; }

/// <summary>
/// Returns the string presentation of the object
/// </summary>
/// <returns>String presentation of the object</returns>
public override string ToString()
{
var sb = new StringBuilder();
sb.Append("class EvalReason {\n");
sb.Append(" Reason: ").Append(Reason).Append("\n");
sb.Append(" Details: ").Append(Details).Append("\n");
sb.Append(" TargetId: ").Append(TargetId).Append("\n");
sb.Append("}\n");
return sb.ToString();
}

/// <summary>
/// Returns the JSON string presentation of the object
/// </summary>
/// <returns>JSON string presentation of the object</returns>
public virtual string ToJson()
{
return JsonConvert.SerializeObject(this, Formatting.Indented);
}

/// <summary>
/// Returns true if objects are equal
/// </summary>
/// <param name="input">Object to be compared</param>
/// <returns>Boolean</returns>
public override bool Equals(object input)
{
return Equals(input as EvalReason);
}

/// <summary>
/// Returns true if EvalReason instances are equal
/// </summary>
/// <param name="input">Instance of EvalReason to be compared</param>
/// <returns>Boolean</returns>
public bool Equals(EvalReason input)
{
if (input == null)
return false;

return
(
Reason == input.Reason ||
(Reason != null && Reason.Equals(input.Reason))
) &&
(
Details == input.Details ||
(Details != null && Details.Equals(input.Details))
) &&
(
TargetId == input.TargetId ||
(TargetId != null && TargetId.Equals(input.TargetId))
);
}

/// <summary>
/// Gets the hash code
/// </summary>
/// <returns>Hash code</returns>
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hashCode = 41;
if (Reason != null)
hashCode = hashCode * 59 + Reason.GetHashCode();
if (Details != null)
hashCode = hashCode * 59 + Details.GetHashCode();
if (TargetId != null)
hashCode = hashCode * 59 + TargetId.GetHashCode();
return hashCode;
}
}
}
}
8 changes: 5 additions & 3 deletions DevCycle.SDK.Server.Common/Model/IVariable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,23 @@ public interface IVariable
public TypeEnum Type { get; set; }

public string Key { get; set; }

public bool IsDefaulted { get; set; }

public string EvalReason { get; set; }

public EvalReason Eval { get; set; }

}

public static class VariableHelper
{
public static Variable<T> Convert<T>(this Variable<object> variable)
{
var defaultValue = variable.DefaultValue;
var value = variable.Value;

return new Variable<T>(variable.Key, (T) value, (T) defaultValue)
return new Variable<T>(variable.Key, (T)value, (T)defaultValue)
{
IsDefaulted = variable.IsDefaulted,
};
Expand Down
14 changes: 11 additions & 3 deletions DevCycle.SDK.Server.Common/Model/ReadOnlyVariable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class ReadOnlyVariable<T>
[DataMember(Name = "_id")]
[JsonProperty("_id")]
public string Id { get; set; }

/// <summary>
/// Variable value can be a string, number, boolean, or JSON
/// </summary>
Expand All @@ -27,7 +27,7 @@ public class ReadOnlyVariable<T>
/// Variable type
/// </summary>
/// <value>Variable type</value>
[DataMember(Name="type")]
[DataMember(Name = "type")]
[JsonProperty("type")]
public string Type { get; set; }

Expand All @@ -38,9 +38,17 @@ public class ReadOnlyVariable<T>
[DataMember(Name = "key")]
[JsonProperty("key")]
public string Key { get; set; }

public string EvalReason { get; set; }

/// <summary>
/// Evaluation details
/// </summary>
/// <value>Evaluation details</value>
[DataMember(Name = "eval", EmitDefaultValue = false)]
[JsonProperty("eval")]
public EvalReason Eval { get; set; }

/// <summary>
/// Returns the string presentation of the object
/// </summary>
Expand Down
20 changes: 14 additions & 6 deletions DevCycle.SDK.Server.Common/Model/Variable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ public static Variable<T> InitializeFromVariable(Variable<T> variable, string ke
returnVariable.DefaultValue = defaultValue;
returnVariable.Type = variable.Type;
returnVariable.EvalReason = variable.EvalReason;
returnVariable.Eval = variable.Eval;
returnVariable.IsDefaulted = false;
}
else
Expand Down Expand Up @@ -109,6 +110,13 @@ public static Variable<T> InitializeFromVariable(Variable<T> variable, string ke
[DataMember(Name = "isDefaulted")] public bool IsDefaulted { get; set; }
public string EvalReason { get; set; }

/// <summary>
/// Evaluation details
/// </summary>
/// <value>Evaluation details</value>
[DataMember(Name = "eval", EmitDefaultValue = false)]
public EvalReason Eval { get; set; }

public static TypeEnum DetermineType(T variableValue)
{
TypeEnum typeEnum;
Expand Down Expand Up @@ -148,7 +156,7 @@ public static TypeEnum DetermineType(T variableValue)
throw;
}
}

public override bool Equals(object input)
{
return Equals(input as Variable<T>);
Expand All @@ -164,23 +172,23 @@ public bool Equals(Variable<T> input)
if (input == null)
return false;

return
return
(
Key == input.Key ||
(Key != null &&
Key.Equals(input.Key))
) &&
) &&
(
Type == input.Type ||
Type.Equals(input.Type)
) &&
) &&
(
(Value != null &&
Value.Equals(input.Value))
);
}


/// <summary>
/// Gets the hash code
/// </summary>
Expand Down
28 changes: 18 additions & 10 deletions DevCycle.SDK.Server.Local/Api/DevCycleLocalClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
using Google.Protobuf;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using DevCycle.SDK.Server.Common.Model;

Check warning on line 13 in DevCycle.SDK.Server.Local/Api/DevCycleLocalClient.cs

View workflow job for this annotation

GitHub Actions / build

The using directive for 'DevCycle.SDK.Server.Common.Model' appeared previously in this namespace

Check warning on line 13 in DevCycle.SDK.Server.Local/Api/DevCycleLocalClient.cs

View workflow job for this annotation

GitHub Actions / run-example

The using directive for 'DevCycle.SDK.Server.Common.Model' appeared previously in this namespace

Check warning on line 13 in DevCycle.SDK.Server.Local/Api/DevCycleLocalClient.cs

View workflow job for this annotation

GitHub Actions / run-example

The using directive for 'DevCycle.SDK.Server.Common.Model' appeared previously in this namespace
using System.Runtime.InteropServices;

namespace DevCycle.SDK.Server.Local.Api
Expand Down Expand Up @@ -99,7 +99,7 @@
localBucketing.SetPlatformData(platformData.ToJson());
evalHooksRunner = new EvalHooksRunner(logger, dvcLocalOptions.EvalHooks);

if(dvcLocalOptions.CdnSlug != "")
if (dvcLocalOptions.CdnSlug != "")
{
logger.LogWarning("The config CDN slug is being overriden, please ensure to update the config to v2 according to the config CDN updates documentation.");

Expand Down Expand Up @@ -159,17 +159,17 @@
else if (entry.Value is string strValue)
{
nullableCustomData.Value[entry.Key] = new CustomDataValue()
{ StringValue = strValue, Type = CustomDataType.Str };
{ StringValue = strValue, Type = CustomDataType.Str };
}
else if (entry.Value is double numValue)
{
nullableCustomData.Value[entry.Key] = new CustomDataValue()
{ DoubleValue = numValue, Type = CustomDataType.Num };
{ DoubleValue = numValue, Type = CustomDataType.Num };
}
else if (entry.Value is bool boolValue)
{
nullableCustomData.Value[entry.Key] = new CustomDataValue()
{ BoolValue = boolValue, Type = CustomDataType.Bool };
{ BoolValue = boolValue, Type = CustomDataType.Bool };
}
}

Expand Down Expand Up @@ -342,6 +342,12 @@
}

SDKVariable_PB sdkVariable = SDKVariable_PB.Parser.ParseFrom(variableData);
Console.WriteLine("sdkVariable properties:");
foreach (var prop in sdkVariable.GetType().GetProperties())
{
var value = prop.GetValue(sdkVariable, null);
Console.WriteLine($"{prop.Name}: {value}");
}

if (variableType != sdkVariable.Type)
{
Expand Down Expand Up @@ -390,13 +396,13 @@
ShouldTrackEvent = true
};

Variable<T> existingVariable = Common.Model.Variable<T>.InitializeFromVariable(null, key, defaultValue);;
Variable<T> existingVariable = Common.Model.Variable<T>.InitializeFromVariable(null, key, defaultValue); ;
HookContext<T> hookContext = new HookContext<T>(user, key, defaultValue, null);

var hooks = evalHooksRunner.GetHooks();
var reversedHooks = new List<EvalHook>(hooks);
reversedHooks.Reverse();

try
{
System.Exception beforeError = null;
Expand All @@ -408,7 +414,7 @@
{
beforeError = e;
}

var paramsBuffer = paramsPb.ToByteArray();

byte[] variableData = localBucketing.GetVariableForUserProtobuf(serializedParams: paramsBuffer);
Expand All @@ -426,7 +432,9 @@
if (variableType != sdkVariable.Type)
{
logger.LogWarning("Type of Variable does not match DevCycle configuration. Using default value");
} else {
}
else
{
existingVariable = GetVariable<T>(sdkVariable, defaultValue);
}

Expand All @@ -451,7 +459,7 @@
return existingVariable;
}



public override async Task<T> VariableValue<T>(DevCycleUser user, string key, T defaultValue)
{
Expand Down
Binary file modified DevCycle.SDK.Server.Local/bucketing-lib.release.wasm
Binary file not shown.
8 changes: 8 additions & 0 deletions DevCycle.SDK.Server.Local/variableForUserParams.proto
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,12 @@ message SDKVariable_PB {
double doubleValue = 5;
string stringValue = 6;
NullableString evalReason = 7;
NullableString _feature = 8;
EvalReason_PB eval = 9;
}

message EvalReason_PB {
string reason = 1;
string details = 2;
string target_id = 3;
}
Loading