Example #1
0
        private static TryCatch <IAggregator> TryCreate(bool isMinAggregation, string continuationToken)
        {
            CosmosElement globalMinMax;

            if (continuationToken != null)
            {
                if (continuationToken == MinMaxAggregator.MaxValueContinuationToken)
                {
                    globalMinMax = ItemComparer.MaxValue;
                }
                else if (continuationToken == MinMaxAggregator.MinValueContinuationToken)
                {
                    globalMinMax = ItemComparer.MinValue;
                }
                else if (continuationToken == MinMaxAggregator.UndefinedContinuationToken)
                {
                    globalMinMax = MinMaxAggregator.Undefined;
                }
                else
                {
                    if (!CosmosElement.TryParse(continuationToken, out globalMinMax))
                    {
                        return(TryCatch <IAggregator> .FromException(
                                   new MalformedContinuationTokenException($"Malformed continuation token: {continuationToken}")));
                    }
                }
            }
            else
            {
                globalMinMax = isMinAggregation ? (CosmosElement)ItemComparer.MaxValue : (CosmosElement)ItemComparer.MinValue;
            }

            return(TryCatch <IAggregator> .FromResult(
                       new MinMaxAggregator(isMinAggregation : isMinAggregation, globalMinMax : globalMinMax)));
        }
