From a071d4d1d9f5038868f0dd8640887f1a3ff64080 Mon Sep 17 00:00:00 2001 From: Austin Tan Date: Thu, 4 Mar 2021 11:31:15 -0800 Subject: [PATCH] Resource Attributes allow Primitive Arrays (#1852) * Primitive arrays allowed in Resource Attributes + Tests * Changelog and spacing for build error * Fix Empty Value Test * fixing comprehensive supported types test * Remove check for null key * Moving one test case to separate test method * add support for converted array types * Remove null on key check * Changelog merged fix * Adjusting test --- src/OpenTelemetry/CHANGELOG.md | 3 + src/OpenTelemetry/Resources/Resource.cs | 33 ++++++++++- .../Resources/ResourceTest.cs | 57 ++++++++++++++++++- 3 files changed, 90 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index c8ecf62b05f..74af3d7381b 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -25,6 +25,9 @@ please check the latest changes [self diagnostic configuration file](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry/README.md#troubleshooting). ([#1865](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1865)) +* Resource Attributes now accept primitive arrays as values. + ([#1852](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1852)) + ## 1.0.1 Released 2021-Feb-10 diff --git a/src/OpenTelemetry/Resources/Resource.cs b/src/OpenTelemetry/Resources/Resource.cs index b04c0183e87..11099497812 100644 --- a/src/OpenTelemetry/Resources/Resource.cs +++ b/src/OpenTelemetry/Resources/Resource.cs @@ -109,7 +109,12 @@ private static object SanitizeValue(object value, string keyName) { if (value != null) { - if (value is string || value is bool || value is long || value is double) + if (value is string || value is bool || value is double || value is long) + { + return value; + } + + if (value is string[] || value is bool[] || value is double[] || value is long[]) { return value; } @@ -124,6 +129,32 @@ private static object SanitizeValue(object value, string keyName) return System.Convert.ToDouble(value, System.Globalization.CultureInfo.InvariantCulture); } + if (value is int[] || value is short[]) + { + long[] convertedArr = new long[((System.Array)value).Length]; + int i = 0; + foreach (var val in (System.Array)value) + { + convertedArr[i] = System.Convert.ToInt64(val); + i++; + } + + return convertedArr; + } + + if (value is float[]) + { + double[] convertedArr = new double[((float[])value).Length]; + int i = 0; + foreach (float val in (float[])value) + { + convertedArr[i] = System.Convert.ToDouble(val, System.Globalization.CultureInfo.InvariantCulture); + i++; + } + + return convertedArr; + } + throw new System.ArgumentException("Attribute value type is not an accepted primitive", keyName); } diff --git a/test/OpenTelemetry.Tests/Resources/ResourceTest.cs b/test/OpenTelemetry.Tests/Resources/ResourceTest.cs index 09ac62edbac..624d0c3f404 100644 --- a/test/OpenTelemetry.Tests/Resources/ResourceTest.cs +++ b/test/OpenTelemetry.Tests/Resources/ResourceTest.cs @@ -81,6 +81,20 @@ public void CreateResource_EmptyAttributeValue() Assert.Contains(new KeyValuePair("EmptyValue", string.Empty), resource.Attributes); } + [Fact] + public void CreateResource_EmptyArray() + { + // Arrange + var attributes = new Dictionary { { "EmptyArray", new string[0] } }; + + // does not throw + var resource = new Resource(attributes); + + // Assert + Assert.Single(resource.Attributes); + Assert.Equal(new string[0], resource.Attributes.Where(x => x.Key == "EmptyArray").FirstOrDefault().Value); + } + [Fact] public void CreateResource_EmptyAttribute() { @@ -126,12 +140,13 @@ public void CreateResource_MultipleAttribute() [Fact] public void CreateResource_SupportedAttributeTypes() { + // Arrange var attributes = new Dictionary { { "string", "stringValue" }, - { "long", 1L }, { "bool", true }, { "double", 0.1d }, + { "long", 1L }, // int and float supported by conversion to long and double { "int", 1 }, @@ -139,13 +154,16 @@ public void CreateResource_SupportedAttributeTypes() { "float", 0.1f }, }; + // Act var resource = new Resource(attributes); + // Assert Assert.Equal(7, resource.Attributes.Count()); Assert.Contains(new KeyValuePair("string", "stringValue"), resource.Attributes); - Assert.Contains(new KeyValuePair("long", 1L), resource.Attributes); Assert.Contains(new KeyValuePair("bool", true), resource.Attributes); Assert.Contains(new KeyValuePair("double", 0.1d), resource.Attributes); + Assert.Contains(new KeyValuePair("long", 1L), resource.Attributes); + Assert.Contains(new KeyValuePair("int", 1L), resource.Attributes); Assert.Contains(new KeyValuePair("short", 1L), resource.Attributes); @@ -153,6 +171,41 @@ public void CreateResource_SupportedAttributeTypes() Assert.Contains(new KeyValuePair("float", convertedFloat), resource.Attributes); } + [Fact] + public void CreateResource_SupportedAttributeArrayTypes() + { + // Arrange + var attributes = new Dictionary + { + // natively supported array types + { "string arr", new string[] { "stringValue" } }, + { "bool arr", new bool[] { true } }, + { "double arr", new double[] { 0.1d } }, + { "long arr", new long[] { 1L } }, + + // have to convert to other primitive array types + { "int arr", new int[] { 1 } }, + { "short arr", new short[] { (short)1 } }, + { "float arr", new float[] { 0.1f } }, + }; + + // Act + var resource = new Resource(attributes); + + // Assert + Assert.Equal(7, resource.Attributes.Count()); + Assert.Equal(new string[] { "stringValue" }, resource.Attributes.Where(x => x.Key == "string arr").FirstOrDefault().Value); + Assert.Equal(new bool[] { true }, resource.Attributes.Where(x => x.Key == "bool arr").FirstOrDefault().Value); + Assert.Equal(new double[] { 0.1d }, resource.Attributes.Where(x => x.Key == "double arr").FirstOrDefault().Value); + Assert.Equal(new long[] { 1L }, resource.Attributes.Where(x => x.Key == "long arr").FirstOrDefault().Value); + + var longArr = new long[] { 1 }; + var doubleArr = new double[] { Convert.ToDouble(0.1f, System.Globalization.CultureInfo.InvariantCulture) }; + Assert.Equal(longArr, resource.Attributes.Where(x => x.Key == "int arr").FirstOrDefault().Value); + Assert.Equal(longArr, resource.Attributes.Where(x => x.Key == "short arr").FirstOrDefault().Value); + Assert.Equal(doubleArr, resource.Attributes.Where(x => x.Key == "float arr").FirstOrDefault().Value); + } + [Fact] public void CreateResource_NotSupportedAttributeTypes() {