Skip to content

Commit

Permalink
Fixed GetChanges for backoff and metadata (#769)
Browse files Browse the repository at this point in the history
* Fixed GetChanges for backoff and metadata

* fix uses of obsolete
  • Loading branch information
scottf committed May 12, 2023
1 parent 4da282e commit 11f9958
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 35 deletions.
14 changes: 10 additions & 4 deletions src/NATS.Client/Internals/JsonUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,32 +68,38 @@ public static List<string> StringList(JSONNode node, string field)
return list;
}

public static List<Duration> DurationList(JSONNode node, string field)
public static List<Duration> DurationList(JSONNode node, string field, bool nullIfEmpty = false)
{
List<Duration> list = new List<Duration>();
foreach (var child in node[field].Children)
{
list.Add(Duration.OfNanos(child.AsLong));
}

return list;
return list.Count == 0 && nullIfEmpty ? null : list;
}

public static List<string> OptionalStringList(JSONNode node, string field)
{
List<string> list = StringList(node, field);
return list.Count == 0 ? null : list;
}


[Obsolete("Method name replaced with proper spelling, 'StringStringDictionary'")]
public static Dictionary<string, string> StringStringDictionay(JSONNode node, string field)
{
return StringStringDictionary(node, field, false);
}

public static Dictionary<string, string> StringStringDictionary(JSONNode node, string field, bool nullIfEmpty = false)
{
Dictionary<string, string> temp = new Dictionary<string, string>();
JSONNode meta = node[field];
foreach (string key in meta.Keys)
{
temp[key] = meta[key];
}
return temp;
return temp.Count == 0 && nullIfEmpty ? null : temp;
}

public static MsgHeader AsHeaders(JSONNode node, string field)
Expand Down
20 changes: 17 additions & 3 deletions src/NATS.Client/Internals/Validator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

Expand Down Expand Up @@ -637,6 +638,21 @@ public static bool IsSemVer(String s)
return Regex.IsMatch(s, SemVerPattern);
}

public static bool SequenceEqual<TSource>(IList<TSource> l1, IList<TSource> l2, bool nullSecondEqualsEmptyFirst)
{
if (l1 == null)
{
return l2 == null;
}

if (l2 == null)
{
return nullSecondEqualsEmptyFirst && l1.Count == 0;
}

return l1.SequenceEqual(l2);
}

public static bool DictionariesEqual(IDictionary<string, string> d1, IDictionary<string, string> d2)
{
if (d1 == d2)
Expand All @@ -651,9 +667,7 @@ public static bool DictionariesEqual(IDictionary<string, string> d1, IDictionary

foreach (KeyValuePair<string, string> pair in d1)
{
string value;
if (!d2.TryGetValue(pair.Key, out value) ||
!pair.Value.Equals(value))
if (!d2.TryGetValue(pair.Key, out var value) || !pair.Value.Equals(value))
{
return false;
}
Expand Down
75 changes: 50 additions & 25 deletions src/NATS.Client/JetStream/ConsumerConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public sealed class ConsumerConfiguration : JsonSerializable
internal bool? _flowControl;
internal bool? _headersOnly;
internal bool? _memStorage;
internal IList<Duration> _backoff;
internal Dictionary<string, string> _metadata;

public DeliverPolicy DeliverPolicy => _deliverPolicy ?? DeliverPolicy.All;
public AckPolicy AckPolicy => _ackPolicy ?? AckPolicy.Explicit;
Expand Down Expand Up @@ -85,8 +87,8 @@ public sealed class ConsumerConfiguration : JsonSerializable
public bool FlowControl => _flowControl ?? false;
public bool HeadersOnly => _headersOnly ?? false;
public bool MemStorage => _memStorage ?? false;
public IList<Duration> Backoff { get; }
public Dictionary<string, string> Metadata { get; }
public IList<Duration> Backoff => _backoff ?? new List<Duration>();
public Dictionary<string, string> Metadata => _metadata ?? new Dictionary<string, string>();

internal ConsumerConfiguration(string json) : this(JSON.Parse(json)) {}

Expand Down Expand Up @@ -122,8 +124,8 @@ internal ConsumerConfiguration(JSONNode ccNode)
_headersOnly = ccNode[ApiConstants.HeadersOnly].AsBool;
_memStorage = ccNode[ApiConstants.MemStorage].AsBool;

Backoff = DurationList(ccNode, ApiConstants.Backoff);
Metadata = JsonUtils.StringStringDictionay(ccNode, ApiConstants.Metadata);
_backoff = DurationList(ccNode, ApiConstants.Backoff, true);
_metadata = StringStringDictionary(ccNode, ApiConstants.Metadata, true);
}

private ConsumerConfiguration(ConsumerConfigurationBuilder builder)
Expand Down Expand Up @@ -158,8 +160,8 @@ private ConsumerConfiguration(ConsumerConfigurationBuilder builder)
_maxBytes = builder._maxBytes;
_numReplicas = builder._numReplicas;

Backoff = builder._backoff;
Metadata = builder._metadata;
_backoff = builder._backoff;
_metadata = builder._metadata;
}

public override JSONNode ToJsonNode()
Expand Down Expand Up @@ -230,13 +232,9 @@ internal IList<string> GetChanges(ConsumerConfiguration server)
RecordWouldBeChange(SampleFrequency, server.SampleFrequency, "SampleFrequency", changes);
RecordWouldBeChange(DeliverSubject, server.DeliverSubject, "DeliverSubject", changes);
RecordWouldBeChange(DeliverGroup, server.DeliverGroup, "DeliverGroup", changes);

if (!Backoff.SequenceEqual(server.Backoff)) { changes.Add("Backoff"); }

if (!Validator.DictionariesEqual(Metadata, server.Metadata))
{
changes.Add("Metadata");
}
if (_backoff != null && !SequenceEqual(_backoff, server._backoff, true)) { changes.Add("Backoff"); }
if (_metadata != null && !DictionariesEqual(_metadata, server._metadata)) { changes.Add("Metadata"); }

return changes;
}
Expand Down Expand Up @@ -334,8 +332,8 @@ public sealed class ConsumerConfigurationBuilder
internal bool? _flowControl;
internal bool? _headersOnly;
internal bool? _memStorage;
internal IList<Duration> _backoff = new List<Duration>();
internal Dictionary<string, string> _metadata = new Dictionary<string, string>();
internal IList<Duration> _backoff;
internal Dictionary<string, string> _metadata;

