Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ namespace Microsoft.Azure.Cosmos
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos.Query.Core.Monads;
using Microsoft.Azure.Cosmos.Routing;
using Microsoft.Azure.Cosmos.Tracing;
using Newtonsoft.Json;

/// <summary>
/// FeedRangeContinuation using Composite Continuation Tokens and split proof.
Expand Down Expand Up @@ -113,7 +114,7 @@ public override FeedRange GetFeedRange()

public override string ToString()
{
return JsonConvert.SerializeObject(this);
return JsonSerializer.Serialize(this, CosmosSerializerContext.Default.FeedRangeCompositeContinuation);
}

public override void ReplaceContinuation(string continuationToken)
Expand Down Expand Up @@ -199,7 +200,7 @@ public override Documents.ShouldRetryResult HandleChangeFeedNotModified(Response
{
try
{
feedToken = JsonConvert.DeserializeObject<FeedRangeCompositeContinuation>(toStringValue);
feedToken = JsonSerializer.Deserialize<FeedRangeCompositeContinuation>(toStringValue, CosmosSerializerContext.Default.FeedRangeCompositeContinuation);
return true;
}
catch (JsonException)
Expand All @@ -218,7 +219,7 @@ private static bool TryParseAsCompositeContinuationToken(
{
if (providedContinuation.Trim().StartsWith("[", StringComparison.Ordinal))
{
List<CompositeContinuationToken> compositeContinuationTokens = JsonConvert.DeserializeObject<List<CompositeContinuationToken>>(providedContinuation);
List<CompositeContinuationToken> compositeContinuationTokens = JsonSerializer.Deserialize<List<CompositeContinuationToken>>(providedContinuation, CosmosSerializerContext.Default.ListCompositeContinuationToken);

if (compositeContinuationTokens != null && compositeContinuationTokens.Count > 0)
{
Expand All @@ -229,7 +230,7 @@ private static bool TryParseAsCompositeContinuationToken(
}
else if (providedContinuation.Trim().StartsWith("{", StringComparison.Ordinal))
{
compositeContinuationToken = JsonConvert.DeserializeObject<CompositeContinuationToken>(providedContinuation);
compositeContinuationToken = JsonSerializer.Deserialize<CompositeContinuationToken>(providedContinuation, CosmosSerializerContext.Default.CompositeContinuationToken);
return compositeContinuationToken != null;
}

Expand Down Expand Up @@ -279,7 +280,7 @@ private void CreateChildRanges(IReadOnlyList<Documents.PartitionKeyRange> keyRan
{
// Update the internal composite continuation
continuationAsComposite.Range = this.CurrentToken.Range;
this.CurrentToken.Token = JsonConvert.SerializeObject(continuationAsComposite);
this.CurrentToken.Token = JsonSerializer.Serialize(continuationAsComposite, CosmosSerializerContext.Default.CompositeContinuationToken);
// Add children
foreach (Documents.PartitionKeyRange keyRange in keyRanges.Skip(1))
{
Expand All @@ -288,7 +289,7 @@ private void CreateChildRanges(IReadOnlyList<Documents.PartitionKeyRange> keyRan
FeedRangeCompositeContinuation.CreateCompositeContinuationTokenForRange(
keyRange.MinInclusive,
keyRange.MaxExclusive,
JsonConvert.SerializeObject(continuationAsComposite)));
JsonSerializer.Serialize(continuationAsComposite, CosmosSerializerContext.Default.CompositeContinuationToken)));
}
}
else
Expand Down
49 changes: 46 additions & 3 deletions Microsoft.Azure.Cosmos/src/HttpClient/CosmosHttpClientCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,51 @@ public static HttpMessageHandler CreateHttpClientHandler(
return CosmosHttpClientCore.CreateHttpClientHandlerHelper(gatewayModeMaxConnectionLimit, webProxy, serverCertificateCustomValidationCallback);
}

#if COSMOS_GW_AOT
public static HttpMessageHandler CreateSocketsHttpHandlerHelper(
int gatewayModeMaxConnectionLimit,
IWebProxy webProxy,
int gatewayModeMaxConnectionLimit,
IWebProxy webProxy,
Func<X509Certificate2, X509Chain, SslPolicyErrors, bool> serverCertificateCustomValidationCallback)
{
var socketsHandler = new SocketsHttpHandler();

// Set pooled connection lifetime to a random value between 5 and 5.5 minutes
TimeSpan connectionTimeSpan = TimeSpan.FromMinutes(5) + TimeSpan.FromSeconds(30 * CustomTypeExtensions.GetRandomNumber().NextDouble());
socketsHandler.PooledConnectionLifetime = connectionTimeSpan;

// Set proxy if provided
if (webProxy != null)
{
socketsHandler.Proxy = webProxy;
}

// Set max connections per server
try
{
socketsHandler.MaxConnectionsPerServer = gatewayModeMaxConnectionLimit;
}
catch (PlatformNotSupportedException)
{
// Ignore if not supported
}

// Set custom server certificate validation callback if provided
if (serverCertificateCustomValidationCallback != null)
{
socketsHandler.SslOptions.RemoteCertificateValidationCallback =
(object _, X509Certificate certificate, X509Chain x509Chain, SslPolicyErrors sslPolicyErrors) =>
serverCertificateCustomValidationCallback(
certificate is { } ? new X509Certificate2(certificate) : null,
x509Chain,
sslPolicyErrors);
}

return socketsHandler;
}
#else
public static HttpMessageHandler CreateSocketsHttpHandlerHelper(
int gatewayModeMaxConnectionLimit,
IWebProxy webProxy,
Func<X509Certificate2, X509Chain, SslPolicyErrors, bool> serverCertificateCustomValidationCallback)
{
// TODO: Remove Reflection when multitargetting is possible
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about having two separate implementations in two helpers methods and use pre-processor to select one? Will help port changes between?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - make sense. Let me quickly refactor.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored.

Expand All @@ -162,7 +204,7 @@ public static HttpMessageHandler CreateSocketsHttpHandlerHelper(
try
{
PropertyInfo maxConnectionsPerServerInfo = socketHandlerType.GetProperty("MaxConnectionsPerServer");
maxConnectionsPerServerInfo.SetValue(socketHttpHandler, gatewayModeMaxConnectionLimit);
maxConnectionsPerServerInfo.SetValue(socketHttpHandler, gatewayModeMaxConnectionLimit);
}
// MaxConnectionsPerServer is not supported on some platforms.
catch (PlatformNotSupportedException)
Expand All @@ -187,6 +229,7 @@ public static HttpMessageHandler CreateSocketsHttpHandlerHelper(

return (HttpMessageHandler)socketHttpHandler;
}
#endif

public static HttpMessageHandler CreateHttpClientHandlerHelper(
int gatewayModeMaxConnectionLimit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ namespace Microsoft.Azure.Cosmos.Resource.CosmosExceptions
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Text;
using System.Text.Json;
using Microsoft.Azure.Cosmos.Tracing;
using Microsoft.Azure.Documents;
using Newtonsoft.Json.Linq;
Expand Down Expand Up @@ -166,7 +167,7 @@ internal static (Error, string) GetErrorFromStream(
try
{
JObject errorObj = JObject.Parse(errorContent);
Error error = errorObj.ToObject<Error>();
Error error = JsonSerializer.Deserialize<Error>(errorContent, CosmosSerializerContext.Default.Error);
if (error != null)
{
StringBuilder message = new StringBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ namespace Microsoft.Azure.Cosmos
[JsonSerializable(typeof(RangeIndex))]
[JsonSerializable(typeof(SpatialIndex))]
[JsonSerializable(typeof(Error))]
[JsonSerializable(typeof(FeedRangeCompositeContinuation))]
internal partial class CosmosSerializerContext : JsonSerializerContext
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
namespace Microsoft.Azure.Cosmos
{
using System;
using System.ClientModel;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Azure.Cosmos.Routing;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

internal sealed class FeedRangeCompositeContinuationConverter : JsonConverter
internal sealed class FeedRangeCompositeContinuationConverter : JsonConverter<FeedRangeCompositeContinuation>
{
private const string VersionPropertyName = "V";
private const string RidPropertyName = "Rid";
Expand All @@ -21,61 +22,66 @@ public override bool CanConvert(Type objectType)
return objectType == typeof(FeedRangeCompositeContinuation);
}

public override object ReadJson(
JsonReader reader,
Type objectType,
object existingValue,
JsonSerializer serializer)
public override FeedRangeCompositeContinuation Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonToken.Null)
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}

if (reader.TokenType != JsonToken.StartObject)
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonReaderException();
throw new JsonException();
}

JObject jObject = JObject.Load(reader);
string containerRid = null;
List<CompositeContinuationToken> ranges = null;
FeedRangeInternal feedRangeInternal = null;

if (!jObject.TryGetValue(FeedRangeCompositeContinuationConverter.ContinuationPropertyName, out JToken continuationJToken))
using (JsonDocument document = JsonDocument.ParseValue(ref reader))
{
throw new JsonReaderException();
}
JsonElement root = document.RootElement;

string containerRid = null;
if (jObject.TryGetValue(FeedRangeCompositeContinuationConverter.RidPropertyName, out JToken ridJToken))
{
containerRid = ridJToken.Value<string>();
}
if (root.TryGetProperty(RidPropertyName, out JsonElement ridElement))
{
containerRid = ridElement.GetString();
}

List<CompositeContinuationToken> ranges = serializer.Deserialize<List<CompositeContinuationToken>>(continuationJToken.CreateReader());
FeedRangeInternal feedRangeInternal = FeedRangeInternalConverter.ReadJObject(jObject, serializer);
if (!root.TryGetProperty(ContinuationPropertyName, out JsonElement continuationElement))
{
throw new JsonException();
}

ranges = JsonSerializer.Deserialize<List<CompositeContinuationToken>>(continuationElement.GetRawText(), CosmosSerializerContext.Default.ListCompositeContinuationToken);

feedRangeInternal = FeedRangeInternalConverter.ReadJsonElement(root, options);
}

return new FeedRangeCompositeContinuation(
containerRid: containerRid,
feedRange: feedRangeInternal,
deserializedTokens: ranges);
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
public override void Write(Utf8JsonWriter writer, FeedRangeCompositeContinuation value, JsonSerializerOptions options)
{
if (value is FeedRangeCompositeContinuation feedRangeCompositeContinuation)
if (value == null)
{
writer.WriteStartObject();
writer.WritePropertyName(FeedRangeCompositeContinuationConverter.VersionPropertyName);
writer.WriteValue(FeedRangeContinuationVersion.V1);
writer.WritePropertyName(FeedRangeCompositeContinuationConverter.RidPropertyName);
writer.WriteValue(feedRangeCompositeContinuation.ContainerRid);
writer.WritePropertyName(FeedRangeCompositeContinuationConverter.ContinuationPropertyName);
serializer.Serialize(writer, feedRangeCompositeContinuation.CompositeContinuationTokens.ToArray());
FeedRangeInternalConverter.WriteJObject(writer, feedRangeCompositeContinuation.FeedRange, serializer);
writer.WriteEndObject();
writer.WriteNullValue();
return;
}

throw new JsonSerializationException(ClientResources.FeedToken_UnrecognizedFeedToken);
writer.WriteStartObject();
writer.WritePropertyName(VersionPropertyName);
writer.WriteNumberValue((int)FeedRangeContinuationVersion.V1);
writer.WritePropertyName(RidPropertyName);
writer.WriteStringValue(value.ContainerRid);
writer.WritePropertyName(ContinuationPropertyName);
JsonSerializer.Serialize(writer, value.CompositeContinuationTokens, CosmosSerializerContext.Default.ListCompositeContinuationToken);

FeedRangeInternalConverter.WriteJsonElement(writer, value.FeedRange, options);

writer.WriteEndObject();
}
}
}
Loading