internal static ResponseMessage ToCosmosResponseMessage(this DocumentServiceResponse response, RequestMessage requestMessage)
        {
            Debug.Assert(requestMessage != null, nameof(requestMessage));

            ResponseMessage cosmosResponse = new ResponseMessage(response.StatusCode, requestMessage);

            if (response.ResponseBody != null)
            {
                cosmosResponse.Content = response.ResponseBody;
            }

            if (response.Headers != null)
            {
                foreach (string key in response.Headers)
                {
                    cosmosResponse.Headers.Add(key, response.Headers[key]);
                }
            }

            return(cosmosResponse);
        }
            public override async Task <ResponseMessage> SendAsync(
                RequestMessage request,
                CancellationToken cancellationToken)
            {
                this.ProcessMessagesAsyncThrew = false;
                this.SendAsyncCalls++;
                try
                {
                    using (new ActivityScope(Guid.NewGuid()))
                    {
                        DocumentServiceResponse response = await base.ProcessMessageAsync(request, cancellationToken);

                        return(response.ToCosmosResponseMessage(request));
                    }
                }
                catch (DocumentClientException)
                {
                    this.ProcessMessagesAsyncThrew = true;
                    throw;
                }
            }
示例#3
0
        public override async Task <ResponseMessage> SendAsync(
            RequestMessage request,
            CancellationToken cancellationToken)
        {
            using (new ActivityScope(Guid.NewGuid()))
            {
                try
                {
                    DocumentServiceResponse response = await this.ProcessMessageAsync(request, cancellationToken);

                    Debug.Assert(Trace.CorrelationManager.ActivityId != Guid.Empty, "Trace activity id is missing");
                    return(response.ToCosmosResponseMessage(request));
                }
                //catch DocumentClientException and exceptions that inherit it. Other exception types happen before a backend request
                catch (DocumentClientException ex)
                {
                    Debug.Assert(Trace.CorrelationManager.ActivityId != Guid.Empty, "Trace activity id is missing");
                    return(ex.ToCosmosResponseMessage(request));
                }
                catch (CosmosException ce)
                {
                    Debug.Assert(Trace.CorrelationManager.ActivityId != Guid.Empty, "Trace activity id is missing");
                    return(ce.ToCosmosResponseMessage(request));
                }
                catch (AggregateException ex)
                {
                    Debug.Assert(Trace.CorrelationManager.ActivityId != Guid.Empty, "Trace activity id is missing");
                    // TODO: because the SDK underneath this path uses ContinueWith or task.Result we need to catch AggregateExceptions here
                    // in order to ensure that underlying DocumentClientExceptions get propagated up correctly. Once all ContinueWith and .Result
                    // is removed this catch can be safely removed.
                    ResponseMessage errorMessage = AggregateExceptionConverter(ex, request);
                    if (errorMessage != null)
                    {
                        return(errorMessage);
                    }

                    throw;
                }
            }
        }
