Skip to content

[Backport 8.0] Complete implementation of Metrics type. #7132

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

Merged
merged 1 commit into from
Dec 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
84 changes: 60 additions & 24 deletions src/Elastic.Clients.Elasticsearch/Core/Infer/Metric/Metrics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,87 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Linq;
using Elastic.Transport;

namespace Elastic.Clients.Elasticsearch;

/// <summary>
/// Represents a collection of unique metric names to be included in URL paths to limit the request.
/// </summary>
public sealed class Metrics : IEquatable<Metrics>, IUrlParameter
{
// TODO: Complete this
private static readonly HashSet<string> EmptyMetrics = new();

//internal Metrics(IndicesStatsMetric metric) => Value = metric;
/// <summary>
/// An instance of <see cref="Metrics"/> representing all statistics.
/// </summary>
public static Metrics All { get; } = new("_all");

//internal Metrics(NodesStatsMetric metric) => Value = metric;
/// <summary>
/// Initializes a new instance of the <see cref="Metrics"/> class containing a single metric name.
/// </summary>
public Metrics(string metric)
{
if (string.IsNullOrEmpty(metric))
Values = EmptyMetrics;

//internal Metrics(NodesInfoMetric metric) => Value = metric;
Values = new HashSet<string>()
{
metric
};
}

//internal Metrics(ClusterStateMetric metric) => Value = metric;
/// <summary>
/// Initializes a new instance of the <see cref="Metrics"/> class containing a collection of metric names.
/// </summary>
public Metrics(IEnumerable<string> metrics)
{
if (metrics is null)
Values = EmptyMetrics;

//internal Metrics(WatcherStatsMetric metric) => Value = metric;
Values = new HashSet<string>(metrics);
}

//internal Metrics(NodesUsageMetric metric) => Value = metric;
private HashSet<string> Values { get; }

internal Enum Value { get; }
/// <inheritdoc />
public bool Equals(Metrics other)
{
if (other is null) return false;

public bool Equals(Metrics other) => Value.Equals(other.Value);
// Equality is true when the metrics names in both instances are equal, regardless of their order in the set.
return Values.OrderBy(t => t).SequenceEqual(other.Values.OrderBy(t => t));
}

string IUrlParameter.GetString(ITransportConfiguration settings) => string.Empty; // TODO Value.GetStringValue();
string IUrlParameter.GetString(ITransportConfiguration settings) => GetString();

//public static implicit operator Metrics(IndicesStatsMetric metric) => new Metrics(metric);
/// <inheritdoc />
public override string ToString() => GetString();

//public static implicit operator Metrics(NodesStatsMetric metric) => new Metrics(metric);
private string GetString()
{
if (Values == EmptyMetrics)
return string.Empty;

//public static implicit operator Metrics(NodesInfoMetric metric) => new Metrics(metric);
return string.Join(",", Values);
}

//public static implicit operator Metrics(ClusterStateMetric metric) => new Metrics(metric);
/// <inheritdoc />
public override int GetHashCode() => Values != null ? Values.GetHashCode() : 0;

//public static implicit operator Metrics(WatcherStatsMetric metric) => new Metrics(metric);

//public static implicit operator Metrics(NodesUsageMetric metric) => new Metrics(metric);

public bool Equals(Enum other) => Value.Equals(other);

public override bool Equals(object obj) => obj is Enum e ? Equals(e) : obj is Metrics m && Equals(m.Value);
public static bool operator ==(Metrics left, Metrics right) => Equals(left, right);
public static bool operator !=(Metrics left, Metrics right) => !Equals(left, right);

public override int GetHashCode() => Value != null ? Value.GetHashCode() : 0;
public static implicit operator Metrics(string metric) => new(metric);
public static implicit operator Metrics(string[] metrics) => new(metrics);

public static bool operator ==(Metrics left, Metrics right) => Equals(left, right);
/// <inheritdoc />
public override bool Equals(object obj)
{
if (obj is not Metrics metrics) return false;

public static bool operator !=(Metrics left, Metrics right) => !Equals(left, right);
return Equals(metrics);
}
}
67 changes: 67 additions & 0 deletions tests/Tests/Common/UrlParameters/Metrics/MetricsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using Tests.Core.Extensions;

using M = Elastic.Clients.Elasticsearch.Metrics;

namespace Tests.Common.UrlParameters.Metrics;

public class MetricsTests
{
[U]
public void Equal()
{
var metrics = M.All;

M[] equal = { M.All };

foreach (var value in equal)
{
(value == metrics).ShouldBeTrue(value);
value.Should().Be(metrics);
}

metrics.Should().Be(M.All);
}

[U]
public void SequenceEqual()
{
M metricsOne = new[] { "completion", "merge" };
M metricsTwo = new[] { "merge", "completion" };

(metricsOne == metricsTwo).Should().BeTrue();
metricsOne.Should().Be(metricsTwo);
}

[U]
public void ToStringOverride()
{
M metrics = new[] { "completion", "merge" };
metrics.ToString().Should().Be("completion,merge");
}

[U]
public void NotEqual()
{
var metrics = M.All;

M[] notEqual = { "completion", "merge" };

foreach (var value in notEqual)
{
(value != metrics).ShouldBeTrue(value);
value.Should().NotBe(metrics);
}
}

[U]
public void Null()
{
var value = M.All;
(value == null).Should().BeFalse();
(null == value).Should().BeFalse();
}
}