コード例 #1
0
        public static async Task <PartitionedQueryExecutionInfo> GetQueryPlanWithServiceInteropAsync(
            CosmosQueryClient queryClient,
            SqlQuerySpec sqlQuerySpec,
            PartitionKeyDefinition partitionKeyDefinition,
            bool hasLogicalPartitionKey,
            ITrace trace,
            CancellationToken cancellationToken = default)
        {
            if (queryClient == null)
            {
                throw new ArgumentNullException(nameof(queryClient));
            }

            if (sqlQuerySpec == null)
            {
                throw new ArgumentNullException(nameof(sqlQuerySpec));
            }

            if (partitionKeyDefinition == null)
            {
                throw new ArgumentNullException(nameof(partitionKeyDefinition));
            }

            cancellationToken.ThrowIfCancellationRequested();

            using (ITrace serviceInteropTrace = trace.StartChild("Service Interop Query Plan", TraceComponent.Query, TraceLevel.Info))
            {
                QueryPlanHandler queryPlanHandler = new QueryPlanHandler(queryClient);

                TryCatch <PartitionedQueryExecutionInfo> tryGetQueryPlan = await queryPlanHandler.TryGetQueryPlanAsync(
                    sqlQuerySpec,
                    partitionKeyDefinition,
                    QueryPlanRetriever.SupportedQueryFeatures,
                    hasLogicalPartitionKey,
                    cancellationToken);

                if (!tryGetQueryPlan.Succeeded)
                {
                    if (tryGetQueryPlan.Exception is CosmosException)
                    {
                        throw tryGetQueryPlan.Exception;
                    }

                    throw CosmosExceptionFactory.CreateBadRequestException(
                              message: tryGetQueryPlan.Exception.ToString(),
                              stackTrace: tryGetQueryPlan.Exception.StackTrace);
                }

                return(tryGetQueryPlan.Result);
            }
        }
コード例 #2
0
        public async Task FeedEstimatorRunner_TransientErrorsShouldContinue()
        {
            const long estimation = 10;
            bool       detectedEstimationCorrectly          = false;
            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(500);

            Task estimatorDispatcher(long detectedEstimation, CancellationToken token)
            {
                detectedEstimationCorrectly = estimation == detectedEstimation;
                cancellationTokenSource.Cancel();
                return(Task.CompletedTask);
            }

            Mock <FeedResponse <ChangeFeedProcessorState> > mockedResponse = new Mock <FeedResponse <ChangeFeedProcessorState> >();

            mockedResponse.Setup(r => r.Count).Returns(1);
            mockedResponse.Setup(r => r.GetEnumerator()).Returns(new List <ChangeFeedProcessorState>()
            {
                new ChangeFeedProcessorState(string.Empty, estimation, string.Empty)
            }.GetEnumerator());

            CosmosException exception = CosmosExceptionFactory.CreateThrottledException("throttled", new Headers());
            Mock <FeedIterator <ChangeFeedProcessorState> > mockedIterator = new Mock <FeedIterator <ChangeFeedProcessorState> >();

            mockedIterator.SetupSequence(i => i.ReadNextAsync(It.IsAny <CancellationToken>()))
            .ThrowsAsync(exception)
            .ReturnsAsync(mockedResponse.Object);

            Mock <ChangeFeedEstimator> mockedEstimator = new Mock <ChangeFeedEstimator>();

            mockedEstimator.Setup(e => e.GetCurrentStateIterator(It.IsAny <ChangeFeedEstimatorRequestOptions>())).Returns(mockedIterator.Object);

            Mock <ChangeFeedProcessorHealthMonitor> healthMonitor = new Mock <ChangeFeedProcessorHealthMonitor>();

            FeedEstimatorRunner estimatorCore = new FeedEstimatorRunner(estimatorDispatcher, mockedEstimator.Object, healthMonitor.Object, TimeSpan.FromMilliseconds(10));

            try
            {
                await estimatorCore.RunAsync(cancellationTokenSource.Token);
            }
            catch (TaskCanceledException)
            {
                // expected
            }

            Assert.IsTrue(detectedEstimationCorrectly);
            mockedIterator.Verify(i => i.ReadNextAsync(It.IsAny <CancellationToken>()), Times.Exactly(2));

            healthMonitor
            .Verify(m => m.NotifyErrorAsync(It.IsAny <string>(), exception), Times.Once);
        }
