public async Task CreateDropFixedDatabase()
        {
            DatabaseInternal database = (DatabaseInlineCore)await this.cosmosClient.CreateDatabaseAsync(
                nameof(CreateDropAutoscaleDatabase) + Guid.NewGuid().ToString(),
                ThroughputProperties.CreateManualThroughput(5000));

            ThroughputResponse fixedDatabaseThroughput = await database.ReadThroughputAsync(requestOptions : null);

            Assert.IsNotNull(fixedDatabaseThroughput);
            Assert.AreEqual(5000, fixedDatabaseThroughput.Resource.Throughput);
            Assert.IsNull(fixedDatabaseThroughput.Resource.AutoscaleMaxThroughput);
            Assert.IsNull(fixedDatabaseThroughput.Resource.AutoUpgradeMaxThroughputIncrementPercentage);

            ThroughputResponse fixedReplaced = await database.ReplaceThroughputAsync(
                ThroughputProperties.CreateManualThroughput(6000));

            Assert.IsNotNull(fixedReplaced);
            Assert.AreEqual(6000, fixedReplaced.Resource.Throughput);
            Assert.IsNull(fixedReplaced.Resource.AutoscaleMaxThroughput);
            Assert.IsNull(fixedReplaced.Resource.AutoUpgradeMaxThroughputIncrementPercentage);

            ThroughputResponse fixedReplacedIfExists = await database.ReplaceThroughputPropertiesIfExistsAsync(
                ThroughputProperties.CreateManualThroughput(7000));

            Assert.IsNotNull(fixedReplacedIfExists);
            Assert.AreEqual(7000, fixedReplacedIfExists.Resource.Throughput);
            Assert.IsNull(fixedReplacedIfExists.Resource.AutoscaleMaxThroughput);
            Assert.IsNull(fixedReplacedIfExists.Resource.AutoUpgradeMaxThroughputIncrementPercentage);

            await database.DeleteAsync();
        }
        public async Task <Container> InitializeCollection(CosmosClient client)
        {
            Database  database        = client.GetDatabase(_cosmosDataStoreConfiguration.DatabaseId);
            Container containerClient = database.GetContainer(_collectionId);

            _logger.LogInformation("Finding Container: {collectionId}", _collectionId);
            var existingContainer = await database.TryGetContainerAsync(_collectionId);

            if (existingContainer == null)
            {
                _logger.LogInformation("Creating Cosmos Container if not exits: {collectionId}", _collectionId);

                var containerResponse = await database.CreateContainerIfNotExistsAsync(
                    _collectionId,
                    $"/{KnownDocumentProperties.PartitionKey}",
                    _initialCollectionThroughput);

                containerResponse.Resource.DefaultTimeToLive = -1;

                existingContainer = await containerClient.ReplaceContainerAsync(containerResponse);

                if (_initialCollectionThroughput.HasValue)
                {
                    ThroughputProperties throughputProperties = ThroughputProperties.CreateManualThroughput(_initialCollectionThroughput.Value);
                    await containerClient.ReplaceThroughputAsync(throughputProperties);
                }
            }

            await _upgradeManager.SetupContainerAsync(containerClient);

            return(existingContainer);
        }
예제 #3
0
        public IEventStoreCqrsBuilder AddInitialization(
            int throughput,
            Func <IServiceProvider, Task>?additionInitialization = null)
        {
            builder.Services.AddSingleton <IDependencyInitializer>(s =>
                                                                   new DependencyInitializer(
                                                                       async() =>
            {
                await s.GetRequiredService <IEventStoreInitializer>()
                .CreateEventStoreAsync(
                    ThroughputProperties.CreateManualThroughput(throughput),
                    CancellationToken.None)
                .ConfigureAwait(false);

                if (additionInitialization is not null)
                {
                    await additionInitialization
                    .Invoke(s)
                    .ConfigureAwait(false);
                }
            }));
            builder.Services.AddHostedService <DependencyInitializerJob>();

            return(this);
        }
        public async Task SC00_MigrateDB()
        {
            CosmosClient client = new CosmosClient(EndpointUrl, AuthorizationKey);

            await client.CreateDatabaseIfNotExistsAsync(DatabaseId, ThroughputProperties.CreateManualThroughput(400));

            Database database = client.GetDatabase(DatabaseId);

            await database.DefineContainer("events", "/stream/id").CreateIfNotExistsAsync();

            await database.DefineContainer("leases", "/id").CreateIfNotExistsAsync();

            await database.DefineContainer("views", "/id").CreateIfNotExistsAsync();

            await database.DefineContainer("snapshots", "/id").CreateIfNotExistsAsync();

            StoredProcedureProperties storedProcedureProperties = new StoredProcedureProperties
            {
                Id   = "spAppendToStream",
                Body = File.ReadAllText("js/spAppendToStream.js")
            };

            Container eventsContainer = database.GetContainer("events");

            try
            {
                await eventsContainer.Scripts.DeleteStoredProcedureAsync("spAppendToStream");
            }
            catch (CosmosException ex) when(ex.StatusCode == HttpStatusCode.NotFound)
            {
                // Stored procedure didn't exist yet.
            }
            await eventsContainer.Scripts.CreateStoredProcedureAsync(storedProcedureProperties);
        }
