Example #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DocumentCollectionInfo"/> class.
 /// </summary>
 /// <param name="other">The other <see cref="DocumentCollectionInfo"/> to copy settings from.</param>
 public DocumentCollectionInfo(DocumentCollectionInfo other)
 {
     this.Uri              = other.Uri;
     this.MasterKey        = other.MasterKey;
     this.DatabaseName     = other.DatabaseName;
     this.CollectionName   = other.CollectionName;
     this.ConnectionPolicy = other.ConnectionPolicy;
 }
Example #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ChangeFeedEventHost"/> class.
 /// </summary>
 /// <param name="hostName">Unique name for this host.</param>
 /// <param name="feedCollectionLocation">Specifies location of the Cosmos DB collection to monitor changes for.</param>
 /// <param name="leaseCollectionLocation">Specifies location of auxiliary data for load-balancing instances of <see cref="ChangeFeedEventHost" />.</param>
 /// <param name="changeFeedHostOptions">Additional options to control load-balancing of <see cref="ChangeFeedEventHost" /> instances.</param>
 public ChangeFeedEventHost(
     string hostName,
     DocumentCollectionInfo feedCollectionLocation,
     DocumentCollectionInfo leaseCollectionLocation,
     ChangeFeedHostOptions changeFeedHostOptions)
     : this(hostName, feedCollectionLocation, leaseCollectionLocation, new ChangeFeedOptions(), changeFeedHostOptions)
 {
 }
Example #3
0
 /// <summary>
 /// Sets the <see cref="DocumentCollectionInfo"/> of the collection to use for leases.
 /// </summary>
 /// <param name="leaseCollectionLocation">The instance of a <see cref="DocumentCollectionInfo"/> to use.</param>
 /// <returns>The instance of <see cref="ChangeFeedProcessorBuilder"/> to use.</returns>
 public ChangeFeedProcessorBuilder WithLeaseCollection(DocumentCollectionInfo leaseCollectionLocation)
 {
     if (leaseCollectionLocation == null)
     {
         throw new ArgumentNullException(nameof(leaseCollectionLocation));
     }
     this.leaseCollectionLocation = leaseCollectionLocation.Canonicalize();
     return(this);
 }
        private async Task <ILeaseStoreManager> GetLeaseStoreManagerAsync(
            DocumentCollectionInfo collectionInfo,
            bool isPartitionKeyByIdRequiredIfPartitioned)
        {
            if (this.LeaseStoreManager == null)
            {
                var leaseDocumentClient = this.leaseDocumentClient ?? this.leaseCollectionLocation.CreateDocumentClient();
                var collection          = await leaseDocumentClient.GetDocumentCollectionAsync(collectionInfo).ConfigureAwait(false);

                bool isPartitioned =
                    collection.PartitionKey != null &&
                    collection.PartitionKey.Paths != null &&
                    collection.PartitionKey.Paths.Count > 0;
                if (isPartitioned && isPartitionKeyByIdRequiredIfPartitioned &&
                    (collection.PartitionKey.Paths.Count != 1 || collection.PartitionKey.Paths[0] != "/id"))
                {
                    throw new ArgumentException("The lease collection, if partitioned, must have partition key equal to id.");
                }

                var requestOptionsFactory = isPartitioned ?
                                            (IRequestOptionsFactory) new PartitionedByIdCollectionRequestOptionsFactory() :
                                            (IRequestOptionsFactory) new SinglePartitionRequestOptionsFactory();

                string leasePrefix = this.GetLeasePrefix();
                var    leaseStoreManagerBuilder = new DocumentServiceLeaseStoreManagerBuilder()
                                                  .WithLeasePrefix(leasePrefix)
                                                  .WithLeaseCollection(this.leaseCollectionLocation)
                                                  .WithLeaseCollectionLink(collection.SelfLink)
                                                  .WithRequestOptionsFactory(requestOptionsFactory)
                                                  .WithHostName(this.HostName);

                leaseStoreManagerBuilder = leaseStoreManagerBuilder.WithLeaseDocumentClient(leaseDocumentClient);

                this.LeaseStoreManager = await leaseStoreManagerBuilder.BuildAsync().ConfigureAwait(false);
            }

            return(this.LeaseStoreManager);
        }