コード例 #3
0
        internal async Task <ThroughputResponse> ReplaceThroughputPropertiesIfExistsAsync(
            string targetRID,
            ThroughputProperties throughputProperties,
            RequestOptions requestOptions,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            try
            {
                ThroughputProperties currentProperty = await this.GetOfferV2Async <ThroughputProperties>(targetRID, failIfNotConfigured : false, cancellationToken : cancellationToken);

                if (currentProperty == null)
                {
                    CosmosException notFound = CosmosExceptionFactory.CreateNotFoundException(
                        $"Throughput is not configured for {targetRID}");
                    return(new ThroughputResponse(
                               httpStatusCode: notFound.StatusCode,
                               headers: notFound.Headers,
                               throughputProperties: null,
                               diagnostics: notFound.Diagnostics));
                }

                currentProperty.Content = throughputProperties.Content;

                return(await this.GetThroughputResponseAsync(
                           streamPayload : this.ClientContext.SerializerCore.ToStream(currentProperty),
                           operationType : OperationType.Replace,
                           linkUri : new Uri(currentProperty.SelfLink, UriKind.Relative),
                           resourceType : ResourceType.Offer,
                           requestOptions : requestOptions,
                           cancellationToken : cancellationToken));
            }
            catch (DocumentClientException dce)
            {
                ResponseMessage responseMessage = dce.ToCosmosResponseMessage(null);
                return(new ThroughputResponse(
                           responseMessage.StatusCode,
                           headers: responseMessage.Headers,
                           throughputProperties: null,
                           diagnostics: responseMessage.Diagnostics));
            }
            catch (AggregateException ex)
            {
                ResponseMessage responseMessage = TransportHandler.AggregateExceptionConverter(ex, null);
                return(new ThroughputResponse(
                           responseMessage.StatusCode,
                           headers: responseMessage.Headers,
                           throughputProperties: null,
                           diagnostics: responseMessage.Diagnostics));
            }
        }
コード例 #4
0
            public override CosmosException Visit(MalformedContinuationTokenException malformedContinuationTokenException, ITrace trace)
            {
                Headers headers = new Headers()
                {
                    SubStatusCode = Documents.SubStatusCodes.MalformedContinuationToken
                };

                return(CosmosExceptionFactory.CreateBadRequestException(
                           message: malformedContinuationTokenException.Message,
                           headers: headers,
                           stackTrace: malformedContinuationTokenException.StackTrace,
                           innerException: malformedContinuationTokenException,
                           trace: trace));
            }
コード例 #5
0
        /// <summary>
        /// Get the next set of results from the cosmos service
        /// </summary>
        /// <param name="cancellationToken">(Optional) <see cref="CancellationToken"/> representing request cancellation.</param>
        /// <returns>A query response from cosmos service</returns>
        public override async Task <ResponseMessage> ReadNextAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            CosmosDiagnosticsContext diagnostics = CosmosDiagnosticsContext.Create(this.changeFeedOptions);

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

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

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

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

                        await this.InitializeFeedContinuationAsync(cancellationToken);
                    }
                }

                return(await this.ReadNextInternalAsync(diagnostics, cancellationToken));
            }
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        /// <summary>
        /// Gets the container's Properties by using the internal cache.
        /// In case the cache does not have information about this container, it may end up making a server call to fetch the data.
        /// </summary>
        /// <param name="cancellationToken"><see cref="CancellationToken"/> representing request cancellation.</param>
        /// <returns>A <see cref="Task"/> containing the <see cref="ContainerProperties"/> for this container.</returns>
        internal override async Task <ContainerProperties> GetCachedContainerPropertiesAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            ClientCollectionCache collectionCache = await this.ClientContext.DocumentClient.GetCollectionCacheAsync();

            try
            {
                return(await collectionCache.ResolveByNameAsync(HttpConstants.Versions.CurrentVersion, this.LinkUri.OriginalString, cancellationToken));
            }
            catch (DocumentClientException ex)
            {
                throw CosmosExceptionFactory.Create(
                          dce: ex,
                          diagnosticsContext: null);
            }
        }
