public override CosmosException Visit(UnexpectedQueryPartitionProviderException unexpectedQueryPartitionProviderException) { return(CosmosExceptionFactory.CreateInternalServerErrorException( message: $"{nameof(CosmosException)} due to {nameof(UnexpectedQueryPartitionProviderException)}", headers: new Headers(), innerException: unexpectedQueryPartitionProviderException)); }
private async Task <JObject> DecryptContentAsync( EncryptionProperties encryptionProperties, DatabaseCore database, CosmosDiagnosticsContext diagnosticsContext, CancellationToken cancellationToken) { if (encryptionProperties.EncryptionFormatVersion != 1) { throw CosmosExceptionFactory.CreateInternalServerErrorException($"Unknown encryption format version: {encryptionProperties.EncryptionFormatVersion}. Please upgrade your SDK to the latest version."); } DataEncryptionKeyCore tempDek = (DataEncryptionKeyInlineCore)database.GetDataEncryptionKey(id: "unknown"); (DataEncryptionKeyProperties _, InMemoryRawDek inMemoryRawDek) = await tempDek.FetchUnwrappedByRidAsync( encryptionProperties.DataEncryptionKeyRid, diagnosticsContext, cancellationToken); byte[] plainText = inMemoryRawDek.AlgorithmUsingRawDek.DecryptData(encryptionProperties.EncryptedData); JObject plainTextJObj = null; using (MemoryStream memoryStream = new MemoryStream(plainText)) using (StreamReader streamReader = new StreamReader(memoryStream)) using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader)) { plainTextJObj = JObject.Load(jsonTextReader); } return(plainTextJObj); }
private async Task <JObject> DecryptContentAsync( EncryptionProperties encryptionProperties, Encryptor encryptor, CosmosDiagnosticsContext diagnosticsContext, CancellationToken cancellationToken) { if (encryptionProperties.EncryptionFormatVersion != 2) { throw CosmosExceptionFactory.CreateInternalServerErrorException($"Unknown encryption format version: {encryptionProperties.EncryptionFormatVersion}. Please upgrade your SDK to the latest version."); } byte[] plainText = await encryptor.DecryptAsync( encryptionProperties.EncryptedData, encryptionProperties.DataEncryptionKeyId, encryptionProperties.EncryptionAlgorithm, cancellationToken); if (plainText == null) { throw new InvalidOperationException($"{nameof(Encryptor)} returned null plainText from {nameof(DecryptAsync)}."); } JObject plainTextJObj; using (MemoryStream memoryStream = new MemoryStream(plainText)) using (StreamReader streamReader = new StreamReader(memoryStream)) using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader)) { plainTextJObj = JObject.Load(jsonTextReader); } return(plainTextJObj); }
public async Task <IReadOnlyList <FeedRange> > GetFeedRangesAsync( ITrace trace, CancellationToken cancellationToken = default) { PartitionKeyRangeCache partitionKeyRangeCache = await this.ClientContext.DocumentClient.GetPartitionKeyRangeCacheAsync(trace); string containerRId; containerRId = await this.GetCachedRIDAsync( forceRefresh : false, trace, cancellationToken); IReadOnlyList <PartitionKeyRange> partitionKeyRanges = await partitionKeyRangeCache.TryGetOverlappingRangesAsync( containerRId, ContainerCore.allRanges, trace, forceRefresh : true); if (partitionKeyRanges == null) { string refreshedContainerRId; refreshedContainerRId = await this.GetCachedRIDAsync( forceRefresh : true, trace, cancellationToken); if (string.Equals(containerRId, refreshedContainerRId)) { throw CosmosExceptionFactory.CreateInternalServerErrorException( $"Container rid {containerRId} did not have a partition key range after refresh", headers: new Headers(), trace: trace); } partitionKeyRanges = await partitionKeyRangeCache.TryGetOverlappingRangesAsync( containerRId, ContainerCore.allRanges, trace, forceRefresh : true); if (partitionKeyRanges == null) { throw CosmosExceptionFactory.CreateInternalServerErrorException( $"Container rid {containerRId} returned partitionKeyRanges null after Container RID refresh", headers: new Headers(), trace: trace); } } List <FeedRange> feedTokens = new List <FeedRange>(partitionKeyRanges.Count); foreach (PartitionKeyRange partitionKeyRange in partitionKeyRanges) { feedTokens.Add(new FeedRangeEpk(partitionKeyRange.ToRange())); } return(feedTokens); }
public void EnsureCorrectStatusCode() { string testMessage = "Test" + Guid.NewGuid().ToString(); string activityId = Guid.NewGuid().ToString(); int substatuscode = 9000; string substatus = substatuscode.ToString(); double requestCharge = 42; double retryAfter = 9000; string retryAfterLiteral = retryAfter.ToString(); List <(HttpStatusCode statusCode, CosmosException exception)> exceptionsToStatusCodes = new List <(HttpStatusCode, CosmosException)>() { (HttpStatusCode.NotFound, CosmosExceptionFactory.CreateNotFoundException(testMessage, new Headers() { SubStatusCodeLiteral = substatus, ActivityId = activityId, RequestCharge = requestCharge, RetryAfterLiteral = retryAfterLiteral })), (HttpStatusCode.InternalServerError, CosmosExceptionFactory.CreateInternalServerErrorException(testMessage, new Headers() { SubStatusCodeLiteral = substatus, ActivityId = activityId, RequestCharge = requestCharge, RetryAfterLiteral = retryAfterLiteral })), (HttpStatusCode.BadRequest, CosmosExceptionFactory.CreateBadRequestException(testMessage, new Headers() { SubStatusCodeLiteral = substatus, ActivityId = activityId, RequestCharge = requestCharge, RetryAfterLiteral = retryAfterLiteral })), (HttpStatusCode.RequestTimeout, CosmosExceptionFactory.CreateRequestTimeoutException(testMessage, new Headers() { SubStatusCodeLiteral = substatus, ActivityId = activityId, RequestCharge = requestCharge, RetryAfterLiteral = retryAfterLiteral })), ((HttpStatusCode)429, CosmosExceptionFactory.CreateThrottledException(testMessage, new Headers() { SubStatusCodeLiteral = substatus, ActivityId = activityId, RequestCharge = requestCharge, RetryAfterLiteral = retryAfterLiteral })), }; foreach ((HttpStatusCode statusCode, CosmosException exception) in exceptionsToStatusCodes) { this.ValidateExceptionInfo( exception, statusCode, substatus, testMessage, activityId, requestCharge, retryAfter); } CosmosException cosmosException = CosmosExceptionFactory.CreateNotFoundException(testMessage, new Headers() { SubStatusCodeLiteral = ((int)SubStatusCodes.ReadSessionNotAvailable).ToString(), ActivityId = activityId, RequestCharge = requestCharge, RetryAfterLiteral = retryAfterLiteral }); this.ValidateExceptionInfo( cosmosException, HttpStatusCode.NotFound, ((int)SubStatusCodes.ReadSessionNotAvailable).ToString(), testMessage, activityId, requestCharge, retryAfter); }
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); }
public void EnsureCorrectStatusCode() { string testMessage = "Test" + Guid.NewGuid().ToString(); List <(HttpStatusCode statusCode, CosmosException exception)> exceptionsToStatusCodes = new List <(HttpStatusCode, CosmosException)>() { (HttpStatusCode.NotFound, CosmosExceptionFactory.CreateNotFoundException(testMessage, activityId: Guid.NewGuid().ToString())), (HttpStatusCode.InternalServerError, CosmosExceptionFactory.CreateInternalServerErrorException(testMessage, activityId: Guid.NewGuid().ToString())), (HttpStatusCode.BadRequest, CosmosExceptionFactory.CreateBadRequestException(testMessage, activityId: Guid.NewGuid().ToString())), (HttpStatusCode.RequestTimeout, CosmosExceptionFactory.CreateRequestTimeoutException(testMessage, activityId: Guid.NewGuid().ToString())), ((HttpStatusCode)429, CosmosExceptionFactory.CreateThrottledException(testMessage, activityId: Guid.NewGuid().ToString())), }; foreach ((HttpStatusCode statusCode, CosmosException exception)item in exceptionsToStatusCodes) { this.ValidateExceptionInfo(item.exception, item.statusCode, testMessage); } }
public static CosmosException CreateFromException(Exception exception) { if (exception is CosmosException cosmosException) { return(cosmosException); } if (exception is Microsoft.Azure.Documents.DocumentClientException documentClientException) { return(CreateFromDocumentClientException(documentClientException)); } if (exception is QueryException queryException) { return(queryException.Accept(QueryExceptionConverter.Singleton)); } if (exception is ChangeFeedException changeFeedException) { return(changeFeedException.Accept(ChangeFeedExceptionConverter.Singleton)); } if (exception is ExceptionWithStackTraceException exceptionWithStackTrace) { return(CreateFromExceptionWithStackTrace(exceptionWithStackTrace)); } if (exception.InnerException != null) { // retry with the inner exception return(ExceptionToCosmosException.CreateFromException(exception.InnerException)); } return(CosmosExceptionFactory.CreateInternalServerErrorException( message: exception.Message, stackTrace: exception.StackTrace, headers: new Headers() { ActivityId = EmptyGuidString, }, trace: NoOpTrace.Singleton, innerException: exception)); }
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, 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 = new CosmosDiagnosticsContextCore(); diagnosticsContext.AddDiagnosticsInternal(new PointOperationStatistics( Guid.NewGuid().ToString(), System.Net.HttpStatusCode.OK, subStatusCode: SubStatusCodes.Unknown, responseTimeUtc: DateTime.UtcNow, requestCharge: 42, errorMessage: null, method: HttpMethod.Post, requestUri: new Uri("http://localhost.com"), requestSessionToken: null, responseSessionToken: null)); QueryPageDiagnostics diagnostics = new QueryPageDiagnostics( clientQueryCorrelationId: Guid.NewGuid(), partitionKeyRangeId: "0", queryMetricText: "SomeRandomQueryMetricText", indexUtilizationText: null, diagnosticsContext: diagnosticsContext); 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>(), cancellationTokenSource.Token)).Returns( Task.FromResult(QueryResponseCore.CreateSuccess( result: cosmosElements, requestCharge: 42, activityId: "AA470D71-6DEF-4D61-9A08-272D8C9ABCFE", 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 = new CosmosDiagnosticsContextCore(); diagnosticsContextInternalServerError.AddDiagnosticsInternal(new PointOperationStatistics( Guid.NewGuid().ToString(), System.Net.HttpStatusCode.InternalServerError, subStatusCode: SubStatusCodes.Unknown, responseTimeUtc: DateTime.UtcNow, requestCharge: 10.2, errorMessage: "Error message", method: HttpMethod.Post, requestUri: new Uri("http://localhost.com"), requestSessionToken: null, responseSessionToken: null)); diagnostics = new QueryPageDiagnostics( clientQueryCorrelationId: Guid.NewGuid(), partitionKeyRangeId: "0", queryMetricText: null, indexUtilizationText: null, diagnosticsContext: diagnosticsContextInternalServerError); 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>(), cancellationTokenSource.Token)).Returns( Task.FromResult(QueryResponseCore.CreateFailure( statusCode: HttpStatusCode.InternalServerError, subStatusCodes: null, cosmosException: CosmosExceptionFactory.CreateInternalServerErrorException( "Error message"), requestCharge: 10.2, activityId: Guid.NewGuid().ToString()))); 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>(), 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 <Stream> DecryptAsync( Stream input, DatabaseCore database, EncryptionKeyWrapProvider encryptionKeyWrapProvider, CosmosDiagnosticsContext diagnosticsContext, CancellationToken cancellationToken) { Debug.Assert(input != null); Debug.Assert(database != null); Debug.Assert(input.CanSeek); Debug.Assert(diagnosticsContext != null); if (encryptionKeyWrapProvider == null) { return(input); } JObject itemJObj = EncryptionProcessor.baseSerializer.FromStream <JObject>(input); JProperty encryptionPropertiesJProp = itemJObj.Property(Constants.Properties.EncryptedInfo); JObject encryptionPropertiesJObj = null; if (encryptionPropertiesJProp != null && encryptionPropertiesJProp.Value != null && encryptionPropertiesJProp.Value.Type == JTokenType.Object) { encryptionPropertiesJObj = (JObject)encryptionPropertiesJProp.Value; } if (encryptionPropertiesJObj == null) { input.Position = 0; return(input); } EncryptionProperties encryptionProperties = encryptionPropertiesJObj.ToObject <EncryptionProperties>(); if (encryptionProperties.EncryptionFormatVersion != 1) { throw CosmosExceptionFactory.CreateInternalServerErrorException($"Unknown encryption format version: {encryptionProperties.EncryptionFormatVersion}. Please upgrade your SDK to the latest version."); } DataEncryptionKeyCore tempDek = (DataEncryptionKeyInlineCore)database.GetDataEncryptionKey(id: "unknown"); (DataEncryptionKeyProperties _, InMemoryRawDek inMemoryRawDek) = await tempDek.FetchUnwrappedByRidAsync( encryptionProperties.DataEncryptionKeyRid, diagnosticsContext, cancellationToken); byte[] plainText = inMemoryRawDek.AlgorithmUsingRawDek.DecryptData(encryptionProperties.EncryptedData); JObject plainTextJObj = null; using (MemoryStream memoryStream = new MemoryStream(plainText)) using (StreamReader streamReader = new StreamReader(memoryStream)) using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader)) { plainTextJObj = JObject.Load(jsonTextReader); } foreach (JProperty property in plainTextJObj.Properties()) { itemJObj.Add(property.Name, property.Value); } itemJObj.Remove(Constants.Properties.EncryptedInfo); return(EncryptionProcessor.baseSerializer.ToStream(itemJObj)); }
public async Task <IReadOnlyList <FeedRange> > GetFeedRangesAsync( CosmosDiagnosticsContext diagnosticsContext, ITrace trace, CancellationToken cancellationToken = default) { PartitionKeyRangeCache partitionKeyRangeCache = await this.ClientContext.DocumentClient.GetPartitionKeyRangeCacheAsync(); string containerRId; using (diagnosticsContext.CreateScope(nameof(GetCachedRIDAsync))) { containerRId = await this.GetCachedRIDAsync( forceRefresh : false, cancellationToken); } IReadOnlyList <PartitionKeyRange> partitionKeyRanges; using (diagnosticsContext.CreateScope(nameof(partitionKeyRangeCache.TryGetOverlappingRangesAsync))) { partitionKeyRanges = await partitionKeyRangeCache.TryGetOverlappingRangesAsync( containerRId, ContainerCore.allRanges, forceRefresh : true); } if (partitionKeyRanges == null) { string refreshedContainerRId; using (diagnosticsContext.CreateScope("GetRIDAsyncForceRefresh")) { refreshedContainerRId = await this.GetCachedRIDAsync( forceRefresh : true, cancellationToken); } if (string.Equals(containerRId, refreshedContainerRId)) { throw CosmosExceptionFactory.CreateInternalServerErrorException( $"Container rid {containerRId} did not have a partition key range after refresh", diagnosticsContext: diagnosticsContext); } using (diagnosticsContext.CreateScope(nameof(partitionKeyRangeCache.TryGetOverlappingRangesAsync))) { partitionKeyRanges = await partitionKeyRangeCache.TryGetOverlappingRangesAsync( containerRId, ContainerCore.allRanges, forceRefresh : true); } if (partitionKeyRanges == null) { throw CosmosExceptionFactory.CreateInternalServerErrorException( $"Container rid {containerRId} returned partitionKeyRanges null after Container RID refresh", diagnosticsContext: diagnosticsContext); } } List <FeedRange> feedTokens = new List <FeedRange>(partitionKeyRanges.Count); foreach (PartitionKeyRange partitionKeyRange in partitionKeyRanges) { feedTokens.Add(new FeedRangeEpk(partitionKeyRange.ToRange())); } return(feedTokens); }
public override CosmosException Visit(UnexpectedQueryPartitionProviderException unexpectedQueryPartitionProviderException) => CosmosExceptionFactory.CreateInternalServerErrorException( message: $"{nameof(CosmosException)} due to {nameof(UnexpectedQueryPartitionProviderException)}", innerException: unexpectedQueryPartitionProviderException);
private async Task<ResponseMessage> ReadNextInternalAsync( CosmosDiagnosticsContext diagnostics, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); Stream stream = null; OperationType operation = OperationType.ReadFeed; if (this.querySpec != null) { stream = this.clientContext.SerializerCore.ToStreamSqlQuerySpec(this.querySpec, this.resourceType); operation = OperationType.Query; } if (this.feedTokenInternal == null) { TryCatch<FeedTokenInternal> tryCatchFeedTokeninternal = await this.TryInitializeFeedTokenAsync(cancellationToken); if (!tryCatchFeedTokeninternal.Succeeded) { if (tryCatchFeedTokeninternal.Exception.InnerException is CosmosException cosmosException) { return cosmosException.ToCosmosResponseMessage(new RequestMessage(method: null, requestUri: null, diagnosticsContext: diagnostics)); } return CosmosExceptionFactory.CreateInternalServerErrorException( message: tryCatchFeedTokeninternal.Exception.InnerException.Message, innerException: tryCatchFeedTokeninternal.Exception.InnerException, diagnosticsContext: diagnostics).ToCosmosResponseMessage(new RequestMessage(method: null, requestUri: null, diagnosticsContext: diagnostics)); } this.feedTokenInternal = tryCatchFeedTokeninternal.Result; } ResponseMessage response = await this.clientContext.ProcessResourceOperationStreamAsync( resourceUri: this.resourceLink, resourceType: this.resourceType, operationType: operation, requestOptions: this.requestOptions, cosmosContainerCore: null, partitionKey: this.requestOptions?.PartitionKey, streamPayload: stream, requestEnricher: request => { QueryRequestOptions.FillContinuationToken(request, this.ContinuationToken); if (this.querySpec != null) { request.Headers.Add(HttpConstants.HttpHeaders.ContentType, MediaTypes.QueryJson); request.Headers.Add(HttpConstants.HttpHeaders.IsQuery, bool.TrueString); } this.feedTokenInternal?.EnrichRequest(request); }, diagnosticsContext: diagnostics, cancellationToken: cancellationToken); // Retry in case of splits or other scenarios only on partitioned resources if (this.containerCore != null && await this.feedTokenInternal.ShouldRetryAsync(this.containerCore, response, cancellationToken)) { return await this.ReadNextInternalAsync(diagnostics, cancellationToken); } if (response.IsSuccessStatusCode) { this.feedTokenInternal.UpdateContinuation(response.Headers.ContinuationToken); this.ContinuationToken = this.feedTokenInternal.GetContinuation(); this.hasMoreResultsInternal = !this.feedTokenInternal.IsDone; } else { this.hasMoreResultsInternal = false; } return response; }
private async Task <ResponseMessage> ReadNextInternalAsync( CosmosDiagnosticsContext diagnosticsScope, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); if (this.feedTokenInternal == null) { TryCatch <FeedTokenInternal> tryCatchFeedTokeninternal = await this.TryInitializeFeedTokenAsync(cancellationToken); if (!tryCatchFeedTokeninternal.Succeeded) { if (tryCatchFeedTokeninternal.Exception.InnerException is CosmosException cosmosException) { return(cosmosException.ToCosmosResponseMessage(new RequestMessage(method: null, requestUri: null, diagnosticsContext: diagnosticsScope))); } return(CosmosExceptionFactory.CreateInternalServerErrorException( message: tryCatchFeedTokeninternal.Exception.InnerException.Message, innerException: tryCatchFeedTokeninternal.Exception.InnerException, diagnosticsContext: diagnosticsScope).ToCosmosResponseMessage(new RequestMessage(method: null, requestUri: null, diagnosticsContext: diagnosticsScope))); } this.feedTokenInternal = tryCatchFeedTokeninternal.Result; } Uri resourceUri = this.container.LinkUri; ResponseMessage responseMessage = await this.clientContext.ProcessResourceOperationStreamAsync( resourceUri : resourceUri, resourceType : Documents.ResourceType.Document, operationType : Documents.OperationType.ReadFeed, requestOptions : this.changeFeedOptions, cosmosContainerCore : this.container, requestEnricher : request => { ChangeFeedRequestOptions.FillContinuationToken(request, this.feedTokenInternal.GetContinuation()); this.feedTokenInternal.EnrichRequest(request); }, partitionKey : null, streamPayload : null, diagnosticsContext : diagnosticsScope, cancellationToken : cancellationToken); // Retry in case of splits or other scenarios if (await this.feedTokenInternal.ShouldRetryAsync(this.container, responseMessage, cancellationToken)) { if (responseMessage.IsSuccessStatusCode || responseMessage.StatusCode == HttpStatusCode.NotModified) { // Change Feed read uses Etag for continuation this.feedTokenInternal.UpdateContinuation(responseMessage.Headers.ETag); } return(await this.ReadNextInternalAsync(diagnosticsScope, cancellationToken)); } if (responseMessage.IsSuccessStatusCode || responseMessage.StatusCode == HttpStatusCode.NotModified) { // Change Feed read uses Etag for continuation this.feedTokenInternal.UpdateContinuation(responseMessage.Headers.ETag); } this.hasMoreResults = responseMessage.IsSuccessStatusCode; return(responseMessage); }