Beispiel #1
0
        public override async Task <ResponseMessage> ReadNextAsync(CancellationToken cancellationToken = default)
        {
            CosmosDiagnosticsContext diagnostics = CosmosDiagnosticsContext.Create(this.requestOptions);

            using (diagnostics.GetOverallScope())
            {
                // This catches exception thrown by the pipeline and converts it to QueryResponse
                QueryResponseCore responseCore = await this.cosmosQueryExecutionContext.ExecuteNextAsync(cancellationToken);

                // This swaps the diagnostics in the context. This shows all the page reads between the previous ReadNextAsync and the current ReadNextAsync
                diagnostics.AddDiagnosticsInternal(this.cosmosQueryContext.GetAndResetDiagnostics());

                if (responseCore.IsSuccess)
                {
                    List <CosmosElement> decryptedCosmosElements = null;
                    if (this.clientContext.ClientOptions.Encryptor != null)
                    {
                        decryptedCosmosElements = await this.GetDecryptedElementResponseAsync(responseCore.CosmosElements, diagnostics, cancellationToken);
                    }

                    return(QueryResponse.CreateSuccess(
                               result: decryptedCosmosElements ?? responseCore.CosmosElements,
                               count: responseCore.CosmosElements.Count,
                               responseLengthBytes: responseCore.ResponseLengthBytes,
                               diagnostics: diagnostics,
                               serializationOptions: this.cosmosSerializationFormatOptions,
                               responseHeaders: new CosmosQueryResponseMessageHeaders(
                                   responseCore.ContinuationToken,
                                   responseCore.DisallowContinuationTokenMessage,
                                   this.cosmosQueryContext.ResourceTypeEnum,
                                   this.cosmosQueryContext.ContainerResourceId)
                    {
                        RequestCharge = responseCore.RequestCharge,
                        ActivityId = responseCore.ActivityId,
                        SubStatusCode = responseCore.SubStatusCode ?? Documents.SubStatusCodes.Unknown
                    }));
                }

                if (responseCore.CosmosException != null)
                {
                    return(responseCore.CosmosException.ToCosmosResponseMessage(null));
                }

                return(QueryResponse.CreateFailure(
                           statusCode: responseCore.StatusCode,
                           cosmosException: responseCore.CosmosException,
                           requestMessage: null,
                           diagnostics: diagnostics,
                           responseHeaders: new CosmosQueryResponseMessageHeaders(
                               responseCore.ContinuationToken,
                               responseCore.DisallowContinuationTokenMessage,
                               this.cosmosQueryContext.ResourceTypeEnum,
                               this.cosmosQueryContext.ContainerResourceId)
                {
                    RequestCharge = responseCore.RequestCharge,
                    ActivityId = responseCore.ActivityId,
                    SubStatusCode = responseCore.SubStatusCode ?? Documents.SubStatusCodes.Unknown,
                }));
            }
        }
        public static QueryResponseCore CreateQueryResponse(
            IList <ToDoItem> items,
            bool isOrderByQuery,
            string continuationToken,
            string collectionRid)
        {
            MemoryStream memoryStream;
            string       json;

            if (isOrderByQuery)
            {
                memoryStream = SerializeForOrderByQuery(items);
                using (StreamReader sr = new StreamReader(SerializeForOrderByQuery(items)))
                {
                    json = sr.ReadToEnd();
                }
            }
            else
            {
                memoryStream = (MemoryStream)MockCosmosUtil.Serializer.ToStream <IList <ToDoItem> >(items);
            }

            long responseLengthBytes = memoryStream.Length;

            IJsonNavigator           jsonNavigator      = JsonNavigator.Create(memoryStream.ToArray());
            IJsonNavigatorNode       jsonNavigatorNode  = jsonNavigator.GetRootNode();
            CosmosArray              cosmosArray        = CosmosArray.Create(jsonNavigator, jsonNavigatorNode);
            CosmosDiagnosticsContext diagnosticsContext = new CosmosDiagnosticsContext();

            diagnosticsContext.AddDiagnosticsInternal(new PointOperationStatistics(
                                                          activityId: Guid.NewGuid().ToString(),
                                                          statusCode: HttpStatusCode.OK,
                                                          subStatusCode: SubStatusCodes.Unknown,
                                                          requestCharge: 4,
                                                          errorMessage: null,
                                                          method: HttpMethod.Post,
                                                          requestUri: new Uri("http://localhost.com"),
                                                          requestSessionToken: null,
                                                          responseSessionToken: null,
                                                          clientSideRequestStatistics: null));
            IReadOnlyCollection <QueryPageDiagnostics> diagnostics = new List <QueryPageDiagnostics>()
            {
                new QueryPageDiagnostics("0",
                                         "SomeQueryMetricText",
                                         "SomeIndexUtilText",
                                         diagnosticsContext,
                                         new SchedulingStopwatch())
            };

            QueryResponseCore message = QueryResponseCore.CreateSuccess(
                result: cosmosArray,
                requestCharge: 4,
                activityId: Guid.NewGuid().ToString(),
                diagnostics: diagnostics,
                responseLengthBytes: responseLengthBytes,
                disallowContinuationTokenMessage: null,
                continuationToken: continuationToken);

            return(message);
        }
        public override async Task <ResponseMessage> ReadNextAsync(CancellationToken cancellationToken = default)
        {
            CosmosDiagnosticsContext diagnostics = new CosmosDiagnosticsContext();

            using (diagnostics.CreateScope("QueryReadNextAsync"))
            {
                // This catches exception thrown by the pipeline and converts it to QueryResponse
                QueryResponseCore responseCore = await this.cosmosQueryExecutionContext.ExecuteNextAsync(cancellationToken);

                CosmosQueryContext cosmosQueryContext = this.cosmosQueryContext;

                foreach (QueryPageDiagnostics queryPage in responseCore.Diagnostics)
                {
                    diagnostics.Summary.Append(queryPage.DiagnosticsContext.Summary);
                    diagnostics.AddDiagnosticsInternal(queryPage);
                }

                QueryResponse queryResponse;
                if (responseCore.IsSuccess)
                {
                    queryResponse = QueryResponse.CreateSuccess(
                        result: responseCore.CosmosElements,
                        count: responseCore.CosmosElements.Count,
                        responseLengthBytes: responseCore.ResponseLengthBytes,
                        diagnostics: diagnostics,
                        serializationOptions: this.cosmosSerializationFormatOptions,
                        responseHeaders: new CosmosQueryResponseMessageHeaders(
                            responseCore.ContinuationToken,
                            responseCore.DisallowContinuationTokenMessage,
                            cosmosQueryContext.ResourceTypeEnum,
                            cosmosQueryContext.ContainerResourceId)
                    {
                        RequestCharge = responseCore.RequestCharge,
                        ActivityId    = responseCore.ActivityId,
                        SubStatusCode = responseCore.SubStatusCode ?? Documents.SubStatusCodes.Unknown
                    });
                }
                else
                {
                    queryResponse = QueryResponse.CreateFailure(
                        statusCode: responseCore.StatusCode,
                        error: null,
                        errorMessage: responseCore.ErrorMessage,
                        requestMessage: null,
                        diagnostics: diagnostics,
                        responseHeaders: new CosmosQueryResponseMessageHeaders(
                            responseCore.ContinuationToken,
                            responseCore.DisallowContinuationTokenMessage,
                            cosmosQueryContext.ResourceTypeEnum,
                            cosmosQueryContext.ContainerResourceId)
                    {
                        RequestCharge = responseCore.RequestCharge,
                        ActivityId    = responseCore.ActivityId,
                        SubStatusCode = responseCore.SubStatusCode ?? Documents.SubStatusCodes.Unknown
                    });
                }

                return(queryResponse);
            }
        }
