diff --git a/src/Elastic.Clients.Elasticsearch/Core/Infer/Metric/Metrics.cs b/src/Elastic.Clients.Elasticsearch/Core/Infer/Metric/Metrics.cs
index 5bfcad4e8d3..808bc73c7cd 100644
--- a/src/Elastic.Clients.Elasticsearch/Core/Infer/Metric/Metrics.cs
+++ b/src/Elastic.Clients.Elasticsearch/Core/Infer/Metric/Metrics.cs
@@ -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;
+///
+/// Represents a collection of unique metric names to be included in URL paths to limit the request.
+///
public sealed class Metrics : IEquatable, IUrlParameter
{
- // TODO: Complete this
+ private static readonly HashSet EmptyMetrics = new();
- //internal Metrics(IndicesStatsMetric metric) => Value = metric;
+ ///
+ /// An instance of representing all statistics.
+ ///
+ public static Metrics All { get; } = new("_all");
- //internal Metrics(NodesStatsMetric metric) => Value = metric;
+ ///
+ /// Initializes a new instance of the class containing a single metric name.
+ ///
+ public Metrics(string metric)
+ {
+ if (string.IsNullOrEmpty(metric))
+ Values = EmptyMetrics;
- //internal Metrics(NodesInfoMetric metric) => Value = metric;
+ Values = new HashSet()
+ {
+ metric
+ };
+ }
- //internal Metrics(ClusterStateMetric metric) => Value = metric;
+ ///
+ /// Initializes a new instance of the class containing a collection of metric names.
+ ///
+ public Metrics(IEnumerable metrics)
+ {
+ if (metrics is null)
+ Values = EmptyMetrics;
- //internal Metrics(WatcherStatsMetric metric) => Value = metric;
+ Values = new HashSet(metrics);
+ }
- //internal Metrics(NodesUsageMetric metric) => Value = metric;
+ private HashSet Values { get; }
- internal Enum Value { get; }
+ ///
+ 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);
+ ///
+ 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);
+ ///
+ 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);
+ ///
+ 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);
+ }
}
diff --git a/tests/Tests/Common/UrlParameters/Metrics/MetricsTests.cs b/tests/Tests/Common/UrlParameters/Metrics/MetricsTests.cs
new file mode 100644
index 00000000000..d784e2129c8
--- /dev/null
+++ b/tests/Tests/Common/UrlParameters/Metrics/MetricsTests.cs
@@ -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();
+ }
+}