コード例 #8
0
        private ShouldRetryResult GetShouldRetryFromException(
            Exception exception)
        {
            if (exception is OperationCanceledException operationCanceledException)
            {
                // throw timeout if the cancellationToken is not canceled (i.e. httpClient timed out)
                string message =
                    $"GatewayStoreClient Request Timeout. Start Time Utc:{this.startDateTimeUtc}; Total Duration:{(DateTime.UtcNow - this.startDateTimeUtc).TotalMilliseconds} Ms; Http Client Timeout:{this.gatewayRequestTimeout.TotalMilliseconds} Ms; Activity id: {Trace.CorrelationManager.ActivityId.ToString()};";
                return(ShouldRetryResult.NoRetry(CosmosExceptionFactory.CreateRequestTimeoutException(
                                                     message,
                                                     innerException: operationCanceledException,
                                                     diagnosticsContext: this.diagnosticsContext)));
            }

            return(ShouldRetryResult.NoRetry());
        }
コード例 #9
0
        public async Task ProcessChanges_WhenCheckpointThrows_ShouldThrow()
        {
            CosmosException original = CosmosExceptionFactory.CreateThrottledException("throttled", new Headers());
            Mock <PartitionCheckpointer> checkpointer = new Mock <PartitionCheckpointer>();

            checkpointer.Setup(c => c.CheckpointPartitionAsync(It.IsAny <string>())).ThrowsAsync(original);

            ResponseMessage responseMessage = new ResponseMessage();

            responseMessage.Headers.ContinuationToken = Guid.NewGuid().ToString();
            ChangeFeedObserverContextCore observerContext = new ChangeFeedObserverContextCore(Guid.NewGuid().ToString(), feedResponse: responseMessage, checkpointer.Object);

            CosmosException caught = await Assert.ThrowsExceptionAsync <CosmosException>(() => this.sut.ProcessChangesAsync(observerContext, this.stream, CancellationToken.None));

            Assert.AreEqual(original, caught);
        }
コード例 #10
0
        internal static ResponseMessage ToCosmosResponseMessage(this DocumentServiceResponse documentServiceResponse, RequestMessage requestMessage)
        {
            Debug.Assert(requestMessage != null, nameof(requestMessage));
            Headers headers = documentServiceResponse.Headers.ToCosmosHeaders();

            // Only record point operation stats if ClientSideRequestStats did not record the response.
            CosmosClientSideRequestStatistics clientSideRequestStatistics = documentServiceResponse.RequestStats as CosmosClientSideRequestStatistics;

            if (clientSideRequestStatistics == null ||
                (clientSideRequestStatistics.ContactedReplicas.Count == 0 && clientSideRequestStatistics.FailedReplicas.Count == 0))
            {
                requestMessage.DiagnosticsContext.AddDiagnosticsInternal(new PointOperationStatistics(
                                                                             activityId: headers.ActivityId,
                                                                             responseTimeUtc: DateTime.UtcNow,
                                                                             statusCode: documentServiceResponse.StatusCode,
                                                                             subStatusCode: documentServiceResponse.SubStatusCode,
                                                                             requestCharge: headers.RequestCharge,
                                                                             errorMessage: null,
                                                                             method: requestMessage?.Method,
                                                                             requestUri: requestMessage?.RequestUri,
                                                                             requestSessionToken: requestMessage?.Headers?.Session,
                                                                             responseSessionToken: headers.Session));
            }

            // If it's considered a failure create the corresponding CosmosException
            if (!documentServiceResponse.StatusCode.IsSuccess())
            {
                CosmosException cosmosException = CosmosExceptionFactory.Create(
                    documentServiceResponse,
                    headers,
                    requestMessage);

                return(cosmosException.ToCosmosResponseMessage(requestMessage));
            }

            ResponseMessage responseMessage = new ResponseMessage(
                statusCode: documentServiceResponse.StatusCode,
                requestMessage: requestMessage,
                headers: headers,
                cosmosException: null,
                diagnostics: requestMessage.DiagnosticsContext)
            {
                Content = documentServiceResponse.ResponseBody
            };

            return(responseMessage);
        }