Example #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ChangeFeedEventHost"/> class.
        /// </summary>
        /// <param name="hostName">Unique name for this host.</param>
        /// <param name="feedCollectionLocation">Specifies location of the Cosmos DB collection to monitor changes for.</param>
        /// <param name="leaseCollectionLocation">Specifies location of auxiliary data for load-balancing instances of <see cref="ChangeFeedEventHost" />.</param>
        /// <param name="changeFeedOptions">Options to pass to the DocumentClient.CreateDocumentChangeFeedQuery API.</param>
        /// <param name="changeFeedHostOptions">Additional options to control load-balancing of <see cref="ChangeFeedEventHost" /> instances.</param>
        public ChangeFeedEventHost(
            string hostName,
            DocumentCollectionInfo feedCollectionLocation,
            DocumentCollectionInfo leaseCollectionLocation,
            ChangeFeedOptions changeFeedOptions,
            ChangeFeedHostOptions changeFeedHostOptions)
        {
            if (string.IsNullOrEmpty(hostName))
            {
                throw new ArgumentNullException(nameof(hostName));
            }
            if (feedCollectionLocation == null)
            {
                throw new ArgumentNullException(nameof(feedCollectionLocation));
            }
            if (leaseCollectionLocation == null)
            {
                throw new ArgumentNullException(nameof(leaseCollectionLocation));
            }
            if (changeFeedOptions == null)
            {
                throw new ArgumentNullException(nameof(changeFeedOptions));
            }
            if (changeFeedHostOptions == null)
            {
                throw new ArgumentNullException(nameof(changeFeedHostOptions));
            }

            ChangeFeedEventHost.TraceLogProvider.OpenNestedContext(hostName);

            this.builder
            .WithHostName(hostName)
            .WithFeedCollection(feedCollectionLocation)
            .WithProcessorOptions(ChangeFeedEventHost.CreateProcessorOptions(changeFeedOptions, changeFeedHostOptions))
            .WithLeaseCollection(leaseCollectionLocation);
        }