示例#4
0
        public async Task TestServerStoreModelWithRequestEventHandler()
        {
            EventHandler <SendingRequestEventArgs>   sendingRequest;
            EventHandler <ReceivedResponseEventArgs> receivedResponse;

            sendingRequest   = this.SendingRequestEventHandler;
            receivedResponse = this.ReceivedRequestEventHandler;
            ServerStoreModel storeModel = new ServerStoreModel(GetMockStoreClient(), sendingRequest, receivedResponse);

            using (new ActivityScope(Guid.NewGuid()))
            {
                using (DocumentServiceRequest request = DocumentServiceRequest.Create(
                           OperationType.Read,
                           ResourceType.Document,
                           AuthorizationTokenType.PrimaryMasterKey))
                {
                    DocumentServiceResponse result = await storeModel.ProcessMessageAsync(request);

                    Assert.IsTrue(request.Headers.Get(newHeaderKey) != null);
                }
            }
        }
        private async Task <PartitionAddressInformation> GetAddressesForRangeIdAsync(
            DocumentServiceRequest request,
            string collectionRid,
            string partitionKeyRangeId,
            bool forceRefresh)
        {
            using (DocumentServiceResponse response =
                       await this.GetServerAddressesViaGatewayAsync(request, collectionRid, new[] { partitionKeyRangeId }, forceRefresh))
            {
                FeedResource <Address> addressFeed = response.GetResource <FeedResource <Address> >();

                bool inNetworkRequest = this.IsInNetworkRequest(response);

                IEnumerable <Tuple <PartitionKeyRangeIdentity, PartitionAddressInformation> > addressInfos =
                    addressFeed.Where(addressInfo => ProtocolFromString(addressInfo.Protocol) == this.protocol)
                    .GroupBy(address => address.PartitionKeyRangeId, StringComparer.Ordinal)
                    .Select(group => this.ToPartitionAddressAndRange(collectionRid, @group.ToList(), inNetworkRequest));

                Tuple <PartitionKeyRangeIdentity, PartitionAddressInformation> result =
                    addressInfos.SingleOrDefault(
                        addressInfo => StringComparer.Ordinal.Equals(addressInfo.Item1.PartitionKeyRangeId, partitionKeyRangeId));

                if (result == null)
                {
                    string errorMessage = string.Format(
                        CultureInfo.InvariantCulture,
                        RMResources.PartitionKeyRangeNotFound,
                        partitionKeyRangeId,
                        collectionRid);

                    throw new PartitionKeyRangeGoneException(errorMessage)
                          {
                              ResourceAddress = collectionRid
                          };
                }

                return(result.Item2);
            }
        }
示例#6
0
        internal async Task <ResponseMessage> ProcessMessageAsync(
            RequestMessage request,
            CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            DocumentServiceRequest serviceRequest = request.ToDocumentServiceRequest();

            //TODO: extrace auth into a separate handler
            string authorization = await((ICosmosAuthorizationTokenProvider)this.client.DocumentClient).GetUserAuthorizationTokenAsync(
                serviceRequest.ResourceAddress,
                PathsHelper.GetResourcePath(request.ResourceType),
                request.Method.ToString(),
                serviceRequest.Headers,
                AuthorizationTokenType.PrimaryMasterKey,
                request.DiagnosticsContext);

            serviceRequest.Headers[HttpConstants.HttpHeaders.Authorization] = authorization;

            IStoreModel storeProxy = this.client.DocumentClient.GetStoreProxy(serviceRequest);

            using (ITrace processMessageAsyncTrace = request.Trace.StartChild(
                       name: $"{storeProxy.GetType().FullName} Transport Request",
                       TraceComponent.Transport,
                       Tracing.TraceLevel.Info))
            {
                using (request.DiagnosticsContext.CreateScope(storeProxy.GetType().FullName))
                {
                    DocumentServiceResponse response = request.OperationType == OperationType.Upsert
                        ? await this.ProcessUpsertAsync(storeProxy, serviceRequest, cancellationToken)
                        : await storeProxy.ProcessMessageAsync(serviceRequest, cancellationToken);

                    return(response.ToCosmosResponseMessage(request, processMessageAsyncTrace));
                }
            }
        }
        private async Task <ContainerProperties> ReadCollectionAsync(string collectionLink, CancellationToken cancellationToken, IDocumentClientRetryPolicy retryPolicyInstance)
        {
            cancellationToken.ThrowIfCancellationRequested();

            using (DocumentServiceRequest request = DocumentServiceRequest.Create(
                       OperationType.Read,
                       ResourceType.Collection,
                       collectionLink,
                       AuthorizationTokenType.PrimaryMasterKey,
                       new DictionaryNameValueCollection()))
            {
                request.Headers[HttpConstants.HttpHeaders.XDate] = DateTime.UtcNow.ToString("r");

                string payload;
                string authorizationToken = this.tokenProvider.GetUserAuthorizationToken(
                    request.ResourceAddress,
                    PathsHelper.GetResourcePath(request.ResourceType),
                    HttpConstants.HttpMethods.Get,
                    request.Headers,
                    AuthorizationTokenType.PrimaryMasterKey,
                    out payload);

                request.Headers[HttpConstants.HttpHeaders.Authorization] = authorizationToken;

                using (new ActivityScope(Guid.NewGuid()))
                {
                    if (retryPolicyInstance != null)
                    {
                        retryPolicyInstance.OnBeforeSendRequest(request);
                    }

                    using (DocumentServiceResponse response = await this.storeModel.ProcessMessageAsync(request))
                    {
                        return(CosmosResource.FromStream <ContainerProperties>(response));
                    }
                }
            }
        }
