private async Task RefreshAsync(DocumentServiceRequest request, CancellationToken cancellationToken) { System.Diagnostics.Debug.Assert(request.IsNameBased); string resourceFullName = PathsHelper.GetCollectionPath(request.ResourceAddress); if (request.RequestContext.ResolvedCollectionRid != null) { // Here we will issue backend call only if cache wasn't already refreshed (if whatever is there corresponds to presiously resolved collection rid). await this.collectionInfoByNameCache.GetAsync( resourceFullName, CosmosContainerSettings.CreateWithResourceId(request.RequestContext.ResolvedCollectionRid), async() => { CosmosContainerSettings collection = await this.GetByNameAsync(resourceFullName, cancellationToken); if (collection != null) { this.collectionInfoByIdCache.Set(collection.ResourceId, collection); } return(collection); }, cancellationToken); } else { // In case of ForceRefresh directive coming from client, there will be no ResolvedCollectionRid, so we // need to refresh unconditionally. this.Refresh(request.ResourceAddress); } request.RequestContext.ResolvedCollectionRid = null; }
private async Task RefreshAsync(DocumentServiceRequest request, CancellationToken cancellationToken) { System.Diagnostics.Debug.Assert(request.IsNameBased); InternalCache cache = this.GetCache(request.Headers[HttpConstants.HttpHeaders.Version]); string resourceFullName = PathsHelper.GetCollectionPath(request.ResourceAddress); if (request.RequestContext.ResolvedCollectionRid != null) { // Here we will issue backend call only if cache wasn't already refreshed (if whatever is there corresponds to presiously resolved collection rid). await cache.collectionInfoByName.GetAsync( resourceFullName, CosmosContainerSettings.CreateWithResourceId(request.RequestContext.ResolvedCollectionRid), async() => { DateTime currentTime = DateTime.UtcNow; CosmosContainerSettings collection = await this.GetByNameAsync(request.Headers[HttpConstants.HttpHeaders.Version], resourceFullName, cancellationToken); cache.collectionInfoById.Set(collection.ResourceId, collection); cache.collectionInfoByNameLastRefreshTime.AddOrUpdate(resourceFullName, currentTime, (string currentKey, DateTime currentValue) => currentTime); cache.collectionInfoByIdLastRefreshTime.AddOrUpdate(collection.ResourceId, currentTime, (string currentKey, DateTime currentValue) => currentTime); return(collection); }, cancellationToken); } else { // In case of ForceRefresh directive coming from client, there will be no ResolvedCollectionRid, so we // need to refresh unconditionally. this.Refresh(request.ResourceAddress, request.Headers[HttpConstants.HttpHeaders.Version]); } request.RequestContext.ResolvedCollectionRid = null; }
public void ClearTokenByCollectionFullname(string collectionFullname) { if (!string.IsNullOrEmpty(collectionFullname)) { string collectionName = PathsHelper.GetCollectionPath(collectionFullname); this.rwlock.EnterWriteLock(); try { if (collectionNameByResourceId.ContainsKey(collectionName)) { string ignoreString; ulong ignoreUlong; ulong rid = this.collectionNameByResourceId[collectionName]; ConcurrentDictionary <string, ISessionToken> ignored; this.sessionTokensRIDBased.TryRemove(rid, out ignored); this.collectionResourceIdByName.TryRemove(rid, out ignoreString); this.collectionNameByResourceId.TryRemove(collectionName, out ignoreUlong); } } finally { this.rwlock.ExitWriteLock(); } } }
private static ConcurrentDictionary <string, ISessionToken> GetPartitionKeyRangeIdToTokenMap(SessionContainerState self, DocumentServiceRequest request) { ulong?maybeRID = null; if (request.IsNameBased) { string collectionName = PathsHelper.GetCollectionPath(request.ResourceAddress); if (self.collectionNameByResourceId.TryGetValue(collectionName, out ulong rid)) { maybeRID = rid; } } else { if (!string.IsNullOrEmpty(request.ResourceId)) { ResourceId resourceId = ResourceId.Parse(request.ResourceId); if (resourceId.DocumentCollection != 0) { maybeRID = resourceId.UniqueDocumentCollectionId; } } } ConcurrentDictionary <string, ISessionToken> partitionKeyRangeIdToTokenMap = null; if (maybeRID.HasValue) { self.sessionTokensRIDBased.TryGetValue(maybeRID.Value, out partitionKeyRangeIdToTokenMap); } return(partitionKeyRangeIdToTokenMap); }
public string GetSessionToken(string collectionLink) { bool isNameBased; bool isFeed; string resourceTypeString; string resourceIdOrFullName; ConcurrentDictionary <string, ISessionToken> partitionKeyRangeIdToTokenMap = null; if (PathsHelper.TryParsePathSegments(collectionLink, out isFeed, out resourceTypeString, out resourceIdOrFullName, out isNameBased)) { if (isNameBased) { string collectionName = PathsHelper.GetCollectionPath(resourceIdOrFullName); this.sessionTokensNameBased.TryGetValue(collectionName, out partitionKeyRangeIdToTokenMap); } else { ResourceId resourceId = ResourceId.Parse(resourceIdOrFullName); if (resourceId.DocumentCollection != 0) { this.sessionTokens.TryGetValue(resourceId.UniqueDocumentCollectionId, out partitionKeyRangeIdToTokenMap); } } } if (partitionKeyRangeIdToTokenMap == null) { return(string.Empty); } return(SessionContainer.GetSessionTokenString(partitionKeyRangeIdToTokenMap)); }
public void ClearToken(DocumentServiceRequest request, INameValueCollection responseHeaders) { string ownerFullName = responseHeaders[HttpConstants.HttpHeaders.OwnerFullName]; string collectionName = PathsHelper.GetCollectionPath(ownerFullName); string resourceIdString; if (!request.IsNameBased) { resourceIdString = request.ResourceId; } else { resourceIdString = responseHeaders[HttpConstants.HttpHeaders.OwnerId]; } if (!string.IsNullOrEmpty(resourceIdString)) { ResourceId resourceId = ResourceId.Parse(resourceIdString); if (resourceId.DocumentCollection != 0 && collectionName != null) { ConcurrentDictionary <string, ISessionToken> ignored; this.sessionTokens.TryRemove(resourceId.UniqueDocumentCollectionId, out ignored); this.sessionTokensNameBased.TryRemove(collectionName, out ignored); } } }
private async Task <CosmosContainerSettings> ResolveByNameAsync( string apiVersion, string resourceAddress, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); string resourceFullName = PathsHelper.GetCollectionPath(resourceAddress); InternalCache cache = this.GetCache(apiVersion); return(await cache.collectionInfoByName.GetAsync( resourceFullName, null, async() => { DateTime currentTime = DateTime.UtcNow; CosmosContainerSettings collection = await this.GetByNameAsync(apiVersion, resourceFullName, cancellationToken); cache.collectionInfoById.Set(collection.ResourceId, collection); cache.collectionInfoByNameLastRefreshTime.AddOrUpdate(resourceFullName, currentTime, (string currentKey, DateTime currentValue) => currentTime); cache.collectionInfoByIdLastRefreshTime.AddOrUpdate(collection.ResourceId, currentTime, (string currentKey, DateTime currentValue) => currentTime); return collection; }, cancellationToken)); }
internal virtual async Task <ContainerProperties> ResolveByNameAsync( string apiVersion, string resourceAddress, bool forceRefesh, ITrace trace, IClientSideRequestStatistics clientSideRequestStatistics, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); string resourceFullName = PathsHelper.GetCollectionPath(resourceAddress); InternalCache cache = this.GetCache(apiVersion); if (forceRefesh) { cache.collectionInfoByName.TryRemoveIfCompleted(resourceFullName); } return(await cache.collectionInfoByName.GetAsync( resourceFullName, null, async() => { DateTime currentTime = DateTime.UtcNow; ContainerProperties collection = await this.GetByNameAsync(apiVersion, resourceFullName, trace, clientSideRequestStatistics, cancellationToken); cache.collectionInfoById.Set(collection.ResourceId, collection); cache.collectionInfoByNameLastRefreshTime.AddOrUpdate(resourceFullName, currentTime, (string currentKey, DateTime currentValue) => currentTime); cache.collectionInfoByIdLastRefreshTime.AddOrUpdate(collection.ResourceId, currentTime, (string currentKey, DateTime currentValue) => currentTime); return collection; }, cancellationToken)); }
internal override async Task <IDocumentClientRetryPolicy> GetRetryPolicy(CosmosRequestMessage request) { return(new PartitionKeyRangeGoneRetryPolicy( await client.DocumentClient.GetCollectionCacheAsync(), await client.DocumentClient.GetPartitionKeyRangeCacheAsync(), PathsHelper.GetCollectionPath(request.RequestUri.ToString()), null)); }
/// <summary> /// This method is only used in client SDK in retry policy as it doesn't have request handy. /// </summary> public void Refresh(string resourceAddress, string apiVersion = null) { InternalCache cache = this.GetCache(apiVersion); if (PathsHelper.IsNameBased(resourceAddress)) { string resourceFullName = PathsHelper.GetCollectionPath(resourceAddress); cache.collectionInfoByName.TryRemoveIfCompleted(resourceFullName); } }
private static void SetSessionToken(SessionContainerState self, string collectionRid, string collectionFullname, INameValueCollection responseHeaders) { ResourceId resourceId = ResourceId.Parse(collectionRid); string collectionName = PathsHelper.GetCollectionPath(collectionFullname); string token = responseHeaders[HttpConstants.HttpHeaders.SessionToken]; if (!string.IsNullOrEmpty(token)) { SessionContainer.SetSessionToken(self, resourceId, collectionName, token); } }
public void ClearToken(string collectionRid, string collectionFullname, INameValueCollection responseHeader) { if (!string.IsNullOrEmpty(collectionFullname)) { string collectionName = PathsHelper.GetCollectionPath(collectionFullname); ConcurrentDictionary <string, ISessionToken> ignored; this.sessionTokensNameBased.TryRemove(collectionName, out ignored); } if (!string.IsNullOrEmpty(collectionRid)) { ResourceId resourceId = ResourceId.Parse(collectionRid); ConcurrentDictionary <string, ISessionToken> ignored; this.sessionTokens.TryRemove(resourceId.UniqueDocumentCollectionId, out ignored); } }
internal override Task <ContainerProperties> ResolveByNameAsync( string apiVersion, string resourceAddress, bool forceRefesh, ITrace trace, IClientSideRequestStatistics clientSideRequestStatistics, CancellationToken cancellationToken) { if (forceRefesh && this.sessionContainer != null) { return(TaskHelper.InlineIfPossible( async() => { string oldRid = (await base.ResolveByNameAsync( apiVersion, resourceAddress, forceRefesh: false, trace, clientSideRequestStatistics, cancellationToken))?.ResourceId; ContainerProperties propertiesAfterRefresh = await base.ResolveByNameAsync( apiVersion, resourceAddress, forceRefesh, trace, clientSideRequestStatistics, cancellationToken); if (oldRid != null && oldRid != propertiesAfterRefresh?.ResourceId) { string resourceFullName = PathsHelper.GetCollectionPath(resourceAddress); this.sessionContainer.ClearTokenByCollectionFullname(resourceFullName); } return propertiesAfterRefresh; }, retryPolicy: null, cancellationToken)); } return(TaskHelper.InlineIfPossible( () => base.ResolveByNameAsync( apiVersion, resourceAddress, forceRefesh, trace, clientSideRequestStatistics, cancellationToken), retryPolicy: null, cancellationToken)); }
private static string GetSessionToken(SessionContainerState self, string collectionLink) { bool arePathSegmentsParsed = PathsHelper.TryParsePathSegments( collectionLink, out _, out _, out string resourceIdOrFullName, out bool isNameBased); ConcurrentDictionary <string, ISessionToken> partitionKeyRangeIdToTokenMap = null; if (arePathSegmentsParsed) { ulong?maybeRID = null; if (isNameBased) { string collectionName = PathsHelper.GetCollectionPath(resourceIdOrFullName); if (self.collectionNameByResourceId.TryGetValue(collectionName, out ulong rid)) { maybeRID = rid; } } else { ResourceId resourceId = ResourceId.Parse(resourceIdOrFullName); if (resourceId.DocumentCollection != 0) { maybeRID = resourceId.UniqueDocumentCollectionId; } } if (maybeRID.HasValue) { self.sessionTokensRIDBased.TryGetValue(maybeRID.Value, out partitionKeyRangeIdToTokenMap); } } if (partitionKeyRangeIdToTokenMap == null) { return(string.Empty); } return(SessionContainer.GetSessionTokenString(partitionKeyRangeIdToTokenMap)); }
/// <summary> /// Resolve the ContainerProperties object from the cache. If the collection was read before "refreshAfter" Timespan, force a cache refresh by reading from the backend. /// </summary> /// <param name="request">Request to resolve.</param> /// <param name="refreshAfter"> Time duration to refresh</param> /// <param name="cancellationToken">Cancellation token.</param> /// <param name="trace">The trace.</param> /// <returns>Instance of <see cref="ContainerProperties"/>.</returns> public virtual Task <ContainerProperties> ResolveCollectionAsync( DocumentServiceRequest request, TimeSpan refreshAfter, CancellationToken cancellationToken, ITrace trace) { cancellationToken.ThrowIfCancellationRequested(); InternalCache cache = this.GetCache(request.Headers[HttpConstants.HttpHeaders.Version]); #if !NETSTANDARD16 Debug.Assert(request.ForceNameCacheRefresh == false); #endif DateTime currentTime = DateTime.UtcNow; DateTime lastRefreshTime = DateTime.MinValue; if (request.IsNameBased) { string resourceFullName = PathsHelper.GetCollectionPath(request.ResourceAddress); if (cache.collectionInfoByNameLastRefreshTime.TryGetValue(resourceFullName, out lastRefreshTime)) { TimeSpan cachedItemStaleness = currentTime - lastRefreshTime; if (cachedItemStaleness > refreshAfter) { cache.collectionInfoByName.TryRemoveIfCompleted(resourceFullName); } } } else { ResourceId resourceIdParsed = ResourceId.Parse(request.ResourceId); string collectionResourceId = resourceIdParsed.DocumentCollectionId.ToString(); if (cache.collectionInfoByIdLastRefreshTime.TryGetValue(collectionResourceId, out lastRefreshTime)) { TimeSpan cachedItemStaleness = currentTime - lastRefreshTime; if (cachedItemStaleness > refreshAfter) { cache.collectionInfoById.TryRemoveIfCompleted(request.ResourceId); } } } return(this.ResolveCollectionAsync(request, cancellationToken, trace)); }
private static bool ShouldUpdateSessionToken( DocumentServiceRequest request, INameValueCollection responseHeaders, out ResourceId resourceId, out string collectionName) { resourceId = null; string ownerFullName = responseHeaders[HttpConstants.HttpHeaders.OwnerFullName]; if (string.IsNullOrEmpty(ownerFullName)) { ownerFullName = request.ResourceAddress; } collectionName = PathsHelper.GetCollectionPath(ownerFullName); string resourceIdString; if (request.IsNameBased) { resourceIdString = responseHeaders[HttpConstants.HttpHeaders.OwnerId]; if (string.IsNullOrEmpty(resourceIdString)) { resourceIdString = request.ResourceId; } } else { resourceIdString = request.ResourceId; } if (!string.IsNullOrEmpty(resourceIdString)) { resourceId = ResourceId.Parse(resourceIdString); if (resourceId.DocumentCollection != 0 && collectionName != null && !ReplicatedResourceClient.IsReadingFromMaster(request.ResourceType, request.OperationType)) { return(true); } } return(false); }
/// <summary> /// This method is only used in client SDK in retry policy as it doesn't have request handy. /// </summary> public void Refresh(string resourceAddress) { if (PathsHelper.IsNameBased(resourceAddress)) { string resourceFullName = PathsHelper.GetCollectionPath(resourceAddress); this.collectionInfoByNameCache.Refresh( resourceFullName, async() => { CosmosContainerSettings collection = await this.GetByNameAsync(resourceFullName, CancellationToken.None); if (collection != null) { this.collectionInfoByIdCache.Set(collection.ResourceId, collection); } return(collection); }, CancellationToken.None); } }
private static void ClearTokenByCollectionFullname(SessionContainerState self, string collectionFullname) { if (!string.IsNullOrEmpty(collectionFullname)) { string collectionName = PathsHelper.GetCollectionPath(collectionFullname); self.rwlock.EnterWriteLock(); try { if (self.collectionNameByResourceId.ContainsKey(collectionName)) { ulong rid = self.collectionNameByResourceId[collectionName]; self.sessionTokensRIDBased.TryRemove(rid, out _); self.collectionResourceIdByName.TryRemove(rid, out _); self.collectionNameByResourceId.TryRemove(collectionName, out _); } } finally { self.rwlock.ExitWriteLock(); } } }
internal Task <CosmosContainerSettings> ResolveByNameAsync( string resourceAddress, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); string resourceFullName = PathsHelper.GetCollectionPath(resourceAddress); return(this.collectionInfoByNameCache.GetAsync( resourceFullName, null, async() => { CosmosContainerSettings collection = await this.GetByNameAsync(resourceFullName, cancellationToken); if (collection != null) { this.collectionInfoByIdCache.Set(collection.ResourceId, collection); } return collection; }, cancellationToken)); }
private ConcurrentDictionary <string, ISessionToken> GetPartitionKeyRangeIdToTokenMap(DocumentServiceRequest request) { ConcurrentDictionary <string, ISessionToken> partitionKeyRangeIdToTokenMap = null; if (!request.IsNameBased) { if (!string.IsNullOrEmpty(request.ResourceId)) { ResourceId resourceId = ResourceId.Parse(request.ResourceId); if (resourceId.DocumentCollection != 0) { this.sessionTokens.TryGetValue(resourceId.UniqueDocumentCollectionId, out partitionKeyRangeIdToTokenMap); } } } else { string collectionName = PathsHelper.GetCollectionPath(request.ResourceAddress); this.sessionTokensNameBased.TryGetValue(collectionName, out partitionKeyRangeIdToTokenMap); } return(partitionKeyRangeIdToTokenMap); }
protected override async Task <FeedResponse <dynamic> > ExecuteInternalAsync(CancellationToken cancellationToken) { CollectionCache collectionCache = await this.Client.GetCollectionCacheAsync(); PartitionKeyRangeCache partitionKeyRangeCache = await this.Client.GetPartitionKeyRangeCache(); IDocumentClientRetryPolicy retryPolicyInstance = this.Client.RetryPolicy.GetRequestPolicy(); retryPolicyInstance = new InvalidPartitionExceptionRetryPolicy(collectionCache, retryPolicyInstance); if (base.ResourceTypeEnum.IsPartitioned()) { retryPolicyInstance = new PartitionKeyRangeGoneRetryPolicy( collectionCache, partitionKeyRangeCache, PathsHelper.GetCollectionPath(base.ResourceLink), retryPolicyInstance); } return(await BackoffRetryUtility <FeedResponse <dynamic> > .ExecuteAsync( async() => { this.fetchExecutionRangeAccumulator.BeginFetchRange(); ++this.retries; this.fetchSchedulingMetrics.Start(); this.fetchExecutionRangeAccumulator.BeginFetchRange(); FeedResponse <dynamic> response = await this.ExecuteOnceAsync(retryPolicyInstance, cancellationToken); this.fetchSchedulingMetrics.Stop(); this.fetchExecutionRangeAccumulator.EndFetchRange(response.Count, this.retries); if (!string.IsNullOrEmpty(response.Headers[HttpConstants.HttpHeaders.QueryMetrics])) { this.fetchExecutionRangeAccumulator.EndFetchRange(response.Count, this.retries); response = new FeedResponse <dynamic>( response, response.Count, response.Headers, response.UseETagAsContinuation, new Dictionary <string, QueryMetrics> { { singlePartitionKeyId, QueryMetrics.CreateFromDelimitedStringAndClientSideMetrics( response.Headers[HttpConstants.HttpHeaders.QueryMetrics], new ClientSideMetrics( this.retries, response.RequestCharge, this.fetchExecutionRangeAccumulator.GetExecutionRanges(), string.IsNullOrEmpty(response.ResponseContinuation) ? new List <Tuple <string, SchedulingTimeSpan> >() { new Tuple <string, SchedulingTimeSpan>(singlePartitionKeyId, this.fetchSchedulingMetrics.Elapsed) } : new List <Tuple <string, SchedulingTimeSpan> >()), Guid.Parse(response.ActivityId)) } }, response.RequestStatistics, response.DisallowContinuationTokenMessage, response.ResponseLengthBytes); } this.retries = -1; return response; }, retryPolicyInstance, cancellationToken)); }
protected override async Task <DocumentFeedResponse <CosmosElement> > ExecuteInternalAsync(CancellationToken token) { CollectionCache collectionCache = await this.Client.GetCollectionCacheAsync(); PartitionKeyRangeCache partitionKeyRangeCache = await this.Client.GetPartitionKeyRangeCacheAsync(); IDocumentClientRetryPolicy retryPolicyInstance = this.Client.ResetSessionTokenRetryPolicy.GetRequestPolicy(); retryPolicyInstance = new InvalidPartitionExceptionRetryPolicy(retryPolicyInstance); if (base.ResourceTypeEnum.IsPartitioned()) { retryPolicyInstance = new PartitionKeyRangeGoneRetryPolicy( collectionCache, partitionKeyRangeCache, PathsHelper.GetCollectionPath(base.ResourceLink), retryPolicyInstance); } return(await BackoffRetryUtility <DocumentFeedResponse <CosmosElement> > .ExecuteAsync( async() => { this.fetchExecutionRangeAccumulator.BeginFetchRange(); ++this.retries; Tuple <DocumentFeedResponse <CosmosElement>, string> responseAndPartitionIdentifier = await this.ExecuteOnceAsync(retryPolicyInstance, token); DocumentFeedResponse <CosmosElement> response = responseAndPartitionIdentifier.Item1; string partitionIdentifier = responseAndPartitionIdentifier.Item2; if (!string.IsNullOrEmpty(response.ResponseHeaders[HttpConstants.HttpHeaders.QueryMetrics])) { this.fetchExecutionRangeAccumulator.EndFetchRange( partitionIdentifier, response.ActivityId, response.Count, this.retries); response = new DocumentFeedResponse <CosmosElement>( response, response.Count, response.Headers, response.UseETagAsContinuation, new Dictionary <string, QueryMetrics> { { partitionIdentifier, QueryMetrics.CreateFromDelimitedStringAndClientSideMetrics( response.ResponseHeaders[HttpConstants.HttpHeaders.QueryMetrics], response.ResponseHeaders[HttpConstants.HttpHeaders.IndexUtilization], new ClientSideMetrics( this.retries, response.RequestCharge, this.fetchExecutionRangeAccumulator.GetExecutionRanges())) } }, response.RequestStatistics, response.DisallowContinuationTokenMessage, response.ResponseLengthBytes); } this.retries = -1; return response; }, retryPolicyInstance, token)); }
private async Task <FeedResource <Address> > GetServerAddressesViaGatewayAsync( DocumentServiceRequest request, string collectionRid, IEnumerable <string> partitionKeyRangeIds, bool forceRefresh) { string entryUrl = PathsHelper.GeneratePath(ResourceType.Document, collectionRid, true); INameValueCollection addressQuery = new DictionaryNameValueCollection(); addressQuery.Add(HttpConstants.QueryStrings.Url, HttpUtility.UrlEncode(entryUrl)); INameValueCollection headers = new DictionaryNameValueCollection(); if (forceRefresh) { headers.Set(HttpConstants.HttpHeaders.ForceRefresh, bool.TrueString); } if (request.ForceCollectionRoutingMapRefresh) { headers.Set(HttpConstants.HttpHeaders.ForceCollectionRoutingMapRefresh, bool.TrueString); } addressQuery.Add(HttpConstants.QueryStrings.Filter, this.protocolFilter); addressQuery.Add(HttpConstants.QueryStrings.PartitionKeyRangeIds, string.Join(",", partitionKeyRangeIds)); string resourceTypeToSign = PathsHelper.GetResourcePath(ResourceType.Document); headers.Set(HttpConstants.HttpHeaders.XDate, DateTime.UtcNow.ToString("r", CultureInfo.InvariantCulture)); string token = null; try { token = this.tokenProvider.GetUserAuthorizationToken( collectionRid, resourceTypeToSign, HttpConstants.HttpMethods.Get, headers, AuthorizationTokenType.PrimaryMasterKey); } catch (UnauthorizedException) { } if (token == null && request.IsNameBased) { // User doesn't have rid based resource token. Maybe he has name based. string collectionAltLink = PathsHelper.GetCollectionPath(request.ResourceAddress); token = this.tokenProvider.GetUserAuthorizationToken( collectionAltLink, resourceTypeToSign, HttpConstants.HttpMethods.Get, headers, AuthorizationTokenType.PrimaryMasterKey); } headers.Set(HttpConstants.HttpHeaders.Authorization, token); Uri targetEndpoint = UrlUtility.SetQuery(this.addressEndpoint, UrlUtility.CreateQuery(addressQuery)); string identifier = GatewayAddressCache.LogAddressResolutionStart(request, targetEndpoint); using (HttpResponseMessage httpResponseMessage = await this.httpClient.GetAsync(targetEndpoint, headers)) { using (DocumentServiceResponse documentServiceResponse = await ClientExtensions.ParseResponseAsync(httpResponseMessage)) { GatewayAddressCache.LogAddressResolutionEnd(request, identifier); return(documentServiceResponse.GetResource <FeedResource <Address> >()); } } }