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 static QueryResponseCore CreateFromExceptionWithStackTrace(ExceptionWithStackTraceException exceptionWithStackTrace) { // Use the original stack trace from the inner exception. if (exceptionWithStackTrace.InnerException is DocumentClientException || exceptionWithStackTrace.InnerException is CosmosException) { return(QueryResponseFactory.CreateFromException(exceptionWithStackTrace.InnerException)); } QueryResponseCore queryResponseCore = QueryResponseFactory.CreateFromException(exceptionWithStackTrace.InnerException); CosmosException cosmosException = queryResponseCore.CosmosException; queryResponseCore = QueryResponseCore.CreateFailure( statusCode: queryResponseCore.StatusCode, subStatusCodes: queryResponseCore.SubStatusCode, cosmosException: CosmosExceptionFactory.Create( statusCode: cosmosException.StatusCode, message: cosmosException.Message, stackTrace: exceptionWithStackTrace.StackTrace, headers: cosmosException.Headers, trace: cosmosException.Trace, error: cosmosException.Error, innerException: cosmosException.InnerException), requestCharge: queryResponseCore.RequestCharge, activityId: queryResponseCore.ActivityId); return(queryResponseCore); }
public static QueryResponseCore CreateFailureResponse( HttpStatusCode httpStatusCode, SubStatusCodes subStatusCodes, string errorMessage) { IReadOnlyCollection <QueryPageDiagnostics> diagnostics = new List <QueryPageDiagnostics>() { new QueryPageDiagnostics("0", "SomeQueryMetricText", "SomeIndexUtilText", new PointOperationStatistics( Guid.NewGuid().ToString(), 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), new SchedulingStopwatch()) }; QueryResponseCore splitResponse = QueryResponseCore.CreateFailure( statusCode: httpStatusCode, subStatusCodes: subStatusCodes, errorMessage: errorMessage, requestCharge: 10.4, activityId: Guid.NewGuid().ToString(), diagnostics: diagnostics); return(splitResponse); }
private (Func <string, Task <IDocumentQueryExecutionComponent> >, QueryResponseCore) SetupBaseContextToVerifyFailureScenario() { IReadOnlyCollection <QueryPageDiagnostics> diagnostics = new List <QueryPageDiagnostics>() { new QueryPageDiagnostics("0", "SomeQueryMetricText", "SomeIndexUtilText", 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"), clientSideRequestStatistics: null), 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)); Func <string, Task <IDocumentQueryExecutionComponent> > callBack = x => Task.FromResult <IDocumentQueryExecutionComponent>(baseContext.Object); return(callBack, failure); }
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,
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)); } }
private static QueryResponseCore CreateFromCosmosException(CosmosException cosmosException) { QueryResponseCore queryResponseCore = QueryResponseCore.CreateFailure( statusCode: cosmosException.StatusCode, subStatusCodes: (Microsoft.Azure.Documents.SubStatusCodes)cosmosException.SubStatusCode, cosmosException: cosmosException, requestCharge: 0, activityId: cosmosException.ActivityId); return(queryResponseCore); }
private static QueryResponseCore CreateFromCosmosException(CosmosException cosmosException) { QueryResponseCore queryResponseCore = QueryResponseCore.CreateFailure( statusCode: cosmosException.StatusCode, subStatusCodes: (Microsoft.Azure.Documents.SubStatusCodes)cosmosException.SubStatusCode, errorMessage: cosmosException.ToString(), requestCharge: 0, activityId: cosmosException.ActivityId, diagnostics: QueryResponseCore.EmptyDiagnostics); return(queryResponseCore); }
public static QueryResponseCore CreateFromException(Exception exception) { QueryResponseCore queryResponseCore; if (exception is CosmosException cosmosException) { queryResponseCore = CreateFromCosmosException(cosmosException); } else if (exception is Microsoft.Azure.Documents.DocumentClientException documentClientException) { queryResponseCore = CreateFromDocumentClientException(documentClientException); } else if (exception is QueryException queryException) { CosmosException convertedException = queryException.Accept(QueryExceptionConverter.Singleton); queryResponseCore = CreateFromCosmosException(convertedException); } else if (exception is ExceptionWithStackTraceException exceptionWithStackTrace) { queryResponseCore = QueryResponseFactory.CreateFromExceptionWithStackTrace(exceptionWithStackTrace); } else { if (exception.InnerException != null) { // retry with the inner exception queryResponseCore = QueryResponseFactory.CreateFromException(exception.InnerException); } else { CosmosException unkownCosmosException = CosmosExceptionFactory.CreateInternalServerErrorException( headers: new Headers() { SubStatusCode = SubStatusCodes.PartitionKeyRangeGone, ActivityId = QueryResponseCore.EmptyGuidString }, message: exception.Message, stackTrace: exception.StackTrace, trace: NoOpTrace.Singleton, innerException: exception); // Unknown exception type should become a 500 queryResponseCore = QueryResponseCore.CreateFailure( statusCode: System.Net.HttpStatusCode.InternalServerError, subStatusCodes: null, cosmosException: unkownCosmosException, requestCharge: 0, activityId: QueryResponseCore.EmptyGuidString); } } return(queryResponseCore); }
private static QueryResponseCore CreateFromDocumentClientException(Microsoft.Azure.Documents.DocumentClientException documentClientException) { QueryResponseCore queryResponseCore = QueryResponseCore.CreateFailure( statusCode: documentClientException.StatusCode.GetValueOrDefault(System.Net.HttpStatusCode.InternalServerError), subStatusCodes: null, errorMessage: documentClientException.ToString(), requestCharge: 0, activityId: documentClientException.ActivityId, diagnostics: QueryResponseCore.EmptyDiagnostics); return(queryResponseCore); }
public static QueryResponseCore CreateSplitResponse(string collectionRid) { QueryResponseCore splitResponse = QueryResponseCore.CreateFailure( statusCode: HttpStatusCode.Gone, subStatusCodes: SubStatusCodes.PartitionKeyRangeGone, errorMessage: "Partition split error", requestCharge: 10.4, activityId: Guid.NewGuid().ToString(), queryMetricsText: null, queryMetrics: null); return(splitResponse); }
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)); } }
public static QueryResponseCore CreateFromException(Exception exception) { QueryResponseCore queryResponseCore; if (exception is CosmosException cosmosException) { queryResponseCore = CreateFromCosmosException(cosmosException); } else if (exception is Microsoft.Azure.Documents.DocumentClientException documentClientException) { queryResponseCore = CreateFromDocumentClientException(documentClientException); } else if (exception is QueryException queryException) { CosmosException convertedException = queryException.Accept(QueryExceptionConverter.Singleton); queryResponseCore = CreateFromCosmosException(convertedException); } else if (exception is ExceptionWithStackTraceException exceptionWithStackTrace) { QueryResponseCore innerExceptionResponse = QueryResponseFactory.CreateFromException(exceptionWithStackTrace.InnerException); queryResponseCore = QueryResponseCore.CreateFailure( statusCode: innerExceptionResponse.StatusCode, subStatusCodes: innerExceptionResponse.SubStatusCode, errorMessage: exceptionWithStackTrace.ToString(), requestCharge: innerExceptionResponse.RequestCharge, activityId: innerExceptionResponse.ActivityId, diagnostics: innerExceptionResponse.Diagnostics); } else { if (exception.InnerException != null) { // retry with the inner exception queryResponseCore = QueryResponseFactory.CreateFromException(exception.InnerException); } else { // Unknown exception type should become a 500 queryResponseCore = QueryResponseCore.CreateFailure( statusCode: System.Net.HttpStatusCode.InternalServerError, subStatusCodes: null, errorMessage: exception?.ToString(), requestCharge: 0, activityId: QueryResponseCore.EmptyGuidString, diagnostics: QueryResponseCore.EmptyDiagnostics); } } return(queryResponseCore); }
private static QueryResponseCore CreateFromDocumentClientException(Microsoft.Azure.Documents.DocumentClientException documentClientException) { CosmosException cosmosException = CosmosExceptionFactory.Create( documentClientException, null); QueryResponseCore queryResponseCore = QueryResponseCore.CreateFailure( statusCode: documentClientException.StatusCode.GetValueOrDefault(System.Net.HttpStatusCode.InternalServerError), subStatusCodes: null, cosmosException: cosmosException, requestCharge: 0, activityId: documentClientException.ActivityId); return(queryResponseCore); }
public static QueryResponseCore CreateFailureResponse( HttpStatusCode httpStatusCode, SubStatusCodes subStatusCodes, string errorMessage) { QueryResponseCore splitResponse = QueryResponseCore.CreateFailure( statusCode: httpStatusCode, subStatusCodes: subStatusCodes, errorMessage: errorMessage, requestCharge: 10.4, activityId: Guid.NewGuid().ToString(), queryMetricsText: null, queryMetrics: null); return(splitResponse); }
private QueryResponseCore GetCosmosElementResponse( QueryRequestOptions requestOptions, ResourceType resourceType, ResponseMessage cosmosResponseMessage) { using (cosmosResponseMessage) { if (!cosmosResponseMessage.IsSuccessStatusCode) { return(QueryResponseCore.CreateFailure( statusCode: cosmosResponseMessage.StatusCode, subStatusCodes: cosmosResponseMessage.Headers.SubStatusCode, errorMessage: cosmosResponseMessage.ErrorMessage, requestCharge: cosmosResponseMessage.Headers.RequestCharge, activityId: cosmosResponseMessage.Headers.ActivityId, queryMetricsText: cosmosResponseMessage.Headers.QueryMetricsText, queryMetrics: null)); } 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, queryMetricsText: cosmosResponseMessage.Headers.QueryMetricsText, queryMetrics: null, requestStatistics: null, responseLengthBytes: cosmosResponseMessage.Headers.ContentLengthAsLong, disallowContinuationTokenMessage: null, continuationToken: cosmosResponseMessage.Headers.ContinuationToken)); } }
private (Func <string, Task <IDocumentQueryExecutionComponent> >, QueryResponseCore) SetupBaseContextToVerifyFailureScenario() { QueryResponseCore failure = QueryResponseCore.CreateFailure( System.Net.HttpStatusCode.Unauthorized, SubStatusCodes.PartitionKeyMismatch, "Random error message", 42.89, "TestActivityId", null, null); Mock <IDocumentQueryExecutionComponent> baseContext = new Mock <IDocumentQueryExecutionComponent>(); baseContext.Setup(x => x.DrainAsync(It.IsAny <int>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult <QueryResponseCore>(failure)); Func <string, Task <IDocumentQueryExecutionComponent> > callBack = x => Task.FromResult <IDocumentQueryExecutionComponent>(baseContext.Object); return(callBack, failure); }
public static QueryResponseCore CreateFromException(Exception exception) { // Get the inner most exception while (exception.InnerException != null) { exception = exception.InnerException; } QueryResponseCore queryResponseCore; if (exception is CosmosException cosmosException) { queryResponseCore = CreateFromCosmosException(cosmosException); } else if (exception is Microsoft.Azure.Documents.DocumentClientException documentClientException) { queryResponseCore = CreateFromDocumentClientException(documentClientException); } else if (exception is QueryException queryException) { CosmosException convertedException = queryException.Accept(QueryExceptionConverter.Singleton); queryResponseCore = CreateFromCosmosException(convertedException); } else { // Unknown exception type should become a 500 queryResponseCore = QueryResponseCore.CreateFailure( statusCode: System.Net.HttpStatusCode.InternalServerError, subStatusCodes: null, errorMessage: exception.ToString(), requestCharge: 0, activityId: QueryResponseCore.EmptyGuidString, diagnostics: QueryResponseCore.EmptyDiagnostics); } return(queryResponseCore); }
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); }
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" }; ItemProducerTree.ProduceAsyncCompleteDelegate produceAsyncCompleteCallback = ( ItemProducerTree producer, int itemsBuffered, double resourceUnitUsage, QueryMetrics queryMetrics, 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 }; 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>(), cancellationTokenSource.Token)).Returns( Task.FromResult(QueryResponseCore.CreateSuccess( result: cosmosElements, requestCharge: 42, activityId: "AA470D71-6DEF-4D61-9A08-272D8C9ABCFE", queryMetrics: null, queryMetricsText: null, requestStatistics: null, 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, deferFirstPage: false, collectionRid: "collectionRid", initialContinuationToken: null, initialPageSize: 50); // Buffer to success responses await itemProducerTree.BufferMoreDocumentsAsync(cancellationTokenSource.Token); await itemProducerTree.BufferMoreDocumentsAsync(cancellationTokenSource.Token); // Buffer a failure mockQueryContext.Setup(x => x.ExecuteQueryAsync( sqlQuerySpec, It.IsAny <string>(), It.IsAny <PartitionKeyRangeIdentity>(), It.IsAny <bool>(), It.IsAny <int>(), cancellationTokenSource.Token)).Returns( Task.FromResult(QueryResponseCore.CreateFailure( statusCode: HttpStatusCode.InternalServerError, subStatusCodes: null, errorMessage: "Error message", requestCharge: 10.2, activityId: Guid.NewGuid().ToString(), queryMetricsText: null, queryMetrics: null))); await itemProducerTree.BufferMoreDocumentsAsync(cancellationTokenSource.Token); // First item should be a success (bool successfullyMovedNext, QueryResponseCore? failureResponse)result = await itemProducerTree.MoveNextAsync(cancellationTokenSource.Token); Assert.IsTrue(result.successfullyMovedNext); Assert.IsNull(result.failureResponse); Assert.IsTrue(itemProducerTree.HasMoreResults); // Second item should be a success result = await itemProducerTree.MoveNextAsync(cancellationTokenSource.Token); Assert.IsTrue(result.successfullyMovedNext); Assert.IsNull(result.failureResponse); Assert.IsTrue(itemProducerTree.HasMoreResults); // Third item should be a failure result = await itemProducerTree.MoveNextAsync(cancellationTokenSource.Token); Assert.IsFalse(result.successfullyMovedNext); Assert.IsNotNull(result.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>(), cancellationTokenSource.Token)). Throws(new Exception("Previous buffer failed. Operation should return original failure and not try again")); await itemProducerTree.BufferMoreDocumentsAsync(cancellationTokenSource.Token); Assert.IsFalse(result.successfullyMovedNext); Assert.IsNotNull(result.failureResponse); Assert.IsFalse(itemProducerTree.HasMoreResults); }