Exemplo n.º 1
0
        private static QueryResponseCore GetCosmosElementResponse(
            Guid clientQueryCorrelationId,
            QueryRequestOptions requestOptions,
            ResourceType resourceType,
            ResponseMessage cosmosResponseMessage,
            PartitionKeyRangeIdentity partitionKeyRangeIdentity,
            Action <QueryPageDiagnostics> queryPageDiagnostics)
        {
            using (cosmosResponseMessage)
            {
                QueryPageDiagnostics queryPage = new QueryPageDiagnostics(
                    clientQueryCorrelationId: clientQueryCorrelationId,
                    partitionKeyRangeId: partitionKeyRangeIdentity.PartitionKeyRangeId,
                    queryMetricText: cosmosResponseMessage.Headers.QueryMetricsText,
                    indexUtilizationText: cosmosResponseMessage.Headers[HttpConstants.HttpHeaders.IndexUtilization],
                    diagnosticsContext: cosmosResponseMessage.DiagnosticsContext);
                queryPageDiagnostics(queryPage);

                if (!cosmosResponseMessage.IsSuccessStatusCode)
                {
                    return(QueryResponseCore.CreateFailure(
                               statusCode: cosmosResponseMessage.StatusCode,
                               subStatusCodes: cosmosResponseMessage.Headers.SubStatusCode,
                               cosmosException: cosmosResponseMessage.CosmosException,
                               requestCharge: cosmosResponseMessage.Headers.RequestCharge,
                               activityId: cosmosResponseMessage.Headers.ActivityId));
                }

                if (!(cosmosResponseMessage.Content is MemoryStream memoryStream))
                {
                    memoryStream = new MemoryStream();
                    cosmosResponseMessage.Content.CopyTo(memoryStream);
                }

                long        responseLengthBytes = memoryStream.Length;
                CosmosArray cosmosArray         = CosmosQueryClientCore.ParseElementsFromRestStream(
                    memoryStream,
                    resourceType,
                    requestOptions.CosmosSerializationFormatOptions);

                CosmosQueryExecutionInfo cosmosQueryExecutionInfo;
                if (cosmosResponseMessage.Headers.TryGetValue(QueryExecutionInfoHeader, out string queryExecutionInfoString))
                {
                    cosmosQueryExecutionInfo = JsonConvert.DeserializeObject <CosmosQueryExecutionInfo>(queryExecutionInfoString);
                }
                else
                {
                    cosmosQueryExecutionInfo = default;
                }

                return(QueryResponseCore.CreateSuccess(
                           result: cosmosArray,
                           requestCharge: cosmosResponseMessage.Headers.RequestCharge,
                           activityId: cosmosResponseMessage.Headers.ActivityId,
                           responseLengthBytes: responseLengthBytes,
                           disallowContinuationTokenMessage: null,
                           continuationToken: cosmosResponseMessage.Headers.ContinuationToken,
                           cosmosQueryExecutionInfo: cosmosQueryExecutionInfo));
            }
        }