示例#8
0
        public async Task TestJsonParseHandling()
        {
            HttpRequestMessage  httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "https://*****:*****@"{ ""id"": ""test"", ""message"": ""Conflict"", ""Code"": ""409""}",
                encoding: Encoding.Default,
                mediaType: "application/json");

            try
            {
                DocumentServiceResponse dsr = await ClientExtensions.ParseResponseAsync(message);
            }
            catch (DocumentClientException dce)
            {
                Assert.IsNotNull(dce.Message);
                Assert.AreEqual(HttpStatusCode.Conflict, dce.StatusCode);
                Assert.AreEqual("Id already exists", dce.StatusDescription);
            }
        }
示例#9
0
        private DocumentFeedResponse <CosmosElement> GetFeedResponse(
            DocumentServiceRequest documentServiceRequest,
            DocumentServiceResponse documentServiceResponse)
        {
            // Execute the callback an each element of the page
            // For example just could get a response like this
            // {
            //    "_rid": "qHVdAImeKAQ=",
            //    "Documents": [{
            //        "id": "03230",
            //        "_rid": "qHVdAImeKAQBAAAAAAAAAA==",
            //        "_self": "dbs\/qHVdAA==\/colls\/qHVdAImeKAQ=\/docs\/qHVdAImeKAQBAAAAAAAAAA==\/",
            //        "_etag": "\"410000b0-0000-0000-0000-597916b00000\"",
            //        "_attachments": "attachments\/",
            //        "_ts": 1501107886
            //    }],
            //    "_count": 1
            // }
            // And you should execute the callback on each document in "Documents".
            MemoryStream memoryStream = new MemoryStream();

            documentServiceResponse.ResponseBody.CopyTo(memoryStream);
            long responseLengthBytes = memoryStream.Length;

            ReadOnlyMemory <byte> content;

            if (memoryStream.TryGetBuffer(out ArraySegment <byte> buffer))
            {
                content = buffer;
            }
            else
            {
                content = memoryStream.ToArray();
            }

            IJsonNavigator jsonNavigator = null;

            // Use the users custom navigator first. If it returns null back try the
            // internal navigator.
            if (this.feedOptions.CosmosSerializationFormatOptions != null)
            {
                jsonNavigator = this.feedOptions.CosmosSerializationFormatOptions.CreateCustomNavigatorCallback(content);
                if (jsonNavigator == null)
                {
                    throw new InvalidOperationException("The CosmosSerializationOptions did not return a JSON navigator.");
                }
            }
            else
            {
                jsonNavigator = JsonNavigator.Create(content);
            }

            string resourceName = this.GetRootNodeName(documentServiceRequest.ResourceType);

            if (!jsonNavigator.TryGetObjectProperty(
                    jsonNavigator.GetRootNode(),
                    resourceName,
                    out ObjectProperty objectProperty))
            {
                throw new InvalidOperationException($"Response Body Contract was violated. QueryResponse did not have property: {resourceName}");
            }

            IJsonNavigatorNode cosmosElements = objectProperty.ValueNode;

            if (!(CosmosElement.Dispatch(
                      jsonNavigator,
                      cosmosElements) is CosmosArray cosmosArray))
            {
                throw new InvalidOperationException($"QueryResponse did not have an array of : {resourceName}");
            }

            int itemCount = cosmosArray.Count;

            return(new DocumentFeedResponse <CosmosElement>(
                       cosmosArray,
                       itemCount,
                       documentServiceResponse.Headers,
                       documentServiceResponse.RequestStats,
                       responseLengthBytes));
        }