예제 #5
0
        public static async Task createAzureDocumentDatabase(string EndpointUrl, string PrimaryKey)
        {
            var client = new CosmosClient(EndpointUrl, PrimaryKey);
            DatabaseResponse databaseResponse = await client.CreateDatabaseIfNotExistsAsync(dbName);

            Database           database           = databaseResponse;
            DatabaseProperties databaseProperties = databaseResponse;

            // Create a database with a shared manual provisioned throughput
            string databaseIdManual = dbName;

            database = await client.CreateDatabaseIfNotExistsAsync(databaseIdManual, ThroughputProperties.CreateManualThroughput(OfferThroughput));

            ContainerResponse container = await database.CreateContainerIfNotExistsAsync(
                id : collectionName,
                partitionKeyPath : partitionKey,
                throughput : OfferThroughput);



            //Database dataBase = new Database { Id = dbName };
            //await client.CreateDatabaseIfNotExistsAsync(dataBase).ConfigureAwait(false);
            //DocumentCollection myCollection = new DocumentCollection();
            //myCollection.Id = collectionName;
            //myCollection.PartitionKey.Paths.Add(partitionKey);
            //await client.CreateDocumentCollectionIfNotExistsAsync(
            //    UriFactory.CreateDatabaseUri(dbName),
            //    myCollection,
            //    new RequestOptions { OfferThroughput = OfferThroughput }).ConfigureAwait(false);
        }
        private async Task PreTestAsync(int requestUnits)
        {
            Console.WriteLine($"Creating database {DatabaseName}...");
            _database = await _client.CreateDatabaseIfNotExistsAsync(DatabaseName, ThroughputProperties.CreateManualThroughput(requestUnits));

            Console.WriteLine($"Creating container {DevicesContainer}...");
            _devicesContainer = await _database.DefineContainer(DevicesContainer, "/id")
                                .WithDefaultTimeToLive(TimeSpan.FromDays(7))
                                .WithIndexingPolicy()
                                .WithIndexingMode(IndexingMode.Consistent)
                                .WithIncludedPaths()
                                .Attach()
                                .WithExcludedPaths()
                                .Path("/*")
                                .Attach()
                                .Attach()
                                .CreateIfNotExistsAsync();

            Console.WriteLine($"Creating container {DeviceLocationsContainer}...");
            _deviceLocationsContainer = await _database.DefineContainer(DeviceLocationsContainer, "/deviceId")
                                        .WithDefaultTimeToLive(TimeSpan.FromDays(7))
                                        .WithIndexingPolicy()
                                        .WithIndexingMode(IndexingMode.Consistent)
                                        .WithIncludedPaths()
                                        .Attach()
                                        .WithExcludedPaths()
                                        .Path("/*")
                                        .Attach()
                                        .Attach()
                                        .CreateIfNotExistsAsync();

            await CreateStoredProcedure(BulkImport);
            await CreateStoredProcedure(BulkCleanUp);
        }
예제 #7
0
 /// <summary>
 ///     Sets the provisioned throughput at database scope.
 /// </summary>
 /// <param name="model">The model.</param>
 /// <param name="throughput">The throughput to set.</param>
 /// <param name="autoscale">Whether autoscale is enabled.</param>
 public static void SetThroughput(this IMutableModel model, int?throughput, bool?autoscale)
 => model.SetOrRemoveAnnotation(
     CosmosAnnotationNames.Throughput,
     throughput == null || autoscale == null
             ? null
             : autoscale.Value
                 ? ThroughputProperties.CreateAutoscaleThroughput(throughput.Value)
                 : ThroughputProperties.CreateManualThroughput(throughput.Value));
