Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Porting SDK to Direct 3.0.0.25-preview #136

Merged
merged 11 commits into from
Apr 23, 2019
11 changes: 3 additions & 8 deletions Microsoft.Azure.Cosmos/src/AuthorizationHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,13 @@
//------------------------------------------------------------
namespace Microsoft.Azure.Cosmos
{
using Microsoft.Azure.Cosmos.Collections;
using Microsoft.Azure.Cosmos.Internal;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Collections;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Security;
using System.Security.Cryptography;
using System.Text;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Collections;

// This class is used by both client (for generating the auth header with master/system key) and
// by the G/W when verifying the auth header. Some additional logic is also used by management service.
Expand Down Expand Up @@ -51,7 +46,7 @@ public static string GenerateKeyAuthorizationSignature(string verb,
{
throw new ArgumentNullException("headers");
}

string resourceType = string.Empty;
string resourceIdValue = string.Empty;
bool isNameBased = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,9 @@
namespace Microsoft.Azure.Cosmos
{
using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos.Internal;
using Microsoft.Azure.Cosmos.Routing;
using Microsoft.Azure.Documents;

/// <summary>
Expand Down
137 changes: 7 additions & 130 deletions Microsoft.Azure.Cosmos/src/ClientExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,19 @@
namespace Microsoft.Azure.Cosmos
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos.Collections;
using Microsoft.Azure.Cosmos.Internal;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Collections;
using Newtonsoft.Json;

#if !NETSTANDARD16
using System.Diagnostics;
using Microsoft.Azure.Documents.Collections;
using Microsoft.Azure.Documents;
#endif

internal static class ClientExtensions
{
internal const string MediaTypeJson = "application/json";

public static async Task<HttpResponseMessage> GetAsync(this HttpClient client,
Uri uri,
INameValueCollection additionalHeaders = null,
Expand All @@ -40,7 +33,7 @@ public static async Task<HttpResponseMessage> GetAsync(this HttpClient client,
{
foreach (string header in additionalHeaders)
{
if (GatewayStoreModel.IsAllowedRequestHeader(header))
if (GatewayStoreClient.IsAllowedRequestHeader(header))
{
requestMessage.Headers.TryAddWithoutValidation(header, additionalHeaders[header]);
}
Expand All @@ -50,140 +43,24 @@ public static async Task<HttpResponseMessage> GetAsync(this HttpClient client,
}
}

public static async Task<DocumentServiceResponse> ParseResponseAsync(HttpResponseMessage responseMessage, JsonSerializerSettings serializerSettings = null, DocumentServiceRequest request = null)
public static Task<DocumentServiceResponse> ParseResponseAsync(HttpResponseMessage responseMessage, JsonSerializerSettings serializerSettings = null, DocumentServiceRequest request = null)
{
using (responseMessage)
{
if ((int)responseMessage.StatusCode < 400)
{
MemoryStream bufferedStream = new MemoryStream();

await responseMessage.Content.CopyToAsync(bufferedStream);

bufferedStream.Position = 0;

INameValueCollection headers = ClientExtensions.ExtractResponseHeaders(responseMessage);
return new DocumentServiceResponse(bufferedStream, headers, responseMessage.StatusCode, serializerSettings);
}
else if (request != null
&& request.IsValidStatusCodeForExceptionlessRetry((int)responseMessage.StatusCode))
{
INameValueCollection headers = ClientExtensions.ExtractResponseHeaders(responseMessage);
return new DocumentServiceResponse(null, headers, responseMessage.StatusCode, serializerSettings);
}
else
{
throw await ClientExtensions.CreateDocumentClientException(responseMessage);
}
}
return GatewayStoreClient.ParseResponseAsync(responseMessage, serializerSettings, request);
}

public static async Task<DocumentServiceResponse> ParseMediaResponseAsync(HttpResponseMessage responseMessage, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
if ((int)responseMessage.StatusCode < 400)
{
INameValueCollection headers = ClientExtensions.ExtractResponseHeaders(responseMessage);
INameValueCollection headers = GatewayStoreClient.ExtractResponseHeaders(responseMessage);
MediaStream mediaStream = new MediaStream(responseMessage, await responseMessage.Content.ReadAsStreamAsync());
return new DocumentServiceResponse(mediaStream, headers, responseMessage.StatusCode);
}
else
{
throw await ClientExtensions.CreateDocumentClientException(responseMessage);
}
}

private static async Task<DocumentClientException> CreateDocumentClientException(HttpResponseMessage responseMessage)
{
// ensure there is no local ActivityId, since in Gateway mode ActivityId
// should always come from message headers
Trace.CorrelationManager.ActivityId = Guid.Empty;

string resourceLink = responseMessage.RequestMessage.RequestUri.LocalPath;
if (!PathsHelper.TryParsePathSegments(
resourceLink,
out bool isFeed,
out string resourceTypeString,
out string resourceIdOrFullName,
out bool isNameBased))
{
// if resourceLink is invalid - we will not set resourceAddress in exception.
}

// If service rejects the initial payload like header is to large it will return an HTML error instead of JSON.
if (string.Equals(responseMessage.Content?.Headers?.ContentType?.MediaType, ClientExtensions.MediaTypeJson, StringComparison.OrdinalIgnoreCase))
{
Stream readStream = await responseMessage.Content.ReadAsStreamAsync();
Error error = Resource.LoadFrom<Error>(readStream);
return new DocumentClientException(
error,
responseMessage.Headers,
responseMessage.StatusCode)
{
StatusDescription = responseMessage.ReasonPhrase,
ResourceAddress = resourceIdOrFullName
};
}
else
{
string message = responseMessage.Content == null ? null : await responseMessage.Content.ReadAsStringAsync();
return new DocumentClientException(
message: message,
innerException: null,
responseHeaders: responseMessage.Headers,
statusCode: responseMessage.StatusCode,
requestUri: responseMessage.RequestMessage.RequestUri)
{
StatusDescription = responseMessage.ReasonPhrase,
ResourceAddress = resourceIdOrFullName
};
}
}

private static INameValueCollection ExtractResponseHeaders(HttpResponseMessage responseMessage)
{
INameValueCollection headers = new StringKeyValueCollection();

foreach (KeyValuePair<string, IEnumerable<string>> headerPair in responseMessage.Headers)
{
if (string.Compare(headerPair.Key, HttpConstants.HttpHeaders.OwnerFullName, StringComparison.Ordinal) == 0)
{
foreach (string val in headerPair.Value)
{
headers.Add(headerPair.Key, Uri.UnescapeDataString(val));
}
}
else
{
foreach (string val in headerPair.Value)
{
headers.Add(headerPair.Key, val);
}
}
throw await GatewayStoreClient.CreateDocumentClientException(responseMessage);
}

if (responseMessage.Content != null)
{
foreach (KeyValuePair<string, IEnumerable<string>> headerPair in responseMessage.Content.Headers)
{
if (string.Compare(headerPair.Key, HttpConstants.HttpHeaders.OwnerFullName, StringComparison.Ordinal) == 0)
{
foreach (string val in headerPair.Value)
{
headers.Add(headerPair.Key, Uri.UnescapeDataString(val));
}
}
else
{
foreach (string val in headerPair.Value)
{
headers.Add(headerPair.Key, val);
}
}
}
}

return headers;
}
}
}
Loading