Skip to content

Commit

Permalink
Use Utf8JsonWriter to write JsonElement to stream instead of using th… (
Browse files Browse the repository at this point in the history
  • Loading branch information
azabbasi authored and jongio committed Feb 9, 2021
1 parent 670114e commit 9acb079
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ internal async Task<ResponseWithHeaders<QueryResult<T>, QueryQueryTwinsHeaders>>
QuerySpecification querySpecification,
QueryOptions queryTwinsOptions = null,
ObjectSerializer objectSerializer = null,
ObjectSerializer defaultObjectSerializer = null,
CancellationToken cancellationToken = default)
{
if (querySpecification == null)
Expand All @@ -37,7 +36,7 @@ internal async Task<ResponseWithHeaders<QueryResult<T>, QueryQueryTwinsHeaders>>
case 200:
{
using JsonDocument document = await JsonDocument.ParseAsync(message.Response.ContentStream, default, cancellationToken).ConfigureAwait(false);
QueryResult<T> value = QueryResult<T>.DeserializeQueryResult(document.RootElement, objectSerializer, defaultObjectSerializer);
QueryResult<T> value = QueryResult<T>.DeserializeQueryResult(document.RootElement, objectSerializer);
return ResponseWithHeaders.FromValue(value, headers, message.Response);
}
default:
Expand All @@ -49,7 +48,6 @@ internal ResponseWithHeaders<QueryResult<T>, QueryQueryTwinsHeaders> QueryTwins<
QuerySpecification querySpecification,
QueryOptions queryTwinsOptions = null,
ObjectSerializer objectSerializer = null,
ObjectSerializer defaultObjectSerializer = null,
CancellationToken cancellationToken = default)
{
if (querySpecification == null)
Expand All @@ -70,7 +68,7 @@ internal ResponseWithHeaders<QueryResult<T>, QueryQueryTwinsHeaders> QueryTwins<
case 200:
{
using var document = JsonDocument.Parse(message.Response.ContentStream);
QueryResult<T> value = QueryResult<T>.DeserializeQueryResult(document.RootElement, objectSerializer, defaultObjectSerializer);
QueryResult<T> value = QueryResult<T>.DeserializeQueryResult(document.RootElement, objectSerializer);
return ResponseWithHeaders.FromValue(value, headers, message.Response);
}
default:
Expand Down
17 changes: 0 additions & 17 deletions sdk/digitaltwins/Azure.DigitalTwins.Core/src/DigitalTwinsClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,6 @@ public class DigitalTwinsClient

private readonly ObjectSerializer _objectSerializer;

/// <summary>
/// In order to serialize/deserialize JsonElements into and out of a stream, we have to use the out of the box ObjectSerializer (JsonObjectSerializer).
/// If the user specifies a different type of serializer to instantiate the client than the default one, the SDK will instantiate a new JsonObjectSerializer of its own.
/// </summary>
private readonly ObjectSerializer _defaultObjectSerializer;

private readonly DigitalTwinsRestClient _dtRestClient;
private readonly DigitalTwinModelsRestClient _dtModelsRestClient;
private readonly EventRoutesRestClient _eventRoutesRestClient;
Expand Down Expand Up @@ -99,13 +93,6 @@ public DigitalTwinsClient(Uri endpoint, TokenCredential credential, DigitalTwins

_objectSerializer = options.Serializer ?? new JsonObjectSerializer();

// If the objectSerializer is of type JsonObjectSerializer, we will re-use the same object and set it as the defaultObjectSerializer.
// Otherwise, we will instantiate it and re-use it in the future.
_defaultObjectSerializer =
(_objectSerializer is JsonObjectSerializer)
? _objectSerializer
: new JsonObjectSerializer();

options.AddPolicy(new BearerTokenAuthenticationPolicy(credential, GetAuthorizationScopes()), HttpPipelinePosition.PerCall);
_httpPipeline = HttpPipelineBuilder.Build(options);

Expand Down Expand Up @@ -2058,7 +2045,6 @@ async Task<Page<T>> FirstPageFunc(int? pageSizeHint)
querySpecification,
options,
_objectSerializer,
_defaultObjectSerializer,
cancellationToken)
.ConfigureAwait(false);

Expand Down Expand Up @@ -2093,7 +2079,6 @@ async Task<Page<T>> NextPageFunc(string nextLink, int? pageSizeHint)
querySpecification,
options,
_objectSerializer,
_defaultObjectSerializer,
cancellationToken)
.ConfigureAwait(false);