예제 #8
0
        public async Task <Container> InitializeCollection(CosmosClient client)
        {
            Database  database        = client.GetDatabase(_cosmosDataStoreConfiguration.DatabaseId);
            Container containerClient = database.GetContainer(_cosmosCollectionConfiguration.CollectionId);

            _logger.LogInformation("Finding Container: {collectionId}", _cosmosCollectionConfiguration.CollectionId);

            AsyncPolicy retryPolicy = _retryExceptionPolicyFactory.GetRetryPolicy();

            var existingContainer = await retryPolicy.ExecuteAsync(async() => await database.TryGetContainerAsync(_cosmosCollectionConfiguration.CollectionId));

            _logger.LogInformation("Creating Cosmos Container if not exits: {collectionId}", _cosmosCollectionConfiguration.CollectionId);

            ContainerResponse containerResponse = await retryPolicy.ExecuteAsync(async() =>
                                                                                 await database.CreateContainerIfNotExistsAsync(
                                                                                     _cosmosCollectionConfiguration.CollectionId,
                                                                                     $"/{KnownDocumentProperties.PartitionKey}",
                                                                                     _cosmosCollectionConfiguration.InitialCollectionThroughput));

            if (containerResponse.StatusCode == HttpStatusCode.Created || containerResponse.Resource.DefaultTimeToLive != -1)
            {
                if (_cosmosCollectionConfiguration.InitialCollectionThroughput.HasValue)
                {
                    var throughputProperties = ThroughputProperties.CreateManualThroughput(_cosmosCollectionConfiguration.InitialCollectionThroughput.Value);
                    await retryPolicy.ExecuteAsync(async() => await containerClient.ReplaceThroughputAsync(throughputProperties));
                }

                containerResponse.Resource.DefaultTimeToLive = -1;
                existingContainer = await retryPolicy.ExecuteAsync(async() => await containerClient.ReplaceContainerAsync(containerResponse));
            }

            await retryPolicy.ExecuteAsync(async() =>
            {
                try
                {
                    await _clientTestProvider.PerformTest(existingContainer, _cosmosDataStoreConfiguration, _cosmosCollectionConfiguration);
                }
                catch (CosmosException e) when(e.StatusCode == HttpStatusCode.TooManyRequests)
                {
                    // This is the very first interaction with the collection, and we might get this exception
                    // when it calls GetCachedContainerPropertiesAsync, which does not use our request handler.
                    throw new RequestRateExceededException(e.RetryAfter);
                }
            });

            await _upgradeManager.SetupContainerAsync(containerClient);

            return(existingContainer);
        }
예제 #9
0
        /// <summary>
        ///     Sets the provisioned throughput at database scope.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="throughput">The throughput to set.</param>
        /// <param name="autoscale">Whether autoscale is enabled.</param>
        /// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>
        public static int?SetThroughput(
            this IConventionModel model,
            int?throughput,
            bool?autoscale,
            bool fromDataAnnotation = false)
        {
            var valueSet = (ThroughputProperties?)model.SetOrRemoveAnnotation(
                CosmosAnnotationNames.Throughput,
                throughput == null || autoscale == null
                    ? null
                    : autoscale.Value
                        ? ThroughputProperties.CreateAutoscaleThroughput(throughput.Value)
                        : ThroughputProperties.CreateManualThroughput(throughput.Value),
                fromDataAnnotation)?.Value;

            return(valueSet?.AutoscaleMaxThroughput ?? valueSet?.Throughput);
        }
