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

Headers: Adds optimized request headers #3177

Merged
merged 11 commits into from
May 17, 2022
8 changes: 4 additions & 4 deletions Microsoft.Azure.Cosmos/src/DocumentClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6732,7 +6732,7 @@ private INameValueCollection GetRequestHeaders(
this.isSuccessfullyInitialized,
"GetRequestHeaders should be called after initialization task has been awaited to avoid blocking while accessing ConsistencyLevel property");

INameValueCollection headers = new StoreRequestNameValueCollection();
RequestNameValueCollection headers = new RequestNameValueCollection();

if (this.UseMultipleWriteLocations)
{
Expand All @@ -6755,7 +6755,7 @@ private INameValueCollection GetRequestHeaders(
this.accountServiceConfiguration.DefaultConsistencyLevel));
}

headers.Set(HttpConstants.HttpHeaders.ConsistencyLevel, this.desiredConsistencyLevel.Value.ToString());
headers.ConsistencyLevel = this.desiredConsistencyLevel.Value.ToString();
}

if (options == null)
Expand All @@ -6767,11 +6767,11 @@ private INameValueCollection GetRequestHeaders(
{
if (options.AccessCondition.Type == Documents.Client.AccessConditionType.IfMatch)
{
headers.Set(HttpConstants.HttpHeaders.IfMatch, options.AccessCondition.Condition);
headers.IfMatch = options.AccessCondition.Condition;
}
else
{
headers.Set(HttpConstants.HttpHeaders.IfNoneMatch, options.AccessCondition.Condition);
headers.IfNoneMatch = options.AccessCondition.Condition;
}
}

Expand Down
2 changes: 1 addition & 1 deletion Microsoft.Azure.Cosmos/src/GatewayAccountReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public GatewayAccountReader(Uri serviceEndpoint,

private async Task<AccountProperties> GetDatabaseAccountAsync(Uri serviceEndpoint)
{
INameValueCollection headers = new StoreRequestNameValueCollection();
INameValueCollection headers = new RequestNameValueCollection();
await this.cosmosAuthorization.AddAuthorizationHeaderAsync(
headersCollection: headers,
serviceEndpoint,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ await this.partitionRoutingHelper.TryGetTargetRangeFromContinuationTokenRangeAsy
else
{
if (!await this.partitionRoutingHelper.TryAddPartitionKeyRangeToContinuationTokenAsync(
response.Headers.CosmosMessageHeaders,
response.Headers.CosmosMessageHeaders.INameValueCollection,
providedPartitionKeyRanges: providedRanges,
routingMapProvider: routingMapProvider,
collectionRid: collectionFromCache.ResourceId,
Expand Down
10 changes: 5 additions & 5 deletions Microsoft.Azure.Cosmos/src/Handler/RequestInvokerHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public virtual async Task<ResponseMessage> SendAsync(
Content = streamPayload,
};

request.Headers[HttpConstants.HttpHeaders.SDKSupportedCapabilities] = Headers.SDKSupportedCapabilities;
request.Headers.SDKSupportedCapabilities = Headers.SDKSUPPORTEDCAPABILITIES;

if (feedRange != null)
{
Expand Down Expand Up @@ -257,9 +257,9 @@ public virtual async Task<ResponseMessage> SendAsync(
// In this case we route to the physical partition and
// pass the epk range headers to filter within partition
request.PartitionKeyRangeId = new Documents.PartitionKeyRangeIdentity(overlappingRanges[0].Id);
request.Headers[HttpConstants.HttpHeaders.ReadFeedKeyType] = RntbdConstants.RntdbReadFeedKeyType.EffectivePartitionKeyRange.ToString();
request.Headers[HttpConstants.HttpHeaders.StartEpk] = feedRangeEpk.Range.Min;
request.Headers[HttpConstants.HttpHeaders.EndEpk] = feedRangeEpk.Range.Max;
request.Headers.ReadFeedKeyType = RntbdConstants.RntdbReadFeedKeyType.EffectivePartitionKeyRange.ToString();
request.Headers.StartEpk = feedRangeEpk.Range.Min;
request.Headers.EndEpk = feedRangeEpk.Range.Max;
}
}
}
Expand Down Expand Up @@ -396,7 +396,7 @@ private async Task ValidateAndSetConsistencyLevelAsync(RequestMessage requestMes
resourceType: requestMessage.ResourceType))
{
// ConsistencyLevel compatibility with back-end configuration will be done by RequestInvokeHandler
requestMessage.Headers.Add(HttpConstants.HttpHeaders.ConsistencyLevel, consistencyLevel.Value.ToString());
requestMessage.Headers.ConsistencyLevel = consistencyLevel.Value.ToString();
}
else
{
Expand Down
4 changes: 2 additions & 2 deletions Microsoft.Azure.Cosmos/src/Handler/RequestMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ internal DocumentServiceRequest ToDocumentServiceRequest()
resourceIdOrFullName: null,
resourceType: this.ResourceType,
body: this.Content,
headers: this.Headers.CosmosMessageHeaders,
headers: this.Headers.CosmosMessageHeaders.INameValueCollection,
isNameBased: false,
authorizationTokenType: AuthorizationTokenType.PrimaryMasterKey);
}
Expand All @@ -263,7 +263,7 @@ internal DocumentServiceRequest ToDocumentServiceRequest()
this.RequestUriString,
this.Content,
AuthorizationTokenType.PrimaryMasterKey,
this.Headers.CosmosMessageHeaders);
this.Headers.CosmosMessageHeaders.INameValueCollection);
}

if (this.UseGatewayMode.HasValue)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Microsoft.Azure.Cosmos
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Collections;

internal abstract class CosmosMessageHeadersInternal : INameValueCollection
internal abstract class CosmosMessageHeadersInternal
{
public virtual string Authorization
{
Expand Down Expand Up @@ -141,6 +141,44 @@ public virtual string PageSize
set => this.SetProperty(HttpConstants.HttpHeaders.PageSize, value);
}

public virtual string ConsistencyLevel
{
get => this.GetValueOrDefault(HttpConstants.HttpHeaders.ConsistencyLevel);
set => this.SetProperty(HttpConstants.HttpHeaders.ConsistencyLevel, value);
}

public virtual string SDKSupportedCapabilities
{
get => this.GetValueOrDefault(HttpConstants.HttpHeaders.SDKSupportedCapabilities);
set => this.SetProperty(HttpConstants.HttpHeaders.SDKSupportedCapabilities, value);
}

public virtual string ContentSerializationFormat
{
get => this.GetValueOrDefault(HttpConstants.HttpHeaders.ContentSerializationFormat);
set => this.SetProperty(HttpConstants.HttpHeaders.ContentSerializationFormat, value);
}

public virtual string ReadFeedKeyType
{
get => this.GetValueOrDefault(HttpConstants.HttpHeaders.ReadFeedKeyType);
set => this.SetProperty(HttpConstants.HttpHeaders.ReadFeedKeyType, value);
}

public virtual string StartEpk
{
get => this.GetValueOrDefault(HttpConstants.HttpHeaders.StartEpk);
set => this.SetProperty(HttpConstants.HttpHeaders.StartEpk, value);
}

public virtual string EndEpk
{
get => this.GetValueOrDefault(HttpConstants.HttpHeaders.EndEpk);
set => this.SetProperty(HttpConstants.HttpHeaders.EndEpk, value);
}

public abstract INameValueCollection INameValueCollection { get; }

public virtual string this[string headerName]
{
get
Expand Down Expand Up @@ -170,18 +208,10 @@ public virtual string this[string headerName]

public abstract string[] AllKeys();

public abstract void Clear();

public abstract int Count();

public abstract INameValueCollection Clone();

public abstract string[] GetValues(string key);

public abstract IEnumerable<string> Keys();

public abstract NameValueCollection ToNameValueCollection();

protected void SetProperty(
string headerName,
string value)
Expand Down Expand Up @@ -245,10 +275,5 @@ public virtual void Add(INameValueCollection collection)
this.Set(key, collection[key]);
}
}

IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
}
42 changes: 38 additions & 4 deletions Microsoft.Azure.Cosmos/src/Headers/Headers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Microsoft.Azure.Cosmos
/// <seealso cref="RequestMessage"/>
public class Headers : IEnumerable
{
private static readonly string sdkSupportedCapabilities = SDKSupportedCapabilitiesHelpers.GetSDKSupportedCapabilities().ToString(
internal static readonly string SDKSUPPORTEDCAPABILITIES = SDKSupportedCapabilitiesHelpers.GetSDKSupportedCapabilities().ToString(
CultureInfo.InvariantCulture);

internal virtual SubStatusCodes SubStatusCode
Expand Down Expand Up @@ -210,12 +210,48 @@ internal virtual string BackendRequestDurationMilliseconds
set => this.CosmosMessageHeaders.BackendRequestDurationMilliseconds = value;
}

internal virtual string ConsistencyLevel
{
get => this.CosmosMessageHeaders.ConsistencyLevel;
set => this.CosmosMessageHeaders.ConsistencyLevel = value;
}

internal virtual string SDKSupportedCapabilities
{
get => this.CosmosMessageHeaders.SDKSupportedCapabilities;
set => this.CosmosMessageHeaders.SDKSupportedCapabilities = value;
}

internal virtual string ContentSerializationFormat
{
get => this.CosmosMessageHeaders.ContentSerializationFormat;
set => this.CosmosMessageHeaders.ContentSerializationFormat = value;
}

internal virtual string ReadFeedKeyType
{
get => this.CosmosMessageHeaders.ReadFeedKeyType;
set => this.CosmosMessageHeaders.ReadFeedKeyType = value;
}

internal virtual string StartEpk
{
get => this.CosmosMessageHeaders.StartEpk;
set => this.CosmosMessageHeaders.StartEpk = value;
}

internal virtual string EndEpk
{
get => this.CosmosMessageHeaders.EndEpk;
set => this.CosmosMessageHeaders.EndEpk = value;
}

/// <summary>
/// Creates a new instance of <see cref="Headers"/>.
/// </summary>
public Headers()
{
this.CosmosMessageHeaders = new StoreRequestNameValueCollection();
this.CosmosMessageHeaders = new StoreRequestHeaders();
}

internal Headers(INameValueCollection nameValueCollection)
Expand Down Expand Up @@ -398,7 +434,5 @@ internal static SubStatusCodes GetSubStatusCodes(string value)

return null;
}

