예제 #1
0
        static async Task Main(string[] args)
        {
            CommandLineOptions commandLineOptions = null;

            Parser.Default.ParseArguments <CommandLineOptions>(args)
            .WithParsed(opt => commandLineOptions = opt)
            .WithNotParsed(errors => {});

            if (commandLineOptions == null)
            {
                return;
            }

            //Determines the working environment as IHostingEnvironment is unavailable in a console app
            var devEnvironmentVariable = Environment.GetEnvironmentVariable("NETCORE_ENVIRONMENT");
            var isDevelopment          = devEnvironmentVariable != null && devEnvironmentVariable.ToLower() == "development";

            var builder = new ConfigurationBuilder()
                          .SetBasePath(Directory.GetCurrentDirectory())
                          .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);

            // Build now because we need configuration from appsettings.json to build the configuration for key vault.
            Configuration = builder.Build();

            var loggingSection = Configuration.GetSection("Logging");

            var serviceProvider = new ServiceCollection()
                                  .AddLogging(cfg => {
                cfg.AddConsole();
                if (isDevelopment)
                {
                    cfg.AddDebug();
                }
            })
                                  .AddLogging(cfg => cfg.AddFile(loggingSection))
                                  .Configure <LoggerFilterOptions>(cfg => cfg.MinLevel = LogLevel.Trace)
                                  .BuildServiceProvider();

            Logger = serviceProvider.GetService <ILogger <Program> >();

            HarvesterSettings = new HarvesterSettings();
            Configuration.Bind("HarvesterSettings", HarvesterSettings);

            if (commandLineOptions.IgnoreSecretSettings)
            {
                Logger.LogInformation("Ignoring user secrets and key vault settings - forcing usage of appsettings.json");
            }
            else
            {
                // Only add secrets in development - otherwise use key vault.
                if (isDevelopment)
                {
                    Logger.LogInformation("Using local configuration settings");
                    builder.AddUserSecrets <Program>();
                    Configuration = builder.Build();
                }
                else
                {
                    Logger.LogInformation("Using key vault's configuration settings");

                    if (string.IsNullOrWhiteSpace(HarvesterSettings.KeyVaultUri))
                    {
                        Logger.LogError("Cannot launch harvester - 'KeyVaultUri' is missing from appsettings.json.");
                        return;
                    }

                    if (string.IsNullOrWhiteSpace(commandLineOptions.KeyVaultClientId))
                    {
                        Logger.LogError("Cannot launch harvester - command line parameter 'keyvaultclientid' must be specified.");
                        return;
                    }

                    if (string.IsNullOrWhiteSpace(commandLineOptions.KeyVaultClientSecret))
                    {
                        Logger.LogError("Cannot launch harvester - command line parameter 'keyvaultclientsecret' must be specified.");
                        return;
                    }

                    // Use Azure Key Vault from a console app: https://c-sharx.net/read-secrets-from-azure-key-vault-in-a-net-core-console-app
                    builder.AddAzureKeyVault(HarvesterSettings.KeyVaultUri, clientId: commandLineOptions.KeyVaultClientId, clientSecret: commandLineOptions.KeyVaultClientSecret);
                    Configuration = builder.Build();
                }
            }

            // Bind again because values from user secrets or key vault have been added.
            // Important: recreate the settings or array-types will be duplicated.
            HarvesterSettings = new HarvesterSettings();
            Configuration.Bind("HarvesterSettings", HarvesterSettings);

            Console.WriteLine("Dashboard Harvester");
            Console.WriteLine();
            await RunHarvester(commandLineOptions);
        }
예제 #2
0
        public static async Task ProcessSource(SourceConfig sourceConfig, CosmosClient dbClient, HarvesterSettings harvesterSettings, IConfiguration configuration, ILogger logger)
        {
            logger.LogInformation($"Config entry to be processed: {sourceConfig}");

            var sourceTypeName = ("source" + sourceConfig.Id).ToLowerInvariant();
            var sourceType     = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(t => t.IsClass && t.Name.ToLowerInvariant() == sourceTypeName);

            if (sourceType == null)
            {
                logger.LogCritical($"Failed to find type for source ID '{sourceConfig.Id}'. Used '{sourceTypeName}' to scan for it.");
                return;
            }

            var source = (SourceBase)Activator.CreateInstance(sourceType, harvesterSettings, logger);

            if (source == null)
            {
                logger.LogCritical($"Failed to create instance of source for type '{sourceType}'");
                return;
            }

            SourceData sourceData = null;

            try
            {
                sourceData = await source.GetData();
            }
            catch (Exception ex)
            {
                logger.LogCritical($"Error getting source data: {ex}");
            }


            // Update source configuration.
            sourceConfig.LastUpdateUtc = DateTimeOffset.UtcNow;
            var      sourceConfigCronExpression = CronExpression.Parse(sourceConfig.CronExecutionTime);
            var      lastUpdateUtc    = sourceConfig.LastUpdateUtc != null ? sourceConfig.LastUpdateUtc.Value.UtcDateTime : DateTimeOffset.UtcNow.UtcDateTime;
            DateTime?nextExecutionUtc = sourceConfigCronExpression.GetNextOccurrence(lastUpdateUtc);

            sourceConfig.NextExecutionDueUtc = sourceConfigCronExpression.GetNextOccurrence(sourceConfig.LastUpdateUtc.Value.UtcDateTime);
            SaveSourceConfig(sourceConfig, logger);

            if (sourceData == null)
            {
                return;
            }

            // Save to database.
            if (dbClient != null)
            {
                var container = dbClient.GetContainer("dashboard", "sourcedata");
                await container.UpsertItemAsync(sourceData);
            }
            else
            {
                logger.LogWarning("CosmosClient is NULL - not saving source data!");
            }
        }