コード例 #11
0
        public async Task TryCheckpoint_OnCosmosException()
        {
            CosmosException cosmosException = CosmosExceptionFactory.CreateThrottledException("throttled", new Headers());
            string          leaseToken      = Guid.NewGuid().ToString();
            string          continuation    = Guid.NewGuid().ToString();
            ResponseMessage responseMessage = new ResponseMessage(HttpStatusCode.OK);

            responseMessage.Headers.ContinuationToken = continuation;
            Mock <PartitionCheckpointer> checkpointer = new Mock <PartitionCheckpointer>();

            checkpointer.Setup(c => c.CheckpointPartitionAsync(It.Is <string>(s => s == continuation))).ThrowsAsync(cosmosException);
            ChangeFeedObserverContextCore changeFeedObserverContextCore = new ChangeFeedObserverContextCore(leaseToken, responseMessage, checkpointer.Object);

            CosmosException exception = await Assert.ThrowsExceptionAsync <CosmosException>(() => changeFeedObserverContextCore.CheckpointAsync());

            Assert.ReferenceEquals(cosmosException, exception);
        }
コード例 #12
0
        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);
            }
        }
コード例 #13
0
        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);
            }
        }
コード例 #14
0
        internal static ResponseMessage ToCosmosResponseMessage(this DocumentClientException documentClientException, RequestMessage requestMessage)
        {
            CosmosDiagnosticsContext diagnosticsContext = requestMessage?.DiagnosticsContext;

            if (diagnosticsContext == null)
            {
                diagnosticsContext = CosmosDiagnosticsContextCore.Create();
            }

            CosmosException cosmosException = CosmosExceptionFactory.Create(
                documentClientException,
                diagnosticsContext);

            PointOperationStatistics pointOperationStatistics = new PointOperationStatistics(
                activityId: cosmosException.Headers.ActivityId,
                statusCode: cosmosException.StatusCode,
                subStatusCode: (int)SubStatusCodes.Unknown,
                requestCharge: cosmosException.Headers.RequestCharge,
                errorMessage: cosmosException.Message,
                method: requestMessage?.Method,
                requestUri: requestMessage?.RequestUri,
                requestSessionToken: requestMessage?.Headers?.Session,
                responseSessionToken: cosmosException.Headers.Session,
                clientSideRequestStatistics: documentClientException.RequestStatistics as CosmosClientSideRequestStatistics);

            diagnosticsContext.AddDiagnosticsInternal(pointOperationStatistics);

            // if StatusCode is null it is a client business logic error and it never hit the backend, so throw
            if (documentClientException.StatusCode == null)
            {
                throw cosmosException;
            }

            // if there is a status code then it came from the backend, return error as http error instead of throwing the exception
            ResponseMessage responseMessage = cosmosException.ToCosmosResponseMessage(requestMessage);

            if (requestMessage != null)
            {
                requestMessage.Properties.Remove(nameof(DocumentClientException));
                requestMessage.Properties.Add(nameof(DocumentClientException), documentClientException);
            }

            return(responseMessage);
        }
コード例 #15
0
        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));
        }
