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)); } }
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); }
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);
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); }