Example #2
0
        public override async ValueTask <bool> MoveNextAsync(ITrace trace)
        {
            if (trace == null)
            {
                throw new ArgumentNullException(nameof(trace));
            }

            try
            {
                if (!await this.inputStage.MoveNextAsync(trace))
                {
                    this.Current = default;
                    return(false);
                }

                this.Current = this.inputStage.Current;
                return(true);
            }
            catch (Exception ex)
            {
                if (!ExceptionToCosmosException.TryCreateFromException(ex, trace, out CosmosException cosmosException))
                {
                    throw;
                }

                this.Current = TryCatch <QueryPage> .FromException(cosmosException);

                return(true);
            }
        }
            public static TryCatch <IQueryPipelineStage> MonadicCreate(
                DCountInfo info,
                CosmosElement continuationToken,
                CancellationToken cancellationToken,
                MonadicCreatePipelineStage monadicCreatePipelineStage)
            {
                cancellationToken.ThrowIfCancellationRequested();

                DCountContinuationToken dcountContinuationToken;

                if (continuationToken != null)
                {
                    if (!DCountContinuationToken.TryCreateFromCosmosElement(
                            continuationToken,
                            out dcountContinuationToken))
                    {
                        return(TryCatch <IQueryPipelineStage> .FromException(
                                   new MalformedContinuationTokenException(
                                       $"Malfomed {nameof(DCountContinuationToken)}: '{continuationToken}'")));
                    }
                }
                else
                {
                    dcountContinuationToken = new DCountContinuationToken(count: 0, sourceContinuationToken: null);
                }

                TryCatch <IQueryPipelineStage> tryCreateSource;

                if (dcountContinuationToken.SourceContinuationToken is CosmosString stringToken && (stringToken.Value == DoneSourceToken.Value))
                {
                    tryCreateSource = TryCatch <IQueryPipelineStage> .FromResult(EmptyQueryPipelineStage.Singleton);
                }
        private static TryCatch <IReadOnlyList <CompositeContinuationToken> > TryParseCompositeContinuationList(
            CosmosElement requestContinuationToken)
        {
            if (requestContinuationToken == null)
            {
                throw new ArgumentNullException(nameof(requestContinuationToken));
            }

            if (!(requestContinuationToken is CosmosArray compositeContinuationTokenListRaw))
            {
                return(TryCatch <IReadOnlyList <CompositeContinuationToken> > .FromException(
                           new MalformedContinuationTokenException(
                               $"Invalid format for continuation token {requestContinuationToken} for {nameof(CosmosParallelItemQueryExecutionContext)}")));
            }

            List <CompositeContinuationToken> compositeContinuationTokens = new List <CompositeContinuationToken>();

            foreach (CosmosElement compositeContinuationTokenRaw in compositeContinuationTokenListRaw)
            {
                TryCatch <CompositeContinuationToken> tryCreateCompositeContinuationToken = CompositeContinuationToken.TryCreateFromCosmosElement(compositeContinuationTokenRaw);
                if (!tryCreateCompositeContinuationToken.Succeeded)
                {
                    return(TryCatch <IReadOnlyList <CompositeContinuationToken> > .FromException(tryCreateCompositeContinuationToken.Exception));
                }

                compositeContinuationTokens.Add(tryCreateCompositeContinuationToken.Result);
            }

            return(TryCatch <IReadOnlyList <CompositeContinuationToken> > .FromResult(compositeContinuationTokens));
        }
            protected override Task <TryCatch <OrderByQueryPage> > GetNextPageAsync(ITrace trace, CancellationToken cancellationToken)
            {
                // Unfortunately we need to keep both the epk range and partition key for queries
                // Since the continuation token format uses epk range even though we only need the partition key to route the request.
                FeedRangeInternal feedRange = this.PartitionKey.HasValue ? new FeedRangePartitionKey(this.PartitionKey.Value) : this.Range;

                return(this.queryDataSource
                       .MonadicQueryAsync(
                           sqlQuerySpec: this.SqlQuerySpec,
                           continuationToken: this.State == null ? null : ((CosmosString)this.State.Value).Value,
                           feedRange: feedRange,
                           pageSize: this.PageSize,
                           trace: trace,
                           cancellationToken)
                       .ContinueWith <TryCatch <OrderByQueryPage> >(antecedent =>
                {
                    TryCatch <QueryPage> monadicQueryPage = antecedent.Result;
                    if (monadicQueryPage.Failed)
                    {
                        return TryCatch <OrderByQueryPage> .FromException(monadicQueryPage.Exception);
                    }

                    QueryPage queryPage = monadicQueryPage.Result;
                    return TryCatch <OrderByQueryPage> .FromResult(new OrderByQueryPage(queryPage));
                }));
            }
        private static TryCatch <PartitionMapping <CompositeContinuationToken> > TryGetPartitionKeyRangeToCompositeContinuationToken(
            IReadOnlyList <PartitionKeyRange> partitionKeyRanges,
            CosmosElement continuationToken)
        {
            if (continuationToken == null)
            {
                Dictionary <PartitionKeyRange, CompositeContinuationToken> dictionary = new Dictionary <PartitionKeyRange, CompositeContinuationToken>();
                foreach (PartitionKeyRange partitionKeyRange in partitionKeyRanges)
                {
                    dictionary.Add(key: partitionKeyRange, value: null);
                }

                return(TryCatch <PartitionMapping <CompositeContinuationToken> > .FromResult(
                           new PartitionMapping <CompositeContinuationToken>(
                               partitionsLeftOfTarget : new Dictionary <PartitionKeyRange, CompositeContinuationToken>(),
                               targetPartition : dictionary,
                               partitionsRightOfTarget : new Dictionary <PartitionKeyRange, CompositeContinuationToken>())));
            }

            TryCatch <IReadOnlyList <CompositeContinuationToken> > tryParseCompositeContinuationTokens = TryParseCompositeContinuationList(continuationToken);

            if (!tryParseCompositeContinuationTokens.Succeeded)
            {
                return(TryCatch <PartitionMapping <CompositeContinuationToken> > .FromException(tryParseCompositeContinuationTokens.Exception));
            }

            return(CosmosCrossPartitionQueryExecutionContext.TryGetInitializationInfo <CompositeContinuationToken>(
                       partitionKeyRanges,
                       tryParseCompositeContinuationTokens.Result));
        }
        private async Task<TryCatch<FeedTokenInternal>> TryInitializeFeedTokenAsync(CancellationToken cancellationToken)
        {
            string containerRId = string.Empty;
            if (this.containerCore != null)
            {
                try
                {
                    containerRId = await this.containerCore.GetRIDAsync(cancellationToken);
                }
                catch (Exception cosmosException)
                {
                    return TryCatch<FeedTokenInternal>.FromException(cosmosException);
                }
            }

            // Create FeedToken for the full Range
            FeedTokenEPKRange feedTokenInternal = new FeedTokenEPKRange(
                containerRId,
                new PartitionKeyRange()
                {
                    MinInclusive = Documents.Routing.PartitionKeyInternal.MinimumInclusiveEffectivePartitionKey,
                    MaxExclusive = Documents.Routing.PartitionKeyInternal.MaximumExclusiveEffectivePartitionKey
                });
            // Initialize with the ContinuationToken that the user passed, if any
            if (this.ContinuationToken != null)
            {
                feedTokenInternal.UpdateContinuation(this.ContinuationToken);
            }

            return TryCatch<FeedTokenInternal>.FromResult(feedTokenInternal);
        }
        public TryCatch <PartitionedQueryExecutionInfo> TryGetPartitionedQueryExecutionInfo(
            SqlQuerySpec querySpec,
            PartitionKeyDefinition partitionKeyDefinition,
            bool requireFormattableOrderByQuery,
            bool isContinuationExpected,
            bool allowNonValueAggregateQuery,
            bool hasLogicalPartitionKey,
            bool allowDCount)
        {
            TryCatch <PartitionedQueryExecutionInfoInternal> tryGetInternalQueryInfo = this.TryGetPartitionedQueryExecutionInfoInternal(
                querySpec: querySpec,
                partitionKeyDefinition: partitionKeyDefinition,
                requireFormattableOrderByQuery: requireFormattableOrderByQuery,
                isContinuationExpected: isContinuationExpected,
                allowNonValueAggregateQuery: allowNonValueAggregateQuery,
                hasLogicalPartitionKey: hasLogicalPartitionKey,
                allowDCount: allowDCount);

            if (!tryGetInternalQueryInfo.Succeeded)
            {
                return(TryCatch <PartitionedQueryExecutionInfo> .FromException(tryGetInternalQueryInfo.Exception));
            }

            PartitionedQueryExecutionInfo queryInfo = this.ConvertPartitionedQueryExecutionInfo(tryGetInternalQueryInfo.Result, partitionKeyDefinition);

            return(TryCatch <PartitionedQueryExecutionInfo> .FromResult(queryInfo));
        }
Example #9
0
            public static TryCatch <IQueryPipelineStage> MonadicCreate(
                CosmosElement requestContinuation,
                CancellationToken cancellationToken,
                MonadicCreatePipelineStage monadicCreatePipelineStage,
                IReadOnlyDictionary <string, AggregateOperator?> groupByAliasToAggregateType,
                IReadOnlyList <string> orderedAliases,
                bool hasSelectValue,
                int pageSize)
            {
                TryCatch <GroupingTable> tryCreateGroupingTable = GroupingTable.TryCreateFromContinuationToken(
                    groupByAliasToAggregateType,
                    orderedAliases,
                    hasSelectValue,
                    continuationToken: null);

                if (tryCreateGroupingTable.Failed)
                {
                    return(TryCatch <IQueryPipelineStage> .FromException(tryCreateGroupingTable.Exception));
                }

                TryCatch <IQueryPipelineStage> tryCreateSource = monadicCreatePipelineStage(requestContinuation, cancellationToken);

                if (tryCreateSource.Failed)
                {
                    return(tryCreateSource);
                }

                IQueryPipelineStage stage = new ClientGroupByQueryPipelineStage(
                    tryCreateSource.Result,
                    cancellationToken,
                    tryCreateGroupingTable.Result,
                    pageSize);

                return(TryCatch <IQueryPipelineStage> .FromResult(stage));
            }
Example #10
0
            public static async Task <TryCatch <T> > Retry429 <T>(
                Func <Task <TryCatch <T> > > function,
                int maxRetryCount          = 10,
                int maxDelayInMilliseconds = 10000)
            {
                TryCatch <T> tryMonad = await function();

                return(await tryMonad.CatchAsync(
                           onError : async(exception) =>
                {
                    if (!(exception is RequestRateTooLargeException requestRateTooLargeExecption))
                    {
                        return TryCatch <T> .FromException(exception);
                    }

                    if (maxRetryCount <= 0)
                    {
                        return TryCatch <T> .FromException(requestRateTooLargeExecption);
                    }

                    if (requestRateTooLargeExecption.RetryAfter.TotalMilliseconds > maxDelayInMilliseconds)
                    {
                        return TryCatch <T> .FromException(requestRateTooLargeExecption);
                    }

                    await Task.Delay(requestRateTooLargeExecption.RetryAfter);

                    return await Retry429(
                        function,
                        maxRetryCount - 1,
                        maxDelayInMilliseconds);
                }));
            }
Example #11
0
        public async ValueTask <bool> MoveNextAsync()
        {
            if (!await this.enumerator.MoveNextAsync())
            {
                return(false);
            }

            TryCatch <CrossFeedRangePage <Pagination.ReadFeedPage, ReadFeedState> > monadicInnerReadFeedPage = this.enumerator.Current;

            if (monadicInnerReadFeedPage.Failed)
            {
                this.Current = TryCatch <ReadFeedPage> .FromException(monadicInnerReadFeedPage.Exception);

                return(true);
            }

            CrossFeedRangePage <Pagination.ReadFeedPage, ReadFeedState> innerReadFeedPage = monadicInnerReadFeedPage.Result;
            CrossFeedRangeState <ReadFeedState> crossFeedRangeState = innerReadFeedPage.State;
            ReadFeedCrossFeedRangeState?        state = crossFeedRangeState != null ? new ReadFeedCrossFeedRangeState(crossFeedRangeState.Value) : (ReadFeedCrossFeedRangeState?)null;

            CosmosArray documents = CosmosQueryClientCore.ParseElementsFromRestStream(
                innerReadFeedPage.Page.Content,
                Documents.ResourceType.Document,
                cosmosSerializationOptions: null);
            ReadFeedPage page = new ReadFeedPage(
                documents,
                innerReadFeedPage.Page.RequestCharge,
                innerReadFeedPage.Page.ActivityId,
                state);

            this.Current = TryCatch <ReadFeedPage> .FromResult(page);

            return(true);
        }
Example #12
0
            public static async Task <TryCatch <IDocumentQueryExecutionComponent> > TryCreateAsync(
                CosmosElement requestContinuation,
                Func <CosmosElement, Task <TryCatch <IDocumentQueryExecutionComponent> > > tryCreateSourceAsync,
                IReadOnlyDictionary <string, AggregateOperator?> groupByAliasToAggregateType,
                IReadOnlyList <string> orderedAliases,
                bool hasSelectValue)
            {
                GroupByContinuationToken groupByContinuationToken;

                if (requestContinuation != null)
                {
                    if (!GroupByContinuationToken.TryParse(requestContinuation, out groupByContinuationToken))
                    {
                        return(TryCatch <IDocumentQueryExecutionComponent> .FromException(
                                   new MalformedContinuationTokenException($"Invalid {nameof(GroupByContinuationToken)}: '{requestContinuation}'")));
                    }
                }
                else
                {
                    groupByContinuationToken = new GroupByContinuationToken(
                        groupingTableContinuationToken: null,
                        sourceContinuationToken: null);
                }

                TryCatch <IDocumentQueryExecutionComponent> tryCreateSource;

                if ((groupByContinuationToken.SourceContinuationToken is CosmosString sourceContinuationToken) &&
                    (sourceContinuationToken.Value == ComputeGroupByDocumentQueryExecutionComponent.DoneReadingGroupingsContinuationToken))
                {
                    tryCreateSource = TryCatch <IDocumentQueryExecutionComponent> .FromResult(DoneDocumentQueryExecutionComponent.Value);
                }
Example #13
0
            internal static TryCatch <ChangeFeedCrossFeedRangeState> CreateFromCosmosElement(CosmosElement cosmosElement)
            {
                if (cosmosElement == null)
                {
                    throw new ArgumentNullException(nameof(cosmosElement));
                }

                if (!(cosmosElement is CosmosArray cosmosArray))
                {
                    return(TryCatch <ChangeFeedCrossFeedRangeState> .FromException(
                               new FormatException(
                                   $"Expected array: {cosmosElement}")));
                }

                List <FeedRangeState <ChangeFeedState> > changeFeedFeedRangeStates = new List <FeedRangeState <ChangeFeedState> >(capacity: cosmosArray.Count);

                foreach (CosmosElement arrayItem in cosmosArray)
                {
                    TryCatch <FeedRangeState <ChangeFeedState> > monadicChangeFeedFeedRangeState = ChangeFeedFeedRangeStateSerializer.Monadic.CreateFromCosmosElement(arrayItem);
                    if (monadicChangeFeedFeedRangeState.Failed)
                    {
                        return(TryCatch <ChangeFeedCrossFeedRangeState> .FromException(monadicChangeFeedFeedRangeState.Exception));
                    }

                    changeFeedFeedRangeStates.Add(monadicChangeFeedFeedRangeState.Result);
                }

                ImmutableArray <FeedRangeState <ChangeFeedState> > feedRangeStates = changeFeedFeedRangeStates.ToImmutableArray();
                ChangeFeedCrossFeedRangeState changeFeedCrossFeedRangeState        = new ChangeFeedCrossFeedRangeState(feedRangeStates);

                return(TryCatch <ChangeFeedCrossFeedRangeState> .FromResult(changeFeedCrossFeedRangeState));
            }
Example #14
0
            public static TryCatch <TCosmosElement> CreateFromBuffer <TCosmosElement>(ReadOnlyMemory <byte> buffer)
                where TCosmosElement : CosmosElement
            {
                if (buffer.IsEmpty)
                {
                    TryCatch <TCosmosElement> .FromException(
                        new ArgumentException($"{nameof(buffer)} must not be empty."));
                }

                CosmosElement unTypedCosmosElement;

                try
                {
                    IJsonNavigator     jsonNavigator     = JsonNavigator.Create(buffer);
                    IJsonNavigatorNode jsonNavigatorNode = jsonNavigator.GetRootNode();
                    unTypedCosmosElement = CosmosElement.Dispatch(jsonNavigator, jsonNavigatorNode);
                }
                catch (JsonParseException jpe)
                {
                    return(TryCatch <TCosmosElement> .FromException(jpe));
                }

                if (!(unTypedCosmosElement is TCosmosElement typedCosmosElement))
                {
                    return(TryCatch <TCosmosElement> .FromException(
                               new CosmosElementWrongTypeException(
                                   message : $"buffer was incorrect cosmos element type: {unTypedCosmosElement.GetType()} when {typeof(TCosmosElement)} was requested.")));
                }

                return(TryCatch <TCosmosElement> .FromResult(typedCosmosElement));
            }
Example #15
0
        public static TryCatch <CrossPartitionChangeFeedAsyncEnumerator> MonadicCreate(
            IDocumentContainer documentContainer,
            ChangeFeedRequestOptions changeFeedRequestOptions,
            ChangeFeedStartFrom changeFeedStartFrom,
            CancellationToken cancellationToken)
        {
            changeFeedRequestOptions ??= new ChangeFeedRequestOptions();

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

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

            TryCatch <CrossPartitionState <ChangeFeedState> > monadicCrossPartitionState = changeFeedStartFrom.Accept(CrossPartitionStateExtractor.Singleton);

            if (monadicCrossPartitionState.Failed)
            {
                return(TryCatch <CrossPartitionChangeFeedAsyncEnumerator> .FromException(monadicCrossPartitionState.Exception));
            }

            CrossPartitionRangePageAsyncEnumerator <ChangeFeedPage, ChangeFeedState> crossPartitionEnumerator = new CrossPartitionRangePageAsyncEnumerator <ChangeFeedPage, ChangeFeedState>(
                documentContainer,
                CrossPartitionChangeFeedAsyncEnumerator.MakeCreateFunction(
                    documentContainer,
                    changeFeedRequestOptions.PageSizeHint.GetValueOrDefault(int.MaxValue),
                    cancellationToken),
                comparer: default /* this uses a regular queue instead of prioirty queue */,
            public static TryCatch <IQueryPipelineStage> MonadicCreate(
                CosmosElement requestContinuation,
                CancellationToken cancellationToken,
                MonadicCreatePipelineStage monadicCreatePipelineStage,
                IReadOnlyDictionary <string, AggregateOperator?> groupByAliasToAggregateType,
                IReadOnlyList <string> orderedAliases,
                bool hasSelectValue,
                int pageSize)
            {
                GroupByContinuationToken groupByContinuationToken;

                if (requestContinuation != null)
                {
                    if (!GroupByContinuationToken.TryParse(requestContinuation, out groupByContinuationToken))
                    {
                        return(TryCatch <IQueryPipelineStage> .FromException(
                                   new MalformedContinuationTokenException(
                                       $"Invalid {nameof(GroupByContinuationToken)}: '{requestContinuation}'")));
                    }
                }
                else
                {
                    groupByContinuationToken = new GroupByContinuationToken(
                        groupingTableContinuationToken: null,
                        sourceContinuationToken: null);
                }

                TryCatch <IQueryPipelineStage> tryCreateSource;

                if ((groupByContinuationToken.SourceContinuationToken is CosmosString sourceContinuationToken) &&
                    (sourceContinuationToken.Value == ComputeGroupByQueryPipelineStage.DoneReadingGroupingsContinuationToken))
                {
                    tryCreateSource = TryCatch <IQueryPipelineStage> .FromResult(EmptyQueryPipelineStage.Singleton);
                }
            public static async Task <TryCatch <IDocumentQueryExecutionComponent> > TryCreateAsync(
                IReadOnlyList <AggregateOperator> aggregates,
                IReadOnlyDictionary <string, AggregateOperator?> aliasToAggregateType,
                IReadOnlyList <string> orderedAliases,
                bool hasSelectValue,
                CosmosElement continuationToken,
                Func <CosmosElement, Task <TryCatch <IDocumentQueryExecutionComponent> > > tryCreateSourceAsync)
            {
                if (tryCreateSourceAsync == null)
                {
                    throw new ArgumentNullException(nameof(tryCreateSourceAsync));
                }

                TryCatch <SingleGroupAggregator> tryCreateSingleGroupAggregator = SingleGroupAggregator.TryCreate(
                    aggregates,
                    aliasToAggregateType,
                    orderedAliases,
                    hasSelectValue,
                    continuationToken: null);

                if (!tryCreateSingleGroupAggregator.Succeeded)
                {
                    return(TryCatch <IDocumentQueryExecutionComponent> .FromException(tryCreateSingleGroupAggregator.Exception));
                }

                return((await tryCreateSourceAsync(continuationToken))
                       .Try <IDocumentQueryExecutionComponent>((source) =>
                {
                    return new ClientAggregateDocumentQueryExecutionComponent(
                        source,
                        tryCreateSingleGroupAggregator.Result,
                        hasSelectValue);
                }));
            }
            public static async Task <TryCatch <IDocumentQueryExecutionComponent> > TryCreateAsync(
                CosmosElement requestContinuation,
                Func <CosmosElement, Task <TryCatch <IDocumentQueryExecutionComponent> > > tryCreateSource,
                IReadOnlyDictionary <string, AggregateOperator?> groupByAliasToAggregateType,
                IReadOnlyList <string> orderedAliases,
                bool hasSelectValue)
            {
                TryCatch <GroupingTable> tryCreateGroupingTable = GroupingTable.TryCreateFromContinuationToken(
                    groupByAliasToAggregateType,
                    orderedAliases,
                    hasSelectValue,
                    continuationToken: null);

                if (!tryCreateGroupingTable.Succeeded)
                {
                    return(TryCatch <IDocumentQueryExecutionComponent> .FromException(tryCreateGroupingTable.Exception));
                }

                return((await tryCreateSource(requestContinuation)).Try <IDocumentQueryExecutionComponent>(source =>
                {
                    return new ClientGroupByDocumentQueryExecutionComponent(
                        source,
                        tryCreateGroupingTable.Result);
                }));
            }
        private async Task <TryCatch <FeedTokenInternal> > TryInitializeFeedTokenAsync(CancellationToken cancellationToken)
        {
            Routing.PartitionKeyRangeCache partitionKeyRangeCache = await this.clientContext.DocumentClient.GetPartitionKeyRangeCacheAsync();

            string containerRId = string.Empty;

            try
            {
                containerRId = await this.container.GetRIDAsync(cancellationToken);
            }
            catch (Exception cosmosException)
            {
                return(TryCatch <FeedTokenInternal> .FromException(cosmosException));
            }

            IReadOnlyList <Documents.PartitionKeyRange> partitionKeyRanges = await partitionKeyRangeCache.TryGetOverlappingRangesAsync(
                containerRId,
                new Documents.Routing.Range <string>(
                    Documents.Routing.PartitionKeyInternal.MinimumInclusiveEffectivePartitionKey,
                    Documents.Routing.PartitionKeyInternal.MaximumExclusiveEffectivePartitionKey,
                    isMinInclusive: true,
                    isMaxInclusive: false),
                forceRefresh : true);

            // ReadAll scenario, initialize with one token for all
            return(TryCatch <FeedTokenInternal> .FromResult(new FeedTokenEPKRange(containerRId, partitionKeyRanges)));
        }
        public async ValueTask <bool> MoveNextAsync(ITrace trace)
        {
            if (trace == null)
            {
                throw new ArgumentNullException(nameof(trace));
            }

            using (ITrace moveNextAsyncTrace = trace.StartChild(name: nameof(MoveNextAsync), component: TraceComponent.ReadFeed, level: TraceLevel.Info))
            {
                if (!await this.crossPartitionEnumerator.MoveNextAsync(moveNextAsyncTrace))
                {
                    this.Current = default;
                    return(false);
                }

                TryCatch <CrossFeedRangePage <ReadFeedPage, ReadFeedState> > monadicCrossPartitionPage = this.crossPartitionEnumerator.Current;
                if (monadicCrossPartitionPage.Failed)
                {
                    this.Current = TryCatch <CrossFeedRangePage <ReadFeedPage, ReadFeedState> > .FromException(monadicCrossPartitionPage.Exception);

                    return(true);
                }

                CrossFeedRangePage <ReadFeedPage, ReadFeedState> crossPartitionPage = monadicCrossPartitionPage.Result;
                this.Current = TryCatch <CrossFeedRangePage <ReadFeedPage, ReadFeedState> > .FromResult(crossPartitionPage);

                return(true);
            }
        }
Example #21
0
        public override async ValueTask <bool> MoveNextAsync()
        {
            this.cancellationToken.ThrowIfCancellationRequested();

            try
            {
                if (!await this.inputStage.MoveNextAsync())
                {
                    this.Current = default;
                    return(false);
                }

                this.Current = this.inputStage.Current;
                return(true);
            }
            catch (OperationCanceledException) when(this.cancellationToken.IsCancellationRequested)
            {
                // Per cancellationToken.ThrowIfCancellationRequested(); line above, this function should still throw OperationCanceledException.
                throw;
            }
            catch (Exception ex)
            {
                CosmosException cosmosException = ExceptionToCosmosException.CreateFromException(ex);
                this.Current = TryCatch <QueryPage> .FromException(cosmosException);

                return(true);
            }
        }
            internal static TryCatch <ReadFeedCrossFeedRangeState> CreateFromCosmosElement(CosmosElement cosmosElement)
            {
                if (cosmosElement == null)
                {
                    throw new ArgumentNullException(nameof(cosmosElement));
                }

                if (!(cosmosElement is CosmosArray cosmosArray))
                {
                    return(TryCatch <ReadFeedCrossFeedRangeState> .FromException(
                               new FormatException(
                                   $"Expected array: {cosmosElement}")));
                }

                FeedRangeState <ReadFeedState>[] feedRangeStates = new FeedRangeState <ReadFeedState> [cosmosArray.Count];
                int i = 0;

                foreach (CosmosElement arrayItem in cosmosArray)
                {
                    TryCatch <FeedRangeState <ReadFeedState> > monadicFeedRangeState = ReadFeedFeedRangeStateSerializer.Monadic.CreateFromCosmosElement(arrayItem);
                    if (monadicFeedRangeState.Failed)
                    {
                        return(TryCatch <ReadFeedCrossFeedRangeState> .FromException(monadicFeedRangeState.Exception));
                    }

                    feedRangeStates[i++] = monadicFeedRangeState.Result;
                }

                ReadFeedCrossFeedRangeState crossFeedRangeState = new ReadFeedCrossFeedRangeState(feedRangeStates.AsMemory());

                return(TryCatch <ReadFeedCrossFeedRangeState> .FromResult(crossFeedRangeState));
            }
Example #23
0
        public async Task <TryCatch <QueryPage> > VisitAsync(
            FeedRangeEpk feedRange,
            Arguments argument,
            CancellationToken cancellationToken)
        {
            // Check to see if it lines up exactly with one physical partition
            TryCatch <List <PartitionKeyRange> > tryGetFeedRanges = await this.documentContainer.MonadicGetChildRangeAsync(
                new PartitionKeyRange()
            {
                MinInclusive = feedRange.Range.Min,
                MaxExclusive = feedRange.Range.Max,
            },
                cancellationToken);

            if (tryGetFeedRanges.Failed)
            {
                return(TryCatch <QueryPage> .FromException(tryGetFeedRanges.Exception));
            }

            List <PartitionKeyRange> feedRanges = tryGetFeedRanges.Result;

            if (feedRanges.Count != 1)
            {
                // Simulate a split exception, since we don't have a partition key range id to route to.
                CosmosException goneException = new CosmosException(
                    message: $"Epk Range: {feedRange.Range} is gone.",
                    statusCode: System.Net.HttpStatusCode.Gone,
                    subStatusCode: (int)SubStatusCodes.PartitionKeyRangeGone,
                    activityId: Guid.NewGuid().ToString(),
                    requestCharge: default);
            public static TryCatch <SingleGroupAggregator> TryCreate(
                IReadOnlyDictionary <string, AggregateOperator?> aggregateAliasToAggregateType,
                IReadOnlyList <string> orderedAliases,
                string continuationToken)
            {
                CosmosObject aliasToContinuationToken;

                if (continuationToken != null)
                {
                    if (!CosmosElement.TryParse(continuationToken, out aliasToContinuationToken))
                    {
                        return(TryCatch <SingleGroupAggregator> .FromException(
                                   new MalformedContinuationTokenException(
                                       $"{nameof(SelectListAggregateValues)} continuation token is malformed: {continuationToken}.")));
                    }
                }
                else
                {
                    aliasToContinuationToken = null;
                }

                Dictionary <string, AggregateValue> groupingTable = new Dictionary <string, AggregateValue>();

                foreach (KeyValuePair <string, AggregateOperator?> aliasToAggregate in aggregateAliasToAggregateType)
                {
                    string            alias             = aliasToAggregate.Key;
                    AggregateOperator?aggregateOperator = aliasToAggregate.Value;
                    string            aliasContinuationToken;
                    if (aliasToContinuationToken != null)
                    {
                        if (!(aliasToContinuationToken[alias] is CosmosString parsedAliasContinuationToken))
                        {
                            return(TryCatch <SingleGroupAggregator> .FromException(
                                       new MalformedContinuationTokenException(
                                           $"{nameof(SelectListAggregateValues)} continuation token is malformed: {continuationToken}.")));
                        }

                        aliasContinuationToken = parsedAliasContinuationToken.Value;
                    }
                    else
                    {
                        aliasContinuationToken = null;
                    }

                    TryCatch <AggregateValue> tryCreateAggregateValue = AggregateValue.TryCreate(
                        aggregateOperator,
                        aliasContinuationToken);
                    if (tryCreateAggregateValue.Succeeded)
                    {
                        groupingTable[alias] = tryCreateAggregateValue.Result;
                    }
                    else
                    {
                        return(TryCatch <SingleGroupAggregator> .FromException(tryCreateAggregateValue.Exception));
                    }
                }

                return(TryCatch <SingleGroupAggregator> .FromResult(new SelectListAggregateValues(groupingTable, orderedAliases)));
            }
            public TryCatch <object> Visit(CosmosNull cosmosNull, Type type)
            {
                if (type.IsValueType && !(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)))
                {
                    return(TryCatch <object> .FromException(Visitor.Exceptions.ExpectedReferenceOrNullableType));
                }

                return(TryCatch <object> .FromResult(default));
            public static TryCatch <GroupingTable> TryCreateFromContinuationToken(
                IReadOnlyDictionary <string, AggregateOperator?> groupByAliasToAggregateType,
                IReadOnlyList <string> orderedAliases,
                bool hasSelectValue,
                string groupingTableContinuationToken)
            {
                GroupingTable groupingTable = new GroupingTable(
                    groupByAliasToAggregateType,
                    orderedAliases,
                    hasSelectValue);

                if (groupingTableContinuationToken != null)
                {
                    if (!CosmosElement.TryParse(
                            groupingTableContinuationToken,
                            out CosmosObject parsedGroupingTableContinuations))
                    {
                        return(TryCatch <GroupingTable> .FromException(
                                   new MalformedContinuationTokenException($"Invalid GroupingTableContinuationToken")));
                    }

                    foreach (KeyValuePair <string, CosmosElement> kvp in parsedGroupingTableContinuations)
                    {
                        string        key   = kvp.Key;
                        CosmosElement value = kvp.Value;

                        if (!UInt128.TryParse(key, out UInt128 groupByKey))
                        {
                            return(TryCatch <GroupingTable> .FromException(
                                       new MalformedContinuationTokenException($"Invalid GroupingTableContinuationToken")));
                        }

                        if (!(value is CosmosString singleGroupAggregatorContinuationToken))
                        {
                            return(TryCatch <GroupingTable> .FromException(
                                       new MalformedContinuationTokenException($"Invalid GroupingTableContinuationToken")));
                        }

                        TryCatch <SingleGroupAggregator> tryCreateSingleGroupAggregator = SingleGroupAggregator.TryCreate(
                            EmptyAggregateOperators,
                            groupByAliasToAggregateType,
                            orderedAliases,
                            hasSelectValue,
                            singleGroupAggregatorContinuationToken.Value);

                        if (tryCreateSingleGroupAggregator.Succeeded)
                        {
                            groupingTable.table[groupByKey] = tryCreateSingleGroupAggregator.Result;
                        }
                        else
                        {
                            return(TryCatch <GroupingTable> .FromException(tryCreateSingleGroupAggregator.Exception));
                        }
                    }
                }

                return(TryCatch <GroupingTable> .FromResult(groupingTable));
            }
        public static TryCatch <CompositeContinuationToken> TryCreateFromCosmosElement(CosmosElement cosmosElement)
        {
            if (!(cosmosElement is CosmosObject cosmosObject))
            {
                return(TryCatch <CompositeContinuationToken> .FromException(
                           new MalformedContinuationTokenException($"{nameof(CompositeContinuationToken)} is not an object: {cosmosElement}")));
            }

            if (!cosmosObject.TryGetValue(PropertyNames.Token, out CosmosElement rawToken))
            {
                return(TryCatch <CompositeContinuationToken> .FromException(
                           new MalformedContinuationTokenException($"{nameof(CompositeContinuationToken)} is missing field: '{PropertyNames.Token}': {cosmosElement}")));
            }

            string token;

            if (rawToken is CosmosString rawTokenString)
            {
                token = rawTokenString.Value;
            }
            else
            {
                token = null;
            }

            if (!cosmosObject.TryGetValue(PropertyNames.Range, out CosmosObject rawRange))
            {
                return(TryCatch <CompositeContinuationToken> .FromException(
                           new MalformedContinuationTokenException($"{nameof(CompositeContinuationToken)} is missing field: '{PropertyNames.Range}': {cosmosElement}")));
            }

            if (!rawRange.TryGetValue(PropertyNames.Min, out CosmosString rawMin))
            {
                return(TryCatch <CompositeContinuationToken> .FromException(
                           new MalformedContinuationTokenException($"{nameof(CompositeContinuationToken)} is missing field: '{PropertyNames.Min}': {cosmosElement}")));
            }

            string min = rawMin.Value;

            if (!rawRange.TryGetValue(PropertyNames.Max, out CosmosString rawMax))
            {
                return(TryCatch <CompositeContinuationToken> .FromException(
                           new MalformedContinuationTokenException($"{nameof(CompositeContinuationToken)} is missing field: '{PropertyNames.Max}': {cosmosElement}")));
            }

            string max = rawMax.Value;

            Documents.Routing.Range <string> range = new Documents.Routing.Range <string>(min, max, true, false);

            CompositeContinuationToken compositeContinuationToken = new CompositeContinuationToken()
            {
                Token = token,
                Range = range,
            };

            return(TryCatch <CompositeContinuationToken> .FromResult(compositeContinuationToken));
        }
            public TryCatch <object> Visit(CosmosGuid cosmosGuid, Type type)
            {
                if (type != typeof(Guid))
                {
                    return(TryCatch <object> .FromException(Visitor.Exceptions.ExpectedGuid));
                }

                return(TryCatch <object> .FromResult((object)cosmosGuid.Value));
            }
            public TryCatch <object> Visit(CosmosBoolean cosmosBoolean, Type type)
            {
                if (type != typeof(bool))
                {
                    return(TryCatch <object> .FromException(Visitor.Exceptions.ExpectedBoolean));
                }

                return(TryCatch <object> .FromResult(cosmosBoolean.Value?Visitor.BoxedValues.True : Visitor.BoxedValues.False));
            }
            public TryCatch <object> Visit(CosmosBinary cosmosBinary, Type type)
            {
                if (type != typeof(ReadOnlyMemory <byte>))
                {
                    return(TryCatch <object> .FromException(Visitor.Exceptions.ExpectedBinary));
                }

                return(TryCatch <object> .FromResult((object)cosmosBinary.Value));
            }