From 5b4ebab917c29cbc8872b962392f2fc73e9ecad1 Mon Sep 17 00:00:00 2001 From: m-nash <64171366+m-nash@users.noreply.github.com> Date: Mon, 14 Mar 2022 14:43:54 -0700 Subject: [PATCH] Update to serialize / deserialize BinaryData to support untyped yet dynamic used cases (#27382) * wip * wip * update proj references for files needed by lro * refactor code * update api and unit tests * update keyvault includes * add round trip validation for all cases * remove dupe from storage * one more dupe in storage * change to IDictionary * fix proj files for storage * Remove from json * update to use jsonelement * rename back to ToDictionaryFromJson * throw exception if the json was not a json object * Update sdk/core/Azure.Core/src/Serialization/AzureCoreExtensions.cs Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> --- eng/Directory.Build.Common.targets | 10 +- eng/Packages.Data.props | 2 +- .../src/Azure.ServiceTemplate.Template.csproj | 8 - .../Azure.Verticals.AgriFood.Farming.csproj | 5 - .../src/Azure.AI.AnomalyDetector.csproj | 5 - .../src/Azure.Security.Attestation.csproj | 5 - .../Azure.AI.Language.Conversations.csproj | 5 - ...Azure.AI.Language.QuestionAnswering.csproj | 5 - .../Azure.Communication.CallingServer.csproj | 5 - .../src/Azure.Communication.Chat.csproj | 5 - .../src/Azure.Communication.Identity.csproj | 5 - ...zure.Communication.NetworkTraversal.csproj | 5 - .../Azure.Communication.PhoneNumbers.csproj | 5 - .../src/Azure.Communication.Sms.csproj | 5 - .../Azure.Security.ConfidentialLedger.csproj | 5 - .../Azure.Containers.ContainerRegistry.csproj | 5 - .../src/Azure.Core.Experimental.csproj | 5 - .../src/Azure.Core.TestFramework.csproj | 5 - sdk/core/Azure.Core/api/Azure.Core.net461.cs | 1 + sdk/core/Azure.Core/api/Azure.Core.net5.0.cs | 1 + .../api/Azure.Core.netcoreapp2.1.cs | 1 + .../api/Azure.Core.netstandard2.0.cs | 1 + .../Azure.Core/perf/Azure.Core.Perf.csproj | 8 +- .../Azure.Core/perf/DynamicObjectBenchmark.cs | 104 +++++++ .../perf/TestData/JsonFormattedString.json | 1 + .../src/Serialization/AzureCoreExtensions.cs | 58 ++++ .../Azure.Core/tests/Azure.Core.Tests.csproj | 5 + .../tests/BinaryDataSerializationTests.cs | 256 ++++++++++++++++++ .../Azure.Core/tests/ModelWithBinaryData.cs | 69 +++++ sdk/core/Azure.Core/tests/ModelWithObject.cs | 64 +++++ .../tests/Properties/AssemblyInfo.cs | 6 + .../BinaryData/JsonFormattedString.json | 1 + .../tests/TestData/BinaryData/Properties.json | 1 + .../BinaryData/PropertiesWithArrays.json | 1 + .../PropertiesWithArraysOfArrays.json | 1 + .../PropertiesWithArraysOfObjects.json | 1 + .../PropertiesWithDifferentValueTypes.json | 1 + .../src/Azure.IoT.DeviceUpdate.csproj | 5 - .../src/Azure.DigitalTwins.Core.csproj | 13 - .../src/Azure.Messaging.EventGrid.csproj | 5 - .../src/Azure.AI.FormRecognizer.csproj | 5 - .../src/Azure.IoT.Hub.Service.csproj | 13 - ...re.Security.KeyVault.Administration.csproj | 5 - ...zure.Security.KeyVault.Certificates.csproj | 5 - .../src/Azure.Security.KeyVault.Keys.csproj | 7 - .../Azure.Security.KeyVault.Secrets.csproj | 5 - .../src/Azure.AI.MetricsAdvisor.csproj | 5 - .../Azure.MixedReality.Authentication.csproj | 5 - .../src/Azure.IoT.ModelsRepository.csproj | 13 - ...zure.Monitor.OpenTelemetry.Exporter.csproj | 5 - .../src/Azure.Monitor.Query.csproj | 5 - ...xedReality.ObjectAnchors.Conversion.csproj | 5 - .../src/Azure.AI.Personalizer.csproj | 5 - .../Azure.Analytics.Purview.Account.csproj | 5 - ...re.Analytics.Purview.Administration.csproj | 5 - .../Azure.Analytics.Purview.Catalog.csproj | 5 - .../Azure.Analytics.Purview.Scanning.csproj | 5 - .../src/Azure.Quantum.Jobs.csproj | 5 - .../Azure.MixedReality.RemoteRendering.csproj | 5 - .../src/Azure.Data.SchemaRegistry.csproj | 5 - .../src/Azure.Search.Documents.csproj | 5 - .../src/Azure.Storage.Blobs.Batch.csproj | 5 - .../src/Azure.Storage.Blobs.csproj | 5 - .../src/Azure.Storage.Common.csproj | 3 +- .../tests/Azure.Storage.Common.Tests.csproj | 4 - .../src/Azure.Storage.Files.DataLake.csproj | 5 - .../src/Azure.Storage.Files.Shares.csproj | 5 - .../src/Azure.Storage.Queues.csproj | 5 - ...ure.Analytics.Synapse.AccessControl.csproj | 5 - .../Azure.Analytics.Synapse.Artifacts.csproj | 5 - ...ics.Synapse.ManagedPrivateEndpoints.csproj | 5 - .../Azure.Analytics.Synapse.Monitoring.csproj | 5 - .../src/Azure.Analytics.Synapse.Spark.csproj | 5 - .../src/Azure.Data.Tables.csproj | 5 - .../Azure.Template/src/Azure.Template.csproj | 5 - .../src/Azure.AI.TextAnalytics.csproj | 5 - .../src/Azure.IoT.TimeSeriesInsights.csproj | 5 - .../src/Azure.AI.Translation.Document.csproj | 5 - .../src/Azure.Media.VideoAnalyzer.Edge.csproj | 8 - .../src/Azure.Messaging.WebPubSub.csproj | 5 - 80 files changed, 587 insertions(+), 330 deletions(-) create mode 100644 sdk/core/Azure.Core/perf/DynamicObjectBenchmark.cs create mode 100644 sdk/core/Azure.Core/perf/TestData/JsonFormattedString.json create mode 100644 sdk/core/Azure.Core/tests/ModelWithBinaryData.cs create mode 100644 sdk/core/Azure.Core/tests/ModelWithObject.cs create mode 100644 sdk/core/Azure.Core/tests/Properties/AssemblyInfo.cs create mode 100644 sdk/core/Azure.Core/tests/TestData/BinaryData/JsonFormattedString.json create mode 100644 sdk/core/Azure.Core/tests/TestData/BinaryData/Properties.json create mode 100644 sdk/core/Azure.Core/tests/TestData/BinaryData/PropertiesWithArrays.json create mode 100644 sdk/core/Azure.Core/tests/TestData/BinaryData/PropertiesWithArraysOfArrays.json create mode 100644 sdk/core/Azure.Core/tests/TestData/BinaryData/PropertiesWithArraysOfObjects.json create mode 100644 sdk/core/Azure.Core/tests/TestData/BinaryData/PropertiesWithDifferentValueTypes.json diff --git a/eng/Directory.Build.Common.targets b/eng/Directory.Build.Common.targets index 4b1e005fcaab6..f1855cf41e195 100644 --- a/eng/Directory.Build.Common.targets +++ b/eng/Directory.Build.Common.targets @@ -202,6 +202,11 @@ + + + + + @@ -211,12 +216,7 @@ - - - - - diff --git a/eng/Packages.Data.props b/eng/Packages.Data.props index c7c75276e3339..e09d471b2f91b 100644 --- a/eng/Packages.Data.props +++ b/eng/Packages.Data.props @@ -182,7 +182,7 @@ - + diff --git a/eng/templates/Azure.ServiceTemplate.Template/src/Azure.ServiceTemplate.Template.csproj b/eng/templates/Azure.ServiceTemplate.Template/src/Azure.ServiceTemplate.Template.csproj index a1d1c526c4958..409f41a167f31 100644 --- a/eng/templates/Azure.ServiceTemplate.Template/src/Azure.ServiceTemplate.Template.csproj +++ b/eng/templates/Azure.ServiceTemplate.Template/src/Azure.ServiceTemplate.Template.csproj @@ -13,15 +13,7 @@ - - - - - - - - diff --git a/sdk/agrifood/Azure.Verticals.AgriFood.Farming/src/Azure.Verticals.AgriFood.Farming.csproj b/sdk/agrifood/Azure.Verticals.AgriFood.Farming/src/Azure.Verticals.AgriFood.Farming.csproj index 4b3b35695c2a1..ac82769678483 100644 --- a/sdk/agrifood/Azure.Verticals.AgriFood.Farming/src/Azure.Verticals.AgriFood.Farming.csproj +++ b/sdk/agrifood/Azure.Verticals.AgriFood.Farming/src/Azure.Verticals.AgriFood.Farming.csproj @@ -18,13 +18,8 @@ - - - - - diff --git a/sdk/anomalydetector/Azure.AI.AnomalyDetector/src/Azure.AI.AnomalyDetector.csproj b/sdk/anomalydetector/Azure.AI.AnomalyDetector/src/Azure.AI.AnomalyDetector.csproj index 342412019d95c..dd1a2e3976010 100644 --- a/sdk/anomalydetector/Azure.AI.AnomalyDetector/src/Azure.AI.AnomalyDetector.csproj +++ b/sdk/anomalydetector/Azure.AI.AnomalyDetector/src/Azure.AI.AnomalyDetector.csproj @@ -17,14 +17,9 @@ - - - - - diff --git a/sdk/attestation/Azure.Security.Attestation/src/Azure.Security.Attestation.csproj b/sdk/attestation/Azure.Security.Attestation/src/Azure.Security.Attestation.csproj index 8d3a9ec828488..3375544b4c476 100644 --- a/sdk/attestation/Azure.Security.Attestation/src/Azure.Security.Attestation.csproj +++ b/sdk/attestation/Azure.Security.Attestation/src/Azure.Security.Attestation.csproj @@ -18,12 +18,7 @@ - - - - - diff --git a/sdk/cognitivelanguage/Azure.AI.Language.Conversations/src/Azure.AI.Language.Conversations.csproj b/sdk/cognitivelanguage/Azure.AI.Language.Conversations/src/Azure.AI.Language.Conversations.csproj index d43893a35c809..7b0e56888520d 100644 --- a/sdk/cognitivelanguage/Azure.AI.Language.Conversations/src/Azure.AI.Language.Conversations.csproj +++ b/sdk/cognitivelanguage/Azure.AI.Language.Conversations/src/Azure.AI.Language.Conversations.csproj @@ -16,14 +16,9 @@ - - - - - diff --git a/sdk/cognitivelanguage/Azure.AI.Language.QuestionAnswering/src/Azure.AI.Language.QuestionAnswering.csproj b/sdk/cognitivelanguage/Azure.AI.Language.QuestionAnswering/src/Azure.AI.Language.QuestionAnswering.csproj index 6930bdda4f667..deac062f2ec4d 100644 --- a/sdk/cognitivelanguage/Azure.AI.Language.QuestionAnswering/src/Azure.AI.Language.QuestionAnswering.csproj +++ b/sdk/cognitivelanguage/Azure.AI.Language.QuestionAnswering/src/Azure.AI.Language.QuestionAnswering.csproj @@ -18,14 +18,9 @@ - - - - - diff --git a/sdk/communication/Azure.Communication.CallingServer/src/Azure.Communication.CallingServer.csproj b/sdk/communication/Azure.Communication.CallingServer/src/Azure.Communication.CallingServer.csproj index 6ce05f7cdafca..6543de2a8833c 100644 --- a/sdk/communication/Azure.Communication.CallingServer/src/Azure.Communication.CallingServer.csproj +++ b/sdk/communication/Azure.Communication.CallingServer/src/Azure.Communication.CallingServer.csproj @@ -20,16 +20,11 @@ - - - - - diff --git a/sdk/communication/Azure.Communication.Chat/src/Azure.Communication.Chat.csproj b/sdk/communication/Azure.Communication.Chat/src/Azure.Communication.Chat.csproj index 4c574b657f848..379667cea8106 100644 --- a/sdk/communication/Azure.Communication.Chat/src/Azure.Communication.Chat.csproj +++ b/sdk/communication/Azure.Communication.Chat/src/Azure.Communication.Chat.csproj @@ -27,12 +27,7 @@ - - - - - diff --git a/sdk/communication/Azure.Communication.Identity/src/Azure.Communication.Identity.csproj b/sdk/communication/Azure.Communication.Identity/src/Azure.Communication.Identity.csproj index 072dcba061d3a..dee0d77f67674 100644 --- a/sdk/communication/Azure.Communication.Identity/src/Azure.Communication.Identity.csproj +++ b/sdk/communication/Azure.Communication.Identity/src/Azure.Communication.Identity.csproj @@ -28,14 +28,9 @@ - - - - - diff --git a/sdk/communication/Azure.Communication.NetworkTraversal/src/Azure.Communication.NetworkTraversal.csproj b/sdk/communication/Azure.Communication.NetworkTraversal/src/Azure.Communication.NetworkTraversal.csproj index f4f7f3c34bc66..bd1a4421d0504 100644 --- a/sdk/communication/Azure.Communication.NetworkTraversal/src/Azure.Communication.NetworkTraversal.csproj +++ b/sdk/communication/Azure.Communication.NetworkTraversal/src/Azure.Communication.NetworkTraversal.csproj @@ -25,14 +25,9 @@ - - - - - diff --git a/sdk/communication/Azure.Communication.PhoneNumbers/src/Azure.Communication.PhoneNumbers.csproj b/sdk/communication/Azure.Communication.PhoneNumbers/src/Azure.Communication.PhoneNumbers.csproj index e52572f32d7d9..6a5b8c3d88d29 100644 --- a/sdk/communication/Azure.Communication.PhoneNumbers/src/Azure.Communication.PhoneNumbers.csproj +++ b/sdk/communication/Azure.Communication.PhoneNumbers/src/Azure.Communication.PhoneNumbers.csproj @@ -27,14 +27,9 @@ - - - - - diff --git a/sdk/communication/Azure.Communication.Sms/src/Azure.Communication.Sms.csproj b/sdk/communication/Azure.Communication.Sms/src/Azure.Communication.Sms.csproj index bd46bb9b48c2c..6d4377c170729 100644 --- a/sdk/communication/Azure.Communication.Sms/src/Azure.Communication.Sms.csproj +++ b/sdk/communication/Azure.Communication.Sms/src/Azure.Communication.Sms.csproj @@ -25,14 +25,9 @@ - - - - - diff --git a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/Azure.Security.ConfidentialLedger.csproj b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/Azure.Security.ConfidentialLedger.csproj index 1d1f22aa86e10..eae260fadf8bd 100644 --- a/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/Azure.Security.ConfidentialLedger.csproj +++ b/sdk/confidentialledger/Azure.Security.ConfidentialLedger/src/Azure.Security.ConfidentialLedger.csproj @@ -21,15 +21,10 @@ - - - - - diff --git a/sdk/containerregistry/Azure.Containers.ContainerRegistry/src/Azure.Containers.ContainerRegistry.csproj b/sdk/containerregistry/Azure.Containers.ContainerRegistry/src/Azure.Containers.ContainerRegistry.csproj index 67ede240a788c..ab7076d525283 100644 --- a/sdk/containerregistry/Azure.Containers.ContainerRegistry/src/Azure.Containers.ContainerRegistry.csproj +++ b/sdk/containerregistry/Azure.Containers.ContainerRegistry/src/Azure.Containers.ContainerRegistry.csproj @@ -17,15 +17,10 @@ - - - - - diff --git a/sdk/core/Azure.Core.Experimental/src/Azure.Core.Experimental.csproj b/sdk/core/Azure.Core.Experimental/src/Azure.Core.Experimental.csproj index b6956ae0991ce..2b9e7503d195c 100644 --- a/sdk/core/Azure.Core.Experimental/src/Azure.Core.Experimental.csproj +++ b/sdk/core/Azure.Core.Experimental/src/Azure.Core.Experimental.csproj @@ -16,12 +16,7 @@ - - - - - diff --git a/sdk/core/Azure.Core.TestFramework/src/Azure.Core.TestFramework.csproj b/sdk/core/Azure.Core.TestFramework/src/Azure.Core.TestFramework.csproj index 04b8c3740379d..c14e0f6510779 100644 --- a/sdk/core/Azure.Core.TestFramework/src/Azure.Core.TestFramework.csproj +++ b/sdk/core/Azure.Core.TestFramework/src/Azure.Core.TestFramework.csproj @@ -23,14 +23,9 @@ - - - - - diff --git a/sdk/core/Azure.Core/api/Azure.Core.net461.cs b/sdk/core/Azure.Core/api/Azure.Core.net461.cs index 15d56ccb9824d..c014e0da5a019 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net461.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net461.cs @@ -17,6 +17,7 @@ protected AsyncPageable(System.Threading.CancellationToken cancellationToken) { } public static partial class AzureCoreExtensions { + public static System.Collections.Generic.IDictionary ToDictionaryFromJson(this System.BinaryData data) { throw null; } public static System.Threading.Tasks.ValueTask ToObjectAsync(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static T? ToObject(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } diff --git a/sdk/core/Azure.Core/api/Azure.Core.net5.0.cs b/sdk/core/Azure.Core/api/Azure.Core.net5.0.cs index 8c94044c7c5c6..4b1a77bcd6df8 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net5.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net5.0.cs @@ -17,6 +17,7 @@ protected AsyncPageable(System.Threading.CancellationToken cancellationToken) { } public static partial class AzureCoreExtensions { + public static System.Collections.Generic.IDictionary ToDictionaryFromJson(this System.BinaryData data) { throw null; } public static System.Threading.Tasks.ValueTask ToObjectAsync(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static T? ToObject(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } diff --git a/sdk/core/Azure.Core/api/Azure.Core.netcoreapp2.1.cs b/sdk/core/Azure.Core/api/Azure.Core.netcoreapp2.1.cs index 15d56ccb9824d..c014e0da5a019 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.netcoreapp2.1.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.netcoreapp2.1.cs @@ -17,6 +17,7 @@ protected AsyncPageable(System.Threading.CancellationToken cancellationToken) { } public static partial class AzureCoreExtensions { + public static System.Collections.Generic.IDictionary ToDictionaryFromJson(this System.BinaryData data) { throw null; } public static System.Threading.Tasks.ValueTask ToObjectAsync(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static T? ToObject(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } diff --git a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs index 15d56ccb9824d..c014e0da5a019 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs @@ -17,6 +17,7 @@ protected AsyncPageable(System.Threading.CancellationToken cancellationToken) { } public static partial class AzureCoreExtensions { + public static System.Collections.Generic.IDictionary ToDictionaryFromJson(this System.BinaryData data) { throw null; } public static System.Threading.Tasks.ValueTask ToObjectAsync(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static T? ToObject(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } diff --git a/sdk/core/Azure.Core/perf/Azure.Core.Perf.csproj b/sdk/core/Azure.Core/perf/Azure.Core.Perf.csproj index d7724bbb97113..316cd80e305eb 100644 --- a/sdk/core/Azure.Core/perf/Azure.Core.Perf.csproj +++ b/sdk/core/Azure.Core/perf/Azure.Core.Perf.csproj @@ -1,4 +1,4 @@ - + Exe @@ -10,6 +10,7 @@ + @@ -18,5 +19,10 @@ + + + Always + + diff --git a/sdk/core/Azure.Core/perf/DynamicObjectBenchmark.cs b/sdk/core/Azure.Core/perf/DynamicObjectBenchmark.cs new file mode 100644 index 0000000000000..9123b550da750 --- /dev/null +++ b/sdk/core/Azure.Core/perf/DynamicObjectBenchmark.cs @@ -0,0 +1,104 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Text.Json; +using Azure.Core.Tests; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Jobs; + +namespace Azure.Core.Perf +{ + [MemoryDiagnoser] + [SimpleJob(RuntimeMoniker.NetCoreApp31, baseline: true)] + [SimpleJob(RuntimeMoniker.Net461)] + [SimpleJob(RuntimeMoniker.Net60)] + public class DynamicObjectBenchmark + { + private static string _fileName = Path.Combine(Path.Combine(Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName, "TestData", "JsonFormattedString.json")); + private JsonDocument _jsonDocument; + private ModelWithBinaryData _modelWithBinaryData; + private ModelWithObject _modelWithObject; + + [GlobalSetup] + public void SetUp() + { + using var fs = new FileStream(_fileName, FileMode.Open, FileAccess.Read, FileShare.Read); + _jsonDocument = JsonDocument.Parse(fs); + + var anon = new + { + a = "properties.a.value", + innerProperties = new + { + a = "properties.innerProperties.a.value" + } + }; + + _modelWithBinaryData = new ModelWithBinaryData(); + _modelWithBinaryData.A = "a.value"; + _modelWithBinaryData.Properties = BinaryData.FromObjectAsJson(anon); + + _modelWithObject = new ModelWithObject(); + _modelWithObject.A = "a.value"; + _modelWithObject.Properties = new Dictionary() + { + { "a", "a.value" }, + { "innerProperties", new Dictionary() + { + {"a", "properties.innerProperties.a.value" } + } + } + }; + } + + [Benchmark] + public void DeserializeWithObject() + { + var model = ModelWithObject.DeserializeModelWithObject(_jsonDocument.RootElement); + } + + [Benchmark] + public void DeserializeWithObjectAndAccess() + { + var model = ModelWithObject.DeserializeModelWithObject(_jsonDocument.RootElement); + var properties = model.Properties as Dictionary; + var innerProperties = properties["innerProperties"] as Dictionary; + var innerA = innerProperties["a"] as string; + } + + [Benchmark] + public void SerializeWithObject() + { + using var ms = new MemoryStream(); + using var writer = new Utf8JsonWriter(ms); + _modelWithObject.Write(writer); + } + + [Benchmark] + public void DeserializeWithBinaryData() + { + var model = ModelWithBinaryData.DeserializeModelWithBinaryData(_jsonDocument.RootElement); + } + + [Benchmark] + public void DeserializeWithBinaryDataAndAccess() + { + var model = ModelWithBinaryData.DeserializeModelWithBinaryData(_jsonDocument.RootElement); + var properties = model.Properties.ToDictionaryFromJson(); + var innerProperties = properties["innerProperties"] as Dictionary; + var innerA = innerProperties["a"] as string; + } + + [Benchmark] + public void SerializeWithBinaryData() + { + using var ms = new MemoryStream(); + using var writer = new Utf8JsonWriter(ms); + _modelWithBinaryData.Write(writer); + } + } +} diff --git a/sdk/core/Azure.Core/perf/TestData/JsonFormattedString.json b/sdk/core/Azure.Core/perf/TestData/JsonFormattedString.json new file mode 100644 index 0000000000000..fab40d4914a24 --- /dev/null +++ b/sdk/core/Azure.Core/perf/TestData/JsonFormattedString.json @@ -0,0 +1 @@ +{"a":"a.value","properties":{"a":"properties.a.value","innerProperties":{"a":"properties.innerProperties.a.value"}}} diff --git a/sdk/core/Azure.Core/src/Serialization/AzureCoreExtensions.cs b/sdk/core/Azure.Core/src/Serialization/AzureCoreExtensions.cs index 6d78a7eb8b567..e8194e9fbac42 100644 --- a/sdk/core/Azure.Core/src/Serialization/AzureCoreExtensions.cs +++ b/sdk/core/Azure.Core/src/Serialization/AzureCoreExtensions.cs @@ -2,6 +2,8 @@ // Licensed under the MIT License. using System; +using System.Collections.Generic; +using System.Text.Json; using System.Threading; using System.Threading.Tasks; using Azure.Core.Serialization; @@ -40,5 +42,61 @@ public static class AzureCoreExtensions ///The data converted to the specified type. public static async ValueTask ToObjectAsync(this BinaryData data, ObjectSerializer serializer, CancellationToken cancellationToken = default) => (T?)await serializer.DeserializeAsync(data.ToStream(), typeof(T), cancellationToken).ConfigureAwait(false); + + /// + /// Converts the to a Dictionary of string to object. + /// Each value in the key value pair will be strongly typed as an int, long, string, Guid, double or bool. + /// Each value can also be another Dictionary of string object representing an inner object or + /// a List of objects representing an array. + /// + /// The instance to convert. + /// The data converted to the Dictionary of string to object. + public static IDictionary ToDictionaryFromJson(this BinaryData data) + { + JsonElement element = data.ToObjectFromJson(); + return element.GetObject() as Dictionary ?? throw new InvalidOperationException("The BinaryData instance did not represent a JSON object so it cannot be converted into a dictionary."); + } + + private static object? GetObject(in this JsonElement element) + { + switch (element.ValueKind) + { + case JsonValueKind.String: + return element.GetString(); + case JsonValueKind.Number: + if (element.TryGetInt32(out int intValue)) + { + return intValue; + } + if (element.TryGetInt64(out long longValue)) + { + return longValue; + } + return element.GetDouble(); + case JsonValueKind.True: + return true; + case JsonValueKind.False: + return false; + case JsonValueKind.Undefined: + case JsonValueKind.Null: + return null; + case JsonValueKind.Object: + var dictionary = new Dictionary(); + foreach (JsonProperty jsonProperty in element.EnumerateObject()) + { + dictionary.Add(jsonProperty.Name, jsonProperty.Value.GetObject()); + } + return dictionary; + case JsonValueKind.Array: + var list = new List(); + foreach (JsonElement item in element.EnumerateArray()) + { + list.Add(item.GetObject()); + } + return list.ToArray(); + default: + throw new NotSupportedException("Not supported value kind " + element.ValueKind); + } + } } } diff --git a/sdk/core/Azure.Core/tests/Azure.Core.Tests.csproj b/sdk/core/Azure.Core/tests/Azure.Core.Tests.csproj index c8c620af97388..c3501cad23777 100644 --- a/sdk/core/Azure.Core/tests/Azure.Core.Tests.csproj +++ b/sdk/core/Azure.Core/tests/Azure.Core.Tests.csproj @@ -50,4 +50,9 @@ + + + Always + + diff --git a/sdk/core/Azure.Core/tests/BinaryDataSerializationTests.cs b/sdk/core/Azure.Core/tests/BinaryDataSerializationTests.cs index f9cfd913ac87e..ee6314ca4abe5 100644 --- a/sdk/core/Azure.Core/tests/BinaryDataSerializationTests.cs +++ b/sdk/core/Azure.Core/tests/BinaryDataSerializationTests.cs @@ -2,7 +2,10 @@ // Licensed under the MIT License. using System; +using System.Collections.Generic; using System.IO; +using System.Reflection; +using System.Text.Json; using System.Text.Json.Serialization; using System.Threading; using System.Threading.Tasks; @@ -13,6 +16,254 @@ namespace Azure.Core.Tests { public class BinaryDataSerializationTests { + [Test] + public void CanConvertDifferentValueTypes() + { + var expected = File.ReadAllText(GetFileName("PropertiesWithDifferentValueTypes.json")).TrimEnd(); + var model = BinaryData.FromString(expected); + + var properties = model.ToDictionaryFromJson(); + Assert.AreEqual(typeof(string), properties["stringValue"].GetType()); + Assert.AreEqual(typeof(string), properties["dateTimeValue"].GetType()); + Assert.AreEqual(typeof(int), properties["intValue"].GetType()); + Assert.AreEqual(typeof(long), properties["longValue"].GetType()); + Assert.AreEqual(typeof(double), properties["doubleValue"].GetType()); + Assert.AreEqual(typeof(bool), properties["trueValue"].GetType()); + Assert.AreEqual(typeof(bool), properties["falseValue"].GetType()); + Assert.IsNull(properties["nullValue"]); + + Assert.AreEqual(expected, GetSerializedString(model)); + } + + [Test] + public void CanConvertArrays() + { + var expected = File.ReadAllText(GetFileName("PropertiesWithArrays.json")).TrimEnd(); + var model = BinaryData.FromString(expected); + + var properties = model.ToDictionaryFromJson(); + Assert.IsTrue(AllValuesAreType(typeof(string), properties["stringArray"])); + Assert.IsTrue(AllValuesAreType(typeof(string), properties["dateTimeArray"])); + Assert.IsTrue(AllValuesAreType(typeof(int), properties["intArray"])); + Assert.IsTrue(AllValuesAreType(typeof(long), properties["longArray"])); + Assert.IsTrue(AllValuesAreType(typeof(double), properties["doubleArray"])); + Assert.IsTrue(AllValuesAreType(typeof(bool), properties["boolArray"])); + foreach (var item in properties["nullArray"] as object[]) + { + Assert.IsNull(item); + } + var mixList = properties["mixedNullArray"] as object[]; + for (int i = 0; i < 2; i++) + { + if (i == 0) + { + Assert.IsNull(mixList[i]); + } + else + { + Assert.IsNotNull(mixList[i]); + } + } + Assert.AreEqual(expected, GetSerializedString(model)); + } + + [Test] + public void CanConvertArrayOfObjects() + { + var expected = File.ReadAllText(GetFileName("PropertiesWithArraysOfObjects.json")).TrimEnd(); + var model = BinaryData.FromString(expected); + var properties = model.ToDictionaryFromJson(); + var objArray = properties["objectArray"] as object[]; + for (int i = 0; i < 3; i++) + { + var obj = objArray[i] as Dictionary; + Assert.IsNotNull(obj); + Assert.AreEqual(i, obj["intValue"]); + var innerObj = obj["objectValue"] as Dictionary; + Assert.IsNotNull(innerObj); + Assert.AreEqual(i.ToString(), innerObj["stringValue"]); + } + Assert.AreEqual(expected, GetSerializedString(model)); + } + + [Test] + public void CanConvertArrayOfArrays() + { + var expected = File.ReadAllText(GetFileName("PropertiesWithArraysOfArrays.json")).TrimEnd(); + var model = BinaryData.FromString(expected); + var properties = model.ToDictionaryFromJson(); + var arrayArray = properties["arrayArray"] as object[]; + Assert.IsNotNull(arrayArray); + for (int i = 0; i < 2; i++) + { + var array = arrayArray[i] as object[]; + Assert.IsNotNull(array); + foreach (var item in array) + { + Assert.AreEqual(i, item); + } + } + Assert.AreEqual(expected, GetSerializedString(model)); + } + + private bool AllValuesAreType(Type type, object list) + { + foreach (var item in list as object[]) + { + if (!item.GetType().Equals(type)) + return false; + } + return true; + } + + [Test] + public void DeserializeJsonFormattedStringWithObject() + { + using (var fs = new FileStream(GetFileName("JsonFormattedString.json"), FileMode.Open, FileAccess.Read, FileShare.Read)) + { + using var document = JsonDocument.Parse(fs); + var data = ModelWithObject.DeserializeModelWithObject(document.RootElement); + Assert.AreEqual("a.value", data.A); + + var properties = data.Properties as Dictionary; + Assert.AreEqual("properties.a.value", properties["a"]); + var innerProperties = properties["innerProperties"] as IDictionary; + Assert.AreEqual("properties.innerProperties.a.value", innerProperties["a"]); + } + } + + [Test] + public void DeserializeJsonFormattedStringWithBinaryData() + { + using (var fs = new FileStream(GetFileName("JsonFormattedString.json"), FileMode.Open, FileAccess.Read, FileShare.Read)) + { + using var document = JsonDocument.Parse(fs); + var data = ModelWithBinaryData.DeserializeModelWithBinaryData(document.RootElement); + Assert.AreEqual("a.value", data.A); + + var properties = data.Properties.ToDictionaryFromJson(); + Assert.AreEqual("properties.a.value", properties["a"]); + var innerProperties = properties["innerProperties"] as IDictionary; + Assert.AreEqual("properties.innerProperties.a.value", innerProperties["a"]); + } + } + + [Test] + public void SerailizeUsingDictStringObject() + { + var expected = File.ReadAllText(GetFileName("JsonFormattedString.json")).TrimEnd(); + + var payload = new ModelWithBinaryData { A = "a.value" }; + var properties = new Dictionary(); + var innerProperties = new Dictionary(); + properties.Add("a", "properties.a.value"); + innerProperties.Add("a", "properties.innerProperties.a.value"); + properties.Add("innerProperties", innerProperties); + payload.Properties = BinaryData.FromObjectAsJson(properties); + + string actual = GetSerializedString(payload); + Assert.AreEqual(expected, actual); + } + + [Test] + public void SerailizeUsingJsonFormattedString() + { + var expected = File.ReadAllText(GetFileName("JsonFormattedString.json")).TrimEnd(); + + var payload = new ModelWithBinaryData { A = "a.value" }; + payload.Properties = BinaryData.FromString(File.ReadAllText(GetFileName("Properties.json")).TrimEnd()); + + string actual = GetSerializedString(payload); + Assert.AreEqual(expected, actual); + } + + [Test] + public void SerailizeUsingStream() + { + var expected = File.ReadAllText(GetFileName("JsonFormattedString.json")).TrimEnd(); + + var payload = new ModelWithBinaryData { A = "a.value" }; + using var fs = File.Open(GetFileName("Properties.json"), FileMode.Open, FileAccess.Read, FileShare.Read); + payload.Properties = BinaryData.FromStream(fs); + + string actual = GetSerializedString(payload); + //for some reason in dotnet 6 only there is a random new line after the binarydata object + //to make this work in all frameworks we will just do a comparison ignoring whitespace + Assert.IsTrue(CompareIgnoreWhitespace(expected, actual)); + } + + private bool? CompareIgnoreWhitespace(string expected, string actual) + { + int i = 0; + int j = 0; + while (i < expected.Length && j < actual.Length) + { + if (char.IsWhiteSpace(expected[i])) + { + i++; + continue; + } + if (char.IsWhiteSpace(actual[j])) + { + j++; + continue; + } + if (expected[i] != actual[j]) + return false; + i++; + j++; + } + return i == expected.Length && j == actual.Length; + } + + [Test] + public void SerailizeUsingAnonObject() + { + var expected = File.ReadAllText(GetFileName("JsonFormattedString.json")).TrimEnd(); + + var payload = new ModelWithBinaryData { A = "a.value" }; + var properties = new + { + a = "properties.a.value", + innerProperties = new + { + a = "properties.innerProperties.a.value" + } + }; + payload.Properties = BinaryData.FromObjectAsJson(properties); + + string actual = GetSerializedString(payload); + Assert.AreEqual(expected, actual); + } + + private static string GetSerializedString(BinaryData payload) + { + using var ms = new MemoryStream(); + Utf8JsonWriter writer = new Utf8JsonWriter(ms); +#if NET6_0_OR_GREATER + writer.WriteRawValue(payload); +#else + JsonSerializer.Serialize(writer, JsonDocument.Parse(payload.ToString()).RootElement); +#endif + writer.Flush(); + + ms.Position = 0; + using var sr = new StreamReader(ms); + return sr.ReadToEnd(); + } + + private static string GetSerializedString(IUtf8JsonSerializable payload) + { + using var ms = new MemoryStream(); + Utf8JsonWriter writer = new Utf8JsonWriter(ms); + payload.Write(writer); + writer.Flush(); + + ms.Position = 0; + using var sr = new StreamReader(ms); + return sr.ReadToEnd(); + } + [Test] public async Task CanCreateBinaryDataFromCustomType() { @@ -191,5 +442,10 @@ public override void Serialize(Stream stream, object value, Type inputType, Canc public async override ValueTask SerializeAsync(Stream stream, object value, Type inputType, CancellationToken cancellationToken) => await s_serializer.SerializeAsync(stream, value, inputType, cancellationToken).ConfigureAwait(false); } + + private string GetFileName(string file) + { + return Path.Combine(Path.Combine(Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName, "TestData", "BinaryData", file)); + } } } diff --git a/sdk/core/Azure.Core/tests/ModelWithBinaryData.cs b/sdk/core/Azure.Core/tests/ModelWithBinaryData.cs new file mode 100644 index 0000000000000..e31edcc859148 --- /dev/null +++ b/sdk/core/Azure.Core/tests/ModelWithBinaryData.cs @@ -0,0 +1,69 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Azure.Core; +using System.Text.Json; +using System.IO; + +namespace Azure.Core.Tests +{ + internal class ModelWithBinaryData : IUtf8JsonSerializable + { + public string A { get; set; } + public BinaryData Properties { get; set; } + + public ModelWithBinaryData() { } + + private ModelWithBinaryData(string a, BinaryData properties) + { + A = a; + Properties = properties; + } + + public void Write(Utf8JsonWriter writer) + { + writer.WriteStartObject(); + if (Optional.IsDefined(A)) + { + writer.WritePropertyName("a"); + writer.WriteStringValue(A); + } + if (Optional.IsDefined(Properties)) + { + writer.WritePropertyName("properties"); +#if NET6_0_OR_GREATER + writer.WriteRawValue(Properties); +#else + JsonSerializer.Serialize(writer, JsonDocument.Parse(Properties.ToString()).RootElement); +#endif + } + writer.WriteEndObject(); + } + + internal static ModelWithBinaryData DeserializeModelWithBinaryData(JsonElement element) + { + Optional a = default; + Optional properties = default; + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("a")) + { + a = property.Value.GetString(); + continue; + } + if (property.NameEquals("properties")) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + property.ThrowNonNullablePropertyIsNull(); + continue; + } + properties = BinaryData.FromString(property.Value.GetRawText()); + continue; + } + } + return new ModelWithBinaryData(a.Value, properties.Value); + } + } +} diff --git a/sdk/core/Azure.Core/tests/ModelWithObject.cs b/sdk/core/Azure.Core/tests/ModelWithObject.cs new file mode 100644 index 0000000000000..194d0156e4cd2 --- /dev/null +++ b/sdk/core/Azure.Core/tests/ModelWithObject.cs @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Azure.Core; +using System.Text.Json; + +namespace Azure.Core.Tests +{ + internal class ModelWithObject : IUtf8JsonSerializable + { + public string A { get; set; } + public object Properties { get; set; } + + public ModelWithObject() { } + + private ModelWithObject(string a, object properties) + { + A = a; + Properties = properties; + } + + public void Write(Utf8JsonWriter writer) + { + writer.WriteStartObject(); + if (Optional.IsDefined(A)) + { + writer.WritePropertyName("a"); + writer.WriteStringValue(A); + } + if (Optional.IsDefined(Properties)) + { + writer.WritePropertyName("properties"); + writer.WriteObjectValue(Properties); + } + writer.WriteEndObject(); + } + + internal static ModelWithObject DeserializeModelWithObject(JsonElement element) + { + Optional a = default; + Optional properties = default; + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("a")) + { + a = property.Value.GetString(); + continue; + } + if (property.NameEquals("properties")) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + property.ThrowNonNullablePropertyIsNull(); + continue; + } + properties = property.Value.GetObject(); + continue; + } + } + return new ModelWithObject(a.Value, properties.Value); + } + } +} diff --git a/sdk/core/Azure.Core/tests/Properties/AssemblyInfo.cs b/sdk/core/Azure.Core/tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000000..d78129fc60a60 --- /dev/null +++ b/sdk/core/Azure.Core/tests/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Azure.Core.Perf, PublicKey=0024000004800000940000000602000000240000525341310004000001000100d15ddcb29688295338af4b7686603fe614abd555e09efba8fb88ee09e1f7b1ccaeed2e8f823fa9eef3fdd60217fc012ea67d2479751a0b8c087a4185541b851bd8b16f8d91b840e51b1cb0ba6fe647997e57429265e85ef62d565db50a69ae1647d54d7bd855e4db3d8a91510e5bcbd0edfbbecaa20a7bd9ae74593daa7b11b4")] diff --git a/sdk/core/Azure.Core/tests/TestData/BinaryData/JsonFormattedString.json b/sdk/core/Azure.Core/tests/TestData/BinaryData/JsonFormattedString.json new file mode 100644 index 0000000000000..fab40d4914a24 --- /dev/null +++ b/sdk/core/Azure.Core/tests/TestData/BinaryData/JsonFormattedString.json @@ -0,0 +1 @@ +{"a":"a.value","properties":{"a":"properties.a.value","innerProperties":{"a":"properties.innerProperties.a.value"}}} diff --git a/sdk/core/Azure.Core/tests/TestData/BinaryData/Properties.json b/sdk/core/Azure.Core/tests/TestData/BinaryData/Properties.json new file mode 100644 index 0000000000000..2caed46d1d5c0 --- /dev/null +++ b/sdk/core/Azure.Core/tests/TestData/BinaryData/Properties.json @@ -0,0 +1 @@ +{"a":"properties.a.value","innerProperties":{"a":"properties.innerProperties.a.value"}} diff --git a/sdk/core/Azure.Core/tests/TestData/BinaryData/PropertiesWithArrays.json b/sdk/core/Azure.Core/tests/TestData/BinaryData/PropertiesWithArrays.json new file mode 100644 index 0000000000000..eb514ccfded24 --- /dev/null +++ b/sdk/core/Azure.Core/tests/TestData/BinaryData/PropertiesWithArrays.json @@ -0,0 +1 @@ +{"stringArray":["string","string"],"dateTimeArray":["2022-01-01","2022-01-01"],"intArray":[1,1],"longArray":[1000000000000,1000000000000],"doubleArray":[1.1,1.1],"boolArray":[true,false],"nullArray":[null,null],"mixedNullArray":[null,"notNull"]} diff --git a/sdk/core/Azure.Core/tests/TestData/BinaryData/PropertiesWithArraysOfArrays.json b/sdk/core/Azure.Core/tests/TestData/BinaryData/PropertiesWithArraysOfArrays.json new file mode 100644 index 0000000000000..a831a17a708f6 --- /dev/null +++ b/sdk/core/Azure.Core/tests/TestData/BinaryData/PropertiesWithArraysOfArrays.json @@ -0,0 +1 @@ +{"arrayArray":[[0,0],[1,1]]} diff --git a/sdk/core/Azure.Core/tests/TestData/BinaryData/PropertiesWithArraysOfObjects.json b/sdk/core/Azure.Core/tests/TestData/BinaryData/PropertiesWithArraysOfObjects.json new file mode 100644 index 0000000000000..315741459f114 --- /dev/null +++ b/sdk/core/Azure.Core/tests/TestData/BinaryData/PropertiesWithArraysOfObjects.json @@ -0,0 +1 @@ +{"objectArray":[{"intValue":0,"objectValue":{"stringValue":"0"}},{"intValue":1,"objectValue":{"stringValue":"1"}},{"intValue":2,"objectValue":{"stringValue":"2"}}]} diff --git a/sdk/core/Azure.Core/tests/TestData/BinaryData/PropertiesWithDifferentValueTypes.json b/sdk/core/Azure.Core/tests/TestData/BinaryData/PropertiesWithDifferentValueTypes.json new file mode 100644 index 0000000000000..cc33e5b24fc21 --- /dev/null +++ b/sdk/core/Azure.Core/tests/TestData/BinaryData/PropertiesWithDifferentValueTypes.json @@ -0,0 +1 @@ +{"stringValue":"string","dateTimeValue":"2022-01-01","intValue":1000,"longValue":1000000000000,"doubleValue":1.1,"trueValue":true,"falseValue":false,"nullValue":null} diff --git a/sdk/deviceupdate/Azure.IoT.DeviceUpdate/src/Azure.IoT.DeviceUpdate.csproj b/sdk/deviceupdate/Azure.IoT.DeviceUpdate/src/Azure.IoT.DeviceUpdate.csproj index fedd4a51d0d50..2cb254b574340 100644 --- a/sdk/deviceupdate/Azure.IoT.DeviceUpdate/src/Azure.IoT.DeviceUpdate.csproj +++ b/sdk/deviceupdate/Azure.IoT.DeviceUpdate/src/Azure.IoT.DeviceUpdate.csproj @@ -20,12 +20,7 @@ - - - - - diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Azure.DigitalTwins.Core.csproj b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Azure.DigitalTwins.Core.csproj index 29289c319d187..554699a173e6b 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Azure.DigitalTwins.Core.csproj +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Azure.DigitalTwins.Core.csproj @@ -24,22 +24,9 @@ - Shared\Azure.Core - - Shared\Azure.Core - - - Shared\Azure.Core - - - Shared\Azure.Core - - - Shared\Azure.Core - Shared\Azure.Core diff --git a/sdk/eventgrid/Azure.Messaging.EventGrid/src/Azure.Messaging.EventGrid.csproj b/sdk/eventgrid/Azure.Messaging.EventGrid/src/Azure.Messaging.EventGrid.csproj index d02e3f64ee144..86e88246e858e 100644 --- a/sdk/eventgrid/Azure.Messaging.EventGrid/src/Azure.Messaging.EventGrid.csproj +++ b/sdk/eventgrid/Azure.Messaging.EventGrid/src/Azure.Messaging.EventGrid.csproj @@ -18,13 +18,8 @@ - - - - - diff --git a/sdk/formrecognizer/Azure.AI.FormRecognizer/src/Azure.AI.FormRecognizer.csproj b/sdk/formrecognizer/Azure.AI.FormRecognizer/src/Azure.AI.FormRecognizer.csproj index da7c431f7e0d8..537decd92c22f 100644 --- a/sdk/formrecognizer/Azure.AI.FormRecognizer/src/Azure.AI.FormRecognizer.csproj +++ b/sdk/formrecognizer/Azure.AI.FormRecognizer/src/Azure.AI.FormRecognizer.csproj @@ -17,14 +17,9 @@ - - - - - diff --git a/sdk/iot/Azure.IoT.Hub.Service/src/Azure.IoT.Hub.Service.csproj b/sdk/iot/Azure.IoT.Hub.Service/src/Azure.IoT.Hub.Service.csproj index fa22068c20457..fefcac5c4e342 100644 --- a/sdk/iot/Azure.IoT.Hub.Service/src/Azure.IoT.Hub.Service.csproj +++ b/sdk/iot/Azure.IoT.Hub.Service/src/Azure.IoT.Hub.Service.csproj @@ -20,22 +20,9 @@ - Shared\Azure.Core - - Shared\Azure.Core - - - Shared\Azure.Core - - - Shared\Azure.Core - - - Shared\Azure.Core - Shared\Azure.Core diff --git a/sdk/keyvault/Azure.Security.KeyVault.Administration/src/Azure.Security.KeyVault.Administration.csproj b/sdk/keyvault/Azure.Security.KeyVault.Administration/src/Azure.Security.KeyVault.Administration.csproj index c17eea93be9cc..09e349e4b213d 100644 --- a/sdk/keyvault/Azure.Security.KeyVault.Administration/src/Azure.Security.KeyVault.Administration.csproj +++ b/sdk/keyvault/Azure.Security.KeyVault.Administration/src/Azure.Security.KeyVault.Administration.csproj @@ -25,15 +25,10 @@ - - - - - diff --git a/sdk/keyvault/Azure.Security.KeyVault.Certificates/src/Azure.Security.KeyVault.Certificates.csproj b/sdk/keyvault/Azure.Security.KeyVault.Certificates/src/Azure.Security.KeyVault.Certificates.csproj index eed2d3c94aa71..c4c10ae60bbbf 100644 --- a/sdk/keyvault/Azure.Security.KeyVault.Certificates/src/Azure.Security.KeyVault.Certificates.csproj +++ b/sdk/keyvault/Azure.Security.KeyVault.Certificates/src/Azure.Security.KeyVault.Certificates.csproj @@ -26,15 +26,10 @@ - - - - - diff --git a/sdk/keyvault/Azure.Security.KeyVault.Keys/src/Azure.Security.KeyVault.Keys.csproj b/sdk/keyvault/Azure.Security.KeyVault.Keys/src/Azure.Security.KeyVault.Keys.csproj index 754273a323d44..71aca8b9bb620 100644 --- a/sdk/keyvault/Azure.Security.KeyVault.Keys/src/Azure.Security.KeyVault.Keys.csproj +++ b/sdk/keyvault/Azure.Security.KeyVault.Keys/src/Azure.Security.KeyVault.Keys.csproj @@ -16,9 +16,6 @@ - - - @@ -28,14 +25,10 @@ - - - - diff --git a/sdk/keyvault/Azure.Security.KeyVault.Secrets/src/Azure.Security.KeyVault.Secrets.csproj b/sdk/keyvault/Azure.Security.KeyVault.Secrets/src/Azure.Security.KeyVault.Secrets.csproj index 5d3b6922bde17..363f668617c3d 100644 --- a/sdk/keyvault/Azure.Security.KeyVault.Secrets/src/Azure.Security.KeyVault.Secrets.csproj +++ b/sdk/keyvault/Azure.Security.KeyVault.Secrets/src/Azure.Security.KeyVault.Secrets.csproj @@ -24,14 +24,9 @@ - - - - - diff --git a/sdk/metricsadvisor/Azure.AI.MetricsAdvisor/src/Azure.AI.MetricsAdvisor.csproj b/sdk/metricsadvisor/Azure.AI.MetricsAdvisor/src/Azure.AI.MetricsAdvisor.csproj index a13d4b97657c0..5fbcabeeb7748 100644 --- a/sdk/metricsadvisor/Azure.AI.MetricsAdvisor/src/Azure.AI.MetricsAdvisor.csproj +++ b/sdk/metricsadvisor/Azure.AI.MetricsAdvisor/src/Azure.AI.MetricsAdvisor.csproj @@ -20,12 +20,7 @@ - - - - - diff --git a/sdk/mixedreality/Azure.MixedReality.Authentication/src/Azure.MixedReality.Authentication.csproj b/sdk/mixedreality/Azure.MixedReality.Authentication/src/Azure.MixedReality.Authentication.csproj index 7d24ef9fb1f9c..e0215fa3d892c 100644 --- a/sdk/mixedreality/Azure.MixedReality.Authentication/src/Azure.MixedReality.Authentication.csproj +++ b/sdk/mixedreality/Azure.MixedReality.Authentication/src/Azure.MixedReality.Authentication.csproj @@ -20,12 +20,7 @@ - - - - - diff --git a/sdk/modelsrepository/Azure.IoT.ModelsRepository/src/Azure.IoT.ModelsRepository.csproj b/sdk/modelsrepository/Azure.IoT.ModelsRepository/src/Azure.IoT.ModelsRepository.csproj index ee9372c007822..8a1205ca4a178 100644 --- a/sdk/modelsrepository/Azure.IoT.ModelsRepository/src/Azure.IoT.ModelsRepository.csproj +++ b/sdk/modelsrepository/Azure.IoT.ModelsRepository/src/Azure.IoT.ModelsRepository.csproj @@ -27,25 +27,12 @@ - Shared\Azure.Core Shared\Azure.Core - - Shared\Azure.Core - - - Shared\Azure.Core - - - Shared\Azure.Core - - - Shared\Azure.Core - Shared\Azure.Core diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Azure.Monitor.OpenTelemetry.Exporter.csproj b/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Azure.Monitor.OpenTelemetry.Exporter.csproj index 27d0da4b44a14..22bf9cf46bfe2 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Azure.Monitor.OpenTelemetry.Exporter.csproj +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Azure.Monitor.OpenTelemetry.Exporter.csproj @@ -17,13 +17,8 @@ - - - - - diff --git a/sdk/monitor/Azure.Monitor.Query/src/Azure.Monitor.Query.csproj b/sdk/monitor/Azure.Monitor.Query/src/Azure.Monitor.Query.csproj index 2588278604c28..32f86abb88bb2 100644 --- a/sdk/monitor/Azure.Monitor.Query/src/Azure.Monitor.Query.csproj +++ b/sdk/monitor/Azure.Monitor.Query/src/Azure.Monitor.Query.csproj @@ -18,12 +18,7 @@ - - - - - diff --git a/sdk/objectanchors/Azure.MixedReality.ObjectAnchors.Conversion/src/Azure.MixedReality.ObjectAnchors.Conversion.csproj b/sdk/objectanchors/Azure.MixedReality.ObjectAnchors.Conversion/src/Azure.MixedReality.ObjectAnchors.Conversion.csproj index 6ac4c298760f2..5f2cfe1230aa6 100644 --- a/sdk/objectanchors/Azure.MixedReality.ObjectAnchors.Conversion/src/Azure.MixedReality.ObjectAnchors.Conversion.csproj +++ b/sdk/objectanchors/Azure.MixedReality.ObjectAnchors.Conversion/src/Azure.MixedReality.ObjectAnchors.Conversion.csproj @@ -18,12 +18,7 @@ - - - - - diff --git a/sdk/personalizer/Azure.AI.Personalizer/src/Azure.AI.Personalizer.csproj b/sdk/personalizer/Azure.AI.Personalizer/src/Azure.AI.Personalizer.csproj index 664c998cd78c5..62d32bd8dc5f8 100644 --- a/sdk/personalizer/Azure.AI.Personalizer/src/Azure.AI.Personalizer.csproj +++ b/sdk/personalizer/Azure.AI.Personalizer/src/Azure.AI.Personalizer.csproj @@ -13,14 +13,9 @@ - - - - - diff --git a/sdk/purview/Azure.Analytics.Purview.Account/src/Azure.Analytics.Purview.Account.csproj b/sdk/purview/Azure.Analytics.Purview.Account/src/Azure.Analytics.Purview.Account.csproj index 136ab9c93f921..147fc4def1313 100644 --- a/sdk/purview/Azure.Analytics.Purview.Account/src/Azure.Analytics.Purview.Account.csproj +++ b/sdk/purview/Azure.Analytics.Purview.Account/src/Azure.Analytics.Purview.Account.csproj @@ -12,12 +12,7 @@ - - - - - diff --git a/sdk/purview/Azure.Analytics.Purview.Administration/src/Azure.Analytics.Purview.Administration.csproj b/sdk/purview/Azure.Analytics.Purview.Administration/src/Azure.Analytics.Purview.Administration.csproj index 4676b62b6bf91..eb4401284a34f 100644 --- a/sdk/purview/Azure.Analytics.Purview.Administration/src/Azure.Analytics.Purview.Administration.csproj +++ b/sdk/purview/Azure.Analytics.Purview.Administration/src/Azure.Analytics.Purview.Administration.csproj @@ -12,12 +12,7 @@ - - - - - diff --git a/sdk/purview/Azure.Analytics.Purview.Catalog/src/Azure.Analytics.Purview.Catalog.csproj b/sdk/purview/Azure.Analytics.Purview.Catalog/src/Azure.Analytics.Purview.Catalog.csproj index 316a0c0b15da2..a892cb43f6257 100644 --- a/sdk/purview/Azure.Analytics.Purview.Catalog/src/Azure.Analytics.Purview.Catalog.csproj +++ b/sdk/purview/Azure.Analytics.Purview.Catalog/src/Azure.Analytics.Purview.Catalog.csproj @@ -12,12 +12,7 @@ - - - - - diff --git a/sdk/purview/Azure.Analytics.Purview.Scanning/src/Azure.Analytics.Purview.Scanning.csproj b/sdk/purview/Azure.Analytics.Purview.Scanning/src/Azure.Analytics.Purview.Scanning.csproj index f91bd1a9f96ab..67eb17bf46f0f 100644 --- a/sdk/purview/Azure.Analytics.Purview.Scanning/src/Azure.Analytics.Purview.Scanning.csproj +++ b/sdk/purview/Azure.Analytics.Purview.Scanning/src/Azure.Analytics.Purview.Scanning.csproj @@ -12,12 +12,7 @@ - - - - - diff --git a/sdk/quantum/Azure.Quantum.Jobs/src/Azure.Quantum.Jobs.csproj b/sdk/quantum/Azure.Quantum.Jobs/src/Azure.Quantum.Jobs.csproj index dbb47bf15b47b..c833f5f42e914 100644 --- a/sdk/quantum/Azure.Quantum.Jobs/src/Azure.Quantum.Jobs.csproj +++ b/sdk/quantum/Azure.Quantum.Jobs/src/Azure.Quantum.Jobs.csproj @@ -16,12 +16,7 @@ - - - - - diff --git a/sdk/remoterendering/Azure.MixedReality.RemoteRendering/src/Azure.MixedReality.RemoteRendering.csproj b/sdk/remoterendering/Azure.MixedReality.RemoteRendering/src/Azure.MixedReality.RemoteRendering.csproj index 311b74ef9c81b..e163d6db6eed2 100644 --- a/sdk/remoterendering/Azure.MixedReality.RemoteRendering/src/Azure.MixedReality.RemoteRendering.csproj +++ b/sdk/remoterendering/Azure.MixedReality.RemoteRendering/src/Azure.MixedReality.RemoteRendering.csproj @@ -18,12 +18,7 @@ - - - - - diff --git a/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/Azure.Data.SchemaRegistry.csproj b/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/Azure.Data.SchemaRegistry.csproj index 4259a64e75e8c..371b8a785ad03 100644 --- a/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/Azure.Data.SchemaRegistry.csproj +++ b/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/Azure.Data.SchemaRegistry.csproj @@ -16,12 +16,7 @@ - - - - - diff --git a/sdk/search/Azure.Search.Documents/src/Azure.Search.Documents.csproj b/sdk/search/Azure.Search.Documents/src/Azure.Search.Documents.csproj index 513d4c7d83a08..27837b92ad5dd 100644 --- a/sdk/search/Azure.Search.Documents/src/Azure.Search.Documents.csproj +++ b/sdk/search/Azure.Search.Documents/src/Azure.Search.Documents.csproj @@ -19,17 +19,12 @@ - - - - - diff --git a/sdk/storage/Azure.Storage.Blobs.Batch/src/Azure.Storage.Blobs.Batch.csproj b/sdk/storage/Azure.Storage.Blobs.Batch/src/Azure.Storage.Blobs.Batch.csproj index 90cd430d4c860..ac1e01a983673 100644 --- a/sdk/storage/Azure.Storage.Blobs.Batch/src/Azure.Storage.Blobs.Batch.csproj +++ b/sdk/storage/Azure.Storage.Blobs.Batch/src/Azure.Storage.Blobs.Batch.csproj @@ -25,14 +25,9 @@ - - - - - diff --git a/sdk/storage/Azure.Storage.Blobs/src/Azure.Storage.Blobs.csproj b/sdk/storage/Azure.Storage.Blobs/src/Azure.Storage.Blobs.csproj index 0e2e55d6c6852..f6dac3e6598a5 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/Azure.Storage.Blobs.csproj +++ b/sdk/storage/Azure.Storage.Blobs/src/Azure.Storage.Blobs.csproj @@ -26,8 +26,6 @@ - - @@ -37,9 +35,6 @@ - - - diff --git a/sdk/storage/Azure.Storage.Common/src/Azure.Storage.Common.csproj b/sdk/storage/Azure.Storage.Common/src/Azure.Storage.Common.csproj index e6a1ce31fcccd..1a2b0bed7de94 100644 --- a/sdk/storage/Azure.Storage.Common/src/Azure.Storage.Common.csproj +++ b/sdk/storage/Azure.Storage.Common/src/Azure.Storage.Common.csproj @@ -17,16 +17,15 @@ Microsoft Azure Storage REST API Reference - https://docs.microsoft.com/en-us/rest/api/storageservices/ Azure.Storage + true - - diff --git a/sdk/storage/Azure.Storage.Common/tests/Azure.Storage.Common.Tests.csproj b/sdk/storage/Azure.Storage.Common/tests/Azure.Storage.Common.Tests.csproj index 4fc4ae0a3a5df..c2e2431a795fa 100644 --- a/sdk/storage/Azure.Storage.Common/tests/Azure.Storage.Common.Tests.csproj +++ b/sdk/storage/Azure.Storage.Common/tests/Azure.Storage.Common.Tests.csproj @@ -2,7 +2,6 @@ $(RequiredTargetFrameworks) true - true Microsoft Azure.Storage.Common client library tests @@ -15,10 +14,7 @@ - - - diff --git a/sdk/storage/Azure.Storage.Files.DataLake/src/Azure.Storage.Files.DataLake.csproj b/sdk/storage/Azure.Storage.Files.DataLake/src/Azure.Storage.Files.DataLake.csproj index 54e6991a49083..c804b62f56b40 100644 --- a/sdk/storage/Azure.Storage.Files.DataLake/src/Azure.Storage.Files.DataLake.csproj +++ b/sdk/storage/Azure.Storage.Files.DataLake/src/Azure.Storage.Files.DataLake.csproj @@ -28,16 +28,11 @@ - - - - - diff --git a/sdk/storage/Azure.Storage.Files.Shares/src/Azure.Storage.Files.Shares.csproj b/sdk/storage/Azure.Storage.Files.Shares/src/Azure.Storage.Files.Shares.csproj index 2faf88b9f9b59..30979d6acee14 100644 --- a/sdk/storage/Azure.Storage.Files.Shares/src/Azure.Storage.Files.Shares.csproj +++ b/sdk/storage/Azure.Storage.Files.Shares/src/Azure.Storage.Files.Shares.csproj @@ -26,9 +26,7 @@ - - @@ -36,9 +34,6 @@ - - - diff --git a/sdk/storage/Azure.Storage.Queues/src/Azure.Storage.Queues.csproj b/sdk/storage/Azure.Storage.Queues/src/Azure.Storage.Queues.csproj index 6ecb27b91a967..44255328d453d 100644 --- a/sdk/storage/Azure.Storage.Queues/src/Azure.Storage.Queues.csproj +++ b/sdk/storage/Azure.Storage.Queues/src/Azure.Storage.Queues.csproj @@ -27,18 +27,13 @@ - - - - - diff --git a/sdk/synapse/Azure.Analytics.Synapse.AccessControl/src/Azure.Analytics.Synapse.AccessControl.csproj b/sdk/synapse/Azure.Analytics.Synapse.AccessControl/src/Azure.Analytics.Synapse.AccessControl.csproj index d4e4f7ff9a8ac..aebf7344e621c 100644 --- a/sdk/synapse/Azure.Analytics.Synapse.AccessControl/src/Azure.Analytics.Synapse.AccessControl.csproj +++ b/sdk/synapse/Azure.Analytics.Synapse.AccessControl/src/Azure.Analytics.Synapse.AccessControl.csproj @@ -25,14 +25,9 @@ - - - - - diff --git a/sdk/synapse/Azure.Analytics.Synapse.Artifacts/src/Azure.Analytics.Synapse.Artifacts.csproj b/sdk/synapse/Azure.Analytics.Synapse.Artifacts/src/Azure.Analytics.Synapse.Artifacts.csproj index d08b3705f8d2d..f5f44fe88ec35 100644 --- a/sdk/synapse/Azure.Analytics.Synapse.Artifacts/src/Azure.Analytics.Synapse.Artifacts.csproj +++ b/sdk/synapse/Azure.Analytics.Synapse.Artifacts/src/Azure.Analytics.Synapse.Artifacts.csproj @@ -25,14 +25,9 @@ - - - - - diff --git a/sdk/synapse/Azure.Analytics.Synapse.ManagedPrivateEndpoints/src/Azure.Analytics.Synapse.ManagedPrivateEndpoints.csproj b/sdk/synapse/Azure.Analytics.Synapse.ManagedPrivateEndpoints/src/Azure.Analytics.Synapse.ManagedPrivateEndpoints.csproj index 857aab2991c85..390a189d8e303 100644 --- a/sdk/synapse/Azure.Analytics.Synapse.ManagedPrivateEndpoints/src/Azure.Analytics.Synapse.ManagedPrivateEndpoints.csproj +++ b/sdk/synapse/Azure.Analytics.Synapse.ManagedPrivateEndpoints/src/Azure.Analytics.Synapse.ManagedPrivateEndpoints.csproj @@ -25,14 +25,9 @@ - - - - - diff --git a/sdk/synapse/Azure.Analytics.Synapse.Monitoring/src/Azure.Analytics.Synapse.Monitoring.csproj b/sdk/synapse/Azure.Analytics.Synapse.Monitoring/src/Azure.Analytics.Synapse.Monitoring.csproj index 3ccad983436f1..30c37d94b8569 100644 --- a/sdk/synapse/Azure.Analytics.Synapse.Monitoring/src/Azure.Analytics.Synapse.Monitoring.csproj +++ b/sdk/synapse/Azure.Analytics.Synapse.Monitoring/src/Azure.Analytics.Synapse.Monitoring.csproj @@ -25,14 +25,9 @@ - - - - - diff --git a/sdk/synapse/Azure.Analytics.Synapse.Spark/src/Azure.Analytics.Synapse.Spark.csproj b/sdk/synapse/Azure.Analytics.Synapse.Spark/src/Azure.Analytics.Synapse.Spark.csproj index 1a7b02fab7c57..479c815e1806b 100644 --- a/sdk/synapse/Azure.Analytics.Synapse.Spark/src/Azure.Analytics.Synapse.Spark.csproj +++ b/sdk/synapse/Azure.Analytics.Synapse.Spark/src/Azure.Analytics.Synapse.Spark.csproj @@ -27,14 +27,9 @@ - - - - - diff --git a/sdk/tables/Azure.Data.Tables/src/Azure.Data.Tables.csproj b/sdk/tables/Azure.Data.Tables/src/Azure.Data.Tables.csproj index cba47ff14f1b3..a1e670ae17677 100644 --- a/sdk/tables/Azure.Data.Tables/src/Azure.Data.Tables.csproj +++ b/sdk/tables/Azure.Data.Tables/src/Azure.Data.Tables.csproj @@ -22,19 +22,14 @@ - - - - - diff --git a/sdk/template/Azure.Template/src/Azure.Template.csproj b/sdk/template/Azure.Template/src/Azure.Template.csproj index 4a714509ce731..fcae6074b3fb8 100644 --- a/sdk/template/Azure.Template/src/Azure.Template.csproj +++ b/sdk/template/Azure.Template/src/Azure.Template.csproj @@ -15,12 +15,7 @@ - - - - - diff --git a/sdk/textanalytics/Azure.AI.TextAnalytics/src/Azure.AI.TextAnalytics.csproj b/sdk/textanalytics/Azure.AI.TextAnalytics/src/Azure.AI.TextAnalytics.csproj index a2b9cf64b51d4..a6cfb855acf4f 100644 --- a/sdk/textanalytics/Azure.AI.TextAnalytics/src/Azure.AI.TextAnalytics.csproj +++ b/sdk/textanalytics/Azure.AI.TextAnalytics/src/Azure.AI.TextAnalytics.csproj @@ -18,15 +18,10 @@ - - - - - diff --git a/sdk/timeseriesinsights/Azure.IoT.TimeSeriesInsights/src/Azure.IoT.TimeSeriesInsights.csproj b/sdk/timeseriesinsights/Azure.IoT.TimeSeriesInsights/src/Azure.IoT.TimeSeriesInsights.csproj index 489b9d372e093..939fffe6ef051 100644 --- a/sdk/timeseriesinsights/Azure.IoT.TimeSeriesInsights/src/Azure.IoT.TimeSeriesInsights.csproj +++ b/sdk/timeseriesinsights/Azure.IoT.TimeSeriesInsights/src/Azure.IoT.TimeSeriesInsights.csproj @@ -15,13 +15,8 @@ - - - - - diff --git a/sdk/translation/Azure.AI.Translation.Document/src/Azure.AI.Translation.Document.csproj b/sdk/translation/Azure.AI.Translation.Document/src/Azure.AI.Translation.Document.csproj index 385b75f5b3fa6..6fb8a0e986ed5 100644 --- a/sdk/translation/Azure.AI.Translation.Document/src/Azure.AI.Translation.Document.csproj +++ b/sdk/translation/Azure.AI.Translation.Document/src/Azure.AI.Translation.Document.csproj @@ -15,15 +15,10 @@ - - - - - diff --git a/sdk/videoanalyzer/Azure.Media.VideoAnalyzer.Edge/src/Azure.Media.VideoAnalyzer.Edge.csproj b/sdk/videoanalyzer/Azure.Media.VideoAnalyzer.Edge/src/Azure.Media.VideoAnalyzer.Edge.csproj index 9795d9887d24f..116b7c4cd818b 100644 --- a/sdk/videoanalyzer/Azure.Media.VideoAnalyzer.Edge/src/Azure.Media.VideoAnalyzer.Edge.csproj +++ b/sdk/videoanalyzer/Azure.Media.VideoAnalyzer.Edge/src/Azure.Media.VideoAnalyzer.Edge.csproj @@ -21,14 +21,6 @@ - - - - - - - - diff --git a/sdk/webpubsub/Azure.Messaging.WebPubSub/src/Azure.Messaging.WebPubSub.csproj b/sdk/webpubsub/Azure.Messaging.WebPubSub/src/Azure.Messaging.WebPubSub.csproj index 827c7fa090230..4d25cf913f8d9 100644 --- a/sdk/webpubsub/Azure.Messaging.WebPubSub/src/Azure.Messaging.WebPubSub.csproj +++ b/sdk/webpubsub/Azure.Messaging.WebPubSub/src/Azure.Messaging.WebPubSub.csproj @@ -20,13 +20,8 @@ - - - - -