예제 #10
0
        private static async Task SetContainerPerformance(Container container, int desiredThroughput)
        {
            ThroughputProperties throughputProperties = await container.ReadThroughputAsync(requestOptions : null);

            ThroughputResponse throughputResponse = null;

            if (throughputProperties.AutoscaleMaxThroughput != null)
            {
                // Container configured with autoscale throughput

                if (throughputProperties.AutoscaleMaxThroughput.Value == desiredThroughput)
                {
                    WriteLineInColor($"\nThe {container.Id} container is already configured with max throughput: {desiredThroughput}. Skipping performance change request...", ConsoleColor.Yellow);
                }
                else
                {
                    WriteLineInColor($"\nThe {container.Id} container is configured with max throughput: {throughputProperties.AutoscaleMaxThroughput}\nChanging max throughput to {desiredThroughput}", ConsoleColor.White);

                    ThroughputProperties newThroughputProperties = ThroughputProperties.CreateAutoscaleThroughput(desiredThroughput);

                    throughputResponse = await container.ReplaceThroughputAsync(newThroughputProperties);

                    WriteLineInColor($"\nChanged {container.Id}'s max throughput to {desiredThroughput}", ConsoleColor.Cyan);
                }
            }
            else
            {
                // Container configured with manual throughput

                if (throughputProperties.Throughput.HasValue && throughputProperties.Throughput.Value == desiredThroughput)
                {
                    WriteLineInColor($"\nThe {container.Id} container is already configured with throughput: {desiredThroughput}. Skipping performance change request...", ConsoleColor.Yellow);
                }
                else
                {
                    WriteLineInColor($"\nThe {container.Id} container is configured with throughput: {throughputProperties.AutoscaleMaxThroughput}\nChanging throughput to {desiredThroughput}", ConsoleColor.White);

                    ThroughputProperties newThroughputProperties = ThroughputProperties.CreateManualThroughput(desiredThroughput);

                    throughputResponse = await container.ReplaceThroughputAsync(newThroughputProperties);

                    WriteLineInColor($"\nChanged {container.Id}'s throughput to {desiredThroughput}", ConsoleColor.Cyan);
                }
            }
        }
예제 #11
0
        public async Task SC00_CreateDB()
        {
            CosmosClient client = new CosmosClient(EndpointUrl, AuthorizationKey);

            await client.CreateDatabaseIfNotExistsAsync(DatabaseId, ThroughputProperties.CreateManualThroughput(400));

            Database database = client.GetDatabase(DatabaseId);

            await database.DefineContainer(_eventsContainerId, "/stream/id").CreateIfNotExistsAsync();

            await database.DefineContainer(_newEventsContainerId, "/stream/id").CreateIfNotExistsAsync();

            await database.DefineContainer(_leaseContainerId, "/id").CreateIfNotExistsAsync();

            await database.DefineContainer(_viewsContainerId, "/id").CreateIfNotExistsAsync();

            await database.DefineContainer(_snapshotContainerId, "/id").CreateIfNotExistsAsync();

            await AddStoredProc(database, _eventsContainerId);
            await AddStoredProc(database, _newEventsContainerId);
        }
예제 #12
0
        private ThroughputProperties GetThroughputProperties()
        {
            string throughput;

            ThroughputProperties properties = null;

            if (!string.IsNullOrEmpty(this.Configuration.GetValueOrDefault("AutoscaleThroughput")))
            {
                throughput = this.Configuration.GetValueOrDefault("AutoscaleThroughput");

                bool valid = int.TryParse(throughput, out int autoscaleThroughput);

                if (valid)
                {
                    properties = ThroughputProperties.CreateAutoscaleThroughput(autoscaleThroughput);

                    return(properties);
                }
            }

            if (!string.IsNullOrEmpty(this.Configuration.GetValueOrDefault("ManualThroughput")))
            {
                throughput = this.Configuration.GetValueOrDefault("ManualThroughput");

                bool valid = int.TryParse(throughput, out int manualThroughput);

                if (valid)
                {
                    properties = ThroughputProperties.CreateManualThroughput(manualThroughput);

                    return(properties);
                }
            }

            properties = ThroughputProperties.CreateAutoscaleThroughput(4000);

            return(properties);
        }
예제 #13
0
        /// <inheritdoc />
        public async Task InitializeDataStore(CosmosClient client, CosmosDataStoreConfiguration cosmosDataStoreConfiguration, IEnumerable <ICollectionInitializer> collectionInitializers)
        {
            EnsureArg.IsNotNull(client, nameof(client));
            EnsureArg.IsNotNull(cosmosDataStoreConfiguration, nameof(cosmosDataStoreConfiguration));
            EnsureArg.IsNotNull(collectionInitializers, nameof(collectionInitializers));

            try
            {
                _logger.LogInformation("Initializing Cosmos DB Database {DatabaseId} and collections", cosmosDataStoreConfiguration.DatabaseId);

                if (cosmosDataStoreConfiguration.AllowDatabaseCreation)
                {
                    _logger.LogInformation("CreateDatabaseIfNotExists {DatabaseId}", cosmosDataStoreConfiguration.DatabaseId);

                    await client.CreateDatabaseIfNotExistsAsync(
                        cosmosDataStoreConfiguration.DatabaseId,
                        cosmosDataStoreConfiguration.InitialDatabaseThroughput.HasValue?ThroughputProperties.CreateManualThroughput(cosmosDataStoreConfiguration.InitialDatabaseThroughput.Value) : null);
                }

                foreach (var collectionInitializer in collectionInitializers)
                {
                    await collectionInitializer.InitializeCollection(client);
                }

                _logger.LogInformation("Cosmos DB Database {DatabaseId} and collections successfully initialized", cosmosDataStoreConfiguration.DatabaseId);
            }
            catch (Exception ex)
            {
                _logger.LogCritical(ex, "Cosmos DB Database {DatabaseId} and collections initialization failed", cosmosDataStoreConfiguration.DatabaseId);
                throw;
            }
        }
