Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
4e26020
Move MutableJsonDocument and related files to internal shared source
annelo-msft Aug 9, 2023
4c0da7f
Add simple model tests
annelo-msft Aug 9, 2023
7ebe02e
Merge remote-tracking branch 'upstream/main' into core-make-mjdoc-int…
annelo-msft Aug 11, 2023
624aebe
Merge remote-tracking branch 'upstream/main' into core-make-mjdoc-int…
annelo-msft Aug 11, 2023
5cb9d21
fix csproj
annelo-msft Aug 11, 2023
332695c
Move Patch model to IModelJsonSerializable
annelo-msft Aug 11, 2023
44148b4
Illustrate DateTime property set
annelo-msft Aug 11, 2023
2f10dec
Starting on nested models
annelo-msft Aug 11, 2023
189b860
Use analyzer to prevent unknown usage
annelo-msft Aug 11, 2023
27abf0a
Suppress AZC0020 for Patch models
annelo-msft Aug 11, 2023
50bd03b
Updates and tests
annelo-msft Aug 11, 2023
40ba9d2
one approach; and failing test
annelo-msft Aug 11, 2023
5fc50e3
postpone problematic case
annelo-msft Aug 11, 2023
85d2ae1
revert test files
annelo-msft Aug 11, 2023
115b597
updates
annelo-msft Aug 11, 2023
dc9796c
test nit
annelo-msft Aug 11, 2023
7ea10ef
Merge remote-tracking branch 'upstream/main' into core-make-mjdoc-int…
annelo-msft Aug 14, 2023
2ebfe0a
Add tests, update comments
annelo-msft Aug 14, 2023
1cc4e90
simplify
annelo-msft Aug 14, 2023
9046a74
Merge remote-tracking branch 'upstream/main' into core-make-mjdoc-int…
annelo-msft Aug 14, 2023
86be925
Merge branch 'core-make-mjdoc-internal' of https://github.com/annelo-…
annelo-msft Aug 14, 2023
55e4024
Update Patch models to use new Parse method
annelo-msft Aug 14, 2023
0d95c95
nit readonly
annelo-msft Aug 14, 2023
31d9d1b
Merge remote-tracking branch 'upstream/main' into core-make-mjdoc-int…
annelo-msft Aug 15, 2023
7a68dae
add tests - WIP
annelo-msft Aug 15, 2023
ccc7d02
fixes
annelo-msft Aug 15, 2023
8650097
moving to draft - refactor and updates
annelo-msft Aug 15, 2023
43760de
Add benchmark for patch model
annelo-msft Aug 15, 2023
9e5f176
Initial benchmark
annelo-msft Aug 15, 2023
19a3a2a
wip
annelo-msft Aug 15, 2023
5683fc0
updates
annelo-msft Aug 15, 2023
fb9fc06
Hold default serializer options in a static
annelo-msft Aug 15, 2023
b6af79e
Add e2e use case to touch MJD changelist
annelo-msft Aug 16, 2023
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
2 changes: 1 addition & 1 deletion eng/Packages.Data.props
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@
-->
<ItemGroup>
<PackageReference Update="Microsoft.Azure.AutoRest.CSharp" Version="3.0.0-beta.20230814.2" PrivateAssets="All" />
<PackageReference Update="Azure.ClientSdk.Analyzers" Version="0.1.1-dev.20230131.1" PrivateAssets="All" />
<PackageReference Update="Azure.ClientSdk.Analyzers" Version="0.1.1-dev.20230811.4" PrivateAssets="All" />
<PackageReference Update="coverlet.collector" Version="3.2.0" PrivateAssets="All" />
<PackageReference Update="Microsoft.CodeAnalysis.NetAnalyzers" Version="7.0.1" PrivateAssets="All" />
<PackageReference Update="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.2" PrivateAssets="All" />
Expand Down
30 changes: 29 additions & 1 deletion sdk/core/Azure.Core/perf/Serializations/JsonBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,23 @@ public void Serialize_PublicInterface()

[Benchmark]
[BenchmarkCategory("Internal")]
public T Deserialize_Internal()
public T Deserialize_Internal_JsonElement()
{
return Deserialize(_jsonDocument.RootElement);
}

protected virtual T Deserialize(BinaryData data)
{
return Deserialize(JsonDocument.Parse(data).RootElement);
}

[Benchmark]
[BenchmarkCategory("Internal")]
public T Deserialize_Internal_BinaryData()
{
return Deserialize(_data);
}

[Benchmark]
[BenchmarkCategory("Cast")]
public T Deserialize_ExplicitCast()
Expand Down Expand Up @@ -189,5 +201,21 @@ public void JsonDocumentFromBinaryData()
{
using var doc = JsonDocument.Parse(_data);
}