コード例 #16
0
        /// <summary>
        /// Get the next set of results from the cosmos service
        /// </summary>
        /// <param name="cancellationToken">(Optional) <see cref="CancellationToken"/> representing request cancellation.</param>
        /// <returns>A query response from cosmos service</returns>
        public override async Task <ResponseMessage> ReadNextAsync(CancellationToken cancellationToken = default)
        {
            CosmosDiagnosticsContext diagnostics = CosmosDiagnosticsContext.Create(this.queryRequestOptions);

            using (diagnostics.GetOverallScope())
            {
                if (!this.lazyContainerRid.ValueInitialized)
                {
                    using (diagnostics.CreateScope("InitializeContainerResourceId"))
                    {
                        TryCatch <string> tryInitializeContainerRId = await this.lazyContainerRid.GetValueAsync(cancellationToken);

                        if (!tryInitializeContainerRId.Succeeded)
                        {
                            CosmosException cosmosException = tryInitializeContainerRId.Exception.InnerException as CosmosException;
                            return(cosmosException.ToCosmosResponseMessage(new RequestMessage(method: null, requestUri: null, diagnosticsContext: diagnostics)));
                        }
                    }

                    using (diagnostics.CreateScope("InitializeContinuation"))
                    {
                        if (this.FeedRangeContinuation != null)
                        {
                            TryCatch validateContainer = this.FeedRangeContinuation.ValidateContainer(this.lazyContainerRid.Result.Result);
                            if (!validateContainer.Succeeded)
                            {
                                return(CosmosExceptionFactory.CreateBadRequestException(
                                           message: validateContainer.Exception.InnerException.Message,
                                           innerException: validateContainer.Exception.InnerException,
                                           diagnosticsContext: diagnostics).ToCosmosResponseMessage(new RequestMessage(method: null, requestUri: null, diagnosticsContext: diagnostics)));
                            }
                        }
                        else
                        {
                            await this.InitializeFeedContinuationAsync(cancellationToken);
                        }
                    }
                }

                return(await this.ReadNextInternalAsync(diagnostics, cancellationToken));
            }
        }
コード例 #17
0
        private static CosmosException CreateFromExceptionWithStackTrace(ExceptionWithStackTraceException exceptionWithStackTrace)
        {
            // Use the original stack trace from the inner exception.
            if (exceptionWithStackTrace.InnerException is Microsoft.Azure.Documents.DocumentClientException ||
                exceptionWithStackTrace.InnerException is CosmosException)
            {
                return(ExceptionToCosmosException.CreateFromException(exceptionWithStackTrace.InnerException));
            }

            CosmosException cosmosException = ExceptionToCosmosException.CreateFromException(exceptionWithStackTrace.InnerException);

            return(CosmosExceptionFactory.Create(
                       cosmosException.StatusCode,
                       cosmosException.Message,
                       exceptionWithStackTrace.StackTrace,
                       headers: cosmosException.Headers,
                       cosmosException.Trace,
                       cosmosException.Error,
                       cosmosException.InnerException));
        }
コード例 #18
0
        public async Task <ThroughputResponse> ReadThroughputAsync(
            RequestOptions requestOptions,
            ITrace trace,
            CancellationToken cancellationToken = default)
        {
            ThroughputResponse throughputResponse = await this.ReadThroughputIfExistsAsync(
                requestOptions,
                trace,
                cancellationToken);

            if (throughputResponse.StatusCode == HttpStatusCode.NotFound)
            {
                throw CosmosExceptionFactory.CreateNotFoundException(
                          message: $"Throughput is not configured for {this.Id}",
                          headers: throughputResponse.Headers,
                          trace: trace);
            }

            return(throughputResponse);
        }
コード例 #19
0
 public async Task CheckpointAsync()
 {
     try
     {
         await this.checkpointer.CheckpointPartitionAsync(this.responseMessage.Headers.ContinuationToken);
     }
     catch (LeaseLostException leaseLostException)
     {
         // LeaseLost means another instance stole the lease due to load balancing, so the right status is 412
         CosmosException cosmosException = CosmosExceptionFactory.Create(
             statusCode: HttpStatusCode.PreconditionFailed,
             message: "Lease was lost due to load balancing and will be processed by another instance",
             stackTrace: leaseLostException.StackTrace,
             headers: new Headers(),
             trace: NoOpTrace.Singleton,
             error: null,
             innerException: leaseLostException);
         throw cosmosException;
     }
 }
コード例 #20
0
        private void HandleFailedRequest(
            ResponseMessage responseMessage,
            string lastContinuation)
        {
            DocDbError docDbError = ExceptionClassifier.ClassifyStatusCodes(responseMessage.StatusCode, (int)responseMessage.Headers.SubStatusCode);

            switch (docDbError)
            {
            case DocDbError.PartitionSplit:
                throw new FeedRangeGoneException("Partition split.", lastContinuation);

            case DocDbError.Undefined:
                throw CosmosExceptionFactory.Create(responseMessage);

            default:
                DefaultTrace.TraceCritical($"Unrecognized DocDbError enum value {docDbError}");
                Debug.Fail($"Unrecognized DocDbError enum value {docDbError}");
                throw new InvalidOperationException($"Unrecognized DocDbError enum value {docDbError} for status code {responseMessage.StatusCode} and substatus code {responseMessage.Headers.SubStatusCode}");
            }
        }
