diff --git a/Directory.Build.props b/Directory.Build.props index 85066f3..c74a237 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,4 +1,10 @@ + + net9.0 + enable + enable + + Copyright © 2015-2024 Petabridge Petabridge @@ -12,7 +18,4 @@ $(NoWarn);CS1591 - - net8.0 - \ No newline at end of file diff --git a/Directory.Packages.props b/Directory.Packages.props index ef5d59e..0182acb 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -12,20 +12,33 @@ - - - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + - - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/DrawTogether.sln b/DrawTogether.sln index 052d455..9a688d1 100644 --- a/DrawTogether.sln +++ b/DrawTogether.sln @@ -27,6 +27,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{DC3392A7 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DrawTogether.Tests", "tests\DrawTogether.Tests\DrawTogether.Tests.csproj", "{108B25F0-A606-47C6-9151-CB0095110DDC}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "aspire", "aspire", "{0C6E23C7-5F35-475D-85EF-3A3FE13D814A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DrawTogether.AppHost", "src\DrawTogether.AppHost\DrawTogether.AppHost.csproj", "{FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DrawTogether.MigrationService", "src\DrawTogether.MigrationService\DrawTogether.MigrationService.csproj", "{2C615B52-0412-4FE2-B22C-5B1F7839F0AF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -97,6 +103,30 @@ Global {108B25F0-A606-47C6-9151-CB0095110DDC}.Release|x64.Build.0 = Release|Any CPU {108B25F0-A606-47C6-9151-CB0095110DDC}.Release|x86.ActiveCfg = Release|Any CPU {108B25F0-A606-47C6-9151-CB0095110DDC}.Release|x86.Build.0 = Release|Any CPU + {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Debug|x64.ActiveCfg = Debug|Any CPU + {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Debug|x64.Build.0 = Debug|Any CPU + {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Debug|x86.ActiveCfg = Debug|Any CPU + {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Debug|x86.Build.0 = Debug|Any CPU + {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Release|Any CPU.Build.0 = Release|Any CPU + {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Release|x64.ActiveCfg = Release|Any CPU + {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Release|x64.Build.0 = Release|Any CPU + {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Release|x86.ActiveCfg = Release|Any CPU + {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF}.Release|x86.Build.0 = Release|Any CPU + {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Debug|x64.ActiveCfg = Debug|Any CPU + {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Debug|x64.Build.0 = Debug|Any CPU + {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Debug|x86.ActiveCfg = Debug|Any CPU + {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Debug|x86.Build.0 = Debug|Any CPU + {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Release|Any CPU.Build.0 = Release|Any CPU + {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Release|x64.ActiveCfg = Release|Any CPU + {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Release|x64.Build.0 = Release|Any CPU + {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Release|x86.ActiveCfg = Release|Any CPU + {2C615B52-0412-4FE2-B22C-5B1F7839F0AF}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -106,5 +136,6 @@ Global EndGlobalSection GlobalSection(NestedProjects) = preSolution {108B25F0-A606-47C6-9151-CB0095110DDC} = {DC3392A7-58A4-4C8C-9401-6DDCD41FBF16} + {FB2F6129-90DA-4C6C-A318-D492DE6B3DCF} = {0C6E23C7-5F35-475D-85EF-3A3FE13D814A} EndGlobalSection EndGlobal diff --git a/global.json b/global.json index 0cfe4c8..3d8048a 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { "rollForward": "latestMinor", - "version": "8.0.101" + "version": "9.0.100" } } \ No newline at end of file diff --git a/src/DrawTogether.Actors/DrawTogether.Actors.csproj b/src/DrawTogether.Actors/DrawTogether.Actors.csproj index 54ebfa9..84d45bc 100644 --- a/src/DrawTogether.Actors/DrawTogether.Actors.csproj +++ b/src/DrawTogether.Actors/DrawTogether.Actors.csproj @@ -1,11 +1,5 @@  - - net8.0 - enable - enable - - diff --git a/src/DrawTogether.AppHost/DrawTogether.AppHost.csproj b/src/DrawTogether.AppHost/DrawTogether.AppHost.csproj new file mode 100644 index 0000000..7f7845b --- /dev/null +++ b/src/DrawTogether.AppHost/DrawTogether.AppHost.csproj @@ -0,0 +1,20 @@ + + + + + + Exe + true + + + + + + + + + + + + + diff --git a/src/DrawTogether.AppHost/Program.cs b/src/DrawTogether.AppHost/Program.cs new file mode 100644 index 0000000..f660889 --- /dev/null +++ b/src/DrawTogether.AppHost/Program.cs @@ -0,0 +1,17 @@ +var builder = DistributedApplication.CreateBuilder(args); + +var sqlServer = builder.AddSqlServer("sql"); + +var db = sqlServer.AddDatabase("DrawTogetherDb"); + +var migrationService = builder.AddProject("MigrationService") + .WaitFor(db) + .WithReference(db); + +builder.AddProject("DrawTogether") + .WithReference(db, "DefaultConnection") + .WaitForCompletion(migrationService); + +builder + .Build() + .Run(); diff --git a/src/DrawTogether.AppHost/Properties/launchSettings.json b/src/DrawTogether.AppHost/Properties/launchSettings.json new file mode 100644 index 0000000..48f3191 --- /dev/null +++ b/src/DrawTogether.AppHost/Properties/launchSettings.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:17142;http://localhost:15099", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21049", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22281" + } + }, + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:15099", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19227", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20048" + } + } + } +} diff --git a/src/DrawTogether.AppHost/appsettings.Development.json b/src/DrawTogether.AppHost/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/src/DrawTogether.AppHost/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/DrawTogether.AppHost/appsettings.json b/src/DrawTogether.AppHost/appsettings.json new file mode 100644 index 0000000..31c092a --- /dev/null +++ b/src/DrawTogether.AppHost/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "Aspire.Hosting.Dcp": "Warning" + } + } +} diff --git a/src/DrawTogether.Email/DrawTogether.Email.csproj b/src/DrawTogether.Email/DrawTogether.Email.csproj index 8d7ca2b..fac4f72 100644 --- a/src/DrawTogether.Email/DrawTogether.Email.csproj +++ b/src/DrawTogether.Email/DrawTogether.Email.csproj @@ -1,11 +1,5 @@  - - net8.0 - enable - enable - - diff --git a/src/DrawTogether.Entities/DrawTogether.Entities.csproj b/src/DrawTogether.Entities/DrawTogether.Entities.csproj index 6c4eb25..496ed8f 100644 --- a/src/DrawTogether.Entities/DrawTogether.Entities.csproj +++ b/src/DrawTogether.Entities/DrawTogether.Entities.csproj @@ -1,11 +1,5 @@  - - net8.0 - enable - enable - - diff --git a/src/DrawTogether.MigrationService/DrawTogether.MigrationService.csproj b/src/DrawTogether.MigrationService/DrawTogether.MigrationService.csproj new file mode 100644 index 0000000..3a486b1 --- /dev/null +++ b/src/DrawTogether.MigrationService/DrawTogether.MigrationService.csproj @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/DrawTogether.MigrationService/Program.cs b/src/DrawTogether.MigrationService/Program.cs new file mode 100644 index 0000000..e5cda5d --- /dev/null +++ b/src/DrawTogether.MigrationService/Program.cs @@ -0,0 +1,11 @@ +using DrawTogether.Data; +using DrawTogether.MigrationService; + +var builder = Host.CreateApplicationBuilder(args); + +builder.AddSqlServerDbContext("DrawTogetherDb"); + +builder.Services.AddHostedService(); + +var host = builder.Build(); +host.Run(); \ No newline at end of file diff --git a/src/DrawTogether.MigrationService/Properties/launchSettings.json b/src/DrawTogether.MigrationService/Properties/launchSettings.json new file mode 100644 index 0000000..63f5dac --- /dev/null +++ b/src/DrawTogether.MigrationService/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "DrawTogether.MigrationService": { + "commandName": "Project", + "dotnetRunMessages": true, + "environmentVariables": { + "DOTNET_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/DrawTogether.MigrationService/Worker.cs b/src/DrawTogether.MigrationService/Worker.cs new file mode 100644 index 0000000..343bbaa --- /dev/null +++ b/src/DrawTogether.MigrationService/Worker.cs @@ -0,0 +1,55 @@ +using DrawTogether.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage; + +namespace DrawTogether.MigrationService; + +public class Worker( + IServiceProvider serviceProvider, + IHostApplicationLifetime hostApplicationLifetime, + ILogger logger) : BackgroundService +{ + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + try + { + using var scope = serviceProvider.CreateScope(); + var dbContext = scope.ServiceProvider.GetRequiredService(); + + await EnsureCreatedAsync(dbContext, stoppingToken); + await RunMigrationAsync(dbContext, stoppingToken); + } + catch (Exception ex) + { + logger.LogError(ex, "An error occurred while migrating the database"); + } + + hostApplicationLifetime.StopApplication(); + } + + private async Task EnsureCreatedAsync(ApplicationDbContext dbContext, CancellationToken cancellationToken) + { + var strategy = dbContext.Database.CreateExecutionStrategy(); + var databaseCreator = dbContext.Database.GetService(); + + await strategy.ExecuteAsync(async ct => + { + if (!await databaseCreator.ExistsAsync(ct)) + { + await databaseCreator.CreateAsync(ct); + logger.LogInformation("Database created"); + } + }, cancellationToken); + } + + private async Task RunMigrationAsync(ApplicationDbContext dbContext, CancellationToken cancellationToken) + { + var strategy = dbContext.Database.CreateExecutionStrategy(); + await strategy.ExecuteAsync(async ct => + { + await dbContext.Database.MigrateAsync(ct); + logger.LogInformation("Database migrated"); + }, cancellationToken); + } +} \ No newline at end of file diff --git a/src/DrawTogether.MigrationService/appsettings.Development.json b/src/DrawTogether.MigrationService/appsettings.Development.json new file mode 100644 index 0000000..b2dcdb6 --- /dev/null +++ b/src/DrawTogether.MigrationService/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/src/DrawTogether.MigrationService/appsettings.json b/src/DrawTogether.MigrationService/appsettings.json new file mode 100644 index 0000000..b2dcdb6 --- /dev/null +++ b/src/DrawTogether.MigrationService/appsettings.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/src/DrawTogether/Config/AkkaConfiguration.cs b/src/DrawTogether/Config/AkkaConfiguration.cs index 43e85a7..8e4dde5 100644 --- a/src/DrawTogether/Config/AkkaConfiguration.cs +++ b/src/DrawTogether/Config/AkkaConfiguration.cs @@ -23,7 +23,7 @@ public static IServiceCollection ConfigureAkka(this IServiceCollection services, var connectionString = configuration.GetConnectionString("DefaultConnection"); if (connectionString is null) - throw new Exception("DefaultConnection setting is missing"); + throw new Exception("DefaultConnection ConnectionString is missing"); var roleName = ClusterConstants.DrawStateRoleName; diff --git a/src/DrawTogether/DrawTogether.csproj b/src/DrawTogether/DrawTogether.csproj index 2ffe154..906998b 100644 --- a/src/DrawTogether/DrawTogether.csproj +++ b/src/DrawTogether/DrawTogether.csproj @@ -1,9 +1,6 @@ - net8.0 - enable - enable aspnet-DrawTogether-519D8737-B9C5-4479-BE39-7C98C7D228C7 Linux drawtogether-app @@ -32,6 +29,7 @@ + diff --git a/src/DrawTogether/Program.cs b/src/DrawTogether/Program.cs index cf1411c..3592ece 100644 --- a/src/DrawTogether/Program.cs +++ b/src/DrawTogether/Program.cs @@ -42,9 +42,8 @@ }) .AddIdentityCookies(); -var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found."); -builder.Services.AddDbContext(options => - options.UseSqlServer(connectionString)); +builder.AddSqlServerDbContext("DefaultConnection"); + builder.Services.AddDatabaseDeveloperPageExceptionFilter(); builder.Services.AddIdentityCore(options => options.SignIn.RequireConfirmedAccount = true) diff --git a/src/DrawTogether/appsettings.json b/src/DrawTogether/appsettings.json index 59b87d3..ebb3efc 100644 --- a/src/DrawTogether/appsettings.json +++ b/src/DrawTogether/appsettings.json @@ -1,7 +1,4 @@ { - "ConnectionStrings": { - "DefaultConnection": "Server=localhost,1633; Database=DrawTogether; User Id=sa; Password=yourStrong(!)Password; TrustServerCertificate=true;" - }, "Logging": { "LogLevel": { "Default": "Information", diff --git a/tests/DrawTogether.Tests/DrawTogether.Tests.csproj b/tests/DrawTogether.Tests/DrawTogether.Tests.csproj index ffa3667..6e1e42c 100644 --- a/tests/DrawTogether.Tests/DrawTogether.Tests.csproj +++ b/tests/DrawTogether.Tests/DrawTogether.Tests.csproj @@ -1,10 +1,6 @@ - net8.0 - enable - enable - false true