protected virtual void ModifyValues(T model) { }

[Benchmark]
[BenchmarkCategory("Usage")]
public void EndToEndUseCase()
{
// Instantiate an input model
T model = ModelSerializer.Deserialize<T>(_data);

// Set properties on it
ModifyValues(model);

// Send it over the wire - serialize
RequestContent content = CastToRequestContent();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.IO;
using System.Text.Json;
using Azure.Core.Tests.PatchModels;

namespace Azure.Core.Perf.Serializations
{
public class SimplePatchModelBenchmark : JsonBenchmark<SimplePatchModel>
{
protected override SimplePatchModel CastFromResponse() => (SimplePatchModel)_response;

protected override RequestContent CastToRequestContent() => _model;

protected override SimplePatchModel Deserialize(JsonElement jsonElement)
{
using Stream stream = new MemoryStream();
using Utf8JsonWriter writer = new(stream);
jsonElement.WriteTo(writer);
writer.Flush();
stream.Position = 0;
return Deserialize(BinaryData.FromStream(stream));
}

protected override SimplePatchModel Deserialize(BinaryData data) => SimplePatchModel.Deserialize(data);

protected override void Serialize(Utf8JsonWriter writer) => _model.Serialize(writer);

protected override string JsonFileName => "SimplePatchModel.json";

protected override void ModifyValues(SimplePatchModel model)
{
model.Name = "xyz";
model.Count = 2;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Text.Json;
using Azure.Core.Tests.PatchModels;

namespace Azure.Core.Perf.Serializations
{
public class SimpleStandardModelBenchmark : JsonBenchmark<SimpleStandardModel>
{
protected override SimpleStandardModel CastFromResponse() => (SimpleStandardModel)_response;

protected override RequestContent CastToRequestContent() => _model;

protected override SimpleStandardModel Deserialize(JsonElement jsonElement)
{
return SimpleStandardModel.DeserializeSimpleStandardModel(jsonElement, new("J"));
}

protected override void Serialize(Utf8JsonWriter writer) => _model.Serialize(writer);

protected override string JsonFileName => "SimpleStandardModel.json";

protected override void ModifyValues(SimpleStandardModel model)
{
model.Name = "xyz";
model.Count = 2;
}
}
}
9 changes: 9 additions & 0 deletions sdk/core/Azure.Core/src/Azure.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@
<Compile Include="Shared\HttpMessageSanitizer.cs" />
<Compile Include="Shared\InitializationConstructorAttribute.cs" />
<Compile Include="Shared\Multipart\MemoryResponse.cs" />
<Compile Include="Shared\MutableJsonChange.cs" />
<Compile Include="Shared\MutableJsonChangeKind.cs" />
<Compile Include="Shared\MutableJsonDocument.ChangeTracker.cs" />
<Compile Include="Shared\MutableJsonDocument.cs" />
<Compile Include="Shared\MutableJsonElement.ArrayEnumerator.cs" />
<Compile Include="Shared\MutableJsonElement.cs" />
<Compile Include="Shared\MutableJsonElement.ObjectEnumerator.cs" />
<Compile Include="Shared\MutableJsonElement.WriteTo.cs" />
<Compile Include="Shared\MutableJsonElement.WriteTo.MergePatch.cs" />
<Compile Include="Shared\NullableAttributes.cs" />
<Compile Include="Shared\OperationInternalBase.cs" />
<Compile Include="Shared\TrimmingAttribute.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using System.Buffers;
using System.Text.Json;

#nullable enable

namespace Azure.Core.Json
{
internal struct MutableJsonChange
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#nullable enable

namespace Azure.Core.Json
{
internal enum MutableJsonChangeKind
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using System.Diagnostics;
using System.Text.Json;

#nullable enable

namespace Azure.Core.Json
{
internal partial class MutableJsonDocument
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using System.Text.Json;
using System.Text.Json.Serialization;

#nullable enable

namespace Azure.Core.Json
{
/// <summary>
Expand All @@ -16,6 +18,9 @@ namespace Azure.Core.Json
[JsonConverter(typeof(MutableJsonDocumentConverter))]
internal sealed partial class MutableJsonDocument : IDisposable
{
private static readonly ReadOnlyMemory<byte> _emptyJson = "{}"u8.ToArray();
public static ReadOnlyMemory<byte> EmptyJson => _emptyJson;

private readonly ReadOnlyMemory<byte> _original;
private readonly JsonDocument _originalDocument;

Expand Down Expand Up @@ -199,11 +204,12 @@ public void Dispose()
_originalDocument.Dispose();
}

private static JsonSerializerOptions DefaultSerializerOptions = new JsonSerializerOptions();
private MutableJsonDocument(JsonDocument document, ReadOnlyMemory<byte> utf8Json, JsonSerializerOptions? serializerOptions)
{
_originalDocument = document;
_original = utf8Json;
_serializerOptions = serializerOptions ?? new JsonSerializerOptions();
_serializerOptions = serializerOptions ?? DefaultSerializerOptions;
}

private class MutableJsonDocumentConverter : JsonConverter<MutableJsonDocument>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using System.Diagnostics;
using System.Text.Json;

#nullable enable

namespace Azure.Core.Json
{
internal partial struct MutableJsonElement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using System.Diagnostics;
using System.Text.Json;

#nullable enable

namespace Azure.Core.Json
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using System.Diagnostics;
using System.Text.Json;

#nullable enable

namespace Azure.Core.Json
{
internal partial struct MutableJsonElement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using System.Collections.Generic;
using System.Text.Json;

#nullable enable

namespace Azure.Core.Json
{
internal partial struct MutableJsonElement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
using System.Text.Json;
using System.Text.Json.Serialization;

#nullable enable

namespace Azure.Core.Json
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
</ItemGroup>

<ItemGroup>
<None Update="TestData\SimpleStandardModel.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="TestData\SimplePatchModel.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="TestData\AvailabilitySetData.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "abc",
"count": 1,
"updatedOn": "2023-10-19T10:19:10.0190001Z"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "abc",
"count": 1,
"updatedOn": "2023-10-19T10:19:10.0190001Z"
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,16 @@

<!-- Shared source from Azure.Core -->
<ItemGroup>
<Compile Include="$(AzureCoreSharedSources)ArrayBufferWriter.cs" LinkBase="Shared/Core" />
<Compile Include="$(AzureCoreSharedSources)ModelSerializerHelper.cs" LinkBase="Shared/Core" />
<Compile Include="$(AzureCoreSharedSources)MutableJsonChange.cs" LinkBase="Shared" />
<Compile Include="$(AzureCoreSharedSources)MutableJsonChangeKind.cs" LinkBase="Shared" />
<Compile Include="$(AzureCoreSharedSources)MutableJsonDocument.cs" LinkBase="Shared" />
<Compile Include="$(AzureCoreSharedSources)MutableJsonDocument.ChangeTracker.cs" LinkBase="Shared" />
<Compile Include="$(AzureCoreSharedSources)MutableJsonElement.ArrayEnumerator.cs" LinkBase="Shared" />
<Compile Include="$(AzureCoreSharedSources)MutableJsonElement.cs" LinkBase="Shared" />
<Compile Include="$(AzureCoreSharedSources)MutableJsonElement.ObjectEnumerator.cs" LinkBase="Shared" />
<Compile Include="$(AzureCoreSharedSources)MutableJsonElement.WriteTo.cs" LinkBase="Shared" />
<Compile Include="$(AzureCoreSharedSources)MutableJsonElement.WriteTo.MergePatch.cs" LinkBase="Shared" />
</ItemGroup>

</Project>
64 changes: 64 additions & 0 deletions sdk/core/Azure.Core/tests/public/PatchModels/ChildPatchModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Azure.Core.Json;

namespace Azure.Core.Tests.PatchModels
{
/// <summary>
/// This model illustrates a nested child model in a parent model.
/// </summary>
public partial class ChildPatchModel
{
#pragma warning disable AZC0020 // Avoid using banned types in libraries
private readonly MutableJsonElement _element;

// Note: A child patch model doesn't have a public constructor.
//
// When a nested model is also an input to a service method, it will
// need to have a public constructor. When this happens, the parent
// model it is also part of will not allow it to be set, to ensure the
// MutableJsonElements point to the same root MutableJsonDocument when
// they are part of the same input, so the Patch JSON will be correct.

/// <summary> Serialization constructor. </summary>
/// <param name="element"></param>
internal ChildPatchModel(MutableJsonElement element)
{
_element = element;
}

/// <summary>
/// Optional string property corresponding to JSON """{"a": "aaa"}""".
/// </summary>
public string A
{
get
{
if (_element.TryGetProperty("a", out MutableJsonElement value))
{
return value.GetString();
}
return null;
}
set => _element.SetProperty("a", value);
}

/// <summary>
/// Optional string property corresponding to JSON """{"b": "bbb"}""".
/// </summary>
public string B
{
get
{
if (_element.TryGetProperty("b", out MutableJsonElement value))
{
return value.GetString();
}
return null;
}
set => _element.SetProperty("b", value);
}
#pragma warning restore AZC0020 // Avoid using banned types in libraries
}
}
Loading