Skip to content

Commit

Permalink
Update System.Memory.Data (Azure#46134)
Browse files Browse the repository at this point in the history
* link fixes

* Revert "link fixes"

This reverts commit 61d9eaa.

* update

* AOT updates

* SCM test fix

* update API

* Another storage fix

* fixes for communication / openai

* update snippets

* fix

* fixes
  • Loading branch information
m-redding authored and amnguye committed Oct 10, 2024
1 parent 17e57a3 commit 20c63ed
Show file tree
Hide file tree
Showing 14 changed files with 107 additions and 22 deletions.
6 changes: 3 additions & 3 deletions sdk/communication/Azure.Communication.JobRouter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,10 @@ foreach (EventGridEvent egEvent in egEvents)
switch (egEvent.EventType)
{
case "Microsoft.Communication.WorkerOfferIssued":
AcsRouterWorkerOfferIssuedEventData deserializedEventData =
AcsRouterWorkerOfferIssuedEventData? deserializedEventData =
egEvent.Data.ToObjectFromJson<AcsRouterWorkerOfferIssuedEventData>();
Console.Write(deserializedEventData.OfferId); // Offer Id
offerId = deserializedEventData.OfferId;
Console.Write(deserializedEventData?.OfferId); // Offer Id
offerId = deserializedEventData?.OfferId ?? string.Empty;
break;
// Handle any other custom event type
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ foreach (EventGridEvent egEvent in egEvents)
switch (egEvent.EventType)
{
case "Microsoft.Communication.WorkerOfferIssued":
AcsRouterWorkerOfferIssuedEventData deserializedEventData =
AcsRouterWorkerOfferIssuedEventData? deserializedEventData =
egEvent.Data.ToObjectFromJson<AcsRouterWorkerOfferIssuedEventData>();
Console.Write(deserializedEventData.OfferId); // Offer Id
offerId = deserializedEventData.OfferId;
Console.Write(deserializedEventData?.OfferId); // Offer Id
offerId = deserializedEventData?.OfferId ?? string.Empty;
break;
// Handle any other custom event type
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ foreach (EventGridEvent egEvent in egEvents)
switch (egEvent.EventType)
{
case "Microsoft.Communication.WorkerOfferIssued":
AcsRouterWorkerOfferIssuedEventData deserializedEventData =
AcsRouterWorkerOfferIssuedEventData? deserializedEventData =
egEvent.Data.ToObjectFromJson<AcsRouterWorkerOfferIssuedEventData>();
Console.Write(deserializedEventData.OfferId); // Offer Id
offerId = deserializedEventData.OfferId;
Console.Write(deserializedEventData?.OfferId); // Offer Id
offerId = deserializedEventData?.OfferId ?? string.Empty;
break;
// Handle any other custom event type
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ public void ReceivedChangeNotification()
switch (egEvent.EventType)
{
case "Microsoft.Communication.WorkerOfferIssued":
AcsRouterWorkerOfferIssuedEventData deserializedEventData =
AcsRouterWorkerOfferIssuedEventData? deserializedEventData =
egEvent.Data.ToObjectFromJson<AcsRouterWorkerOfferIssuedEventData>();
Console.Write(deserializedEventData.OfferId); // Offer Id
offerId = deserializedEventData.OfferId;
Console.Write(deserializedEventData?.OfferId); // Offer Id
offerId = deserializedEventData?.OfferId ?? string.Empty;
break;
// Handle any other custom event type
default:
Expand Down
2 changes: 2 additions & 0 deletions sdk/core/Azure.Core/api/Azure.Core.net6.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public static partial class AzureCoreExtensions
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("This utilizes reflection-based JSON serialization and deserialization which is not compatible with trimming.")]
public static dynamic ToDynamicFromJson(this System.BinaryData utf8Json, Azure.Core.Serialization.JsonPropertyNames propertyNameFormat, string dateTimeFormat = "o") { throw null; }
public static System.Threading.Tasks.ValueTask<T?> ToObjectAsync<T>(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("This utilizes reflection-based JSON serialization and deserialization which is not compatible with trimming.")]
public static object? ToObjectFromJson(this System.BinaryData data) { throw null; }
public static T? ToObject<T>(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
}
Expand Down Expand Up @@ -1180,6 +1181,7 @@ protected ObjectSerializer() { }
}
namespace Azure.Messaging
{
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("This utilizes reflection-based JSON serialization and deserialization which is not compatible with trimming.")]
public partial class CloudEvent
{
public CloudEvent(string source, string type, System.BinaryData? data, string? dataContentType, Azure.Messaging.CloudEventDataFormat dataFormat = Azure.Messaging.CloudEventDataFormat.Binary) { }
Expand Down
4 changes: 4 additions & 0 deletions sdk/core/Azure.Core/src/Messaging/CloudEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using System.Text.Json.Serialization;
using Azure.Core;
using Azure.Core.Serialization;

namespace Azure.Messaging
{
/// <summary> Represents a CloudEvent conforming to the 1.0 schema. This type has built-in serialization using System.Text.Json.</summary>
[JsonConverter(typeof(CloudEventConverter))]
[RequiresUnreferencedCode(DynamicData.SerializationRequiresUnreferencedCode)]
[RequiresDynamicCode(DynamicData.SerializationRequiresUnreferencedCode)]
public class CloudEvent
{
/// <summary> Initializes a new instance of the <see cref="CloudEvent"/> class. </summary>
Expand Down
4 changes: 4 additions & 0 deletions sdk/core/Azure.Core/src/Messaging/CloudEventConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using System.Text.Json.Serialization;
using Azure.Core;
using Azure.Core.Serialization;

namespace Azure.Messaging
{
/// <summary>
/// A custom converter that attributes the <see cref="CloudEvent"/> type.
/// This allows System.Text.Json to serialize and deserialize CloudEvents by default.
/// </summary>
[RequiresUnreferencedCode(DynamicData.SerializationRequiresUnreferencedCode)]
[RequiresDynamicCode(DynamicData.SerializationRequiresUnreferencedCode)]
internal class CloudEventConverter : JsonConverter<CloudEvent>
{
/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions sdk/core/Azure.Core/src/Serialization/AzureCoreExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ public static class AzureCoreExtensions
/// Otherwise, it returns either an object[] or Dictionary&lt;string, object&gt;.
/// Each value in the key value pair or list will also be converted into a primitive or another complex type recursively.
/// </returns>
[RequiresUnreferencedCode(DynamicData.SerializationRequiresUnreferencedCode)]
[RequiresDynamicCode(DynamicData.SerializationRequiresUnreferencedCode)]
public static object? ToObjectFromJson(this BinaryData data)
{
JsonElement element = data.ToObjectFromJson<JsonElement>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ILC : AOT analysis warning IL3050: Azure\.Core\.Json\.MutableJsonDocument: Using
.*Azure\.Core.src.DynamicData.DynamicData\.ObjectEnumerator\.cs\(\d*\): Trim analysis warning IL2026: Azure\.Core\.Serialization\.DynamicData\.ObjectEnumerator\.Current\.get: Using member 'Azure\.Core\.Serialization\.DynamicData\.DynamicData\(MutableJsonElement,DynamicDataOptions\)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code\. This class utilizes reflection-based JSON serialization and deserialization which is not compatible with trimming
.*Azure\.Core.src.DynamicData.DynamicData\.ObjectEnumerator\.cs\(\d*\): AOT analysis warning IL3050: Azure\.Core\.Serialization\.DynamicData\.ObjectEnumerator\.Current\.get: Using member 'Azure\.Core\.Serialization\.DynamicData\.DynamicData\(MutableJsonElement,DynamicDataOptions\)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling\. This class utilizes reflection-based JSON serialization and deserialization which is not compatible with trimming
.*Azure\.Core.src.DynamicData.DynamicDataProperty\.cs\(\d*\): Trim analysis warning IL2026: Azure\.Core\.Serialization\.DynamicDataProperty\.System\.Dynamic\.IDynamicMetaObjectProvider\.GetMetaObject\(Expression\): Using member 'Azure\.Core\.Serialization\.DynamicDataProperty\.MetaObject\.MetaObject\(Expression,IDynamicMetaObjectProvider\)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code
ILC : Trim analysis warning IL2026: System\.BinaryData\.BinaryData\(Object,JsonSerializerOptions,Type\): Using member 'System\.Text\.Json\.JsonSerializer\.SerializeToUtf8Bytes\(Object,Type,JsonSerializerOptions\)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code\. JSON serialization and deserialization might require types that cannot be statically analyzed\. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved
ILC : Trim analysis warning IL2026: Azure\.Messaging\.CloudEvent: Using member 'Azure\.Messaging\.CloudEventConverter\.CloudEventConverter\(\)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code\. This utilizes reflection-based JSON serialization and deserialization which is not compatible with trimming
ILC : AOT analysis warning IL3050: Azure\.Messaging\.CloudEvent: Using member 'Azure\.Messaging\.CloudEventConverter\.CloudEventConverter\(\)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling\. This utilizes reflection-based JSON serialization and deserialization which is not compatible with trimming
ILC : AOT analysis warning IL3050: System\.BinaryData\.BinaryData\(Object,JsonSerializerOptions,Type\): Using member 'System\.Text\.Json\.JsonSerializer\.SerializeToUtf8Bytes\(Object,Type,JsonSerializerOptions\)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling\. JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation\. Use System\.Text\.Json source generation for native AOT applications
ILC : Trim analysis warning IL2026: System\.BinaryData\.ToObjectFromJson<T>\(JsonSerializerOptions\): Using member 'System\.Text\.Json\.JsonSerializer\.Deserialize\(ReadOnlySpan`1<Byte>,Type,JsonSerializerOptions\)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code\. JSON serialization and deserialization might require types that cannot be statically analyzed\. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved
ILC : AOT analysis warning IL3050: System\.BinaryData\.ToObjectFromJson<T>\(JsonSerializerOptions\): Using member 'System\.Text\.Json\.JsonSerializer\.Deserialize\(ReadOnlySpan`1<Byte>,Type,JsonSerializerOptions\)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling\. JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation\. Use System\.Text\.Json source generation for native AOT applications
ILC : AOT analysis warning IL3050: System\.BinaryData\.ToObjectFromJson<T>\(JsonSerializerOptions\): Using member 'System\.Text\.Json\.JsonSerializer\.Deserialize<T>\(ReadOnlySpan`1<Byte>,JsonSerializerOptions\)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling\. JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation\. Use System\.Text\.Json source generation for native AOT applications
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ public async Task UnbufferedResponseContentStreamContainsResponseContent()
Assert.AreEqual("Mock content", BinaryData.FromStream(message.Response!.ContentStream!).ToString());

// The second time it's read the stream's Position is at the end
Assert.AreEqual(string.Empty, BinaryData.FromStream(message.Response!.ContentStream!).ToString());
Assert.AreEqual(0, BinaryData.FromStream(message.Response!.ContentStream!).ToArray().Length);
}

[Test]
Expand All @@ -372,7 +372,7 @@ public async Task UnbufferedResponseContentStreamEmptyIfNoResponseContent()

await transport.ProcessSyncOrAsync(message, IsAsync);

Assert.AreEqual(string.Empty, BinaryData.FromStream(message.Response!.ContentStream!).ToString());
Assert.AreEqual(0, BinaryData.FromStream(message.Response!.ContentStream!).ToArray().Length);
}

[Test]
Expand Down
52 changes: 52 additions & 0 deletions sdk/openai/tools/TestFramework/src/Mocks/MockPage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright(c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.ClientModel;
using System.ClientModel.Primitives;

namespace OpenAI.TestFramework.Mocks;

/// <summary>
/// Represents a mock page with a collection of values and a reference to the next page.
/// </summary>
/// <typeparam name="TValue">The type of values in the page.</typeparam>
public class MockPage<TValue>
{
/// <summary>
/// Gets or sets the collection of values in the page.
/// </summary>
required public IReadOnlyList<TValue> Values { get; set; }

/// <summary>
/// Gets or sets the first item on the next page.
/// </summary>
required public int Next { get; set; }

/// <summary>
/// Creates a <see cref="MockPage{TValue}"/> instance from a <see cref="ClientResult"/>.
/// </summary>
/// <param name="result">The client result.</param>
/// <returns>The created <see cref="MockPage{TValue}"/> instance.</returns>
public static MockPage<TValue> FromClientResult(ClientResult result)
{
PipelineResponse response = result.GetRawResponse();
response.BufferContent();
MockPage<TValue> mockPage = response.Content.ToObjectFromJson<MockPage<TValue>>() ?? new MockPage<TValue>
{
Values = [],
Next = 0
};
return mockPage;
}

/// <summary>
/// Converts the <see cref="MockPage{TValue}"/> instance to a <see cref="ClientResult"/>.
/// </summary>
/// <returns>The converted <see cref="ClientResult"/> instance.</returns>
public ClientResult AsClientResult()
{
var serialized = BinaryData.FromObjectAsJson(this);
var mockResponse = new MockPipelineResponse(content: serialized);
return ClientResult.FromResponse(mockResponse);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,10 @@ public virtual ClientResult Add(string id, TData data, CancellationToken token =
.ConfigureAwait(false);

var response = result.GetRawResponse();
var entry = response.Content.ToObjectFromJson<MockRestService<TData>.Entry>();
var entryData = entry == null ? default : entry.data;
return ClientResult.FromOptionalValue(
response.Content.ToObjectFromJson<MockRestService<TData>.Entry>().data,
entryData,
response);
}
catch (ClientResultException ex)
Expand Down Expand Up @@ -118,8 +120,10 @@ public virtual ClientResult Add(string id, TData data, CancellationToken token =
{
ClientResult result = SendSyncOrAsync(false, HttpMethod.Get, id, default, token).GetAwaiter().GetResult();
var response = result.GetRawResponse();
var entry = response.Content.ToObjectFromJson<MockRestService<TData>.Entry>();
var entryData = entry == null ? default : entry.data;
return ClientResult.FromOptionalValue(
response.Content.ToObjectFromJson<MockRestService<TData>.Entry>().data,
entryData,
response);
}
catch (ClientResultException ex)
Expand Down Expand Up @@ -263,7 +267,7 @@ protected async ValueTask<ClientResult> SendSyncOrAsync(bool isAsync, HttpMethod
if (message.Response.Content?.ToMemory().Length > 0)
{
var error = message.Response.Content.ToObjectFromJson<MockRestService<TData>.Error>();
throw new ClientResultException($"Error {error.error}: {error.message}", message.Response);
throw new ClientResultException($"Error {error?.error}: {error?.message}", message.Response);
}

throw new ClientResultException(message.Response);
Expand Down
12 changes: 11 additions & 1 deletion sdk/storage/Azure.Storage.Queues/src/Models/QueueMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,17 @@ internal QueueMessage(string messageText)
[EditorBrowsable(EditorBrowsableState.Never)]
public string MessageText
{
get => Body?.ToString();
get
{
try
{
return Body?.ToString();
}
catch (ArgumentNullException) // workaround for: https://github.com/dotnet/runtime/issues/68262 which was fixed in 8.0.0, can remove this after upgrade
{
return string.Empty;
}
}
internal set => Body = value == null ? null : new BinaryData(value);
}

Expand Down
9 changes: 8 additions & 1 deletion sdk/storage/Azure.Storage.Queues/src/QueueMessageCodec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ public static string EncodeMessageBody(BinaryData binaryData, QueueMessageEncodi
switch (messageEncoding)
{
case QueueMessageEncoding.None:
return binaryData.ToString();
try
{
return binaryData.ToString();
}
catch (ArgumentNullException) // workaround for: https://github.com/dotnet/runtime/issues/68262 which was fixed in 8.0.0, can remove this after upgrade
{
return string.Empty;
}
case QueueMessageEncoding.Base64:
if (MemoryMarshal.TryGetArray(binaryData.ToMemory(), out var segment))
{
Expand Down

0 comments on commit 20c63ed

Please sign in to comment.