示例#10
0
        public virtual async Task <AccountProperties> GetDatabaseAccountAsync(HttpRequestMessage requestMessage, CancellationToken cancellationToken = default(CancellationToken))
        {
            AccountProperties databaseAccount = null;

            // Get the ServiceDocumentResource from the gateway.
            using (HttpResponseMessage responseMessage =
                       await this.gatewayStoreClient.SendHttpAsync(requestMessage, cancellationToken))
            {
                using (DocumentServiceResponse documentServiceResponse = await ClientExtensions.ParseResponseAsync(responseMessage))
                {
                    databaseAccount = CosmosResource.FromStream <AccountProperties>(documentServiceResponse);
                }

                long longValue;
                IEnumerable <string> headerValues;
                if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.MaxMediaStorageUsageInMB, out headerValues) &&
                    (headerValues.Count() != 0))
                {
                    if (long.TryParse(headerValues.First(), out longValue))
                    {
                        databaseAccount.MaxMediaStorageUsageInMB = longValue;
                    }
                }

                if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.CurrentMediaStorageUsageInMB, out headerValues) &&
                    (headerValues.Count() != 0))
                {
                    if (long.TryParse(headerValues.First(), out longValue))
                    {
                        databaseAccount.MediaStorageUsageInMB = longValue;
                    }
                }

                if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.DatabaseAccountConsumedDocumentStorageInMB, out headerValues) &&
                    (headerValues.Count() != 0))
                {
                    if (long.TryParse(headerValues.First(), out longValue))
                    {
                        databaseAccount.ConsumedDocumentStorageInMB = longValue;
                    }
                }

                if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.DatabaseAccountProvisionedDocumentStorageInMB, out headerValues) &&
                    (headerValues.Count() != 0))
                {
                    if (long.TryParse(headerValues.First(), out longValue))
                    {
                        databaseAccount.ProvisionedDocumentStorageInMB = longValue;
                    }
                }

                if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.DatabaseAccountReservedDocumentStorageInMB, out headerValues) &&
                    (headerValues.Count() != 0))
                {
                    if (long.TryParse(headerValues.First(), out longValue))
                    {
                        databaseAccount.ReservedDocumentStorageInMB = longValue;
                    }
                }
            }

            return(databaseAccount);
        }
示例#11
0
        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> >());
                }
            }
        }
示例#12
0
 internal DocumentResponse(DocumentServiceResponse response, JsonSerializerSettings settings = null)
     : base(response)
 {
     this.settings = settings;
 }
 internal ResourceResponse(DocumentServiceResponse response, ITypeResolver <TResource> typeResolver = null)
     : base(response)
 {
     this.typeResolver = typeResolver;
 }
 private async Task<DocumentServiceResponse> ProcessUpsertAsync(IStoreModel storeProxy, DocumentServiceRequest serviceRequest, CancellationToken cancellationToken)
 {
     DocumentServiceResponse response = await storeProxy.ProcessMessageAsync(serviceRequest, cancellationToken);
     this.client.DocumentClient.CaptureSessionToken(serviceRequest, response);
     return response;
 }
