Beispiel #1
0
        private static ILeaseStore CreateLeaseStore(IServiceCollection services, CosmosDataStoreOptions cosmosDataStoreOptions)
        {
            var cosmosDbConnectionString = new CosmosDbConnectionString(cosmosDataStoreOptions.ConnectionString);
            var documentClient           = new DocumentClient(cosmosDbConnectionString.ServiceEndpoint, cosmosDbConnectionString.AuthKey);
            var serviceProvider          = services.BuildServiceProvider();

            return(new CosmosDbLeaseStore(documentClient, serviceProvider.GetService <IBigBrother>(),
                                          Options.Create(cosmosDataStoreOptions)));
        }
        /// <summary>
        /// Retrieves a Cosmos DB database and a container with the specified partition key.
        /// </summary>
        /// <returns></returns>
        private static CosmosDbService InitializeCosmosClientInstance(IConfiguration configuration)
        {
            var databaseName             = configuration["DatabaseName"];
            var containerName            = configuration["ContainerName"];
            var connectionString         = configuration["CosmosDBConnection"];
            var cosmosDbConnectionString = new CosmosDbConnectionString(connectionString);

            // TODO 8: Use the CosmosClientBuilder to create the CosmosClient and instantiate a new CosmosDbService so it can be returned.
            // Complete: CosmosClientBuilder clientBuilder = ...; CosmosClient client = ...; CosmosDbService cosmosDbService = ...;

            return(cosmosDbService);
        }
Beispiel #3
0
        /// <summary>
        /// Retrieves a Cosmos DB database and a container with the specified partition key.
        /// </summary>
        /// <returns></returns>
        private static CosmosDbService InitializeCosmosClientInstance(IConfiguration configuration)
        {
            var databaseName                  = configuration["DatabaseName"];
            var containerName                 = configuration["ContainerName"];
            var connectionString              = configuration["CosmosDBConnection"];
            var cosmosDbConnectionString      = new CosmosDbConnectionString(connectionString);
            CosmosClientBuilder clientBuilder = new CosmosClientBuilder(cosmosDbConnectionString.ServiceEndpoint.OriginalString, cosmosDbConnectionString.AuthKey);
            CosmosClient        client        = clientBuilder
                                                .WithConnectionModeDirect()
                                                .Build();
            CosmosDbService cosmosDbService = new CosmosDbService(client, databaseName, containerName);

            return(cosmosDbService);
        }
        public static IServiceCollection AddCosmosDocumentClient(this IServiceCollection services, string connectionString)
        {
            services.TryAddSingleton <IDocumentClient>(provider =>
            {
                var cosmosDBConnectionString = new CosmosDbConnectionString(connectionString);
                return(new DocumentClient(cosmosDBConnectionString.ServiceEndpoint, cosmosDBConnectionString.AuthKey,
                                          new JsonSerializerSettings
                {
                    ContractResolver = new CamelCasePropertyNamesContractResolver()
                }));
            });

            return(services);
        }
        public override void Configure(IFunctionsHostBuilder builder)
        {
            // Add a new HttpClientFactory that can be injected into the functions.
            // We add resilience and transient fault-handling capabilities to the HttpClient instances that the factory creates
            // by adding a Polly Retry policy with a very brief back-off starting at quarter-of-a-second to two seconds.
            // We want the HTTP requests that are sent to the downstream Logic App service to wait before attempting to try
            // sending the message, giving it some "breathing room" in case the service is overwhelmed. We chose to make
            // the time between retries relatively brief so as not to disrupt Cosmos DB message processing for too long, but
            // enough time to hopefully allow the downstream service to recover.
            // See the following for more information:
            // https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/implement-http-call-retries-exponential-backoff-polly
            builder.Services.AddHttpClient(NamedHttpClients.LogicAppClient, client =>
            {
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            })
            .AddTransientHttpErrorPolicy(policyBuilder => policyBuilder.WaitAndRetryAsync(new[]
            {
                TimeSpan.FromMilliseconds(250),
                TimeSpan.FromMilliseconds(500),
                TimeSpan.FromMilliseconds(1000),
                TimeSpan.FromMilliseconds(2000)
            }));

            // Register the Cosmos DB client as a Singleton.
            builder.Services.AddSingleton((s) => {
                var connectionString         = configuration["CosmosDBConnection"];
                var cosmosDbConnectionString = new CosmosDbConnectionString(connectionString);

                if (string.IsNullOrEmpty(connectionString))
                {
                    throw new ArgumentNullException("Please specify a value for CosmosDBConnection in the local.settings.json file or your Azure Functions Settings.");
                }

                CosmosClientBuilder configurationBuilder = new CosmosClientBuilder(cosmosDbConnectionString.ServiceEndpoint.OriginalString, cosmosDbConnectionString.AuthKey);
                return(configurationBuilder
                       .Build());
            });

            // Create Azure Storage queue client reference and create any queues that do not yet exist, through the
            // CreateKnownAzureQueues method.
            builder.Services.Configure <AzureStorageSettings>(configuration);
            StorageQueuesHelper.CreateKnownAzureQueues(configuration["ColdStorageAccount"]);
            builder.Services.AddTransient <IQueueResolver, QueueResolver>();
        }
        /// <summary>
        /// Adds <see cref="DistributedLock"/> to the services collection
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="configuration"></param>
        public static void AddCosmosDistributedLock(this ContainerBuilder builder, IConfigurationRoot configuration)
        {
            var cosmosDataStoreOptions = Options.Create(configuration.BindSection <CosmosDataStoreOptions>(CosmosDataStoreOptions,
                                                                                                           m => { m.AddMapping(x => x.ConnectionString, CosmosConnectionKeyVaultKey); }));

            builder.Register(ctx => cosmosDataStoreOptions)
            .As <IOptions <CosmosDataStoreOptions> >().SingleInstance();

            var cosmosDbConnectionString = new CosmosDbConnectionString(cosmosDataStoreOptions.Value.ConnectionString);
            var documentClient           = new DocumentClient(cosmosDbConnectionString.ServiceEndpoint, cosmosDbConnectionString.AuthKey);

            builder.Register(ctx =>
                             new CosmosDistributedLockStore(
                                 documentClient,
                                 cosmosDataStoreOptions,
                                 ctx.Resolve <IBigBrother>())).As <ICosmosDistributedLockStore>().SingleInstance();

            builder.RegisterType <DistributedLock>().As <IDistributedLock>();
        }