コード例 #21
0
        internal async Task <(DataEncryptionKeyProperties, InMemoryRawDek)> FetchUnwrappedByRidAsync(
            string rid,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            string dekRidSelfLink = PathsHelper.GeneratePath(ResourceType.ClientEncryptionKey, rid, isFeed: false);

            // Server self links end with / but client generate links don't - match them.
            if (!dekRidSelfLink.EndsWith("/"))
            {
                dekRidSelfLink += "/";
            }

            DataEncryptionKeyProperties dekProperties = null;

            try
            {
                dekProperties = await this.ClientContext.DekCache.GetOrAddByRidSelfLinkAsync(
                    dekRidSelfLink,
                    this.Database.Id,
                    this.ReadResourceByRidSelfLinkAsync,
                    this.LinkUri,
                    diagnosticsContext,
                    cancellationToken);
            }
            catch (CosmosException ex) when(ex.StatusCode == HttpStatusCode.NotFound)
            {
                throw CosmosExceptionFactory.CreateNotFoundException(
                          ClientResources.DataEncryptionKeyNotFound,
                          diagnosticsContext: diagnosticsContext,
                          innerException: ex);
            }

            InMemoryRawDek inMemoryRawDek = await this.ClientContext.DekCache.GetOrAddRawDekAsync(
                dekProperties,
                this.UnwrapAsync,
                diagnosticsContext,
                cancellationToken);

            return(dekProperties, inMemoryRawDek);
        }
コード例 #22
0
        internal override async Task <List <Documents.Routing.Range <string> > > GetEffectiveRangesAsync(
            IRoutingMapProvider routingMapProvider,
            string containerRid,
            Documents.PartitionKeyDefinition partitionKeyDefinition,
            ITrace trace)
        {
            Documents.PartitionKeyRange pkRange = await routingMapProvider.TryGetPartitionKeyRangeByIdAsync(
                collectionResourceId : containerRid,
                partitionKeyRangeId : this.PartitionKeyRangeId,
                trace : trace,
                forceRefresh : false);

            if (pkRange == null)
            {
                // Try with a refresh
                pkRange = await routingMapProvider.TryGetPartitionKeyRangeByIdAsync(
                    collectionResourceId : containerRid,
                    partitionKeyRangeId : this.PartitionKeyRangeId,
                    trace : trace,
                    forceRefresh : true);
            }

            if (pkRange == null)
            {
                throw CosmosExceptionFactory.Create(
                          statusCode: HttpStatusCode.Gone,
                          message: $"The PartitionKeyRangeId: \"{this.PartitionKeyRangeId}\" is not valid for the current container {containerRid} .",
                          stackTrace: string.Empty,
                          headers: new Headers()
                {
                    SubStatusCode = SubStatusCodes.PartitionKeyRangeGone,
                },
                          error: null,
                          innerException: null,
                          trace: NoOpTrace.Singleton);
            }

            return(new List <Documents.Routing.Range <string> > {
                pkRange.ToRange()
            });
        }
コード例 #23
0
        /// <summary>
        /// Gets the container's Properties by using the internal cache.
        /// In case the cache does not have information about this container, it may end up making a server call to fetch the data.
        /// </summary>
        /// <param name="forceRefresh">Forces the cache to refresh</param>
        /// <param name="cancellationToken"><see cref="CancellationToken"/> representing request cancellation.</param>
        /// <returns>A <see cref="Task"/> containing the <see cref="ContainerProperties"/> for this container.</returns>
        public override async Task <ContainerProperties> GetCachedContainerPropertiesAsync(
            bool forceRefresh = false,
            CancellationToken cancellationToken = default)
        {
            try
            {
                ClientCollectionCache collectionCache = await this.ClientContext.DocumentClient.GetCollectionCacheAsync();

                return(await collectionCache.ResolveByNameAsync(
                           HttpConstants.Versions.CurrentVersion,
                           this.LinkUri,
                           forceRefresh,
                           cancellationToken));
            }
            catch (DocumentClientException ex)
            {
                throw CosmosExceptionFactory.Create(
                          dce: ex,
                          diagnosticsContext: null);
            }
        }