예제 #14
0
        private static async Task Main(string[] args)
        {
            // go over all galleries and images with comments and update the gallery comment count
            // used as a one-off to set the initial values for this new property, though could potentially be
            // modified to re-calculate all counts if need be.

            // oct '21: modified to fill in null values

            _configuration = new ConfigurationBuilder()
                             .AddJsonFile(args[0], optional: false)
                             .Build();

            // initialise the Application Server
            await Server.Instance.SetConfigurationAsync(_configuration);

            // authenticate with the CosmosDB service and create a client we can re-use
            _cosmosClient = new CosmosClient(_configuration["CosmosDB:Uri"], _configuration["CosmosDB:PrimaryKey"]);

            // create the CosmosDB database if it doesn't already exist
            var response = await _cosmosClient.CreateDatabaseIfNotExistsAsync(_configuration["CosmosDB:DatabaseName"], ThroughputProperties.CreateManualThroughput(400));

            // keep a reference to the database so other parts of the app can easily interact with it
            _database           = response.Database;
            _imagesContainer    = _database.GetContainer(Constants.ImagesContainerName);
            _galleriesContainer = _database.GetContainer(Constants.GalleriesContainerName);

            // query the database for galleries without CommentCount, set their values to zero
            const string galleryQuery           = "SELECT g.id, g.CategoryId FROM Galleries g WHERE NOT IS_DEFINED(g.CommentComment)";
            var          galleryQueryDefinition = new QueryDefinition(galleryQuery);

            Console.WriteLine("Getting gallery stubs...");
            var galleryQueryResult = _galleriesContainer.GetItemQueryIterator <GalleryCommentCountStub>(galleryQueryDefinition);

            Console.WriteLine("Got gallery stubs. Enumerating...");

            while (galleryQueryResult.HasMoreResults)
            {
                var galleryCommentCountStubs = await galleryQueryResult.ReadNextAsync();

                foreach (var galleryCommentCountStub in galleryCommentCountStubs)
                {
                    var gallery = await Server.Instance.Galleries.GetGalleryAsync(galleryCommentCountStub.CategoryId, galleryCommentCountStub.Id);

                    gallery.CommentCount = 0;
                    await Server.Instance.Galleries.UpdateGalleryAsync(gallery);

                    Console.WriteLine("Gallery comments set to zero for gallery id: " + galleryCommentCountStub.Id);
                }
            }

            // query the database for images without CommentCount values, then set them to zero
            const string imageQuery           = "SELECT i.id, i.GalleryId FROM Images i WHERE NOT IS_DEFINED(i.CommentCount)";
            var          imageQueryDefinition = new QueryDefinition(imageQuery);

            Console.WriteLine("Getting image stubs...");
            var imageQueryResult = _imagesContainer.GetItemQueryIterator <ImageCommentCountStub>(imageQueryDefinition);

            Console.WriteLine("Got image stubs. Enumerating...");

            while (imageQueryResult.HasMoreResults)
            {
                var imageCommentCountStubs = await imageQueryResult.ReadNextAsync();

                foreach (var imageCommentCountStub in imageCommentCountStubs)
                {
                    var image = await Server.Instance.Images.GetImageAsync(imageCommentCountStub.GalleryId, imageCommentCountStub.Id);

                    image.CommentCount = 0;
                    await Server.Instance.Images.UpdateImageAsync(image);

                    Console.WriteLine($"Set image CommentCount to zero for image id: {image.Id}");
                }
            }
        }
