private void Initialize()
        {
            if (!this.disposed)
            {
                if (this.serviceProvider == IntPtr.Zero)
                {
                    lock (this.serviceProviderStateLock)
                    {
                        if (!this.disposed && this.serviceProvider == IntPtr.Zero)
                        {
                            TryCatch <IntPtr> tryCreateServiceProvider = QueryPartitionProvider.TryCreateServiceProvider(this.queryengineConfiguration);
                            if (tryCreateServiceProvider.Failed)
                            {
                                throw ExceptionWithStackTraceException.UnWrapMonadExcepion(tryCreateServiceProvider.Exception, NoOpTrace.Singleton);
                            }

                            this.serviceProvider = tryCreateServiceProvider.Result;
                        }
                    }
                }
            }
            else
            {
                throw new ObjectDisposedException(typeof(QueryPartitionProvider).Name);
            }
        }
Esempio n. 2
0
        public static async Task <PartitionedQueryExecutionInfo> GetQueryPlanWithServiceInteropAsync(
            CosmosQueryClient queryClient,
            SqlQuerySpec sqlQuerySpec,
            Documents.ResourceType resourceType,
            PartitionKeyDefinition partitionKeyDefinition,
            bool hasLogicalPartitionKey,
            bool useSystemPrefix,
            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,
                    resourceType,
                    partitionKeyDefinition,
                    QueryPlanRetriever.SupportedQueryFeatures,
                    hasLogicalPartitionKey,
                    useSystemPrefix,
                    cancellationToken);

                if (!tryGetQueryPlan.Succeeded)
                {
                    Exception originalException = ExceptionWithStackTraceException.UnWrapMonadExcepion(tryGetQueryPlan.Exception, serviceInteropTrace);
                    if (originalException is CosmosException)
                    {
                        throw originalException;
                    }

                    throw CosmosExceptionFactory.CreateBadRequestException(
                              message: originalException.Message,
                              headers: new Headers(),
                              stackTrace: tryGetQueryPlan.Exception.StackTrace,
                              innerException: originalException,
                              trace: trace);
                }

                return(tryGetQueryPlan.Result);
            }
        }
        private async Task <ResponseMessage> ReadNextInternalAsync(ITrace trace, CancellationToken cancellationToken = default)
        {
            if (trace == null)
            {
                throw new ArgumentNullException(nameof(trace));
            }

            TryCatch <CrossPartitionChangeFeedAsyncEnumerator> monadicEnumerator = await this.lazyMonadicEnumerator.GetValueAsync(trace, cancellationToken);

            if (monadicEnumerator.Failed)
            {
                Exception createException = monadicEnumerator.Exception;
                if (!ExceptionToCosmosException.TryCreateFromException(
                        createException,
                        trace,
                        out CosmosException cosmosException))
                {
                    // Initialization issue, there are no enumerators to invoke
                    this.hasMoreResults = false;
                    throw createException;
                }

                return(new ResponseMessage(
                           cosmosException.StatusCode,
                           requestMessage: null,
                           headers: cosmosException.Headers,
                           cosmosException: cosmosException,
                           trace: trace));
            }

            CrossPartitionChangeFeedAsyncEnumerator enumerator = monadicEnumerator.Result;

            enumerator.SetCancellationToken(cancellationToken);

            try
            {
                if (!await enumerator.MoveNextAsync(trace))
                {
                    throw new InvalidOperationException("ChangeFeed enumerator should always have a next continuation");
                }
            }
            catch (OperationCanceledException ex) when(!(ex is CosmosOperationCanceledException))
            {
                throw new CosmosOperationCanceledException(ex, trace);
            }

            if (enumerator.Current.Failed)
            {
                if (!ExceptionToCosmosException.TryCreateFromException(
                        enumerator.Current.Exception,
                        trace,
                        out CosmosException cosmosException))
                {
                    throw ExceptionWithStackTraceException.UnWrapMonadExcepion(enumerator.Current.Exception, trace);
                }

                if (!IsRetriableException(cosmosException))
                {
                    this.hasMoreResults = false;
                }

                return(new ResponseMessage(
                           cosmosException.StatusCode,
                           requestMessage: null,
                           headers: cosmosException.Headers,
                           cosmosException: cosmosException,
                           trace: trace));
            }

            CrossFeedRangePage <Pagination.ChangeFeedPage, ChangeFeedState> crossFeedRangePage = enumerator.Current.Result;

            Pagination.ChangeFeedPage changeFeedPage = crossFeedRangePage.Page;
            ResponseMessage           responseMessage;

            if (changeFeedPage is Pagination.ChangeFeedSuccessPage changeFeedSuccessPage)
            {
                responseMessage = new ResponseMessage(statusCode: System.Net.HttpStatusCode.OK)
                {
                    Content = changeFeedSuccessPage.Content
                };
            }
            else
            {
                responseMessage = new ResponseMessage(statusCode: System.Net.HttpStatusCode.NotModified);
            }

            CrossFeedRangeState <ChangeFeedState> crossFeedRangeState           = crossFeedRangePage.State;
            ChangeFeedCrossFeedRangeState         changeFeedCrossFeedRangeState = new ChangeFeedCrossFeedRangeState(crossFeedRangeState.Value);
            string continuationToken = VersionedAndRidCheckedCompositeToken.ToCosmosElement(
                new VersionedAndRidCheckedCompositeToken(
                    VersionedAndRidCheckedCompositeToken.Version.V2,
                    changeFeedCrossFeedRangeState.ToCosmosElement(),
                    await this.documentContainer.GetResourceIdentifierAsync(trace, cancellationToken))).ToString();

            responseMessage.Headers.ContinuationToken = continuationToken;
            responseMessage.Headers.RequestCharge     = changeFeedPage.RequestCharge;
            responseMessage.Headers.ActivityId        = changeFeedPage.ActivityId;
            responseMessage.Trace = trace;

            return(responseMessage);
        }