示例#15
0
 internal ResourceResponseBase(DocumentServiceResponse response)
 {
     this.response     = response;
     this.usageHeaders = new Dictionary <string, long>();
     this.quotaHeaders = new Dictionary <string, long>();
 }
        public virtual async Task <CosmosAccountSettings> GetDatabaseAccountAsync(HttpRequestMessage requestMessage)
        {
            CosmosAccountSettings databaseAccount = null;

            // Get the ServiceDocumentResource from the gateway.
            using (HttpResponseMessage responseMessage =
                       await this.httpClient.SendHttpAsync(requestMessage))
            {
                using (DocumentServiceResponse documentServiceResponse = await ClientExtensions.ParseResponseAsync(responseMessage))
                {
                    databaseAccount = documentServiceResponse.GetInternalResource <CosmosAccountSettings>(CosmosAccountSettings.CreateNewInstance);
                }

                long longValue;
                IEnumerable <string> headerValues;
                if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.MaxMediaStorageUsageInMB, out headerValues) &&
                    (headerValues.Count() != 0))
                {
                    if (long.TryParse(headerValues.First(), out longValue))
                    {
                        databaseAccount.MaxMediaStorageUsageInMB = longValue;
                    }
                }

                if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.CurrentMediaStorageUsageInMB, out headerValues) &&
                    (headerValues.Count() != 0))
                {
                    if (long.TryParse(headerValues.First(), out longValue))
                    {
                        databaseAccount.MediaStorageUsageInMB = longValue;
                    }
                }

                if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.DatabaseAccountConsumedDocumentStorageInMB, out headerValues) &&
                    (headerValues.Count() != 0))
                {
                    if (long.TryParse(headerValues.First(), out longValue))
                    {
                        databaseAccount.ConsumedDocumentStorageInMB = longValue;
                    }
                }

                if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.DatabaseAccountProvisionedDocumentStorageInMB, out headerValues) &&
                    (headerValues.Count() != 0))
                {
                    if (long.TryParse(headerValues.First(), out longValue))
                    {
                        databaseAccount.ProvisionedDocumentStorageInMB = longValue;
                    }
                }

                if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.DatabaseAccountReservedDocumentStorageInMB, out headerValues) &&
                    (headerValues.Count() != 0))
                {
                    if (long.TryParse(headerValues.First(), out longValue))
                    {
                        databaseAccount.ReservedDocumentStorageInMB = longValue;
                    }
                }
            }

            return(databaseAccount);
        }
示例#17
0
        private async Task <CollectionRoutingMap> GetRoutingMapForCollectionAsync(
            string collectionRid,
            CollectionRoutingMap previousRoutingMap,
            ITrace trace,
            IClientSideRequestStatistics clientSideRequestStatistics,
            CancellationToken cancellationToken)
        {
            List <PartitionKeyRange> ranges  = new List <PartitionKeyRange>();
            string changeFeedNextIfNoneMatch = previousRoutingMap == null ? null : previousRoutingMap.ChangeFeedNextIfNoneMatch;

            HttpStatusCode lastStatusCode = HttpStatusCode.OK;

            do
            {
                INameValueCollection headers = new StoreRequestNameValueCollection();

                headers.Set(HttpConstants.HttpHeaders.PageSize, PageSizeString);
                headers.Set(HttpConstants.HttpHeaders.A_IM, HttpConstants.A_IMHeaderValues.IncrementalFeed);
                if (changeFeedNextIfNoneMatch != null)
                {
                    headers.Set(HttpConstants.HttpHeaders.IfNoneMatch, changeFeedNextIfNoneMatch);
                }

                RetryOptions retryOptions = new RetryOptions();
                using (DocumentServiceResponse response = await BackoffRetryUtility <DocumentServiceResponse> .ExecuteAsync(
                           () => this.ExecutePartitionKeyRangeReadChangeFeedAsync(collectionRid, headers, trace, clientSideRequestStatistics),
                           new ResourceThrottleRetryPolicy(retryOptions.MaxRetryAttemptsOnThrottledRequests, retryOptions.MaxRetryWaitTimeInSeconds),
                           cancellationToken))
                {
                    lastStatusCode            = response.StatusCode;
                    changeFeedNextIfNoneMatch = response.Headers[HttpConstants.HttpHeaders.ETag];

                    FeedResource <PartitionKeyRange> feedResource = response.GetResource <FeedResource <PartitionKeyRange> >();
                    if (feedResource != null)
                    {
                        ranges.AddRange(feedResource);
                    }
                }
            }while (lastStatusCode != HttpStatusCode.NotModified);

            IEnumerable <Tuple <PartitionKeyRange, ServiceIdentity> > tuples = ranges.Select(range => Tuple.Create(range, (ServiceIdentity)null));

            CollectionRoutingMap routingMap;

            if (previousRoutingMap == null)
            {
                // Splits could have happened during change feed query and we might have a mix of gone and new ranges.
                HashSet <string> goneRanges = new HashSet <string>(ranges.SelectMany(range => range.Parents ?? Enumerable.Empty <string>()));
                routingMap = CollectionRoutingMap.TryCreateCompleteRoutingMap(
                    tuples.Where(tuple => !goneRanges.Contains(tuple.Item1.Id)),
                    string.Empty,
                    changeFeedNextIfNoneMatch);
            }
            else
            {
                routingMap = previousRoutingMap.TryCombine(tuples, changeFeedNextIfNoneMatch);
            }

            if (routingMap == null)
            {
                // Range information either doesn't exist or is not complete.
                throw new NotFoundException($"{DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture)}: GetRoutingMapForCollectionAsync(collectionRid: {collectionRid}), Range information either doesn't exist or is not complete.");
            }

            return(routingMap);
        }