Example #6
0
        /// <summary>
        /// Example of a code migration template from Change Feed Processor V2 to SDK V3.
        /// </summary>
        /// <returns></returns>
        public static async Task RunMigrationSample(
            string databaseId,
            CosmosClient client,
            IConfigurationRoot configuration)
        {
            await Program.InitializeAsync(databaseId, client);

            Console.WriteLine("Generating 10 items that will be picked up by the old Change Feed Processor library...");
            await Program.GenerateItems(10, client.GetContainer(databaseId, Program.monitoredContainer));

            // This is how you would initialize the processor in V2
            // <ChangeFeedProcessorLibrary>
            ChangeFeedProcessorLibrary.DocumentCollectionInfo monitoredCollectionInfo = new ChangeFeedProcessorLibrary.DocumentCollectionInfo()
            {
                DatabaseName   = databaseId,
                CollectionName = Program.monitoredContainer,
                Uri            = new Uri(configuration["EndPointUrl"]),
                MasterKey      = configuration["AuthorizationKey"]
            };

            ChangeFeedProcessorLibrary.DocumentCollectionInfo leaseCollectionInfo = new ChangeFeedProcessorLibrary.DocumentCollectionInfo()
            {
                DatabaseName   = databaseId,
                CollectionName = Program.leasesContainer,
                Uri            = new Uri(configuration["EndPointUrl"]),
                MasterKey      = configuration["AuthorizationKey"]
            };

            ChangeFeedProcessorLibrary.ChangeFeedProcessorBuilder builder = new ChangeFeedProcessorLibrary.ChangeFeedProcessorBuilder();
            var oldChangeFeedProcessor = await builder
                                         .WithHostName("consoleHost")
                                         .WithProcessorOptions(new ChangeFeedProcessorLibrary.ChangeFeedProcessorOptions
            {
                StartFromBeginning = true,
                LeasePrefix        = "MyLeasePrefix",
                MaxItemCount       = 10,
                FeedPollDelay      = TimeSpan.FromSeconds(1)
            })
                                         .WithFeedCollection(monitoredCollectionInfo)
                                         .WithLeaseCollection(leaseCollectionInfo)
                                         .WithObserver <ChangeFeedObserver>()
                                         .BuildAsync();

            // </ChangeFeedProcessorLibrary>

            await oldChangeFeedProcessor.StartAsync();

            // Wait random time for the delegate to output all messages after initialization is done
            await Task.Delay(5000);

            Console.WriteLine("Now we will stop the V2 Processor and start a V3 with the same parameters to pick up from the same state, press any key to continue...");
            Console.ReadKey();
            await oldChangeFeedProcessor.StopAsync();

            Console.WriteLine("Generating 5 items that will be picked up by the new Change Feed Processor...");
            await Program.GenerateItems(5, client.GetContainer(databaseId, Program.monitoredContainer));

            // This is how you would do the same initialization in V3
            // <ChangeFeedProcessorMigrated>
            Container           leaseContainer      = client.GetContainer(databaseId, Program.leasesContainer);
            Container           monitoredContainer  = client.GetContainer(databaseId, Program.monitoredContainer);
            ChangeFeedProcessor changeFeedProcessor = monitoredContainer
                                                      .GetChangeFeedProcessorBuilder <ToDoItem>("MyLeasePrefix", Program.HandleChangesAsync)
                                                      .WithInstanceName("consoleHost")
                                                      .WithLeaseContainer(leaseContainer)
                                                      .WithMaxItems(10)
                                                      .WithPollInterval(TimeSpan.FromSeconds(1))
                                                      .WithStartTime(DateTime.MinValue.ToUniversalTime())
                                                      .Build();
            // </ChangeFeedProcessorMigrated>

            await changeFeedProcessor.StartAsync();

            // Wait random time for the delegate to output all messages after initialization is done
            await Task.Delay(5000);

            Console.WriteLine("Press any key to continue with the next demo...");
            Console.ReadKey();
            await changeFeedProcessor.StopAsync();
        }
Example #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ChangeFeedEventHost"/> class.
 /// </summary>
 /// <param name="hostName">Unique name for this host.</param>
 /// <param name="documentCollectionLocation">Specifies location of the DocumentDB collection to monitor changes for.</param>
 /// <param name="leaseCollectionLocation ">Specifies location of auxiliary data for load-balancing instances of <see cref="ChangeFeedEventHost" />.</param>
 public ChangeFeedEventHost(string hostName, DocumentCollectionInfo documentCollectionLocation, DocumentCollectionInfo leaseCollectionLocation)
     : this(hostName, documentCollectionLocation, leaseCollectionLocation, new ChangeFeedOptions(), new ChangeFeedHostOptions())
 {
 }
Example #8
0
        private static async Task <string> GetCollectionResourceIdAsync(IChangeFeedDocumentClient documentClient, DocumentCollectionInfo collectionLocation)
        {
            Logger.InfoFormat("Reading collection: '{0}'", collectionLocation.CollectionName);
            DocumentCollection documentCollection = await documentClient.GetDocumentCollectionAsync(collectionLocation).ConfigureAwait(false);

            return(documentCollection.ResourceId);
        }
Example #9
0
        private static async Task <string> GetDatabaseResourceIdAsync(IChangeFeedDocumentClient documentClient, DocumentCollectionInfo collectionLocation)
        {
            Logger.InfoFormat("Reading database: '{0}'", collectionLocation.DatabaseName);
            Uri databaseUri = UriFactory.CreateDatabaseUri(collectionLocation.DatabaseName);
            var response    = await documentClient.ReadDatabaseAsync(databaseUri, null).ConfigureAwait(false);

            return(response.Resource.ResourceId);
        }