예제 #15
0
        private static async Task InitializeCosmosDb()
        {
            _database = await _cosmosDbClient.CreateDatabaseIfNotExistsAsync(DatabaseName);

            #region Telemetry container

            // Create telemetry container with analytical store enabled
            var telemetryContainerDefinition =
                new ContainerProperties(id: TelemetryContainerName, partitionKeyPath: $"/{PartitionKey}")
            {
                IndexingPolicy = { IndexingMode = IndexingMode.Consistent },
                AnalyticalStoreTimeToLiveInSeconds = -1
            };

            // Tune the indexing policy for write-heavy workloads by only including regularly queried paths.
            // Be careful when using an opt-in policy as we are below. Excluding all and only including certain paths removes
            // Cosmos DB's ability to proactively add new properties to the index.
            telemetryContainerDefinition.IndexingPolicy.ExcludedPaths.Clear();
            telemetryContainerDefinition.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath {
                Path = "/*"
            });                                                                                              // Exclude all paths.
            telemetryContainerDefinition.IndexingPolicy.IncludedPaths.Clear();
            telemetryContainerDefinition.IndexingPolicy.IncludedPaths.Add(new IncludedPath {
                Path = "/vin/?"
            });
            telemetryContainerDefinition.IndexingPolicy.IncludedPaths.Add(new IncludedPath {
                Path = "/state/?"
            });
            telemetryContainerDefinition.IndexingPolicy.IncludedPaths.Add(new IncludedPath {
                Path = "/partitionKey/?"
            });

            // Provision the container with autoscale throughput
            ThroughputProperties telemetryThroughputProperties = ThroughputProperties.CreateAutoscaleThroughput(TELEMETRY_CONTAINER_RUS);

            // Create the container with autoscale throughput
            var telemetryContainerResponse = await _database.CreateContainerIfNotExistsAsync(telemetryContainerDefinition, telemetryThroughputProperties);

            #endregion

            #region Metadata container

            // Create metadata container with analytical store enabled
            var metadataContainerDefinition =
                new ContainerProperties(id: MetadataContainerName, partitionKeyPath: $"/{PartitionKey}")
            {
                // Set the indexing policy to consistent and use the default settings because we expect read-heavy workloads in this container (includes all paths (/*) with all range indexes).
                // Indexing all paths when you have write-heavy workloads may impact performance and cost more RU/s than desired.
                IndexingPolicy = { IndexingMode = IndexingMode.Consistent },
                AnalyticalStoreTimeToLiveInSeconds = -1
            };

            // Provision the container with autoscale throughput - start with bulk import throughput since the bulk import will run after this create
            ThroughputProperties metadataThroughputProperties = ThroughputProperties.CreateAutoscaleThroughput(METADATA_CONTAINER_RUS_BULK_IMPORT);

            // Create the container with autoscale throughput
            var metadataContainerResponse = await _database.CreateContainerIfNotExistsAsync(metadataContainerDefinition, metadataThroughputProperties);

            #endregion

            #region Maintenance container

            // Create maintenance container
            var maintenanceContainerDefinition =
                new ContainerProperties(id: MaintenanceContainerName, partitionKeyPath: $"/vin")
            {
                IndexingPolicy = { IndexingMode = IndexingMode.Consistent }
            };

            // Provision the container with fixed throughput
            ThroughputProperties maintenanceThroughputProperties = ThroughputProperties.CreateManualThroughput(MAINTENANCE_CONTAINER_RUS);

            // Create the container
            var maintenanceContainerResponse = await _database.CreateContainerIfNotExistsAsync(maintenanceContainerDefinition, maintenanceThroughputProperties);

            #endregion
        }