public ConsumerConfigurationBuilder() {}

Expand Down Expand Up @@ -372,10 +370,18 @@ public ConsumerConfigurationBuilder(ConsumerConfiguration cc)
_flowControl = cc._flowControl;
_headersOnly = cc._headersOnly;
_memStorage = cc._memStorage;
_backoff = new List<Duration>(cc.Backoff);
foreach (string key in cc.Metadata.Keys)

if (cc._backoff != null)
{
_metadata[key] = cc.Metadata[key];
_backoff = new List<Duration>(cc._backoff);
}

if (cc._metadata != null)
{
foreach (string key in cc.Metadata.Keys)
{
_metadata[key] = cc.Metadata[key];
}
}
}

Expand Down Expand Up @@ -775,20 +781,29 @@ public ConsumerConfigurationBuilder WithNumReplicas(int? numReplicas)
/// </summary>
/// <param name="backoffs">zero or more backoff durations or an array of backoffs</param>
/// <returns>The ConsumerConfigurationBuilder</returns>
public ConsumerConfigurationBuilder WithBackoff(params Duration[] backoffs) {
_backoff.Clear();
if (backoffs != null) {
public ConsumerConfigurationBuilder WithBackoff(params Duration[] backoffs)
{
if (backoffs == null || (backoffs.Length == 1 && backoffs[0] == null))
{
_backoff = null;
}
else
{
_backoff = new List<Duration>();
foreach (Duration d in backoffs)
{
if (d != null) {
if (d != null)
{
if (d.Nanos < DurationMinLong)
{
throw new ArgumentException($"Backoff cannot be less than {DurationMinLong}");
}

_backoff.Add(d);
}
}
}

return this;
}

Expand All @@ -798,8 +813,13 @@ public ConsumerConfigurationBuilder WithNumReplicas(int? numReplicas)
/// <param name="backoffsMillis">zero or more backoff in millis or an array of backoffsMillis</param>
/// <returns>The ConsumerConfigurationBuilder</returns>
public ConsumerConfigurationBuilder WithBackoff(params long[] backoffsMillis) {
_backoff.Clear();
if (backoffsMillis != null) {
if (backoffsMillis == null)
{
_backoff = null;
}
else
{
_backoff = new List<Duration>();
foreach (long ms in backoffsMillis) {
if (ms < DurationMinLong)
{
Expand All @@ -808,6 +828,7 @@ public ConsumerConfigurationBuilder WithNumReplicas(int? numReplicas)
_backoff.Add(Duration.OfMillis(ms));
}
}

return this;
}

Expand All @@ -817,9 +838,13 @@ public ConsumerConfigurationBuilder WithNumReplicas(int? numReplicas)
/// <param name="metadata">the metadata dictionary</param>
/// <returns>The ConsumerConfigurationBuilder</returns>
public ConsumerConfigurationBuilder WithMetadata(Dictionary<string, string> metadata) {
_metadata.Clear();
if (metadata != null)
if (metadata == null)
{
_metadata = null;
}
else
{
_metadata = new Dictionary<string, string>();
foreach (string key in metadata.Keys)
{
_metadata[key] = metadata[key];
Expand Down
2 changes: 1 addition & 1 deletion src/NATS.Client/JetStream/StreamConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ internal StreamConfiguration(JSONNode scNode)
DenyDelete = scNode[ApiConstants.DenyDelete].AsBool;
DenyPurge = scNode[ApiConstants.DenyPurge].AsBool;
DiscardNewPerSubject = scNode[ApiConstants.DiscardNewPerSubject].AsBool;
Metadata = JsonUtils.StringStringDictionay(scNode, ApiConstants.Metadata);
Metadata = JsonUtils.StringStringDictionary(scNode, ApiConstants.Metadata);
}

private StreamConfiguration(StreamConfigurationBuilder builder)
Expand Down
2 changes: 1 addition & 1 deletion src/NATS.Client/Service/Endpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ internal Endpoint(JSONNode node)
Name = node[ApiConstants.Name];
Subject = node[ApiConstants.Subject];
Schema = Schema.OptionalInstance(node[ApiConstants.Schema]);
Metadata = JsonUtils.StringStringDictionay(node, ApiConstants.Metadata);
Metadata = JsonUtils.StringStringDictionary(node, ApiConstants.Metadata);
}

private Endpoint(EndpointBuilder b)
Expand Down
2 changes: 1 addition & 1 deletion src/NATS.Client/Service/ServiceResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ internal ServiceResponse(string type, JSONNode node)
Id = Validator.Required(node[ApiConstants.Id], "Id");
Name = Validator.Required(node[ApiConstants.Name], "Name");
Version = Validator.ValidateSemVer(node[ApiConstants.Version], "Version", true);
Metadata = JsonUtils.StringStringDictionay(node, ApiConstants.Metadata);
Metadata = JsonUtils.StringStringDictionary(node, ApiConstants.Metadata);
}

protected JSONObject BaseJsonObject()
Expand Down

0 comments on commit 11f9958

Please sign in to comment.