示例#18
0
        internal async Task <ResponseMessage> ProcessMessageAsync(
            RequestMessage request,
            CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            DocumentServiceRequest serviceRequest = request.ToDocumentServiceRequest();

            ClientSideRequestStatisticsTraceDatum clientSideRequestStatisticsTraceDatum = new ClientSideRequestStatisticsTraceDatum(DateTime.UtcNow, request.Trace.Summary);

            serviceRequest.RequestContext.ClientRequestStatistics = clientSideRequestStatisticsTraceDatum;

            //TODO: extrace auth into a separate handler
            string authorization = await((ICosmosAuthorizationTokenProvider)this.client.DocumentClient).GetUserAuthorizationTokenAsync(
                serviceRequest.ResourceAddress,
                PathsHelper.GetResourcePath(request.ResourceType),
                request.Method.ToString(),
                serviceRequest.Headers,
                AuthorizationTokenType.PrimaryMasterKey,
                request.Trace);

            serviceRequest.Headers[HttpConstants.HttpHeaders.Authorization] = authorization;

            IStoreModel storeProxy = this.client.DocumentClient.GetStoreProxy(serviceRequest);

            using (ITrace processMessageAsyncTrace = request.Trace.StartChild(
                       name: $"{storeProxy.GetType().FullName} Transport Request",
                       component: TraceComponent.Transport,
                       level: Tracing.TraceLevel.Info))
            {
                request.Trace = processMessageAsyncTrace;
                processMessageAsyncTrace.AddDatum("Client Side Request Stats", clientSideRequestStatisticsTraceDatum);

                DocumentServiceResponse response = null;
                try
                {
                    response = await storeProxy.ProcessMessageAsync(serviceRequest, cancellationToken);
                }
                catch (DocumentClientException dce)
                {
                    // Enrich diagnostics context in-case of auth failures
                    if (dce.StatusCode == System.Net.HttpStatusCode.Unauthorized || dce.StatusCode == System.Net.HttpStatusCode.Forbidden)
                    {
                        TimeSpan authProvideLifeSpan = this.client.DocumentClient.cosmosAuthorization.GetAge();
                        processMessageAsyncTrace.AddDatum("AuthProvider LifeSpan InSec", authProvideLifeSpan.TotalSeconds);
                    }

                    throw;
                }
                finally
                {
                    processMessageAsyncTrace.UpdateRegionContacted(clientSideRequestStatisticsTraceDatum);
                }

                ResponseMessage responseMessage = response.ToCosmosResponseMessage(
                    request,
                    serviceRequest.RequestContext.RequestChargeTracker);

                // Enrich diagnostics context in-case of auth failures
                if (responseMessage?.StatusCode == System.Net.HttpStatusCode.Unauthorized || responseMessage?.StatusCode == System.Net.HttpStatusCode.Forbidden)
                {
                    TimeSpan authProvideLifeSpan = this.client.DocumentClient.cosmosAuthorization.GetAge();
                    processMessageAsyncTrace.AddDatum("AuthProvider LifeSpan InSec", authProvideLifeSpan.TotalSeconds);
                }

                return(responseMessage);
            }
        }