예제 #16
0
        private static async Task Main(string[] args)
        {
            // fixes any incorrect CommentCount values on images. some mismatches have been detected.
            _configuration = new ConfigurationBuilder()
                             .AddJsonFile(args[0], optional: false)
                             .Build();

            // initialise the Application Server
            await Server.Instance.SetConfigurationAsync(_configuration);

            // authenticate with the CosmosDB service and create a client we can re-use
            _cosmosClient = new CosmosClient(_configuration["CosmosDB:Uri"], _configuration["CosmosDB:PrimaryKey"]);

            // create the CosmosDB database if it doesn't already exist
            var response = await _cosmosClient.CreateDatabaseIfNotExistsAsync(_configuration["CosmosDB:DatabaseName"], ThroughputProperties.CreateManualThroughput(400));

            // keep a reference to the database so other parts of the app can easily interact with it
            _database        = response.Database;
            _imagesContainer = _database.GetContainer(Constants.ImagesContainerName);

            // query the database for images without CommentCount values, check if they actually do have comments and update the CommentCount if necessary
            const string imageQuery           = "SELECT i.id, i.GalleryId, i.Comments FROM Images i WHERE i.CommentCount = 0";
            var          imageQueryDefinition = new QueryDefinition(imageQuery);

            Console.WriteLine("Getting image stubs...");
            var imageQueryResult = _imagesContainer.GetItemQueryIterator <ImageStub>(imageQueryDefinition);

            Console.WriteLine("Got image stubs. Enumerating...");

            var commentCountsOkay = 0;

            while (imageQueryResult.HasMoreResults)
            {
                var imageStubs = await imageQueryResult.ReadNextAsync();

                foreach (var imageStub in imageStubs)
                {
                    if (imageStub.Comments.Count > 0)
                    {
                        var image = await Server.Instance.Images.GetImageAsync(imageStub.GalleryId, imageStub.Id);

                        image.CommentCount = imageStub.Comments.Count;
                        await Server.Instance.Images.UpdateImageAsync(image);

                        Console.WriteLine($"Set image CommentCount to {image.CommentCount} for image id: {image.Id}");
                    }
                    else
                    {
                        commentCountsOkay++;
                    }
                }
            }

            Console.WriteLine("---------------------");
            Console.WriteLine($"{commentCountsOkay} image CommentCounts were accurate.");
        }