internal static string SDKSupportedCapabilities => Headers.sdkSupportedCapabilities;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ namespace Microsoft.Azure.Cosmos
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Collections;

internal sealed class HttpResponseHeadersWrapper : CosmosMessageHeadersInternal
internal sealed class HttpResponseHeadersWrapper : CosmosMessageHeadersInternal, INameValueCollection
{
private readonly HttpResponseHeaders httpResponseHeaders;
private readonly HttpContentHeaders httpContentHeaders;
private readonly Lazy<DictionaryNameValueCollection> dictionaryNameValueCollection;

public override INameValueCollection INameValueCollection => this;

/// <summary>
/// HttpResponse can have 2 headers. These headers have restrictions on what values are allowed.
/// This optimizes to combine the 2 headers without iterating overall of them to duplicate it into a new
Expand Down Expand Up @@ -64,7 +66,7 @@ public override void Add(INameValueCollection collection)
this.dictionaryNameValueCollection.Value.Add(collection);
}

public override void Clear()
public void Clear()
{
this.httpResponseHeaders.Clear();

Expand All @@ -90,7 +92,7 @@ public override string[] AllKeys()
return this.Keys().ToArray();
}

public override INameValueCollection Clone()
public INameValueCollection Clone()
{
INameValueCollection headers = new DictionaryNameValueCollection();

Expand Down Expand Up @@ -175,7 +177,7 @@ public override string[] GetValues(string key)
return this.httpResponseHeaders.GetValues(key).ToArray();
}

public override IEnumerable<string> Keys()
public IEnumerable<string> Keys()
{
foreach (KeyValuePair<string, IEnumerable<string>> header in this.AllItems())
{
Expand Down Expand Up @@ -209,7 +211,7 @@ public override void Set(string key, string value)
this.Add(key, value);
}

public override NameValueCollection ToNameValueCollection()
public NameValueCollection ToNameValueCollection()
{
NameValueCollection nameValueCollection = new NameValueCollection();
foreach (KeyValuePair<string, IEnumerable<string>> header in this.AllItems())
Expand All @@ -224,5 +226,10 @@ private string JoinHeaders(IEnumerable<string> headerValues)
{
return headerValues == null ? null : string.Join(",", headerValues);
}

IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
}
Loading