Exemplo n.º 2
0
        private QueryResponseCore GetCosmosElementResponse(
            QueryRequestOptions requestOptions,
            ResourceType resourceType,
            ResponseMessage cosmosResponseMessage,
            PartitionKeyRangeIdentity partitionKeyRangeIdentity,
            SchedulingStopwatch schedulingStopwatch)
        {
            using (cosmosResponseMessage)
            {
                QueryPageDiagnostics diagnostics = new QueryPageDiagnostics(
                    partitionKeyRangeId: partitionKeyRangeIdentity.PartitionKeyRangeId,
                    queryMetricText: cosmosResponseMessage.Headers.QueryMetricsText,
                    indexUtilizationText: cosmosResponseMessage.Headers[HttpConstants.HttpHeaders.IndexUtilization],
                    requestDiagnostics: cosmosResponseMessage.Diagnostics,
                    schedulingStopwatch: schedulingStopwatch);

                IReadOnlyCollection <QueryPageDiagnostics> pageDiagnostics = new List <QueryPageDiagnostics>()
                {
                    diagnostics
                };
                if (!cosmosResponseMessage.IsSuccessStatusCode)
                {
                    return(QueryResponseCore.CreateFailure(
                               statusCode: cosmosResponseMessage.StatusCode,
                               subStatusCodes: cosmosResponseMessage.Headers.SubStatusCode,
                               errorMessage: cosmosResponseMessage.ErrorMessage,
                               requestCharge: cosmosResponseMessage.Headers.RequestCharge,
                               activityId: cosmosResponseMessage.Headers.ActivityId,
                               diagnostics: pageDiagnostics));
                }

                MemoryStream memoryStream = cosmosResponseMessage.Content as MemoryStream;
                if (memoryStream == null)
                {
                    memoryStream = new MemoryStream();
                    cosmosResponseMessage.Content.CopyTo(memoryStream);
                }

                long        responseLengthBytes = memoryStream.Length;
                CosmosArray cosmosArray         = CosmosElementSerializer.ToCosmosElements(
                    memoryStream,
                    resourceType,
                    requestOptions.CosmosSerializationFormatOptions);

                int itemCount = cosmosArray.Count;
                return(QueryResponseCore.CreateSuccess(
                           result: cosmosArray,
                           requestCharge: cosmosResponseMessage.Headers.RequestCharge,
                           activityId: cosmosResponseMessage.Headers.ActivityId,
                           diagnostics: pageDiagnostics,
                           responseLengthBytes: cosmosResponseMessage.Headers.ContentLengthAsLong,
                           disallowContinuationTokenMessage: null,
                           continuationToken: cosmosResponseMessage.Headers.ContinuationToken));
            }
        }
        internal override void AddDiagnosticsInternal(QueryPageDiagnostics queryPageDiagnostics)
        {
            if (queryPageDiagnostics == null)
            {
                throw new ArgumentNullException(nameof(queryPageDiagnostics));
            }

            if (queryPageDiagnostics.DiagnosticsContext != null)
            {
                this.AddSummaryInfo(queryPageDiagnostics.DiagnosticsContext);
            }

            this.ContextList.Add(queryPageDiagnostics);
        }
        private QueryResponseCore GetCosmosElementResponse(
            Guid clientQueryCorrelationId,
            QueryRequestOptions requestOptions,
            ResourceType resourceType,
            ResponseMessage cosmosResponseMessage,
            PartitionKeyRangeIdentity partitionKeyRangeIdentity,
            Action <QueryPageDiagnostics> queryPageDiagnostics)
        {
            using (cosmosResponseMessage)
            {
                QueryPageDiagnostics queryPage = new QueryPageDiagnostics(
                    clientQueryCorrelationId: clientQueryCorrelationId,
                    partitionKeyRangeId: partitionKeyRangeIdentity.PartitionKeyRangeId,
                    queryMetricText: cosmosResponseMessage.Headers.QueryMetricsText,
                    indexUtilizationText: cosmosResponseMessage.Headers[HttpConstants.HttpHeaders.IndexUtilization],
                    diagnosticsContext: cosmosResponseMessage.DiagnosticsContext);
                queryPageDiagnostics(queryPage);

                if (!cosmosResponseMessage.IsSuccessStatusCode)
                {
                    return(QueryResponseCore.CreateFailure(
                               statusCode: cosmosResponseMessage.StatusCode,
                               subStatusCodes: cosmosResponseMessage.Headers.SubStatusCode,
                               cosmosException: cosmosResponseMessage.CosmosException,
                               requestCharge: cosmosResponseMessage.Headers.RequestCharge,
                               activityId: cosmosResponseMessage.Headers.ActivityId));
                }

                if (!(cosmosResponseMessage.Content is MemoryStream memoryStream))
                {
                    memoryStream = new MemoryStream();
                    cosmosResponseMessage.Content.CopyTo(memoryStream);
                }

                long        responseLengthBytes = memoryStream.Length;
                CosmosArray cosmosArray         = CosmosElementSerializer.ToCosmosElements(
                    memoryStream,
                    resourceType,
                    requestOptions.CosmosSerializationFormatOptions);

                int itemCount = cosmosArray.Count;
                return(QueryResponseCore.CreateSuccess(
                           result: cosmosArray,
                           requestCharge: cosmosResponseMessage.Headers.RequestCharge,
                           activityId: cosmosResponseMessage.Headers.ActivityId,
                           responseLengthBytes: responseLengthBytes,
                           disallowContinuationTokenMessage: null,
                           continuationToken: cosmosResponseMessage.Headers.ContinuationToken));
            }
        }
        private static void ValidateQueryPageDiagnostics(QueryPageDiagnostics stats)
        {
            Assert.IsNotNull(stats.PartitionKeyRangeId);
            Assert.IsNotNull(stats.DiagnosticsContext);

            PointDiagnosticValidatorHelper pointDiagnosticValidatorHelper = new PointDiagnosticValidatorHelper();

            pointDiagnosticValidatorHelper.Visit(stats.DiagnosticsContext);

            string info = stats.ToString();

            Assert.IsNotNull(info);
            JObject jObject = JObject.Parse(info.ToString());

            Assert.IsNotNull(jObject["StartUtc"].ToString());
            Assert.IsNotNull(jObject["PKRangeId"].ToString());
            Assert.IsNotNull(jObject["QueryMetric"].ToString());
            Assert.IsNotNull(jObject["Context"].ToString());
        }
 internal abstract void AddDiagnosticsInternal(QueryPageDiagnostics queryPageDiagnostics);
        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
            };

            QueryPageDiagnostics diagnostics = new QueryPageDiagnostics(
                partitionKeyRangeId: "0",
                queryMetricText: "SomeRandomQueryMetricText",
                indexUtilizationText: null,
                requestDiagnostics: 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),
                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);

            diagnostics = new QueryPageDiagnostics(
                partitionKeyRangeId: "0",
                queryMetricText: null,
                indexUtilizationText: null,
                requestDiagnostics: 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),
                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,
                                    errorMessage: "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);
        }