예제 #17
0
        private async Task InitialiseDatabaseAsync()
        {
            // authenticate with the CosmosDB service and create a client we can re-use
            CosmosClient = new CosmosClient(Configuration["CosmosDB:Uri"], Configuration["CosmosDB:PrimaryKey"]);

            // create the CosmosDB database if it doesn't already exist
            var response = await CosmosClient.CreateDatabaseIfNotExistsAsync(Configuration["CosmosDB:DatabaseName"], ThroughputProperties.CreateManualThroughput(400));

            var createdDatabase = response.StatusCode == HttpStatusCode.Created;

            Log.Debug("Server.InitialiseDatabaseAsync: Created database? " + createdDatabase);

            // keep a reference to the database so other parts of the app can easily interact with it
            Database = response.Database;

            // create containers for all our top level objects we want to persist
            var createdCategoriesContainerResponse = await Database.CreateContainerIfNotExistsAsync(Constants.CategoriesContainerName, "/PartitionKey");

            var createdCategoriesContainer = createdCategoriesContainerResponse.StatusCode == HttpStatusCode.Created;

            Log.Information("Server.InitialiseDatabaseAsync: Created categories container? " + createdCategoriesContainer);

            var createdGalleriesContainerResponse = await Database.CreateContainerIfNotExistsAsync(Constants.GalleriesContainerName, "/CategoryId");

            var createdGalleriesContainer = createdGalleriesContainerResponse.StatusCode == HttpStatusCode.Created;

            Log.Information("Server.InitialiseDatabaseAsync: Created galleries container? " + createdGalleriesContainer);

            var createdImagesContainerResponse = await Database.CreateContainerIfNotExistsAsync(Constants.ImagesContainerName, "/GalleryId");

            var createdImagesContainer = createdImagesContainerResponse.StatusCode == HttpStatusCode.Created;

            Log.Information("Server.InitialiseDatabaseAsync: Created images container? " + createdImagesContainer);

            var createdUsersContainerResponse = await Database.CreateContainerIfNotExistsAsync(Constants.UsersContainerName, "/PartitionKey");

            var createdUsersContainer = createdUsersContainerResponse.StatusCode == HttpStatusCode.Created;

            Log.Information("Server.InitialiseDatabaseAsync: Created users container? " + createdUsersContainer);
        }
        public async Task ContainerBuilderAutoscaleTest()
        {
            DatabaseInternal database = (DatabaseInlineCore)await this.cosmosClient.CreateDatabaseAsync(
                nameof(CreateDropAutoscaleDatabase) + Guid.NewGuid().ToString());

            {
                Container container = await database.DefineContainer("Test", "/id")
                                      .CreateAsync(throughputProperties: ThroughputProperties.CreateAutoscaleThroughput(5000));

                ThroughputProperties throughputProperties = await container.ReadThroughputAsync(requestOptions : null);

                Assert.IsNotNull(throughputProperties);
                Assert.IsTrue(throughputProperties.Throughput > 400);
                Assert.AreEqual(5000, throughputProperties.AutoscaleMaxThroughput);
            }

            {
                Container container2 = await database.DefineContainer("Test2", "/id")
                                       .CreateIfNotExistsAsync(throughputProperties: ThroughputProperties.CreateAutoscaleThroughput(5000));

                ThroughputProperties throughputProperties = await container2.ReadThroughputAsync(requestOptions : null);

                Assert.IsNotNull(throughputProperties);
                Assert.IsTrue(throughputProperties.Throughput > 400);
                Assert.AreEqual(5000, throughputProperties.AutoscaleMaxThroughput);


                container2 = await database.DefineContainer(container2.Id, "/id")
                             .CreateIfNotExistsAsync(throughputProperties: ThroughputProperties.CreateAutoscaleThroughput(5000));

                throughputProperties = await container2.ReadThroughputAsync(requestOptions : null);

                Assert.IsNotNull(throughputProperties);
                Assert.IsTrue(throughputProperties.Throughput > 400);
                Assert.AreEqual(5000, throughputProperties.AutoscaleMaxThroughput);
            }

            {
                Container container3 = await database.DefineContainer("Test3", "/id")
                                       .CreateAsync(throughputProperties: ThroughputProperties.CreateManualThroughput(500));

                ThroughputProperties throughputProperties = await container3.ReadThroughputAsync(requestOptions : null);

                Assert.IsNotNull(throughputProperties);
                Assert.IsNull(throughputProperties.AutoscaleMaxThroughput);
                Assert.AreEqual(500, throughputProperties.Throughput);

                container3 = await database.DefineContainer(container3.Id, "/id")
                             .CreateIfNotExistsAsync(throughputProperties: ThroughputProperties.CreateManualThroughput(500));

                throughputProperties = await container3.ReadThroughputAsync(requestOptions : null);

                Assert.IsNotNull(throughputProperties);
                Assert.IsNull(throughputProperties.AutoscaleMaxThroughput);
                Assert.AreEqual(500, throughputProperties.Throughput);
            }

            {
                Container container4 = await database.DefineContainer("Test4", "/id")
                                       .CreateIfNotExistsAsync(throughputProperties: ThroughputProperties.CreateManualThroughput(500));

                ThroughputProperties throughputProperties = await container4.ReadThroughputAsync(requestOptions : null);

                Assert.IsNotNull(throughputProperties);
                Assert.IsNull(throughputProperties.AutoscaleMaxThroughput);
                Assert.AreEqual(500, throughputProperties.Throughput);
            }

            await database.DeleteAsync();
        }
        /// <inheritdoc />
        public async Task InitializeDataStore(CosmosClient client, CosmosDataStoreConfiguration cosmosDataStoreConfiguration, IEnumerable <ICollectionInitializer> collectionInitializers)
        {
            EnsureArg.IsNotNull(client, nameof(client));
            EnsureArg.IsNotNull(cosmosDataStoreConfiguration, nameof(cosmosDataStoreConfiguration));
            EnsureArg.IsNotNull(collectionInitializers, nameof(collectionInitializers));

            try
            {
                _logger.LogInformation("Initializing Cosmos DB Database {DatabaseId} and collections", cosmosDataStoreConfiguration.DatabaseId);

                if (cosmosDataStoreConfiguration.AllowDatabaseCreation)
                {
                    _logger.LogInformation("CreateDatabaseIfNotExists {DatabaseId}", cosmosDataStoreConfiguration.DatabaseId);

                    await _retryExceptionPolicyFactory.GetRetryPolicy().ExecuteAsync(
                        async() =>
                        await client.CreateDatabaseIfNotExistsAsync(
                            cosmosDataStoreConfiguration.DatabaseId,
                            cosmosDataStoreConfiguration.InitialDatabaseThroughput.HasValue ? ThroughputProperties.CreateManualThroughput(cosmosDataStoreConfiguration.InitialDatabaseThroughput.Value) : null));
                }

                foreach (var collectionInitializer in collectionInitializers)
                {
                    await collectionInitializer.InitializeCollection(client);
                }

                _logger.LogInformation("Cosmos DB Database {DatabaseId} and collections successfully initialized", cosmosDataStoreConfiguration.DatabaseId);
            }
            catch (Exception ex)
            {
                LogLevel logLevel = ex is RequestRateExceededException ? LogLevel.Warning : LogLevel.Critical;
                _logger.Log(logLevel, ex, "Cosmos DB Database {DatabaseId} and collections initialization failed", cosmosDataStoreConfiguration.DatabaseId);
                throw;
            }
        }