コード例 #24
0
        public void FeedRangeResponse_ResponseIsAccessible()
        {
            ResponseMessage original = new ResponseMessage(
                System.Net.HttpStatusCode.OK,
                new RequestMessage(),
                new Headers(),
                CosmosExceptionFactory.CreateBadRequestException("test"),
                CosmosDiagnosticsContext.Create(new RequestOptions()));

            original.Content = Mock.Of <MemoryStream>();
            Mock <FeedRangeContinuation> feedContinuation = new Mock <FeedRangeContinuation>();

            ResponseMessage feedRangeResponse = FeedRangeResponse.CreateSuccess(original, feedContinuation.Object);

            Assert.AreEqual(original.Content, feedRangeResponse.Content);
            Assert.AreEqual(original.StatusCode, feedRangeResponse.StatusCode);
            Assert.AreEqual(original.RequestMessage, feedRangeResponse.RequestMessage);
            Assert.AreEqual(original.Headers, feedRangeResponse.Headers);
            Assert.AreEqual(original.CosmosException, feedRangeResponse.CosmosException);
            Assert.AreEqual(original.DiagnosticsContext, feedRangeResponse.DiagnosticsContext);
        }
コード例 #25
0
        public async Task <ThroughputResponse> ReplaceThroughputAsync(
            CosmosDiagnosticsContext diagnosticsContext,
            ThroughputProperties throughputProperties,
            RequestOptions requestOptions       = null,
            CancellationToken cancellationToken = default)
        {
            ThroughputResponse throughputResponse = await this.ReplaceThroughputIfExistsAsync(
                diagnosticsContext,
                throughputProperties,
                requestOptions,
                cancellationToken);

            if (throughputResponse.StatusCode == HttpStatusCode.NotFound)
            {
                throw CosmosExceptionFactory.CreateNotFoundException(
                          message: $"Throughput is not configured for {this.Id}",
                          headers: throughputResponse.Headers,
                          diagnosticsContext: diagnosticsContext);
            }

            return(throughputResponse);
        }
コード例 #26
0
        public void FeedRangeResponse_ResponseIsAccessible()
        {
            Headers         headers  = new Headers();
            ResponseMessage original = new ResponseMessage(
                System.Net.HttpStatusCode.OK,
                new RequestMessage(),
                headers,
                CosmosExceptionFactory.CreateBadRequestException("test", headers),
                NoOpTrace.Singleton)
            {
                Content = Mock.Of <MemoryStream>()
            };
            Mock <FeedRangeContinuation> feedContinuation = new Mock <FeedRangeContinuation>();

            ResponseMessage feedRangeResponse = FeedRangeResponse.CreateSuccess(original, feedContinuation.Object);

            Assert.AreEqual(original.Content, feedRangeResponse.Content);
            Assert.AreEqual(original.StatusCode, feedRangeResponse.StatusCode);
            Assert.AreEqual(original.RequestMessage, feedRangeResponse.RequestMessage);
            Assert.AreEqual(original.Headers, feedRangeResponse.Headers);
            Assert.AreEqual(original.CosmosException, feedRangeResponse.CosmosException);
        }