Beispiel #7
0
        /// <summary>
        /// Retrieves a Cosmos DB database and a container with the specified partition key.
        /// </summary>
        /// <returns></returns>
        private static CosmosDbService InitializeCosmosClientInstance(IConfiguration configuration)
        {
            var databaseName             = configuration["DatabaseName"];
            var containerName            = configuration["ContainerName"];
            var alertsContainerName      = configuration["AlertsContainerName"];
            var connectionString         = configuration["CosmosDBConnection"];
            var cosmosDbConnectionString = new CosmosDbConnectionString(connectionString);

            // Define the container name collection. The first container name listed is the default container
            // the Cosmos DB service class uses if no container name is provided within its methods.
            var containerNames = new List <string> {
                containerName, alertsContainerName
            };

            CosmosClientBuilder clientBuilder = new CosmosClientBuilder(cosmosDbConnectionString.ServiceEndpoint.OriginalString, cosmosDbConnectionString.AuthKey);
            CosmosClient        client        = clientBuilder
                                                .WithConnectionModeDirect()
                                                .Build();
            CosmosDbService cosmosDbService = new CosmosDbService(client, databaseName, containerNames);

            return(cosmosDbService);
        }
Beispiel #8
0
        /// <summary>
        /// Uses the vehicle telemetry contained in Cosmos DB to train the Anomaly Detector model.
        /// </summary>
        private static async Task <bool> TrainAnomalyDetectorModel(AppConfig appConfig)
        {
            var anomalyDetectorTrainUri = $"{appConfig.AnomalyDetector.Endpoint}anomalydetector/v1.0/timeseries/entire/detect";

            var timeSeriesData = new Series
            {
                maxAnomalyRatio = 0.25F,
                sensitivity     = 95,
                granularity     = "minutely"
            };

            // Retrieve data from Cosmos DB
            var cosmosDbConnectionString = new CosmosDbConnectionString(appConfig.CosmosDb.ConnectionString);
            // Set the Cosmos DB connection policy.
            var connectionPolicy = new ConnectionPolicy
            {
                ConnectionMode     = ConnectionMode.Direct,
                ConnectionProtocol = Protocol.Tcp
            };

            using (var cosmosClient = new DocumentClient(cosmosDbConnectionString.ServiceEndpoint, cosmosDbConnectionString.AuthKey, connectionPolicy))
            {
                var containerUri = UriFactory.CreateDocumentCollectionUri(appConfig.CosmosDb.DatabaseId, appConfig.CosmosDb.ContainerId);
                var query        = cosmosClient.CreateDocumentQuery <EngineTempRecord>(containerUri.ToString(),
                                                                                       new Documents.SqlQuerySpec("SELECT TOP 5000 c.engineTemperature FROM c"),
                                                                                       new FeedOptions {
                    MaxItemCount = -1, EnableCrossPartitionQuery = true
                })
                                   .ToList();

                var models        = new List <AnomalyModel>();
                var startDateTime = DateTime.Now.AddDays(-6);
                var i             = 0;
                foreach (var temp in query)
                {
                    models.Add(new AnomalyModel {
                        timestamp = startDateTime.AddMinutes(i), value = temp.engineTemperature
                    });
                    i++;
                }
                timeSeriesData.series = models;
            }

            var requestBody = JsonConvert.SerializeObject(timeSeriesData);

            // Send the training request to the Anomaly Detector batch detect endpoint.
            using (var client = new HttpClient())
            {
                using (var request = new HttpRequestMessage())
                {
                    request.Method     = HttpMethod.Post;
                    request.RequestUri = new Uri(anomalyDetectorTrainUri);
                    request.Content    = new StringContent(requestBody, Encoding.UTF8, "application/json");
                    request.Headers.Add("Ocp-Apim-Subscription-Key", appConfig.AnomalyDetector.Key);

                    var response = await client.SendAsync(request).ConfigureAwait(false);

                    var responseBody = await response.Content.ReadAsStringAsync();

                    Console.ForegroundColor = response.IsSuccessStatusCode ? ConsoleColor.Green : ConsoleColor.Red;
                    Console.WriteLine(responseBody);
                    Console.ResetColor();

                    return(response.IsSuccessStatusCode);
                }
            }
        }
        static async Task Main(string[] args)
        {
            // Setup configuration to either read from the appsettings.json file (if present) or environment variables.
            var builder = new ConfigurationBuilder()
                          .SetBasePath(Directory.GetCurrentDirectory())
                          .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

            _configuration = builder.Build();
            var appConfig = new AppConfig();

            _configuration.Bind(appConfig);

            var statistics = new Statistic[0];

            var progress = new Progress <Progress>();

            progress.ProgressChanged += (sender, progressArgs) =>
            {
                foreach (var message in progressArgs.Messages)
                {
                    WriteLineInColor(message.Message, message.Color.ToConsoleColor());
                }
                statistics = progressArgs.Statistics;
            };

            while (true)
            {
                Console.WriteLine("Data Generator sends generated data into Cosmos DB.");
                Console.WriteLine("** Enter 1 to generate tweets.");
                Console.WriteLine("** Enter 2 to generate vehicle telemetry.");
                Console.WriteLine("** Enter X to exit the console application.");
                Console.WriteLine("");

                var userInput = "";

                while (true)
                {
                    Console.Write("Enter the number of the operation you would like to perform > ");

                    var input = Console.ReadLine();
                    if (input.Equals("1", StringComparison.InvariantCultureIgnoreCase) ||
                        input.Equals("2", StringComparison.InvariantCultureIgnoreCase) ||
                        input.Equals("X", StringComparison.InvariantCultureIgnoreCase))
                    {
                        userInput = input.Trim();
                        break;
                    }
                    else
                    {
                        Console.WriteLine("Invalid input entered. Please enter either 1, 2 or X.");
                    }
                }

                ThreadPool.SetMinThreads(100, 100);

                // Set an optional timeout for the generator.
                var cancellationSource = appConfig.CosmosDb.MillisecondsToRun == 0 ? new CancellationTokenSource() : new CancellationTokenSource(appConfig.CosmosDb.MillisecondsToRun);
                var cancellationToken  = cancellationSource.Token;

                // Handle Control+C or Control+Break.
                Console.CancelKeyPress += (o, e) =>
                {
                    WriteLineInColor("Stopped generator. No more data is being sent.", ConsoleColor.Yellow);
                    cancellationSource.Cancel();

                    // Allow the main thread to continue and exit...
                    WaitHandle.Set();

                    OutputStatistics(statistics);
                };

                Console.WriteLine(string.Empty);
                Console.WriteLine("======");
                WriteLineInColor("Press Ctrl+C or Ctrl+Break to cancel.", ConsoleColor.Cyan);
                Console.WriteLine(string.Empty);
                var dataType = "";

                var cosmosDbConnectionString = new CosmosDbConnectionString(appConfig.CosmosDb.ConnectionString);
                // Set the Cosmos DB connection policy.
                var connectionPolicy = new ConnectionPolicy
                {
                    ConnectionMode     = ConnectionMode.Direct,
                    ConnectionProtocol = Protocol.Tcp
                };

                using (_cosmosDbClient = new DocumentClient(cosmosDbConnectionString.ServiceEndpoint, cosmosDbConnectionString.AuthKey, connectionPolicy))
                {
                    switch (userInput.ToLower())
                    {
                    case "1":
                        await GenerateTweets(appConfig, cancellationToken, progress);

                        dataType = "Tweet";
                        break;

                    case "2":
                        await GenerateVehicleTelemetry(appConfig, cancellationToken, progress);

                        dataType = "Vehicle Telemetry";
                        break;

                    default:
                        // Exit the application
                        cancellationSource.Cancel();
                        return;
                    }
                }

                Console.WriteLine();
                WriteLineInColor($"Done sending generated {dataType} data", ConsoleColor.Cyan);
                Console.WriteLine();
                Console.WriteLine();

                OutputStatistics(statistics);
            }
        }