Beispiel #4
0
        public void ValidateDiagnosticsAppendContext()
        {
            CosmosDiagnosticsContext cosmosDiagnostics = CosmosDiagnosticsContext.Create();

            // Test all the different operations on diagnostics context
            using (cosmosDiagnostics.CreateScope("ValidateScope"))
            {
                Thread.Sleep(TimeSpan.FromSeconds(2));
            }

            cosmosDiagnostics.SetSdkUserAgent("MyCustomUserAgentString");

            CosmosDiagnosticsContext cosmosDiagnostics2 = CosmosDiagnosticsContext.Create();

            using (cosmosDiagnostics.CreateScope("CosmosDiagnostics2Scope"))
            {
                Thread.Sleep(TimeSpan.FromMilliseconds(100));
            }

            cosmosDiagnostics2.AddDiagnosticsInternal(cosmosDiagnostics);

            string diagnostics = cosmosDiagnostics2.ToString();

            Assert.IsTrue(diagnostics.Contains("MyCustomUserAgentString"));
            Assert.IsTrue(diagnostics.Contains("ValidateScope"));
            Assert.IsTrue(diagnostics.Contains("CosmosDiagnostics2Scope"));
        }
        private (Func <string, Task <TryCatch <IDocumentQueryExecutionComponent> > >, QueryResponseCore) SetupBaseContextToVerifyFailureScenario()
        {
            CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create();

            diagnosticsContext.AddDiagnosticsInternal(new PointOperationStatistics(
                                                          Guid.NewGuid().ToString(),
                                                          System.Net.HttpStatusCode.Unauthorized,
                                                          subStatusCode: SubStatusCodes.PartitionKeyMismatch,
                                                          requestCharge: 4,
                                                          errorMessage: null,
                                                          method: HttpMethod.Post,
                                                          requestUri: new Uri("http://localhost.com"),
                                                          requestSessionToken: null,
                                                          responseSessionToken: null,
                                                          clientSideRequestStatistics: null));
            IReadOnlyCollection <QueryPageDiagnostics> diagnostics = new List <QueryPageDiagnostics>()
            {
                new QueryPageDiagnostics(
                    "0",
                    "SomeQueryMetricText",
                    "SomeIndexUtilText",
                    diagnosticsContext,
                    new SchedulingStopwatch())
            };

            QueryResponseCore failure = QueryResponseCore.CreateFailure(
                System.Net.HttpStatusCode.Unauthorized,
                SubStatusCodes.PartitionKeyMismatch,
                new CosmosException(
                    statusCodes: HttpStatusCode.Unauthorized,
                    message: "Random error message",
                    subStatusCode: default,
        public static (QueryResponseCore queryResponse, IList <ToDoItem> items) Create(
            string itemIdPrefix,
            string continuationToken,
            string collectionRid,
            int itemCount = 50)
        {
            // Use -1 to represent a split response
            if (itemCount == QueryResponseMessageFactory.SPLIT)
            {
                return(CreateSplitResponse(collectionRid), new List <ToDoItem>().AsReadOnly());
            }

            IList <ToDoItem> items               = ToDoItem.CreateItems(itemCount, itemIdPrefix);
            MemoryStream     memoryStream        = (MemoryStream)MockCosmosUtil.Serializer.ToStream <IList <ToDoItem> >(items);
            long             responseLengthBytes = memoryStream.Length;

            IJsonNavigator     jsonNavigator     = JsonNavigator.Create(memoryStream.ToArray());
            IJsonNavigatorNode jsonNavigatorNode = jsonNavigator.GetRootNode();
            CosmosArray        cosmosArray       = CosmosArray.Create(jsonNavigator, jsonNavigatorNode);

            double requestCharge = 42;
            string activityId    = Guid.NewGuid().ToString();
            CosmosDiagnosticsContext diagnosticsContext = new CosmosDiagnosticsContext();

            diagnosticsContext.AddDiagnosticsInternal(new PointOperationStatistics(
                                                          activityId: Guid.NewGuid().ToString(),
                                                          statusCode: HttpStatusCode.OK,
                                                          subStatusCode: SubStatusCodes.Unknown,
                                                          requestCharge: requestCharge,
                                                          errorMessage: null,
                                                          method: HttpMethod.Post,
                                                          requestUri: new Uri("http://localhost.com"),
                                                          requestSessionToken: null,
                                                          responseSessionToken: null,
                                                          clientSideRequestStatistics: null));
            IReadOnlyCollection <QueryPageDiagnostics> diagnostics = new List <QueryPageDiagnostics>()
            {
                new QueryPageDiagnostics("0",
                                         "SomeQueryMetricText",
                                         "SomeIndexUtilText",
                                         diagnosticsContext,
                                         new SchedulingStopwatch())
            };

            QueryResponseCore message = QueryResponseCore.CreateSuccess(
                result: cosmosArray,
                continuationToken: continuationToken,
                disallowContinuationTokenMessage: null,
                activityId: activityId,
                requestCharge: requestCharge,
                diagnostics: diagnostics,
                responseLengthBytes: responseLengthBytes);

            return(message, items);
        }
        /// <summary>
        /// Get the next set of results from the cosmos service
        /// </summary>
        /// <param name="cancellationToken">(Optional) <see cref="CancellationToken"/> representing request cancellation.</param>
        /// <returns>A query response from cosmos service</returns>
        public override async Task <ResponseMessage> ReadNextAsync(CancellationToken cancellationToken = default)
        {
            CosmosDiagnosticsContext diagnostics = CosmosDiagnosticsContext.Create(this.changeFeedOptions);

            using (diagnostics.GetOverallScope())
            {
                diagnostics.AddDiagnosticsInternal(
                    new FeedRangeStatistics(
                        this.changeFeedStartFrom.Accept(ChangeFeedRangeExtractor.Singleton)));
                if (!this.lazyContainerRid.ValueInitialized)
                {
                    using (diagnostics.CreateScope("InitializeContainerResourceId"))
                    {
                        TryCatch <string> tryInitializeContainerRId = await this.lazyContainerRid.GetValueAsync(cancellationToken);

                        if (!tryInitializeContainerRId.Succeeded)
                        {
                            if (!(tryInitializeContainerRId.Exception.InnerException is CosmosException cosmosException))
                            {
                                throw new InvalidOperationException("Failed to convert to CosmosException.");
                            }

                            return(cosmosException.ToCosmosResponseMessage(
                                       new RequestMessage(
                                           method: null,
                                           requestUriString: null,
                                           diagnosticsContext: diagnostics)));
                        }
                    }

                    using (diagnostics.CreateScope("InitializeContinuation"))
                    {
                        await this.InitializeFeedContinuationAsync(cancellationToken);
                    }

                    TryCatch validateContainer = this.FeedRangeContinuation.ValidateContainer(this.lazyContainerRid.Result.Result);
                    if (!validateContainer.Succeeded)
                    {
                        return(CosmosExceptionFactory
                               .CreateBadRequestException(
                                   message: validateContainer.Exception.InnerException.Message,
                                   innerException: validateContainer.Exception.InnerException,
                                   diagnosticsContext: diagnostics)
                               .ToCosmosResponseMessage(
                                   new RequestMessage(
                                       method: null,
                                       requestUriString: null,
                                       diagnosticsContext: diagnostics)));
                    }
                }

                return(await this.ReadNextInternalAsync(diagnostics, cancellationToken));
            }
        }
        public void TestCosmosDiagnosticScope()
        {
            (BackendMetricsExtractor.ParseFailureReason parseFailureReason, BackendMetrics extractedBackendMetrics)notFoundResult = MockCosmosDiagnosticScope.Accept(BackendMetricsExtractor.Singleton);
            Assert.AreEqual(BackendMetricsExtractor.ParseFailureReason.MetricsNotFound, notFoundResult.parseFailureReason);

            CosmosDiagnosticsContext contextWithQueryMetrics = CosmosDiagnosticsContext.Create();

            contextWithQueryMetrics.AddDiagnosticsInternal(MockQueryPageDiagnostics);
            (BackendMetricsExtractor.ParseFailureReason parseFailureReason, BackendMetrics extractedBackendMetrics)foundResult = contextWithQueryMetrics.Accept(BackendMetricsExtractor.Singleton);
            Assert.AreEqual(BackendMetricsExtractor.ParseFailureReason.None, foundResult.parseFailureReason);
            Assert.AreEqual(BackendMetricsTests.MockBackendMetrics.IndexLookupTime, foundResult.extractedBackendMetrics.IndexLookupTime);
        }
        private async Task <FeedResponse <ChangeFeedProcessorState> > ReadNextInternalAsync(
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (this.lazyLeaseDocuments.Result.Result.Count == 0)
            {
                // Lease store is empty
                this.hasMoreResults = false;
                return(new ChangeFeedEstimatorEmptyFeedResponse(diagnosticsContext.Diagnostics));
            }

            IEnumerable <DocumentServiceLease> leasesForCurrentPage = this.lazyLeaseDocuments.Result.Result.Skip(this.currentPage * this.pageSize).Take(this.pageSize);
            IEnumerable <Task <List <(ChangeFeedProcessorState, double)> > > tasks = Partitioner.Create(leasesForCurrentPage)
                                                                                     .GetPartitions(this.pageSize)
                                                                                     .Select(partition => Task.Run(async() =>
            {
                List <(ChangeFeedProcessorState, double)> partialResults = new List <(ChangeFeedProcessorState, double)>();
                using (partition)
                {
                    while (!cancellationToken.IsCancellationRequested && partition.MoveNext())
                    {
                        DocumentServiceLease item = partition.Current;
                        if (item?.CurrentLeaseToken == null)
                        {
                            continue;
                        }
                        (long estimation, ResponseMessage responseMessage) = await this.GetRemainingWorkAsync(item, cancellationToken).ConfigureAwait(false);

                        // Attach each diagnostics
                        diagnosticsContext.AddDiagnosticsInternal(responseMessage.DiagnosticsContext);
                        partialResults.Add((new ChangeFeedProcessorState(item.CurrentLeaseToken, estimation, item.Owner), responseMessage.Headers.RequestCharge));
                    }
                }

                return(partialResults);
            })).ToArray();

            IEnumerable <List <(ChangeFeedProcessorState, double)> > partitionResults = await Task.WhenAll(tasks);

            IEnumerable <(ChangeFeedProcessorState, double)> unifiedResults = partitionResults.SelectMany(r => r);

            ReadOnlyCollection <ChangeFeedProcessorState> estimations = unifiedResults.Select(r => r.Item1).ToList().AsReadOnly();

            double totalRUCost = unifiedResults.Sum(r => r.Item2);

            this.hasMoreResults = ++this.currentPage != this.maxPage;

            return(new ChangeFeedEstimatorFeedResponse(diagnosticsContext.Diagnostics, estimations, totalRUCost));
        }
        private async Task <FeedResponse <ChangeFeedProcessorState> > ReadNextInternalAsync(
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (this.lazyLeaseDocuments.Result.Result.Count == 0)
            {
                // Lease store is empty
                this.hasMoreResults = false;
                return(new ChangeFeedEstimatorEmptyFeedResponse(diagnosticsContext.Diagnostics));
            }

            IEnumerable <DocumentServiceLease> leasesForCurrentPage = this.lazyLeaseDocuments.Result.Result.Skip(this.currentPage * this.pageSize).Take(this.pageSize);
            IEnumerable <Task <(ChangeFeedProcessorState, ResponseMessage)> > tasks = leasesForCurrentPage
                                                                                      .Select(lease => Task.Run(async() =>
            {
                (long estimation, ResponseMessage responseMessage) = await this.GetRemainingWorkAsync(lease, cancellationToken);

                return(new ChangeFeedProcessorState(lease.CurrentLeaseToken, estimation, lease.Owner), responseMessage);
            })).ToArray();

            IEnumerable <(ChangeFeedProcessorState, ResponseMessage)> results = await Task.WhenAll(tasks);

            List <ChangeFeedProcessorState> estimations = new List <ChangeFeedProcessorState>();
            double totalRUCost = 0;

            foreach ((ChangeFeedProcessorState, ResponseMessage)result in results)
            {
                using (result.Item2)
                {
                    totalRUCost += result.Item2.Headers.RequestCharge;
                    diagnosticsContext.AddDiagnosticsInternal(result.Item2.DiagnosticsContext);
                }

                estimations.Add(result.Item1);
            }

            this.hasMoreResults = ++this.currentPage != this.maxPage;

            return(new ChangeFeedEstimatorFeedResponse(diagnosticsContext.Diagnostics, estimations.AsReadOnly(), totalRUCost));
        }
        private (Func <string, Task <TryCatch <IDocumentQueryExecutionComponent> > >, QueryResponseCore) SetupBaseContextToVerifyFailureScenario()
        {
            CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create();

            diagnosticsContext.AddDiagnosticsInternal(new PointOperationStatistics(
                                                          Guid.NewGuid().ToString(),
                                                          System.Net.HttpStatusCode.Unauthorized,
                                                          subStatusCode: SubStatusCodes.PartitionKeyMismatch,
                                                          requestCharge: 4,
                                                          errorMessage: null,
                                                          method: HttpMethod.Post,
                                                          requestUri: new Uri("http://localhost.com"),
                                                          requestSessionToken: null,
                                                          responseSessionToken: null,
                                                          clientSideRequestStatistics: null));
            IReadOnlyCollection <QueryPageDiagnostics> diagnostics = new List <QueryPageDiagnostics>()
            {
                new QueryPageDiagnostics(
                    "0",
                    "SomeQueryMetricText",
                    "SomeIndexUtilText",
                    diagnosticsContext,
                    new SchedulingStopwatch())
            };

            QueryResponseCore failure = QueryResponseCore.CreateFailure(
                System.Net.HttpStatusCode.Unauthorized,
                SubStatusCodes.PartitionKeyMismatch,
                "Random error message",
                42.89,
                "TestActivityId",
                diagnostics);

            Mock <IDocumentQueryExecutionComponent> baseContext = new Mock <IDocumentQueryExecutionComponent>();

            baseContext.Setup(x => x.DrainAsync(It.IsAny <int>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult <QueryResponseCore>(failure));
            Task <TryCatch <IDocumentQueryExecutionComponent> > callBack(string x) => Task.FromResult <TryCatch <IDocumentQueryExecutionComponent> >(TryCatch <IDocumentQueryExecutionComponent> .FromResult(baseContext.Object));

            return(callBack, failure);
        }
        public void ToResponseMessage_MapsProperties()
        {
            PointOperationStatistics pointOperationStatistics = new PointOperationStatistics(
                activityId: Guid.NewGuid().ToString(),
                statusCode: HttpStatusCode.OK,
                subStatusCode: SubStatusCodes.Unknown,
                requestCharge: 0,
                errorMessage: string.Empty,
                method: HttpMethod.Get,
                requestUri: new Uri("http://localhost"),
                requestSessionToken: null,
                responseSessionToken: null,
                clientSideRequestStatistics: new CosmosClientSideRequestStatistics());
            CosmosDiagnosticsContext scope = CosmosDiagnosticsContext.Create();

            scope.AddDiagnosticsInternal(pointOperationStatistics);

            TransactionalBatchOperationResult result = new TransactionalBatchOperationResult(HttpStatusCode.OK)
            {
                ResourceStream     = new MemoryStream(new byte[] { 0x41, 0x42 }, index: 0, count: 2, writable: false, publiclyVisible: true),
                ETag               = "1234",
                SubStatusCode      = SubStatusCodes.CompletingSplit,
                RetryAfter         = TimeSpan.FromSeconds(10),
                RequestCharge      = 4.3,
                DiagnosticsContext = scope
            };

            ResponseMessage response = result.ToResponseMessage();

            Assert.AreEqual(result.ResourceStream, response.Content);
            Assert.AreEqual(result.SubStatusCode, response.Headers.SubStatusCode);
            Assert.AreEqual(result.RetryAfter, response.Headers.RetryAfter);
            Assert.AreEqual(result.StatusCode, response.StatusCode);
            Assert.AreEqual(result.RequestCharge, response.Headers.RequestCharge);
            string diagnostics = response.Diagnostics.ToString();

            Assert.IsNotNull(diagnostics);
            Assert.IsTrue(diagnostics.Contains(pointOperationStatistics.ActivityId));
        }
        internal async Task <Response <T> > AggregateResultAsync(CancellationToken cancellationToken = default)
        {
            List <T> result = new List <T>();
            CosmosDiagnosticsContext diagnosticsContext = null;
            Headers          headers           = new Headers();
            FeedIterator <T> localFeedIterator = this.CreateFeedIterator(false);

            while (localFeedIterator.HasMoreResults)
            {
                FeedResponse <T> response = await localFeedIterator.ReadNextAsync();

                headers.RequestCharge += response.RequestCharge;

                // If the first page has a diagnostic context use that. Else create a new one and add the diagnostic to it.
                if (response.Diagnostics is CosmosDiagnosticsContext responseDiagnosticContext)
                {
                    if (diagnosticsContext == null)
                    {
                        diagnosticsContext = responseDiagnosticContext;
                    }
                    else
                    {
                        diagnosticsContext.AddDiagnosticsInternal(responseDiagnosticContext);
                    }
                }
                else
                {
                    throw new ArgumentException($"Invalid diagnostic object {response.Diagnostics.GetType().FullName}");
                }

                result.AddRange(response);
            }

            return(new ItemResponse <T>(
                       System.Net.HttpStatusCode.OK,
                       headers,
                       result.FirstOrDefault(),
                       diagnosticsContext));
        }
        public static QueryResponseCore CreateFailureResponse(
            HttpStatusCode httpStatusCode,
            SubStatusCodes subStatusCodes,
            string errorMessage)
        {
            string acitivityId = Guid.NewGuid().ToString();
            CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create();

            diagnosticsContext.AddDiagnosticsInternal(new PointOperationStatistics(
                                                          acitivityId,
                                                          System.Net.HttpStatusCode.Gone,
                                                          subStatusCode: SubStatusCodes.PartitionKeyRangeGone,
                                                          requestCharge: 10.4,
                                                          errorMessage: null,
                                                          method: HttpMethod.Post,
                                                          requestUri: new Uri("http://localhost.com"),
                                                          requestSessionToken: null,
                                                          responseSessionToken: null,
                                                          clientSideRequestStatistics: null));
            IReadOnlyCollection <QueryPageDiagnostics> diagnostics = new List <QueryPageDiagnostics>()
            {
                new QueryPageDiagnostics("0",
                                         "SomeQueryMetricText",
                                         "SomeIndexUtilText",
                                         diagnosticsContext,
                                         new SchedulingStopwatch())
            };

            QueryResponseCore splitResponse = QueryResponseCore.CreateFailure(
                statusCode: httpStatusCode,
                subStatusCodes: subStatusCodes,
                cosmosException: CosmosExceptionFactory.Create(
                    statusCode: httpStatusCode,
                    subStatusCode: (int)subStatusCodes,
                    message: errorMessage,
                    stackTrace: new System.Diagnostics.StackTrace().ToString(),
                    activityId: acitivityId,
                    requestCharge: 10.4,
                    retryAfter: default,
        private void AddDiagnosticsInBackgroundLoop(
            int count,
            CosmosDiagnosticsContext cosmosDiagnostics,
            ConcurrentStack <Exception> concurrentStack)
        {
            CosmosDiagnosticsContext cosmosDiagnostics2 = new CosmosDiagnosticsContextCore(
                nameof(ValidateDiagnosticsAppendContext),
                "MyCustomUserAgentString");
            Random random = new Random();

            cosmosDiagnostics2.GetOverallScope().Dispose();

            for (int i = 0; i < count; i++)
            {
                try
                {
                    cosmosDiagnostics.AddDiagnosticsInternal(cosmosDiagnostics2);
                }
                catch (Exception e)
                {
                    concurrentStack.Append(e);
                }
            }
        }
Beispiel #16
0
        public void ValidateDiagnosticsContext()
        {
            CosmosDiagnosticsContext cosmosDiagnostics = CosmosDiagnosticsContext.Create();
            string diagnostics = cosmosDiagnostics.ToString();

            //Test the default user agent string
            JObject jObject = JObject.Parse(diagnostics);
            JToken  summary = jObject["Summary"];

            Assert.IsTrue(summary["UserAgent"].ToString().Contains("cosmos-netstandard-sdk"), "Diagnostics should have user agent string");
            Assert.AreEqual("[]", jObject["Context"].ToString());

            // Test all the different operations on diagnostics context
            using (cosmosDiagnostics.CreateOverallScope("OverallScope"))
            {
                Thread.Sleep(TimeSpan.FromSeconds(1));
                using (cosmosDiagnostics.CreateScope("ValidateScope"))
                {
                    Thread.Sleep(TimeSpan.FromSeconds(1));
                    cosmosDiagnostics.AddDiagnosticsInternal(new PointOperationStatistics(
                                                                 new Guid("692ab2f2-41ba-486b-aad7-8c7c6c52379f").ToString(),
                                                                 (HttpStatusCode)429,
                                                                 Documents.SubStatusCodes.Unknown,
                                                                 42,
                                                                 null,
                                                                 HttpMethod.Get,
                                                                 new Uri("http://MockUri.com"),
                                                                 null,
                                                                 null,
                                                                 null));
                }

                using (cosmosDiagnostics.CreateScope("SuccessScope"))
                {
                    cosmosDiagnostics.AddDiagnosticsInternal(new PointOperationStatistics(
                                                                 new Guid("de09baab-71a4-4897-a163-470711c93ed3").ToString(),
                                                                 HttpStatusCode.OK,
                                                                 Documents.SubStatusCodes.Unknown,
                                                                 42,
                                                                 null,
                                                                 HttpMethod.Get,
                                                                 new Uri("http://MockUri.com"),
                                                                 null,
                                                                 null,
                                                                 null));
                }
            }

            cosmosDiagnostics.SetSdkUserAgent("MyCustomUserAgentString");

            string result = cosmosDiagnostics.ToString();

            string regex = @"\{""Summary"":\{""StartUtc"":"".+Z"",""ElapsedTime"":""00:00:.+"",""UserAgent"":""MyCustomUserAgentString"",""TotalRequestCount"":2,""FailedRequestCount"":1\},""Context"":\[\{""Id"":""OverallScope"",""ElapsedTime"":""00:00:0.+""\},\{""Id"":""ValidateScope"",""ElapsedTime"":""00:00:0.+""\},\{""Id"":""PointOperationStatistics"",""ActivityId"":""692ab2f2-41ba-486b-aad7-8c7c6c52379f"",""StatusCode"":429,""SubStatusCode"":0,""RequestCharge"":42.0,""RequestUri"":""http://MockUri.com"",""RequestSessionToken"":null,""ResponseSessionToken"":null\},\{""Id"":""SuccessScope"",""ElapsedTime"":""00:00:.+""\},\{""Id"":""PointOperationStatistics"",""ActivityId"":""de09baab-71a4-4897-a163-470711c93ed3"",""StatusCode"":200,""SubStatusCode"":0,""RequestCharge"":42.0,""RequestUri"":""http://MockUri.com"",""RequestSessionToken"":null,""ResponseSessionToken"":null\}\]\}";

            Assert.IsTrue(Regex.IsMatch(result, regex), result);

            JToken   jToken = JToken.Parse(result);
            TimeSpan total  = jToken["Summary"]["ElapsedTime"].ToObject <TimeSpan>();

            Assert.IsTrue(total > TimeSpan.FromSeconds(2));
            TimeSpan overalScope = jToken["Context"][0]["ElapsedTime"].ToObject <TimeSpan>();

            Assert.IsTrue(total == overalScope);
            TimeSpan innerScope = jToken["Context"][1]["ElapsedTime"].ToObject <TimeSpan>();

            Assert.IsTrue(innerScope > TimeSpan.FromSeconds(1));
        }
Beispiel #17
0
        public async Task TestItemProducerTreeWithFailure()
        {
            int callBackCount = 0;
            Mock <CosmosQueryContext> mockQueryContext = new Mock <CosmosQueryContext>();

            SqlQuerySpec      sqlQuerySpec      = new SqlQuerySpec("Select * from t");
            PartitionKeyRange partitionKeyRange = new PartitionKeyRange {
                Id = "0", MinInclusive = "A", MaxExclusive = "B"
            };

            void produceAsyncCompleteCallback(
                ItemProducerTree producer,
                int itemsBuffered,
                double resourceUnitUsage,
                IReadOnlyCollection <QueryPageDiagnostics> queryPageDiagnostics,
                long responseLengthBytes,
                CancellationToken token)
            {
                callBackCount++;
            }

            Mock <IComparer <ItemProducerTree> >      comparer = new Mock <IComparer <ItemProducerTree> >();
            Mock <IEqualityComparer <CosmosElement> > cosmosElementComparer = new Mock <IEqualityComparer <CosmosElement> >();
            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

            IReadOnlyList <CosmosElement> cosmosElements = new List <CosmosElement>()
            {
                new Mock <CosmosElement>(CosmosElementType.Object).Object
            };

            CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create();

            diagnosticsContext.AddDiagnosticsInternal(new PointOperationStatistics(
                                                          Guid.NewGuid().ToString(),
                                                          System.Net.HttpStatusCode.OK,
                                                          subStatusCode: SubStatusCodes.Unknown,
                                                          requestCharge: 42,
                                                          errorMessage: null,
                                                          method: HttpMethod.Post,
                                                          requestUri: new Uri("http://localhost.com"),
                                                          requestSessionToken: null,
                                                          responseSessionToken: null,
                                                          clientSideRequestStatistics: null));

            QueryPageDiagnostics diagnostics = new QueryPageDiagnostics(
                partitionKeyRangeId: "0",
                queryMetricText: "SomeRandomQueryMetricText",
                indexUtilizationText: null,
                diagnosticsContext: diagnosticsContext,
                schedulingStopwatch: new SchedulingStopwatch());
            IReadOnlyCollection <QueryPageDiagnostics> pageDiagnostics = new List <QueryPageDiagnostics>()
            {
                diagnostics
            };

            mockQueryContext.Setup(x => x.ContainerResourceId).Returns("MockCollectionRid");
            mockQueryContext.Setup(x => x.ExecuteQueryAsync(
                                       sqlQuerySpec,
                                       It.IsAny <string>(),
                                       It.IsAny <PartitionKeyRangeIdentity>(),
                                       It.IsAny <bool>(),
                                       It.IsAny <int>(),
                                       It.IsAny <SchedulingStopwatch>(),
                                       cancellationTokenSource.Token)).Returns(
                Task.FromResult(QueryResponseCore.CreateSuccess(
                                    result: cosmosElements,
                                    requestCharge: 42,
                                    activityId: "AA470D71-6DEF-4D61-9A08-272D8C9ABCFE",
                                    diagnostics: pageDiagnostics,
                                    responseLengthBytes: 500,
                                    disallowContinuationTokenMessage: null,
                                    continuationToken: "TestToken")));

            ItemProducerTree itemProducerTree = new ItemProducerTree(
                queryContext: mockQueryContext.Object,
                querySpecForInit: sqlQuerySpec,
                partitionKeyRange: partitionKeyRange,
                produceAsyncCompleteCallback: produceAsyncCompleteCallback,
                itemProducerTreeComparer: comparer.Object,
                equalityComparer: cosmosElementComparer.Object,
                testSettings: new TestInjections(simulate429s: false, simulateEmptyPages: false),
                deferFirstPage: false,
                collectionRid: "collectionRid",
                initialContinuationToken: null,
                initialPageSize: 50);

            // Buffer to success responses
            await itemProducerTree.BufferMoreDocumentsAsync(cancellationTokenSource.Token);

            await itemProducerTree.BufferMoreDocumentsAsync(cancellationTokenSource.Token);

            CosmosDiagnosticsContext diagnosticsContextInternalServerError = CosmosDiagnosticsContext.Create();

            diagnosticsContextInternalServerError.AddDiagnosticsInternal(new PointOperationStatistics(
                                                                             Guid.NewGuid().ToString(),
                                                                             System.Net.HttpStatusCode.InternalServerError,
                                                                             subStatusCode: SubStatusCodes.Unknown,
                                                                             requestCharge: 10.2,
                                                                             errorMessage: "Error message",
                                                                             method: HttpMethod.Post,
                                                                             requestUri: new Uri("http://localhost.com"),
                                                                             requestSessionToken: null,
                                                                             responseSessionToken: null,
                                                                             clientSideRequestStatistics: null));

            diagnostics = new QueryPageDiagnostics(
                partitionKeyRangeId: "0",
                queryMetricText: null,
                indexUtilizationText: null,
                diagnosticsContext: diagnosticsContextInternalServerError,
                schedulingStopwatch: new SchedulingStopwatch());
            pageDiagnostics = new List <QueryPageDiagnostics>()
            {
                diagnostics
            };

            // Buffer a failure
            mockQueryContext.Setup(x => x.ExecuteQueryAsync(
                                       sqlQuerySpec,
                                       It.IsAny <string>(),
                                       It.IsAny <PartitionKeyRangeIdentity>(),
                                       It.IsAny <bool>(),
                                       It.IsAny <int>(),
                                       It.IsAny <SchedulingStopwatch>(),
                                       cancellationTokenSource.Token)).Returns(
                Task.FromResult(QueryResponseCore.CreateFailure(
                                    statusCode: HttpStatusCode.InternalServerError,
                                    subStatusCodes: null,
                                    cosmosException: CosmosExceptionFactory.CreateInternalServerErrorException(
                                        "Error message"),
                                    requestCharge: 10.2,
                                    activityId: Guid.NewGuid().ToString(),
                                    diagnostics: pageDiagnostics)));

            await itemProducerTree.BufferMoreDocumentsAsync(cancellationTokenSource.Token);

            // First item should be a success
            {
                (bool movedToNextPage, QueryResponseCore? failureResponse) = await itemProducerTree.TryMoveNextPageAsync(cancellationTokenSource.Token);

                Assert.IsTrue(movedToNextPage);
                Assert.IsNull(failureResponse);
                Assert.IsTrue(itemProducerTree.TryMoveNextDocumentWithinPage());
                Assert.IsFalse(itemProducerTree.TryMoveNextDocumentWithinPage());
                Assert.IsTrue(itemProducerTree.HasMoreResults);
            }

            // Second item should be a success
            {
                (bool movedToNextPage, QueryResponseCore? failureResponse) = await itemProducerTree.TryMoveNextPageAsync(cancellationTokenSource.Token);

                Assert.IsTrue(movedToNextPage);
                Assert.IsNull(failureResponse);
                Assert.IsTrue(itemProducerTree.TryMoveNextDocumentWithinPage());
                Assert.IsFalse(itemProducerTree.TryMoveNextDocumentWithinPage());
                Assert.IsTrue(itemProducerTree.HasMoreResults);
            }

            // Third item should be a failure
            {
                (bool movedToNextPage, QueryResponseCore? failureResponse) = await itemProducerTree.TryMoveNextPageAsync(cancellationTokenSource.Token);

                Assert.IsFalse(movedToNextPage);
                Assert.IsNotNull(failureResponse);
                Assert.IsFalse(itemProducerTree.HasMoreResults);
            }

            // Try to buffer after failure. It should return the previous cached failure and not try to buffer again.
            mockQueryContext.Setup(x => x.ExecuteQueryAsync(
                                       sqlQuerySpec,
                                       It.IsAny <string>(),
                                       It.IsAny <PartitionKeyRangeIdentity>(),
                                       It.IsAny <bool>(),
                                       It.IsAny <int>(),
                                       It.IsAny <SchedulingStopwatch>(),
                                       cancellationTokenSource.Token)).
            Throws(new Exception("Previous buffer failed. Operation should return original failure and not try again"));

            await itemProducerTree.BufferMoreDocumentsAsync(cancellationTokenSource.Token);

            Assert.IsFalse(itemProducerTree.HasMoreResults);
        }