Esempio n. 1
0
        public static CrossPartitionChangeFeedAsyncEnumerator Create(
            IDocumentContainer documentContainer,
            ChangeFeedMode changeFeedMode,
            ChangeFeedRequestOptions changeFeedRequestOptions,
            CrossFeedRangeState <ChangeFeedState> state,
            CancellationToken cancellationToken)
        {
            changeFeedRequestOptions ??= new ChangeFeedRequestOptions();

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

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

            CrossPartitionRangePageAsyncEnumerator <ChangeFeedPage, ChangeFeedState> crossPartitionEnumerator = new CrossPartitionRangePageAsyncEnumerator <ChangeFeedPage, ChangeFeedState>(
                documentContainer,
                CrossPartitionChangeFeedAsyncEnumerator.MakeCreateFunction(
                    documentContainer,
                    changeFeedRequestOptions.PageSizeHint.GetValueOrDefault(int.MaxValue),
                    changeFeedMode,
                    changeFeedRequestOptions?.JsonSerializationFormatOptions?.JsonSerializationFormat,
                    cancellationToken),
                comparer: default /* this uses a regular queue instead of prioirty queue */,
Esempio n. 2
0
 public ChangeFeedPaginationOptions(
     ChangeFeedMode mode,
     int?pageSizeHint = null,
     JsonSerializationFormat?jsonSerializationFormat = null,
     Dictionary <string, string> additionalHeaders   = null)
     : base(pageSizeHint, jsonSerializationFormat, additionalHeaders)
 {
     this.Mode = mode ?? throw new ArgumentNullException(nameof(mode));
 }
Esempio n. 3
0
 public ChangeFeedCrossFeedRangeAsyncEnumerable(
     IDocumentContainer documentContainer,
     ChangeFeedMode changeFeedMode,
     ChangeFeedRequestOptions changeFeedRequestOptions,
     ChangeFeedCrossFeedRangeState state)
 {
     this.documentContainer        = documentContainer ?? throw new ArgumentNullException(nameof(documentContainer));
     this.changeFeedMode           = changeFeedMode ?? throw new ArgumentNullException(nameof(changeFeedMode));
     this.changeFeedRequestOptions = changeFeedRequestOptions;
     this.state = state;
 }
 public override FeedIterator <T> GetChangeFeedIterator <T>(
     ChangeFeedStartFrom changeFeedStartFrom,
     ChangeFeedMode changeFeedMode,
     ChangeFeedRequestOptions changeFeedRequestOptions = null)
 {
     return(new EncryptionFeedIterator <T>(
                (EncryptionFeedIterator)this.GetChangeFeedStreamIterator(
                    changeFeedStartFrom,
                    changeFeedMode,
                    changeFeedRequestOptions),
                this.ResponseFactory));
 }
Esempio n. 5
0
 public override FeedIterator GetChangeFeedStreamIterator(
     ChangeFeedStartFrom changeFeedStartFrom,
     ChangeFeedMode changeFeedMode,
     ChangeFeedRequestOptions changeFeedRequestOptions = null)
 {
     return(new EncryptionFeedIterator(
                this.Container.GetChangeFeedStreamIterator(
                    changeFeedStartFrom,
                    changeFeedMode,
                    changeFeedRequestOptions),
                this.EncryptionProcessor));
 }
 public EncryptionFeedIterator(
     EncryptionContainer encryptionContainer,
     ChangeFeedStartFrom changeFeedStartFrom,
     ChangeFeedMode changeFeedMode,
     ChangeFeedRequestOptions changeFeedRequestOptions = null)
 {
     this.encryptionContainer = encryptionContainer ?? throw new ArgumentNullException(nameof(encryptionContainer));
     this.requestOptions      = changeFeedRequestOptions;
     this.FeedIterator        = encryptionContainer.Container.GetChangeFeedStreamIterator(
         changeFeedStartFrom,
         changeFeedMode,
         changeFeedRequestOptions);
 }
Esempio n. 7
0
 public Task <TryCatch <ChangeFeedPage> > MonadicChangeFeedAsync(
     ChangeFeedState state,
     FeedRangeInternal feedRange,
     int pageSize,
     ChangeFeedMode changeFeedMode,
     JsonSerializationFormat?jsonSerializationFormat,
     ITrace trace,
     CancellationToken cancellationToken) => this.monadicDocumentContainer.MonadicChangeFeedAsync(
     state,
     feedRange,
     pageSize,
     changeFeedMode,
     jsonSerializationFormat,
     trace,
     cancellationToken);
Esempio n. 8
0
 public ChangeFeedPartitionRangePageAsyncEnumerator(
     IChangeFeedDataSource changeFeedDataSource,
     FeedRangeInternal range,
     int pageSize,
     ChangeFeedMode changeFeedMode,
     JsonSerializationFormat?jsonSerializationFormat,
     ChangeFeedState state,
     CancellationToken cancellationToken)
     : base(range, cancellationToken, state)
 {
     this.changeFeedDataSource    = changeFeedDataSource ?? throw new ArgumentNullException(nameof(changeFeedDataSource));
     this.changeFeedMode          = changeFeedMode ?? throw new ArgumentNullException(nameof(changeFeedMode));
     this.pageSize                = pageSize;
     this.jsonSerializationFormat = jsonSerializationFormat;
 }
Esempio n. 9
0
 public Task <ChangeFeedPage> ChangeFeedAsync(
     ChangeFeedState state,
     FeedRangeInternal feedRange,
     int pageSize,
     ChangeFeedMode changeFeedMode,
     JsonSerializationFormat?jsonSerializationFormat,
     ITrace trace,
     CancellationToken cancellationToken) => TryCatch <ChangeFeedPage> .UnsafeGetResultAsync(
     this.MonadicChangeFeedAsync(
         state,
         feedRange,
         pageSize,
         changeFeedMode,
         jsonSerializationFormat,
         trace,
         cancellationToken),
     cancellationToken);
Esempio n. 10
0
        public override FeedIterator GetChangeFeedStreamIterator(
            ChangeFeedStartFrom changeFeedStartFrom,
            ChangeFeedMode changeFeedMode,
            ChangeFeedRequestOptions changeFeedRequestOptions = null)
        {
            ChangeFeedRequestOptions clonedchangeFeedRequestOptions = changeFeedRequestOptions != null
                ? (ChangeFeedRequestOptions)changeFeedRequestOptions.ShallowCopy()
                : new ChangeFeedRequestOptions();

            return(new EncryptionFeedIterator(
                       this.container.GetChangeFeedStreamIterator(
                           changeFeedStartFrom,
                           changeFeedMode,
                           clonedchangeFeedRequestOptions),
                       this,
                       clonedchangeFeedRequestOptions));
        }
 public override FeedIterator <T> GetChangeFeedIterator <T>(ChangeFeedStartFrom changeFeedStartFrom, ChangeFeedMode changeFeedMode,
                                                            ChangeFeedRequestOptions changeFeedRequestOptions = null) =>
 throw new NotImplementedException();
Esempio n. 12
0
        public ChangeFeedIteratorCore(
            IDocumentContainer documentContainer,
            ChangeFeedMode changeFeedMode,
            ChangeFeedRequestOptions changeFeedRequestOptions,
            ChangeFeedStartFrom changeFeedStartFrom)
        {
            if (changeFeedStartFrom == null)
            {
                throw new ArgumentNullException(nameof(changeFeedStartFrom));
            }

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

            this.documentContainer        = documentContainer ?? throw new ArgumentNullException(nameof(documentContainer));
            this.changeFeedRequestOptions = changeFeedRequestOptions ?? new ChangeFeedRequestOptions();
            this.lazyMonadicEnumerator    = new AsyncLazy <TryCatch <CrossPartitionChangeFeedAsyncEnumerator> >(
                valueFactory: async(trace, cancellationToken) =>
            {
                if (changeFeedStartFrom is ChangeFeedStartFromContinuation startFromContinuation)
                {
                    TryCatch <CosmosElement> monadicParsedToken = CosmosElement.Monadic.Parse(startFromContinuation.Continuation);
                    if (monadicParsedToken.Failed)
                    {
                        return(TryCatch <CrossPartitionChangeFeedAsyncEnumerator> .FromException(
                                   new MalformedChangeFeedContinuationTokenException(
                                       message: $"Failed to parse continuation token: {startFromContinuation.Continuation}.",
                                       innerException: monadicParsedToken.Exception)));
                    }

                    TryCatch <VersionedAndRidCheckedCompositeToken> monadicVersionedToken = VersionedAndRidCheckedCompositeToken
                                                                                            .MonadicCreateFromCosmosElement(monadicParsedToken.Result);
                    if (monadicVersionedToken.Failed)
                    {
                        return(TryCatch <CrossPartitionChangeFeedAsyncEnumerator> .FromException(
                                   new MalformedChangeFeedContinuationTokenException(
                                       message: $"Failed to parse continuation token: {startFromContinuation.Continuation}.",
                                       innerException: monadicVersionedToken.Exception)));
                    }

                    VersionedAndRidCheckedCompositeToken versionedAndRidCheckedCompositeToken = monadicVersionedToken.Result;
                    if (versionedAndRidCheckedCompositeToken.VersionNumber == VersionedAndRidCheckedCompositeToken.Version.V1)
                    {
                        // Need to migrate continuation token
                        if (!(versionedAndRidCheckedCompositeToken.ContinuationToken is CosmosArray cosmosArray))
                        {
                            return(TryCatch <CrossPartitionChangeFeedAsyncEnumerator> .FromException(
                                       new MalformedChangeFeedContinuationTokenException(
                                           message: $"Failed to parse get array continuation token: {startFromContinuation.Continuation}.")));
                        }

                        List <CosmosElement> changeFeedTokensV2 = new List <CosmosElement>();
                        foreach (CosmosElement arrayItem in cosmosArray)
                        {
                            if (!(arrayItem is CosmosObject cosmosObject))
                            {
                                return(TryCatch <CrossPartitionChangeFeedAsyncEnumerator> .FromException(
                                           new MalformedChangeFeedContinuationTokenException(
                                               message: $"Failed to parse get object in composite continuation: {startFromContinuation.Continuation}.")));
                            }

                            if (!cosmosObject.TryGetValue("min", out CosmosString min))
                            {
                                return(TryCatch <CrossPartitionChangeFeedAsyncEnumerator> .FromException(
                                           new MalformedChangeFeedContinuationTokenException(
                                               message: $"Failed to parse start of range: {cosmosObject}.")));
                            }

                            if (!cosmosObject.TryGetValue("max", out CosmosString max))
                            {
                                return(TryCatch <CrossPartitionChangeFeedAsyncEnumerator> .FromException(
                                           new MalformedChangeFeedContinuationTokenException(
                                               message: $"Failed to parse end of range: {cosmosObject}.")));
                            }

                            if (!cosmosObject.TryGetValue("token", out CosmosElement token))
                            {
                                return(TryCatch <CrossPartitionChangeFeedAsyncEnumerator> .FromException(
                                           new MalformedChangeFeedContinuationTokenException(
                                               message: $"Failed to parse token: {cosmosObject}.")));
                            }

                            FeedRangeEpk feedRangeEpk = new FeedRangeEpk(new Documents.Routing.Range <string>(
                                                                             min: min.Value,
                                                                             max: max.Value,
                                                                             isMinInclusive: true,
                                                                             isMaxInclusive: false));
                            ChangeFeedState state = token is CosmosNull ? ChangeFeedState.Beginning() : ChangeFeedStateContinuation.Continuation(token);

                            FeedRangeState <ChangeFeedState> feedRangeState = new FeedRangeState <ChangeFeedState>(feedRangeEpk, state);
                            changeFeedTokensV2.Add(ChangeFeedFeedRangeStateSerializer.ToCosmosElement(feedRangeState));
                        }

                        CosmosArray changeFeedTokensArrayV2 = CosmosArray.Create(changeFeedTokensV2);

                        versionedAndRidCheckedCompositeToken = new VersionedAndRidCheckedCompositeToken(
                            VersionedAndRidCheckedCompositeToken.Version.V2,
                            changeFeedTokensArrayV2,
                            versionedAndRidCheckedCompositeToken.Rid);
                    }

                    if (versionedAndRidCheckedCompositeToken.VersionNumber != VersionedAndRidCheckedCompositeToken.Version.V2)
                    {
                        return(TryCatch <CrossPartitionChangeFeedAsyncEnumerator> .FromException(
                                   new MalformedChangeFeedContinuationTokenException(
                                       message: $"Wrong version number: {versionedAndRidCheckedCompositeToken.VersionNumber}.")));
                    }

                    string collectionRid = await documentContainer.GetResourceIdentifierAsync(trace, cancellationToken);
                    if (versionedAndRidCheckedCompositeToken.Rid != collectionRid)
                    {
                        return(TryCatch <CrossPartitionChangeFeedAsyncEnumerator> .FromException(
                                   new MalformedChangeFeedContinuationTokenException(
                                       message: $"rids mismatched. Expected: {collectionRid} but got {versionedAndRidCheckedCompositeToken.Rid}.")));
                    }

                    changeFeedStartFrom = ChangeFeedStartFrom.ContinuationToken(versionedAndRidCheckedCompositeToken.ContinuationToken.ToString());
                }

                TryCatch <ChangeFeedCrossFeedRangeState> monadicChangeFeedCrossFeedRangeState = changeFeedStartFrom.Accept(ChangeFeedStateFromToChangeFeedCrossFeedRangeState.Singleton);
                if (monadicChangeFeedCrossFeedRangeState.Failed)
                {
                    return(TryCatch <CrossPartitionChangeFeedAsyncEnumerator> .FromException(
                               new MalformedChangeFeedContinuationTokenException(
                                   message: $"Could not convert to {nameof(ChangeFeedCrossFeedRangeState)}.",
                                   innerException: monadicChangeFeedCrossFeedRangeState.Exception)));
                }

                CrossPartitionChangeFeedAsyncEnumerator enumerator = CrossPartitionChangeFeedAsyncEnumerator.Create(
                    documentContainer,
                    changeFeedMode,
                    changeFeedRequestOptions,
                    new CrossFeedRangeState <ChangeFeedState>(monadicChangeFeedCrossFeedRangeState.Result.FeedRangeStates),
                    cancellationToken: default);

                TryCatch <CrossPartitionChangeFeedAsyncEnumerator> monadicEnumerator = TryCatch <CrossPartitionChangeFeedAsyncEnumerator> .FromResult(enumerator);
                return(monadicEnumerator);
            });
            this.hasMoreResults = true;
        }