コード例 #27
0
        public void ValidateErrorHandling()
        {
            Error error = new Error()
            {
                Code                = System.Net.HttpStatusCode.BadRequest.ToString(),
                Message             = "Unsupported Query",
                AdditionalErrorInfo = "Additional error info message",
            };

            CosmosDiagnosticsContext diagnostics = new CosmosDiagnosticsContextCore();

            CosmosException cosmosException = CosmosExceptionFactory.CreateBadRequestException(
                error.ToString(),
                error: error,
                diagnosticsContext: diagnostics);

            ResponseMessage responseMessage = QueryResponse.CreateFailure(
                statusCode: System.Net.HttpStatusCode.BadRequest,
                cosmosException: cosmosException,
                requestMessage: null,
                diagnostics: diagnostics,
                responseHeaders: null);

            Assert.AreEqual(error, responseMessage.CosmosException.Error);
            Assert.IsTrue(responseMessage.ErrorMessage.Contains(error.Message));
            Assert.IsTrue(responseMessage.ErrorMessage.Contains(error.AdditionalErrorInfo));

            try
            {
                responseMessage.EnsureSuccessStatusCode();
                Assert.Fail("Should throw exception");
            }
            catch (CosmosException ce) when(ce.StatusCode == HttpStatusCode.BadRequest)
            {
                Assert.IsTrue(ce.Message.Contains(error.Message));
                Assert.IsTrue(ce.ToString().Contains(error.Message));
                Assert.IsTrue(ce.ToString().Contains(error.AdditionalErrorInfo));
            }
        }
コード例 #28
0
        internal override async Task <ContainerProperties> GetCachedContainerPropertiesAsync(
            string containerUri,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            CosmosDiagnosticsContextCore diagnosticsContext = new CosmosDiagnosticsContextCore();
            ClientCollectionCache        collectionCache    = await this.DocumentClient.GetCollectionCacheAsync();

            try
            {
                using (diagnosticsContext.CreateScope("ContainerCache.ResolveByNameAsync"))
                {
                    return(await collectionCache.ResolveByNameAsync(
                               HttpConstants.Versions.CurrentVersion,
                               containerUri,
                               cancellationToken));
                }
            }
            catch (DocumentClientException ex)
            {
                throw CosmosExceptionFactory.Create(ex, diagnosticsContext);
            }
        }
コード例 #29
0
        public override async Task <List <Documents.Routing.Range <string> > > GetEffectiveRangesAsync(
            IRoutingMapProvider routingMapProvider,
            string containerRid,
            Documents.PartitionKeyDefinition partitionKeyDefinition)
        {
            Documents.PartitionKeyRange pkRange = await routingMapProvider.TryGetPartitionKeyRangeByIdAsync(
                collectionResourceId : containerRid,
                partitionKeyRangeId : this.PartitionKeyRangeId,
                forceRefresh : false);

            if (pkRange == null)
            {
                // Try with a refresh
                pkRange = await routingMapProvider.TryGetPartitionKeyRangeByIdAsync(
                    collectionResourceId : containerRid,
                    partitionKeyRangeId : this.PartitionKeyRangeId,
                    forceRefresh : true);
            }

            if (pkRange == null)
            {
                throw CosmosExceptionFactory.Create(
                          statusCode: HttpStatusCode.Gone,
                          subStatusCode: (int)SubStatusCodes.PartitionKeyRangeGone,
                          message: $"The PartitionKeyRangeId: \"{this.PartitionKeyRangeId}\" is not valid for the current container {containerRid} .",
                          stackTrace: string.Empty,
                          activityId: string.Empty,
                          requestCharge: 0,
                          retryAfter: null,
                          headers: null,
                          diagnosticsContext: null,
                          error: null,
                          innerException: null);
            }

            return(new List <Documents.Routing.Range <string> > {
                pkRange.ToRange()
            });
        }
コード例 #30
0
        internal static ResponseMessage ToCosmosResponseMessage(this StoreResponse storeResponse, RequestMessage requestMessage)
        {
            // If it's considered a failure create the corresponding CosmosException
            if (!storeResponse.StatusCode.IsSuccess())
            {
                CosmosException cosmosException = CosmosExceptionFactory.Create(
                    storeResponse,
                    requestMessage);

                return(cosmosException.ToCosmosResponseMessage(requestMessage));
            }

            // Is status code conversion lossy?
            ResponseMessage responseMessage = new ResponseMessage((HttpStatusCode)storeResponse.Status, requestMessage);

            if (storeResponse.ResponseBody != null)
            {
                responseMessage.Content = storeResponse.ResponseBody;
            }

            return(responseMessage);
        }