using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.CommandLineUtils; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Serilog; using Strata.Configuration.Client.DependencyInjection; using Strata.ContinuousImprovement.Biz.DbContexts; using Strata.healthchecks.Biz; using Strata.Logging.DependencyInjection; using Strata.Snowflake.Migrations.Client; using System; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Threading.Tasks; namespace Strata.ContinuousImprovement.Api { [ExcludeFromCodeCoverage] public class Program { public static void Main(string[] args) { try { var commandLineApplication = new CommandLineApplication(false); var doMigrate = commandLineApplication.Option( "--ef-migrate", "Apply entity framework migrations and exit", CommandOptionType.NoValue); commandLineApplication.HelpOption("-? | -h | --help"); commandLineApplication.OnExecute(async () => { await ExecuteApp(args, doMigrate); return 0; }); commandLineApplication.Execute(args); } catch (Exception ex) { Log.Error(ex, "There was an unhandled exception that caused the program to crash"); //This is for serilog to ensure that all of the cached logs are flushed when the app crashes //This is useful so we can capture logs when the application crashes during startup: Log.CloseAndFlush(); } } public static async Task ExecuteApp(string[] args, CommandOption doMigrate) { var webHost = CreateWebHostBuilder(args).Build(); if (doMigrate.HasValue()) { using var scope = webHost.Services.CreateScope(); var logger = scope.ServiceProvider.GetRequiredService>(); try { // Snowflake Migrations logger.LogInformation("Uploading and applying Snowflake migrations"); var snowflakeMigrationService = scope.ServiceProvider.GetRequiredService(); var snowflakeMigrationDirectory = Path.Combine(Environment.CurrentDirectory, "SnowflakeMigrations"); var success = await snowflakeMigrationService.PackageMigrations(snowflakeMigrationDirectory); if (!success) { logger.LogError("Failed to package migrations."); Environment.Exit(1); } logger.LogInformation("Snowflake migrations successfully uploaded to S3. Begin apply migrations."); success = await snowflakeMigrationService.ApplyClientMigrations(); if (!success) { logger.LogError("Failed to apply migrations."); Environment.Exit(1); } // EF Migrations logger.LogInformation("Applying Entity Framework migrations"); using var context = scope.ServiceProvider.GetService(); var hostEnv = scope.ServiceProvider.GetService(); context.Database.SetCommandTimeout(TimeSpan.FromMinutes(10)); context.Database.Migrate(); logger.LogInformation("All done, closing app"); Environment.Exit(Environment.ExitCode); } catch (Exception ex) { logger.LogError(ex, "There was an unhandled exception that caused the program to crash"); Environment.Exit(1); } } // no flags provided, so just run the webhost webHost.Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStrataConfiguration() .UseStrataLogging() .UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "Strata.healthchecks.Jazz") .UseStrataHealthChecks() .UseStartup(); } }