Exemplo n.º 8
0
        private static TryCatch <QueryPage> GetCosmosElementResponse(
            Guid clientQueryCorrelationId,
            QueryRequestOptions requestOptions,
            ResourceType resourceType,
            ResponseMessage cosmosResponseMessage,
            PartitionKeyRangeIdentity partitionKeyRangeIdentity,
            Action <QueryPageDiagnostics> queryPageDiagnostics,
            ITrace trace)
        {
            using (ITrace getCosmosElementResponse = trace.StartChild("Get Cosmos Element Response", TraceComponent.Json, Tracing.TraceLevel.Info))
            {
                using (cosmosResponseMessage)
                {
                    QueryPageDiagnostics queryPage = new QueryPageDiagnostics(
                        clientQueryCorrelationId: clientQueryCorrelationId,
                        partitionKeyRangeId: partitionKeyRangeIdentity.PartitionKeyRangeId,
                        queryMetricText: cosmosResponseMessage.Headers.QueryMetricsText,
                        indexUtilizationText: cosmosResponseMessage.Headers[HttpConstants.HttpHeaders.IndexUtilization],
                        diagnosticsContext: cosmosResponseMessage.DiagnosticsContext);
                    queryPageDiagnostics(queryPage);

                    if (
                        cosmosResponseMessage.Headers.QueryMetricsText != null &&
                        BackendMetricsParser.TryParse(cosmosResponseMessage.Headers.QueryMetricsText, out BackendMetrics backendMetrics))
                    {
                        QueryMetricsTraceDatum datum = new QueryMetricsTraceDatum(
                            new QueryMetrics(backendMetrics, IndexUtilizationInfo.Empty, ClientSideMetrics.Empty));
                        trace.AddDatum("Query Metrics", datum);
                    }

                    if (!cosmosResponseMessage.IsSuccessStatusCode)
                    {
                        CosmosException exception;
                        if (cosmosResponseMessage.CosmosException != null)
                        {
                            exception = cosmosResponseMessage.CosmosException;
                        }
                        else
                        {
                            exception = new CosmosException(
                                cosmosResponseMessage.ErrorMessage,
                                cosmosResponseMessage.StatusCode,
                                (int)cosmosResponseMessage.Headers.SubStatusCode,
                                cosmosResponseMessage.Headers.ActivityId,
                                cosmosResponseMessage.Headers.RequestCharge);
                        }

                        return(TryCatch <QueryPage> .FromException(exception));
                    }

                    if (!(cosmosResponseMessage.Content is MemoryStream memoryStream))
                    {
                        memoryStream = new MemoryStream();
                        cosmosResponseMessage.Content.CopyTo(memoryStream);
                    }

                    long        responseLengthBytes = memoryStream.Length;
                    CosmosArray documents           = CosmosQueryClientCore.ParseElementsFromRestStream(
                        memoryStream,
                        resourceType,
                        requestOptions.CosmosSerializationFormatOptions);

                    CosmosQueryExecutionInfo cosmosQueryExecutionInfo;
                    if (cosmosResponseMessage.Headers.TryGetValue(QueryExecutionInfoHeader, out string queryExecutionInfoString))
                    {
                        cosmosQueryExecutionInfo = JsonConvert.DeserializeObject <CosmosQueryExecutionInfo>(queryExecutionInfoString);
                    }
                    else
                    {
                        cosmosQueryExecutionInfo = default;
                    }

                    QueryState queryState;
                    if (cosmosResponseMessage.Headers.ContinuationToken != null)
                    {
                        queryState = new QueryState(CosmosString.Create(cosmosResponseMessage.Headers.ContinuationToken));
                    }
                    else
                    {
                        queryState = default;
                    }

                    QueryPage response = new QueryPage(
                        documents,
                        cosmosResponseMessage.Headers.RequestCharge,
                        cosmosResponseMessage.Headers.ActivityId,
                        responseLengthBytes,
                        cosmosQueryExecutionInfo,
                        disallowContinuationTokenMessage: null,
                        queryState);

                    return(TryCatch <QueryPage> .FromResult(response));
                }
            }
        }
 internal override void AddDiagnosticsInternal(QueryPageDiagnostics queryPageDiagnostics)
 {
 }
 public abstract TResult Visit(QueryPageDiagnostics queryPageDiagnostics);
Exemplo n.º 11
0
 public abstract void Visit(QueryPageDiagnostics queryPageDiagnostics);
 public override void Visit(QueryPageDiagnostics queryPageDiagnostics)
 {
 }
 public override void Visit(QueryPageDiagnostics queryPageDiagnostics)
 {
     throw new ArgumentException($"Point Operation should not have {nameof(queryPageDiagnostics)}");
 }
 public override void Visit(QueryPageDiagnostics queryPageDiagnostics)
 {
     this.isQueryPageVisited = true;
     ValidateQueryPageDiagnostics(queryPageDiagnostics);
 }