Expand Down Expand Up @@ -2169,7 +2154,6 @@ Page<T> FirstPageFunc(int? pageSizeHint)
querySpecification,
options,
_objectSerializer,
_defaultObjectSerializer,
cancellationToken);

return Page.FromValues(response.Value.Value, response.Value.ContinuationToken, response.GetRawResponse());
Expand Down Expand Up @@ -2203,7 +2187,6 @@ Page<T> NextPageFunc(string nextLink, int? pageSizeHint)
querySpecification,
options,
_objectSerializer,
_defaultObjectSerializer,
cancellationToken);

return Page.FromValues(response.Value.Value, response.Value.ContinuationToken, response.GetRawResponse());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@ internal QueryResult(IReadOnlyList<T> value, string continuationToken)
/// </summary>
/// <param name="element">The JSON element to be deserialized into a QueryResult.</param>
/// <param name="objectSerializer">The object serializer instance used to deserialize the items in the collection.</param>
/// <param name="defaultObjectSerializer">The out of the box object serializer to interact with the JsonElement (serialize/deserialize into and out of streams).</param>
/// <returns>A collection of query results deserialized into type <typeparamref name="T"/>.</returns>
internal static QueryResult<T> DeserializeQueryResult(JsonElement element, ObjectSerializer objectSerializer, ObjectSerializer defaultObjectSerializer)
internal static QueryResult<T> DeserializeQueryResult(JsonElement element, ObjectSerializer objectSerializer)
{
IReadOnlyList<T> items = default;
string continuationToken = default;
Expand All @@ -60,10 +59,7 @@ internal static QueryResult<T> DeserializeQueryResult(JsonElement element, Objec

foreach (JsonElement item in property.Value.EnumerateArray())
{
// defaultObjectSerializer of type JsonObjectSerializer needs to be used to serialize the JsonElement into a stream.
// Using any other ObjectSerializer (e.g. NewtonsoftJsonObjectSerializer) won't be able to deserialize the JsonElement into
// a MemoryStream correctly.
using MemoryStream streamedObject = StreamHelper.WriteToStream(item, defaultObjectSerializer, default);
using MemoryStream streamedObject = StreamHelper.WriteJsonElementToStream(item);

// To deserialize the stream object into the generic type of T, the provided ObjectSerializer will be used.
T obj = (T)objectSerializer.Deserialize(streamedObject, typeof(T), default);
Expand Down
18 changes: 18 additions & 0 deletions sdk/digitaltwins/Azure.DigitalTwins.Core/src/StreamHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System.IO;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Azure.Core.Serialization;
Expand Down Expand Up @@ -46,5 +47,22 @@ internal static MemoryStream WriteToStream<T>(T obj, ObjectSerializer objectSeri

return memoryStream;
}

/// <summary>
/// Serializes a JsonElement and writes it into a memory stream.
/// </summary>
/// <param name="item">JsonElement to be deserialized into a stream.</param>
/// <returns>A binary representation of the object written to a stream.</returns>
internal static MemoryStream WriteJsonElementToStream(JsonElement item)
{
var memoryStream = new MemoryStream();
using var writer = new Utf8JsonWriter(memoryStream);

item.WriteTo(writer);
writer.Flush();
memoryStream.Seek(0, SeekOrigin.Begin);

return memoryStream;
}
}
}

0 comments on commit 9acb079

Please sign in to comment.