From 27c63a4efa7f5e02c4ab78e1e5a2847f8808bb4d Mon Sep 17 00:00:00 2001 From: meysamhadeli Date: Sun, 4 Dec 2022 00:54:19 +0330 Subject: [PATCH] - use test container for default database mssql - use test container for default broker rabbitmq - change structure persist-message-db --- .../docker-compose/docker-compose.yaml | 209 +++++++++--------- .../docker-compose/infrastracture.yaml | 36 ++- src/BuildingBlocks/BuildingBlocks.csproj | 6 +- src/BuildingBlocks/EFCore/AppDbContextBase.cs | 6 +- src/BuildingBlocks/EFCore/DatabaseOptions.cs | 2 +- src/BuildingBlocks/EFCore/Extensions.cs | 22 +- src/BuildingBlocks/EFCore/IDbContext.cs | 5 +- src/BuildingBlocks/HealthCheck/Extensions.cs | 11 +- src/BuildingBlocks/MassTransit/Extensions.cs | 2 +- .../Data/DesignTimeDbContextFactory.cs | 16 -- .../20220728155556_initial.Designer.cs | 69 ------ .../Data/Migrations/20220728155556_initial.cs | 41 ---- .../PersistMessageDbContextModelSnapshot.cs | 63 ------ .../Data/PersistMessageDbContext.cs | 23 -- .../PersistMessageProcessor/Data/readme.md | 2 - .../PersistMessageProcessor/Extensions.cs | 21 +- .../IPersistMessageDbContext.cs | 9 - .../PersistMessageProcessor.cs | 25 ++- .../TestBase/IntegrationTestBase.cs | 158 ++++++------- src/BuildingBlocks/TestBase/TestContainers.cs | 29 +-- .../src/Booking.Api/appsettings.docker.json | 2 +- .../Booking/src/Booking.Api/appsettings.json | 4 +- .../src/Booking.Api/appsettings.test.json | 4 +- .../InfrastructureExtensions.cs | 6 +- .../Booking/Features/CreateBookingTests.cs | 11 +- .../Flight/src/Flight.Api/appsettings.json | 7 +- .../src/Flight.Api/appsettings.test.json | 7 +- .../Configurations/AircraftConfiguration.cs | 3 +- .../Configurations/AirportConfiguration.cs | 3 +- .../Configurations/FlightConfiguration.cs | 3 +- .../PersistMessageConfiguration.cs | 45 ++++ .../Data/Configurations/SeatConfiguration.cs | 3 +- .../Flight/Data/DesignTimeDbContextFactory.cs | 3 +- .../Flight/src/Flight/Data/FlightDbContext.cs | 6 +- ....cs => 20221203201848_Initial.Designer.cs} | 43 +++- ...5834_Init.cs => 20221203201848_Initial.cs} | 27 ++- .../FlightDbContextModelSnapshot.cs | 38 +++- .../InfrastructureExtensions.cs | 8 +- .../src/Identity.Api/appsettings.docker.json | 4 +- .../src/Identity.Api/appsettings.json | 7 +- .../src/Identity.Api/appsettings.test.json | 7 +- .../PersistMessageConfiguration.cs | 44 ++++ .../Data/DesignTimeDbContextFactory.cs | 2 +- .../src/Identity/Data/IdentityContext.cs | 11 +- ....cs => 20221203211306_initial.Designer.cs} | 66 ++++-- ...7_initial.cs => 20221203211306_initial.cs} | 70 +++++- .../IdentityContextModelSnapshot.cs | 63 ++++-- .../InfrastructureExtensions.cs | 6 +- .../src/Passenger.Api/appsettings.docker.json | 4 +- .../src/Passenger.Api/appsettings.json | 7 +- .../src/Passenger.Api/appsettings.test.json | 9 +- .../Configurations/PassengerConfiguration.cs | 5 +- .../PersistMessageConfiguration.cs | 8 +- .../Data/DesignTimeDbContextFactory.cs | 2 +- ....cs => 20221203211633_initial.Designer.cs} | 44 +++- ...0_initial.cs => 20221203211633_initial.cs} | 26 +++ .../PassengerDbContextModelSnapshot.cs | 41 +++- .../InfrastructureExtensions.cs | 6 +- 58 files changed, 809 insertions(+), 601 deletions(-) delete mode 100644 src/BuildingBlocks/PersistMessageProcessor/Data/DesignTimeDbContextFactory.cs delete mode 100644 src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20220728155556_initial.Designer.cs delete mode 100644 src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20220728155556_initial.cs delete mode 100644 src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/PersistMessageDbContextModelSnapshot.cs delete mode 100644 src/BuildingBlocks/PersistMessageProcessor/Data/PersistMessageDbContext.cs delete mode 100644 src/BuildingBlocks/PersistMessageProcessor/Data/readme.md delete mode 100644 src/BuildingBlocks/PersistMessageProcessor/IPersistMessageDbContext.cs create mode 100644 src/Services/Flight/src/Flight/Data/Configurations/PersistMessageConfiguration.cs rename src/Services/Flight/src/Flight/Data/Migrations/{20220728175834_Init.Designer.cs => 20221203201848_Initial.Designer.cs} (84%) rename src/Services/Flight/src/Flight/Data/Migrations/{20220728175834_Init.cs => 20221203201848_Initial.cs} (86%) create mode 100644 src/Services/Identity/src/Identity/Data/Configurations/PersistMessageConfiguration.cs rename src/Services/Identity/src/Identity/Data/Migrations/{20220728175937_initial.Designer.cs => 20221203211306_initial.Designer.cs} (83%) rename src/Services/Identity/src/Identity/Data/Migrations/{20220728175937_initial.cs => 20221203211306_initial.cs} (79%) rename src/{BuildingBlocks/PersistMessageProcessor => Services/Passenger/src/Passenger}/Data/Configurations/PersistMessageConfiguration.cs (83%) rename src/Services/Passenger/src/Passenger/Data/Migrations/{20220728180020_initial.Designer.cs => 20221203211633_initial.Designer.cs} (58%) rename src/Services/Passenger/src/Passenger/Data/Migrations/{20220728180020_initial.cs => 20221203211633_initial.cs} (58%) diff --git a/deployments/docker-compose/docker-compose.yaml b/deployments/docker-compose/docker-compose.yaml index e61ddf5..0ba167e 100644 --- a/deployments/docker-compose/docker-compose.yaml +++ b/deployments/docker-compose/docker-compose.yaml @@ -1,9 +1,9 @@ version: "3.3" services: - ####################################################### - # Gateway - ####################################################### + ####################################################### + # Gateway + ####################################################### gateway: image: gateway build: @@ -19,17 +19,15 @@ services: - db - rabbitmq - jaeger - - eventstore.db - elasticsearch - kibana - # - mongo volumes: - - '${USERPROFILE}\.aspnet\https:/https/' + - '${USERPROFILE}\.aspnet\https:/https/' environment: - - 'ASPNETCORE_URLS=https://+;http://+' - - ASPNETCORE_HTTPS_PORT=5001 - - ASPNETCORE_Kestrel__Certificates__Default__Password=password - - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx + - 'ASPNETCORE_URLS=https://+;http://+' + - ASPNETCORE_HTTPS_PORT=5001 + - ASPNETCORE_Kestrel__Certificates__Default__Password=password + - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx networks: - booking @@ -52,17 +50,16 @@ services: - db - rabbitmq - jaeger - - eventstore.db - elasticsearch - kibana - # - mongo + - mongo volumes: - - '${USERPROFILE}\.aspnet\https:/https/' + - '${USERPROFILE}\.aspnet\https:/https/' environment: - - 'ASPNETCORE_URLS=https://+;http://+' - - ASPNETCORE_HTTPS_PORT=5003 - - ASPNETCORE_Kestrel__Certificates__Default__Password=password - - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx + - 'ASPNETCORE_URLS=https://+;http://+' + - ASPNETCORE_HTTPS_PORT=5003 + - ASPNETCORE_Kestrel__Certificates__Default__Password=password + - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx networks: - booking @@ -85,17 +82,15 @@ services: - db - rabbitmq - jaeger - - eventstore.db - elasticsearch - kibana - # - mongo volumes: - - '${USERPROFILE}\.aspnet\https:/https/' + - '${USERPROFILE}\.aspnet\https:/https/' environment: - - 'ASPNETCORE_URLS=https://+;http://+' - - ASPNETCORE_HTTPS_PORT=5005 - - ASPNETCORE_Kestrel__Certificates__Default__Password=password - - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx + - 'ASPNETCORE_URLS=https://+;http://+' + - ASPNETCORE_HTTPS_PORT=5005 + - ASPNETCORE_Kestrel__Certificates__Default__Password=password + - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx networks: - booking @@ -118,17 +113,16 @@ services: - db - rabbitmq - jaeger - - eventstore.db - elasticsearch - kibana - # - mongo + - mongo volumes: - - '${USERPROFILE}\.aspnet\https:/https/' + - '${USERPROFILE}\.aspnet\https:/https/' environment: - - 'ASPNETCORE_URLS=https://+;http://+' - - ASPNETCORE_HTTPS_PORT=5012 - - ASPNETCORE_Kestrel__Certificates__Default__Password=password - - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx + - 'ASPNETCORE_URLS=https://+;http://+' + - ASPNETCORE_HTTPS_PORT=5012 + - ASPNETCORE_Kestrel__Certificates__Default__Password=password + - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx networks: - booking @@ -154,18 +148,49 @@ services: - eventstore.db - elasticsearch - kibana - # - mongo + - mongo volumes: - - '${USERPROFILE}\.aspnet\https:/https/' + - '${USERPROFILE}\.aspnet\https:/https/' environment: - - 'ASPNETCORE_URLS=https://+;http://+' - - ASPNETCORE_HTTPS_PORT=5010 - - ASPNETCORE_Kestrel__Certificates__Default__Password=password - - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx + - 'ASPNETCORE_URLS=https://+;http://+' + - ASPNETCORE_HTTPS_PORT=5010 + - ASPNETCORE_Kestrel__Certificates__Default__Password=password + - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx networks: - booking + ####################################################### + # SqlServer + ####################################################### + db: + container_name: sqldb + image: mcr.microsoft.com/mssql/server:2022-latest + restart: unless-stopped + ports: + - "1433:1433" + environment: + SA_PASSWORD: "@Aa123456" + ACCEPT_EULA: "Y" + networks: + - booking + + +# ###################################################### +# # Postgres +# ###################################################### +# postgres: +# image: postgres:latest +# container_name: postgres +# restart: on-failure +# ports: +# - '5432:5432' +# environment: +# - POSTGRES_USER=postgres +# - POSTGRES_PASSWORD=postgres +# networks: +# - booking + ####################################################### # Rabbitmq @@ -181,22 +206,6 @@ services: - booking - ####################################################### - # SqlServer - ####################################################### - db: - container_name: sqldb - image: mcr.microsoft.com/mssql/server:2017-latest - restart: unless-stopped - ports: - - "1433:1433" - environment: - SA_PASSWORD: "@Aa123456" - ACCEPT_EULA: "Y" - networks: - - booking - - ####################################################### # Jaeger ####################################################### @@ -220,22 +229,22 @@ services: # EventStoreDB ####################################################### eventstore.db: - image: eventstore/eventstore:21.2.0-buster-slim - restart: on-failure - environment: - - EVENTSTORE_CLUSTER_SIZE=1 - - EVENTSTORE_RUN_PROJECTIONS=All - - EVENTSTORE_START_STANDARD_PROJECTIONS=true - - EVENTSTORE_EXT_TCP_PORT=1010 - - EVENTSTORE_EXT_HTTP_PORT=2113 - - EVENTSTORE_INSECURE=true - - EVENTSTORE_ENABLE_EXTERNAL_TCP=true - - EVENTSTORE_ENABLE_ATOM_PUB_OVER_HTTP=true - ports: - - '1010:1113' - - '2113:2113' - networks: - - booking + image: eventstore/eventstore:21.2.0-buster-slim + restart: on-failure + environment: + - EVENTSTORE_CLUSTER_SIZE=1 + - EVENTSTORE_RUN_PROJECTIONS=All + - EVENTSTORE_START_STANDARD_PROJECTIONS=true + - EVENTSTORE_EXT_TCP_PORT=1010 + - EVENTSTORE_EXT_HTTP_PORT=2113 + - EVENTSTORE_INSECURE=true + - EVENTSTORE_ENABLE_EXTERNAL_TCP=true + - EVENTSTORE_ENABLE_ATOM_PUB_OVER_HTTP=true + ports: + - '1010:1113' + - '2113:2113' + networks: + - booking ####################################################### @@ -254,43 +263,43 @@ services: - 27017:27017 volumes: - mongo:/data/db - + ####################################################### # Elastic Search ####################################################### elasticsearch: - container_name: elasticsearch - image: docker.elastic.co/elasticsearch/elasticsearch:7.9.2 - restart: unless-stopped - ports: - - 9200:9200 - volumes: - - elasticsearch-data:/usr/share/elasticsearch/data - environment: - - xpack.monitoring.enabled=true - - xpack.watcher.enabled=false - - "ES_JAVA_OPTS=-Xms512m -Xmx512m" - - discovery.type=single-node - networks: - - booking + container_name: elasticsearch + image: docker.elastic.co/elasticsearch/elasticsearch:7.9.2 + restart: unless-stopped + ports: + - 9200:9200 + volumes: + - elasticsearch-data:/usr/share/elasticsearch/data + environment: + - xpack.monitoring.enabled=true + - xpack.watcher.enabled=false + - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + - discovery.type=single-node + networks: + - booking - ####################################################### - # Kibana - ####################################################### + ####################################################### + # Kibana + ####################################################### kibana: - container_name: kibana - image: docker.elastic.co/kibana/kibana:7.9.2 - restart: unless-stopped - ports: - - 5601:5601 - depends_on: - - elasticsearch - environment: - - ELASTICSEARCH_URL=http://localhost:9200 - networks: - - booking - + container_name: kibana + image: docker.elastic.co/kibana/kibana:7.9.2 + restart: unless-stopped + ports: + - 5601:5601 + depends_on: + - elasticsearch + environment: + - ELASTICSEARCH_URL=http://localhost:9200 + networks: + - booking + networks: @@ -303,7 +312,7 @@ volumes: external: false mongo: driver: local - elasticsearch-data: + elasticsearch-data: diff --git a/deployments/docker-compose/infrastracture.yaml b/deployments/docker-compose/infrastracture.yaml index 4aac29f..d219836 100644 --- a/deployments/docker-compose/infrastracture.yaml +++ b/deployments/docker-compose/infrastracture.yaml @@ -20,7 +20,7 @@ services: ####################################################### db: container_name: sqldb - image: mcr.microsoft.com/mssql/server:2017-latest + image: mcr.microsoft.com/mssql/server:2022-latest restart: unless-stopped ports: - "1433:1433" @@ -31,6 +31,21 @@ services: - booking +# ####################################################### +# # Postgres +# ###################################################### +# postgres: +# image: postgres:latest +# container_name: postgres +# restart: on-failure +# ports: +# - '5432:5432' +# environment: +# - POSTGRES_USER=postgres +# - POSTGRES_PASSWORD=postgres +# networks: +# - booking + ####################################################### # Jaeger ####################################################### @@ -88,7 +103,7 @@ services: - 27017:27017 volumes: - mongo:/data/db - + ####################################################### # Elastic Search @@ -124,7 +139,19 @@ services: - ELASTICSEARCH_URL=http://localhost:9200 networks: - booking - + + ####################################################### + # Redis + ####################################################### + redis: + image: redis + container_name: redis + restart: unless-stopped + networks: + - booking + ports: + - 6379:6379 + networks: @@ -137,7 +164,8 @@ volumes: external: false mongo: driver: local - elasticsearch-data: + elasticsearch-data: + diff --git a/src/BuildingBlocks/BuildingBlocks.csproj b/src/BuildingBlocks/BuildingBlocks.csproj index 1138fc0..430ff9c 100644 --- a/src/BuildingBlocks/BuildingBlocks.csproj +++ b/src/BuildingBlocks/BuildingBlocks.csproj @@ -27,6 +27,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + @@ -123,7 +127,7 @@ - + diff --git a/src/BuildingBlocks/EFCore/AppDbContextBase.cs b/src/BuildingBlocks/EFCore/AppDbContextBase.cs index 9a0852a..220c992 100644 --- a/src/BuildingBlocks/EFCore/AppDbContextBase.cs +++ b/src/BuildingBlocks/EFCore/AppDbContextBase.cs @@ -2,8 +2,8 @@ using System.Collections.Immutable; using System.Data; using BuildingBlocks.Core.Event; using BuildingBlocks.Core.Model; +using BuildingBlocks.PersistMessageProcessor; using BuildingBlocks.Utils; -using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Storage; @@ -11,6 +11,8 @@ namespace BuildingBlocks.EFCore; public abstract class AppDbContextBase : DbContext, IDbContext { + public const string DefaultSchema = "dbo"; + private readonly ICurrentUserProvider _currentUserProvider; private IDbContextTransaction _currentTransaction; @@ -69,7 +71,7 @@ public abstract class AppDbContextBase : DbContext, IDbContext OnBeforeSaving(); return base.SaveChangesAsync(cancellationToken); } - + public IReadOnlyList GetDomainEvents() { var domainEntities = ChangeTracker diff --git a/src/BuildingBlocks/EFCore/DatabaseOptions.cs b/src/BuildingBlocks/EFCore/DatabaseOptions.cs index 9915201..90ef69d 100644 --- a/src/BuildingBlocks/EFCore/DatabaseOptions.cs +++ b/src/BuildingBlocks/EFCore/DatabaseOptions.cs @@ -1,6 +1,6 @@ namespace BuildingBlocks.EFCore; -public class ConnectionStrings +public class DatabaseOptions { public string DefaultConnection { get; set; } } diff --git a/src/BuildingBlocks/EFCore/Extensions.cs b/src/BuildingBlocks/EFCore/Extensions.cs index 35a790d..7b22142 100644 --- a/src/BuildingBlocks/EFCore/Extensions.cs +++ b/src/BuildingBlocks/EFCore/Extensions.cs @@ -1,6 +1,7 @@ using System.Linq.Expressions; using BuildingBlocks.Core.Model; -using BuildingBlocks.PersistMessageProcessor.Data; +using BuildingBlocks.PersistMessageProcessor; +using BuildingBlocks.Web; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; @@ -18,14 +19,17 @@ public static class Extensions IConfiguration configuration) where TContext : DbContext, IDbContext { - services.AddOptions() - .Bind(configuration.GetSection(nameof(ConnectionStrings))) + services.AddOptions() + .Bind(configuration.GetSection(nameof(DatabaseOptions))) .ValidateDataAnnotations(); - services.AddDbContext(options => - options.UseSqlServer( - configuration.GetConnectionString("DefaultConnection"), - x => x.MigrationsAssembly(typeof(TContext).Assembly.GetName().Name))); + services.AddDbContext((sp, options) => + { + var databaseOptions = services.GetOptions(nameof(DatabaseOptions)); + + options.UseSqlServer(databaseOptions?.DefaultConnection, + dbOptions => dbOptions.MigrationsAssembly(typeof(TContext).Assembly.GetName().Name)); + }); services.AddScoped(provider => provider.GetService()); @@ -67,10 +71,8 @@ public static class Extensions { using var scope = serviceProvider.CreateScope(); - var persistMessageContext = scope.ServiceProvider.GetRequiredService(); - await persistMessageContext.Database.MigrateAsync(); - var context = scope.ServiceProvider.GetRequiredService(); + await context.Database.MigrateAsync(); } diff --git a/src/BuildingBlocks/EFCore/IDbContext.cs b/src/BuildingBlocks/EFCore/IDbContext.cs index 186d1b2..473626e 100644 --- a/src/BuildingBlocks/EFCore/IDbContext.cs +++ b/src/BuildingBlocks/EFCore/IDbContext.cs @@ -1,12 +1,13 @@ using BuildingBlocks.Core.Event; +using BuildingBlocks.PersistMessageProcessor; using Microsoft.EntityFrameworkCore; namespace BuildingBlocks.EFCore; public interface IDbContext { - DbSet Set() - where TEntity : class; + DbSet Set() where TEntity : class; + DbSet PersistMessages => Set(); IReadOnlyList GetDomainEvents(); Task BeginTransactionAsync(CancellationToken cancellationToken = default); diff --git a/src/BuildingBlocks/HealthCheck/Extensions.cs b/src/BuildingBlocks/HealthCheck/Extensions.cs index 421c348..86f14ee 100644 --- a/src/BuildingBlocks/HealthCheck/Extensions.cs +++ b/src/BuildingBlocks/HealthCheck/Extensions.cs @@ -3,7 +3,6 @@ using BuildingBlocks.Logging; using BuildingBlocks.MassTransit; using BuildingBlocks.Mongo; using BuildingBlocks.Web; -using DotNetCore.CAP.MongoDB; using HealthChecks.UI.Client; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Diagnostics.HealthChecks; @@ -17,11 +16,11 @@ public static class Extensions { public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services) { - var appOptions = services.GetOptions("AppOptions"); - var sqlOptions = services.GetOptions("ConnectionStrings"); - var rabbitMqOptions = services.GetOptions("RabbitMq"); - var mongoOptions = services.GetOptions("MongoOptions"); - var logOptions = services.GetOptions("LogOptions"); + var appOptions = services.GetOptions(nameof(AppOptions)); + var sqlOptions = services.GetOptions(nameof(DatabaseOptions)); + var rabbitMqOptions = services.GetOptions(nameof(RabbitMqOptions)); + var mongoOptions = services.GetOptions(nameof(MongoOptions)); + var logOptions = services.GetOptions(nameof(LogOptions)); var healthChecksBuilder = services.AddHealthChecks() .AddRabbitMQ(rabbitConnectionString: $"amqp://{rabbitMqOptions.UserName}:{rabbitMqOptions.Password}@{rabbitMqOptions.HostName}") diff --git a/src/BuildingBlocks/MassTransit/Extensions.cs b/src/BuildingBlocks/MassTransit/Extensions.cs index 66b9ed8..d6af590 100644 --- a/src/BuildingBlocks/MassTransit/Extensions.cs +++ b/src/BuildingBlocks/MassTransit/Extensions.cs @@ -46,7 +46,7 @@ public static class Extensions configure.UsingRabbitMq((context, configurator) => { - var rabbitMqOptions = services.GetOptions("RabbitMq"); + var rabbitMqOptions = services.GetOptions(nameof(RabbitMqOptions)); var host = IsRunningInContainer ? "rabbitmq" : rabbitMqOptions.HostName; configurator.Host(host, rabbitMqOptions?.Port ?? 5672, "/", h => diff --git a/src/BuildingBlocks/PersistMessageProcessor/Data/DesignTimeDbContextFactory.cs b/src/BuildingBlocks/PersistMessageProcessor/Data/DesignTimeDbContextFactory.cs deleted file mode 100644 index 538c51f..0000000 --- a/src/BuildingBlocks/PersistMessageProcessor/Data/DesignTimeDbContextFactory.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Design; - -namespace BuildingBlocks.PersistMessageProcessor.Data; - -public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory -{ - public PersistMessageDbContext CreateDbContext(string[] args) - { - var builder = new DbContextOptionsBuilder(); - - builder.UseSqlServer( - "Data Source=.\\sqlexpress;Initial Catalog=PersistMessageDB;Persist Security Info=False;Integrated Security=SSPI"); - return new PersistMessageDbContext(builder.Options); - } -} diff --git a/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20220728155556_initial.Designer.cs b/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20220728155556_initial.Designer.cs deleted file mode 100644 index fbe223d..0000000 --- a/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20220728155556_initial.Designer.cs +++ /dev/null @@ -1,69 +0,0 @@ -// -using System; -using Booking.Data; -using BuildingBlocks.PersistMessageProcessor.Data; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace Booking.Data.Migrations -{ - [DbContext(typeof(PersistMessageDbContext))] - [Migration("20220728155556_initial")] - partial class initial - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "6.0.1") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); - - modelBuilder.Entity("BuildingBlocks.PersistMessageProcessor.PersistMessage", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("ApplicationName") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("Created") - .HasColumnType("datetime2"); - - b.Property("Data") - .HasColumnType("nvarchar(max)"); - - b.Property("DataType") - .HasColumnType("nvarchar(max)"); - - b.Property("DeliveryType") - .IsRequired() - .HasMaxLength(50) - .IsUnicode(false) - .HasColumnType("varchar(50)"); - - b.Property("MessageStatus") - .IsRequired() - .HasMaxLength(50) - .IsUnicode(false) - .HasColumnType("varchar(50)"); - - b.Property("RetryCount") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.ToTable("PersistMessage", "dbo"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20220728155556_initial.cs b/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20220728155556_initial.cs deleted file mode 100644 index b2ddd42..0000000 --- a/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20220728155556_initial.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Booking.Data.Migrations -{ - public partial class initial : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.EnsureSchema( - name: "dbo"); - - migrationBuilder.CreateTable( - name: "PersistMessage", - schema: "dbo", - columns: table => new - { - Id = table.Column(type: "bigint", nullable: false), - DataType = table.Column(type: "nvarchar(max)", nullable: true), - Data = table.Column(type: "nvarchar(max)", nullable: true), - Created = table.Column(type: "datetime2", nullable: false), - RetryCount = table.Column(type: "int", nullable: false), - MessageStatus = table.Column(type: "varchar(50)", unicode: false, maxLength: 50, nullable: false), - DeliveryType = table.Column(type: "varchar(50)", unicode: false, maxLength: 50, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_PersistMessage", x => x.Id); - }); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "PersistMessage", - schema: "dbo"); - } - } -} diff --git a/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/PersistMessageDbContextModelSnapshot.cs b/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/PersistMessageDbContextModelSnapshot.cs deleted file mode 100644 index 5c56774..0000000 --- a/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/PersistMessageDbContextModelSnapshot.cs +++ /dev/null @@ -1,63 +0,0 @@ -// -using System; -using Booking.Data; -using BuildingBlocks.PersistMessageProcessor.Data; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace Booking.Data.Migrations -{ - [DbContext(typeof(PersistMessageDbContext))] - partial class PersistMessageDbContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "6.0.1") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); - - modelBuilder.Entity("BuildingBlocks.PersistMessageProcessor.PersistMessage", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Created") - .HasColumnType("datetime2"); - - b.Property("Data") - .HasColumnType("nvarchar(max)"); - - b.Property("DataType") - .HasColumnType("nvarchar(max)"); - - b.Property("DeliveryType") - .IsRequired() - .HasMaxLength(50) - .IsUnicode(false) - .HasColumnType("varchar(50)"); - - b.Property("MessageStatus") - .IsRequired() - .HasMaxLength(50) - .IsUnicode(false) - .HasColumnType("varchar(50)"); - - b.Property("RetryCount") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.ToTable("PersistMessage", "dbo"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/BuildingBlocks/PersistMessageProcessor/Data/PersistMessageDbContext.cs b/src/BuildingBlocks/PersistMessageProcessor/Data/PersistMessageDbContext.cs deleted file mode 100644 index 8aa3528..0000000 --- a/src/BuildingBlocks/PersistMessageProcessor/Data/PersistMessageDbContext.cs +++ /dev/null @@ -1,23 +0,0 @@ -using BuildingBlocks.EFCore; -using BuildingBlocks.PersistMessageProcessor.Data.Configurations; -using BuildingBlocks.Utils; -using Microsoft.AspNetCore.Http; -using Microsoft.EntityFrameworkCore; - -namespace BuildingBlocks.PersistMessageProcessor.Data; - -public class PersistMessageDbContext : AppDbContextBase, IPersistMessageDbContext -{ - public const string DefaultSchema = "dbo"; - - public PersistMessageDbContext(DbContextOptions options) - : base(options) - { - } - - protected override void OnModelCreating(ModelBuilder builder) - { - builder.ApplyConfiguration(new PersistMessageConfiguration()); - base.OnModelCreating(builder); - } -} diff --git a/src/BuildingBlocks/PersistMessageProcessor/Data/readme.md b/src/BuildingBlocks/PersistMessageProcessor/Data/readme.md deleted file mode 100644 index b7f4097..0000000 --- a/src/BuildingBlocks/PersistMessageProcessor/Data/readme.md +++ /dev/null @@ -1,2 +0,0 @@ -dotnet ef migrations add initial --context PersistMessageDbContext -o "Data\Migrations" -dotnet ef database update --context PersistMessageDbContext diff --git a/src/BuildingBlocks/PersistMessageProcessor/Extensions.cs b/src/BuildingBlocks/PersistMessageProcessor/Extensions.cs index 2a6b0f5..21dcc01 100644 --- a/src/BuildingBlocks/PersistMessageProcessor/Extensions.cs +++ b/src/BuildingBlocks/PersistMessageProcessor/Extensions.cs @@ -1,28 +1,11 @@ -using BuildingBlocks.Core; -using BuildingBlocks.PersistMessageProcessor.Data; -using BuildingBlocks.Web; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; namespace BuildingBlocks.PersistMessageProcessor; public static class Extensions { - public static IServiceCollection AddPersistMessage(this IServiceCollection services, IConfiguration configuration) + public static IServiceCollection AddPersistMessageProcessor(this IServiceCollection services) { - services.AddOptions() - .Bind(configuration.GetSection(nameof(PersistMessageOptions))) - .ValidateDataAnnotations(); - - var persistMessageOptions = services.GetOptions("PersistMessageOptions"); - - services.AddDbContext(options => - options.UseSqlServer(persistMessageOptions.ConnectionString, - x => x.MigrationsAssembly(typeof(PersistMessageDbContext).Assembly.GetName().Name))); - - services.AddScoped(provider => provider.GetService()); - services.AddScoped(); services.AddHostedService(); diff --git a/src/BuildingBlocks/PersistMessageProcessor/IPersistMessageDbContext.cs b/src/BuildingBlocks/PersistMessageProcessor/IPersistMessageDbContext.cs deleted file mode 100644 index 2552126..0000000 --- a/src/BuildingBlocks/PersistMessageProcessor/IPersistMessageDbContext.cs +++ /dev/null @@ -1,9 +0,0 @@ -using BuildingBlocks.EFCore; -using Microsoft.EntityFrameworkCore; - -namespace BuildingBlocks.PersistMessageProcessor; - -public interface IPersistMessageDbContext : IDbContext -{ - DbSet PersistMessages => Set(); -} diff --git a/src/BuildingBlocks/PersistMessageProcessor/PersistMessageProcessor.cs b/src/BuildingBlocks/PersistMessageProcessor/PersistMessageProcessor.cs index f1815a6..72bafad 100644 --- a/src/BuildingBlocks/PersistMessageProcessor/PersistMessageProcessor.cs +++ b/src/BuildingBlocks/PersistMessageProcessor/PersistMessageProcessor.cs @@ -2,6 +2,7 @@ using System.Text.Json; using Ardalis.GuardClauses; using BuildingBlocks.Core.Event; +using BuildingBlocks.EFCore; using BuildingBlocks.IdsGenerator; using BuildingBlocks.Utils; using MassTransit; @@ -15,18 +16,18 @@ public class PersistMessageProcessor : IPersistMessageProcessor { private readonly ILogger _logger; private readonly IMediator _mediator; - private readonly IPersistMessageDbContext _persistMessageDbContext; + private readonly IDbContext _dbContext; private readonly IPublishEndpoint _publishEndpoint; public PersistMessageProcessor( ILogger logger, IMediator mediator, - IPersistMessageDbContext persistMessageDbContext, + IDbContext dbContext, IPublishEndpoint publishEndpoint) { _logger = logger; _mediator = mediator; - _persistMessageDbContext = persistMessageDbContext; + _dbContext = dbContext; _publishEndpoint = publishEndpoint; } @@ -54,13 +55,13 @@ public class PersistMessageProcessor : IPersistMessageProcessor public async Task> GetByFilterAsync(Expression> predicate, CancellationToken cancellationToken = default) { - return (await _persistMessageDbContext.PersistMessages.Where(predicate).ToListAsync(cancellationToken)) + return (await _dbContext.PersistMessages.Where(predicate).ToListAsync(cancellationToken)) .AsReadOnly(); } public Task ExistMessageAsync(long messageId, CancellationToken cancellationToken = default) { - return _persistMessageDbContext.PersistMessages.FirstOrDefaultAsync(x => + return _dbContext.PersistMessages.FirstOrDefaultAsync(x => x.Id == messageId && x.DeliveryType == MessageDeliveryType.Inbox && x.MessageStatus == MessageStatus.Processed, @@ -73,7 +74,7 @@ public class PersistMessageProcessor : IPersistMessageProcessor CancellationToken cancellationToken = default) { var message = - await _persistMessageDbContext.PersistMessages.FirstOrDefaultAsync( + await _dbContext.PersistMessages.FirstOrDefaultAsync( x => x.Id == messageId && x.DeliveryType == deliveryType, cancellationToken); if (message is null) @@ -110,7 +111,7 @@ public class PersistMessageProcessor : IPersistMessageProcessor public async Task ProcessAllAsync(CancellationToken cancellationToken = default) { - var messages = await _persistMessageDbContext.PersistMessages + var messages = await _dbContext.PersistMessages .Where(x => x.MessageStatus != MessageStatus.Processed) .ToListAsync(cancellationToken); @@ -119,7 +120,7 @@ public class PersistMessageProcessor : IPersistMessageProcessor public async Task ProcessInboxAsync(long messageId, CancellationToken cancellationToken = default) { - var message = await _persistMessageDbContext.PersistMessages.FirstOrDefaultAsync( + var message = await _dbContext.PersistMessages.FirstOrDefaultAsync( x => x.Id == messageId && x.DeliveryType == MessageDeliveryType.Inbox && x.MessageStatus == MessageStatus.InProgress, @@ -190,7 +191,7 @@ public class PersistMessageProcessor : IPersistMessageProcessor else id = SnowFlakIdGenerator.NewId(); - await _persistMessageDbContext.PersistMessages.AddAsync( + await _dbContext.PersistMessages.AddAsync( new PersistMessage( id, messageEnvelope.Message.GetType().ToString(), @@ -198,7 +199,7 @@ public class PersistMessageProcessor : IPersistMessageProcessor deliveryType), cancellationToken); - await _persistMessageDbContext.SaveChangesAsync(cancellationToken); + await _dbContext.SaveChangesAsync(cancellationToken); _logger.LogInformation( "Message with id: {MessageID} and delivery type: {DeliveryType} saved in persistence message store.", @@ -212,8 +213,8 @@ public class PersistMessageProcessor : IPersistMessageProcessor { message.ChangeState(MessageStatus.Processed); - _persistMessageDbContext.PersistMessages.Update(message); + _dbContext.PersistMessages.Update(message); - await _persistMessageDbContext.SaveChangesAsync(cancellationToken); + await _dbContext.SaveChangesAsync(cancellationToken); } } diff --git a/src/BuildingBlocks/TestBase/IntegrationTestBase.cs b/src/BuildingBlocks/TestBase/IntegrationTestBase.cs index 83dd3fc..d6a5ddb 100644 --- a/src/BuildingBlocks/TestBase/IntegrationTestBase.cs +++ b/src/BuildingBlocks/TestBase/IntegrationTestBase.cs @@ -2,7 +2,6 @@ using BuildingBlocks.Core.Event; using BuildingBlocks.Core.Model; using BuildingBlocks.EFCore; -using BuildingBlocks.MassTransit; using BuildingBlocks.Mongo; using BuildingBlocks.PersistMessageProcessor; using BuildingBlocks.Web; @@ -14,6 +13,7 @@ using MediatR; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -21,33 +21,31 @@ using Microsoft.Extensions.Options; using Mongo2Go; using NSubstitute; using Respawn; +using Respawn.Graph; using Serilog; using Xunit; using Xunit.Abstractions; namespace BuildingBlocks.TestBase; -public class IntegrationTestFixture : IDisposable +public class IntegrationTestFixture : IAsyncLifetime where TEntryPoint : class { private readonly WebApplicationFactory _factory; - - private int Timeout => 60; // Second - private ITestHarness TestHarness => ServiceProvider.GetTestHarness(); - public HttpClient HttpClient => _factory.CreateClient(); + + public MsSqlTestcontainer MsSqlTestContainer; + public RabbitMqTestcontainer RabbitMqTestContainer; + + private ITestHarness TestHarness => ServiceProvider?.GetTestHarness(); + public HttpClient HttpClient => _factory?.CreateClient(); public GrpcChannel Channel => - GrpcChannel.ForAddress(HttpClient.BaseAddress!, new GrpcChannelOptions {HttpClient = HttpClient}); + GrpcChannel.ForAddress(HttpClient.BaseAddress!, new GrpcChannelOptions { HttpClient = HttpClient }); public Action TestRegistrationServices { get; set; } - public IServiceProvider ServiceProvider => _factory.Services; - public IConfiguration Configuration => _factory.Services.GetRequiredService(); - - public MsSqlTestcontainer SqlTestContainer; - public MsSqlTestcontainer SqlPersistTestContainer; - public MongoDbTestcontainer MongoTestContainer; - public RabbitMqTestcontainer RabbitMqTestContainer; + public IServiceProvider ServiceProvider => _factory?.Services; + public IConfiguration Configuration => _factory?.Services.GetRequiredService(); public IntegrationTestFixture() { @@ -60,12 +58,21 @@ public class IntegrationTestFixture : IDisposable TestRegistrationServices?.Invoke(services); services.ReplaceSingleton(AddHttpContextAccessorMock); }); + + builder.ConfigureAppConfiguration(AddCustomAppSettings); }); } - public void Dispose() + + public async Task InitializeAsync() { - _factory.Dispose(); + await StartTestContainerAsync(); + } + + public async Task DisposeAsync() + { + await StopTestContainerAsync(); + _factory?.DisposeAsync(); } public virtual void RegisterServices(Action services) @@ -190,11 +197,39 @@ public class IntegrationTestFixture : IDisposable }); } + + private async Task StartTestContainerAsync() + { + MsSqlTestContainer = TestContainers.MsSqlTestContainer; + RabbitMqTestContainer = TestContainers.RabbitMqTestContainer; + + await MsSqlTestContainer.StartAsync(); + await RabbitMqTestContainer.StartAsync(); + } + + private async Task StopTestContainerAsync() + { + await MsSqlTestContainer.StopAsync(); + await RabbitMqTestContainer.StopAsync(); + } + + private void AddCustomAppSettings(IConfigurationBuilder configuration) + { + configuration.AddInMemoryCollection(new KeyValuePair[] + { + new("DatabaseOptions:DefaultConnection", MsSqlTestContainer.ConnectionString + "TrustServerCertificate=True"), + new("RabbitMqOptions:HostName", RabbitMqTestContainer.Hostname), + new("RabbitMqOptions:UserName", RabbitMqTestContainer.Username), + new("RabbitMqOptions:Password", RabbitMqTestContainer.Password), + new("RabbitMqOptions:Port", RabbitMqTestContainer.Port.ToString()) + }); + } + private IHttpContextAccessor AddHttpContextAccessorMock(IServiceProvider serviceProvider) { var httpContextAccessorMock = Substitute.For(); using var scope = serviceProvider.CreateScope(); - httpContextAccessorMock.HttpContext = new DefaultHttpContext {RequestServices = scope.ServiceProvider}; + httpContextAccessorMock.HttpContext = new DefaultHttpContext { RequestServices = scope.ServiceProvider }; httpContextAccessorMock.HttpContext.Request.Host = new HostString("localhost", 6012); httpContextAccessorMock.HttpContext.Request.Scheme = "http"; @@ -329,32 +364,9 @@ public class IntegrationTestFixture : Integra public class IntegrationTestFixtureCore : IAsyncLifetime where TEntryPoint : class { - private Checkpoint _checkpointDefaultDB; - private Checkpoint _checkpointPersistMessageDB; + private Respawner _reSpawnerDefaultDb; private MongoDbRunner _mongoRunner; - private string DefaultConnectionString - { - get => Fixture.ServiceProvider.GetRequiredService>()?.Value.DefaultConnection; - set => Fixture.ServiceProvider.GetRequiredService>().Value.DefaultConnection = - value; - } - - private string PersistConnectionString - { - get => Fixture.ServiceProvider.GetRequiredService>()?.Value.ConnectionString; - set => Fixture.ServiceProvider.GetRequiredService>().Value.ConnectionString = - value; - } - - private string MongoConnectionString - { - get => Fixture.ServiceProvider.GetRequiredService>()?.Value?.ConnectionString; - set => Fixture.ServiceProvider.GetRequiredService>().Value.ConnectionString = value; - } - - private RabbitMqOptions RabbitMqOptions => - Fixture.ServiceProvider.GetRequiredService>()?.Value; public IntegrationTestFixtureCore(IntegrationTestFixture integrationTestFixture) { @@ -364,71 +376,43 @@ public class IntegrationTestFixtureCore : IAsyncLifetime public IntegrationTestFixture Fixture { get; } + public async Task InitializeAsync() { - _checkpointDefaultDB = new Checkpoint {TablesToIgnore = new[] {"__EFMigrationsHistory"}}; - _checkpointPersistMessageDB = new Checkpoint {TablesToIgnore = new[] {"__EFMigrationsHistory"}}; + var databaseOptions = Fixture.ServiceProvider.GetRequiredService>()?.Value; + var mongoOptions = Fixture.ServiceProvider.GetRequiredService>()?.Value; - if (!string.IsNullOrEmpty(DefaultConnectionString)) - await _checkpointDefaultDB.Reset(DefaultConnectionString); + if (!string.IsNullOrEmpty(databaseOptions?.DefaultConnection)) + { + var dbConnection = new SqlConnection(databaseOptions.DefaultConnection); + await dbConnection.OpenAsync(); - if (!string.IsNullOrEmpty(PersistConnectionString)) - await _checkpointPersistMessageDB.Reset(PersistConnectionString); + _reSpawnerDefaultDb = await Respawner.CreateAsync(dbConnection, + new RespawnerOptions + { + TablesToIgnore = new Table[] { "__EFMigrationsHistory" }, + }); + + await _reSpawnerDefaultDb.ResetAsync(dbConnection); + } _mongoRunner = MongoDbRunner.Start(); - if (MongoConnectionString != null) - MongoConnectionString = _mongoRunner.ConnectionString; - - //await StartTestContainerAsync(); + if (!string.IsNullOrEmpty(mongoOptions?.ConnectionString)) + mongoOptions.ConnectionString = _mongoRunner.ConnectionString; await SeedDataAsync(); } public async Task DisposeAsync() { - if (!string.IsNullOrEmpty(PersistConnectionString)) - _mongoRunner.Dispose(); - - //await StopTestContainerAsync(); + _mongoRunner.Dispose(); } protected virtual void RegisterTestsServices(IServiceCollection services) { } - private async Task StartTestContainerAsync() - { - // <> - Fixture.SqlTestContainer = TestContainers.SqlTestContainer; - Fixture.SqlPersistTestContainer = TestContainers.SqlPersistTestContainer; - Fixture.MongoTestContainer = TestContainers.MongoTestContainer; - Fixture.RabbitMqTestContainer = TestContainers.RabbitMqTestContainer; - - await Fixture.SqlTestContainer.StartAsync(); - await Fixture.SqlPersistTestContainer.StartAsync(); - await Fixture.MongoTestContainer.StartAsync(); - await Fixture.RabbitMqTestContainer.StartAsync(); - - DefaultConnectionString = Fixture.SqlTestContainer?.ConnectionString; - PersistConnectionString = Fixture.SqlPersistTestContainer?.ConnectionString; - MongoConnectionString = Fixture.MongoTestContainer?.ConnectionString; - - RabbitMqOptions.Password = Fixture.RabbitMqTestContainer.Password; - RabbitMqOptions.UserName = Fixture.RabbitMqTestContainer.Username; - RabbitMqOptions.HostName = Fixture.RabbitMqTestContainer.Hostname; - RabbitMqOptions.Port = (ushort)Fixture.RabbitMqTestContainer.Port; - } - - private async Task StopTestContainerAsync() - { - // <> - await Fixture.SqlTestContainer.StopAsync(); - await Fixture.SqlPersistTestContainer.StopAsync(); - await Fixture.MongoTestContainer.StopAsync(); - await Fixture.RabbitMqTestContainer.StopAsync(); - } - private async Task SeedDataAsync() { using var scope = Fixture.ServiceProvider.CreateScope(); diff --git a/src/BuildingBlocks/TestBase/TestContainers.cs b/src/BuildingBlocks/TestBase/TestContainers.cs index 0044487..3d3fdae 100644 --- a/src/BuildingBlocks/TestBase/TestContainers.cs +++ b/src/BuildingBlocks/TestBase/TestContainers.cs @@ -6,24 +6,30 @@ namespace BuildingBlocks.TestBase; public static class TestContainers { - public static MsSqlTestcontainer SqlTestContainer => new TestcontainersBuilder() + public static PostgreSqlTestcontainer PostgresTestContainer => new TestcontainersBuilder() .WithDatabase( - new MsSqlTestcontainerConfiguration + new PostgreSqlTestcontainerConfiguration { Database = Guid.NewGuid().ToString("D"), - Password = Guid.NewGuid().ToString("D") + Password = Guid.NewGuid().ToString("D"), + Username = Guid.NewGuid().ToString("D") }) - .WithImage("mcr.microsoft.com/mssql/server:2017-latest") + .WithImage("postgres:latest") .Build(); - public static MsSqlTestcontainer SqlPersistTestContainer => new TestcontainersBuilder() - .WithDatabase(new MsSqlTestcontainerConfiguration + + // issue ref: https://github.com/testcontainers/testcontainers-dotnet/discussions/533 + public static MsSqlTestcontainer MsSqlTestContainer = new TestcontainersBuilder() + .WithDatabase(new MsSqlTestcontainerConfiguration() { - Database = Guid.NewGuid().ToString("D"), Password = Guid.NewGuid().ToString("D") + Password = Guid.NewGuid().ToString("D") }) - .WithImage("mcr.microsoft.com/mssql/server:2017-latest") + .WithImage("mcr.microsoft.com/mssql/server:2022-latest") + .WithExposedPort(1433) + .WithPortBinding(1433, true) // Add this line for issue in hangup MsSqlTestContainer in docker desktop .Build(); + public static MongoDbTestcontainer MongoTestContainer => new TestcontainersBuilder() .WithDatabase(new MongoDbTestcontainerConfiguration() { @@ -34,12 +40,9 @@ public static class TestContainers .WithImage("mongo") .Build(); + public static RabbitMqTestcontainer RabbitMqTestContainer => new TestcontainersBuilder() - .WithMessageBroker(new RabbitMqTestcontainerConfiguration() - { - Password = "guest", - Username = "guest" - }) + .WithMessageBroker(new RabbitMqTestcontainerConfiguration() { Password = "guest", Username = "guest" }) .WithImage("rabbitmq:3-management") .Build(); } diff --git a/src/Services/Booking/src/Booking.Api/appsettings.docker.json b/src/Services/Booking/src/Booking.Api/appsettings.docker.json index c1d2f8f..6d567d2 100644 --- a/src/Services/Booking/src/Booking.Api/appsettings.docker.json +++ b/src/Services/Booking/src/Booking.Api/appsettings.docker.json @@ -6,7 +6,7 @@ "Microsoft.AspNetCore": "Warning" } }, - "RabbitMq": { + "RabbitMqOptions": { "HostName": "rabbitmq", "ExchangeName": "booking", "UserName": "guest", diff --git a/src/Services/Booking/src/Booking.Api/appsettings.json b/src/Services/Booking/src/Booking.Api/appsettings.json index 6c425a4..fe9a66f 100644 --- a/src/Services/Booking/src/Booking.Api/appsettings.json +++ b/src/Services/Booking/src/Booking.Api/appsettings.json @@ -19,7 +19,7 @@ "Authority": "https://localhost:5005", "Audience": "booking-api" }, - "RabbitMq": { + "RabbitMqOptions": { "HostName": "localhost", "ExchangeName": "booking", "UserName": "guest", @@ -40,7 +40,7 @@ "PersistMessageOptions": { "Interval": 30, "Enabled": true, - "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" + "ConnectionString": "Server=localhost;Port=5432;Database=persist_message_db;User Id=postgres;Password=postgres;Include Error Detail=true" }, "AllowedHosts": "*" } diff --git a/src/Services/Booking/src/Booking.Api/appsettings.test.json b/src/Services/Booking/src/Booking.Api/appsettings.test.json index 1c2df13..e6a2c63 100644 --- a/src/Services/Booking/src/Booking.Api/appsettings.test.json +++ b/src/Services/Booking/src/Booking.Api/appsettings.test.json @@ -1,5 +1,5 @@ { - "RabbitMq": { + "RabbitMqOptions": { "HostName": "localhost", "ExchangeName": "booking", "UserName": "guest", @@ -17,7 +17,7 @@ "PersistMessageOptions": { "Interval": 1, "Enabled": true, - "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageTestDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" + "ConnectionString": "Server=localhost;Port=5432;Database=persist_message_db_test;User Id=postgres;Password=postgres;Include Error Detail=true" }, "MongoOptions": { "ConnectionString": "mongodb://localhost:27017", diff --git a/src/Services/Booking/src/Booking/Extensions/Infrastructure/InfrastructureExtensions.cs b/src/Services/Booking/src/Booking/Extensions/Infrastructure/InfrastructureExtensions.cs index 3328456..34e5a85 100644 --- a/src/Services/Booking/src/Booking/Extensions/Infrastructure/InfrastructureExtensions.cs +++ b/src/Services/Booking/src/Booking/Extensions/Infrastructure/InfrastructureExtensions.cs @@ -43,7 +43,7 @@ public static class InfrastructureExtensions options.SuppressModelStateInvalidFilter = true; }); - var appOptions = builder.Services.GetOptions("AppOptions"); + var appOptions = builder.Services.GetOptions(nameof(AppOptions)); Console.WriteLine(FiggleFonts.Standard.Render(appOptions.Name)); @@ -58,7 +58,7 @@ public static class InfrastructureExtensions })); }); - builder.Services.AddPersistMessage(configuration); + builder.Services.AddPersistMessageProcessor(); builder.Services.AddMongoDbContext(configuration); builder.AddCustomSerilog(env); @@ -90,7 +90,7 @@ public static class InfrastructureExtensions public static WebApplication UseInfrastructure(this WebApplication app) { var env = app.Environment; - var appOptions = app.GetOptions("AppOptions"); + var appOptions = app.GetOptions(nameof(AppOptions)); app.UseProblemDetails(); app.UseSerilogRequestLogging(); diff --git a/src/Services/Booking/tests/IntegrationTest/Booking/Features/CreateBookingTests.cs b/src/Services/Booking/tests/IntegrationTest/Booking/Features/CreateBookingTests.cs index c77f594..ac8d1a1 100644 --- a/src/Services/Booking/tests/IntegrationTest/Booking/Features/CreateBookingTests.cs +++ b/src/Services/Booking/tests/IntegrationTest/Booking/Features/CreateBookingTests.cs @@ -1,18 +1,15 @@ -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Threading.Tasks; using Booking.Api; using Booking.Data; using BuildingBlocks.Contracts.EventBus.Messages; -using BuildingBlocks.PersistMessageProcessor.Data; +using BuildingBlocks.EFCore; using BuildingBlocks.TestBase; using Flight; using FluentAssertions; using Grpc.Core; using Grpc.Core.Testing; using Integration.Test.Fakes; -using MassTransit; -using MassTransit.Testing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using NSubstitute; @@ -22,10 +19,10 @@ using GetByIdRequest = Flight.GetByIdRequest; namespace Integration.Test.Booking.Features; -public class CreateBookingTests : IntegrationTestBase +public class CreateBookingTests : IntegrationTestBase { public CreateBookingTests( - IntegrationTestFixture integrationTestFixture) : base( + IntegrationTestFixture integrationTestFixture) : base( integrationTestFixture) { } diff --git a/src/Services/Flight/src/Flight.Api/appsettings.json b/src/Services/Flight/src/Flight.Api/appsettings.json index ef2d916..c9d9000 100644 --- a/src/Services/Flight/src/Flight.Api/appsettings.json +++ b/src/Services/Flight/src/Flight.Api/appsettings.json @@ -15,7 +15,7 @@ "interval": "day" } }, - "ConnectionStrings": { + "DatabaseOptions": { "DefaultConnection": "Server=.\\sqlexpress;Database=FlightDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" }, "MongoOptions": { @@ -26,7 +26,7 @@ "Authority": "https://localhost:5005", "Audience": "flight-api" }, - "RabbitMq": { + "RabbitMqOptions": { "HostName": "localhost", "ExchangeName": "flight", "UserName": "guest", @@ -35,8 +35,7 @@ }, "PersistMessageOptions": { "Interval": 30, - "Enabled": true, - "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" + "Enabled": true }, "AllowedHosts": "*" } diff --git a/src/Services/Flight/src/Flight.Api/appsettings.test.json b/src/Services/Flight/src/Flight.Api/appsettings.test.json index 5ec0530..620d0fc 100644 --- a/src/Services/Flight/src/Flight.Api/appsettings.test.json +++ b/src/Services/Flight/src/Flight.Api/appsettings.test.json @@ -1,8 +1,8 @@ { - "ConnectionStrings": { + "DatabaseOptions": { "DefaultConnection": "Server=.\\sqlexpress;Database=FlightDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" }, - "RabbitMq": { + "RabbitMqOptions": { "HostName": "localhost", "ExchangeName": "flight", "UserName": "guest", @@ -19,7 +19,6 @@ }, "PersistMessageOptions": { "Interval": 1, - "Enabled": true, - "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageTestDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" + "Enabled": true } } diff --git a/src/Services/Flight/src/Flight/Data/Configurations/AircraftConfiguration.cs b/src/Services/Flight/src/Flight/Data/Configurations/AircraftConfiguration.cs index 80705fd..b1410ea 100644 --- a/src/Services/Flight/src/Flight/Data/Configurations/AircraftConfiguration.cs +++ b/src/Services/Flight/src/Flight/Data/Configurations/AircraftConfiguration.cs @@ -1,3 +1,4 @@ +using BuildingBlocks.EFCore; using Flight.Aircrafts.Models; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; @@ -8,7 +9,7 @@ public class AircraftConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { - builder.ToTable("Aircraft", FlightDbContext.DefaultSchema); + builder.ToTable("Aircraft", AppDbContextBase.DefaultSchema); builder.HasKey(r => r.Id); builder.Property(r => r.Id).ValueGeneratedNever(); } diff --git a/src/Services/Flight/src/Flight/Data/Configurations/AirportConfiguration.cs b/src/Services/Flight/src/Flight/Data/Configurations/AirportConfiguration.cs index d7c51e4..18a5e6c 100644 --- a/src/Services/Flight/src/Flight/Data/Configurations/AirportConfiguration.cs +++ b/src/Services/Flight/src/Flight/Data/Configurations/AirportConfiguration.cs @@ -1,3 +1,4 @@ +using BuildingBlocks.EFCore; using Flight.Airports.Models; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; @@ -8,7 +9,7 @@ public class AirportConfiguration: IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { - builder.ToTable("Airport", FlightDbContext.DefaultSchema); + builder.ToTable("Airport", AppDbContextBase.DefaultSchema); builder.HasKey(r => r.Id); builder.Property(r => r.Id).ValueGeneratedNever(); diff --git a/src/Services/Flight/src/Flight/Data/Configurations/FlightConfiguration.cs b/src/Services/Flight/src/Flight/Data/Configurations/FlightConfiguration.cs index d20c139..a5ea23c 100644 --- a/src/Services/Flight/src/Flight/Data/Configurations/FlightConfiguration.cs +++ b/src/Services/Flight/src/Flight/Data/Configurations/FlightConfiguration.cs @@ -1,3 +1,4 @@ +using BuildingBlocks.EFCore; using Flight.Aircrafts.Models; using Flight.Airports.Models; using Microsoft.EntityFrameworkCore; @@ -9,7 +10,7 @@ public class FlightConfiguration : IEntityTypeConfiguration builder) { - builder.ToTable("Flight", FlightDbContext.DefaultSchema); + builder.ToTable("Flight", AppDbContextBase.DefaultSchema); builder.HasKey(r => r.Id); builder.Property(r => r.Id).ValueGeneratedNever(); diff --git a/src/Services/Flight/src/Flight/Data/Configurations/PersistMessageConfiguration.cs b/src/Services/Flight/src/Flight/Data/Configurations/PersistMessageConfiguration.cs new file mode 100644 index 0000000..2d0ffc1 --- /dev/null +++ b/src/Services/Flight/src/Flight/Data/Configurations/PersistMessageConfiguration.cs @@ -0,0 +1,45 @@ +using System; +using BuildingBlocks.EFCore; +using BuildingBlocks.PersistMessageProcessor; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace Flight.Data.Configurations; + +public class PersistMessageConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("PersistMessage", AppDbContextBase.DefaultSchema); + + builder.HasKey(x => x.Id); + builder.Property(r => r.Id).ValueGeneratedNever(); + + builder.Property(x => x.Id) + .IsRequired(); + + builder.Property(x => x.DeliveryType) + .HasMaxLength(50) + .HasConversion( + v => v.ToString(), + v => (MessageDeliveryType)Enum.Parse(typeof(MessageDeliveryType), v)) + .IsRequired() + .IsUnicode(false); + + builder.Property(x => x.DeliveryType) + .HasMaxLength(50) + .HasConversion( + v => v.ToString(), + v => (MessageDeliveryType)Enum.Parse(typeof(MessageDeliveryType), v)) + .IsRequired() + .IsUnicode(false); + + builder.Property(x => x.MessageStatus) + .HasMaxLength(50) + .HasConversion( + v => v.ToString(), + v => (MessageStatus)Enum.Parse(typeof(MessageStatus), v)) + .IsRequired() + .IsUnicode(false); + } +} diff --git a/src/Services/Flight/src/Flight/Data/Configurations/SeatConfiguration.cs b/src/Services/Flight/src/Flight/Data/Configurations/SeatConfiguration.cs index ef85463..8033589 100644 --- a/src/Services/Flight/src/Flight/Data/Configurations/SeatConfiguration.cs +++ b/src/Services/Flight/src/Flight/Data/Configurations/SeatConfiguration.cs @@ -1,3 +1,4 @@ +using BuildingBlocks.EFCore; using Flight.Seats.Models; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; @@ -8,7 +9,7 @@ public class SeatConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { - builder.ToTable("Seat", FlightDbContext.DefaultSchema); + builder.ToTable("Seat", AppDbContextBase.DefaultSchema); builder.HasKey(r => r.Id); builder.Property(r => r.Id).ValueGeneratedNever(); diff --git a/src/Services/Flight/src/Flight/Data/DesignTimeDbContextFactory.cs b/src/Services/Flight/src/Flight/Data/DesignTimeDbContextFactory.cs index 546ce72..bc85b4c 100644 --- a/src/Services/Flight/src/Flight/Data/DesignTimeDbContextFactory.cs +++ b/src/Services/Flight/src/Flight/Data/DesignTimeDbContextFactory.cs @@ -9,8 +9,7 @@ namespace Flight.Data { var builder = new DbContextOptionsBuilder(); - builder.UseSqlServer( - "Data Source=.\\sqlexpress;Initial Catalog=FlightDB;Persist Security Info=False;Integrated Security=SSPI"); + builder.UseSqlServer("Data Source=.\\sqlexpress;Initial Catalog=FlightDB;Persist Security Info=False;Integrated Security=SSPI;TrustServerCertificate=True"); return new FlightDbContext(builder.Options, null); } } diff --git a/src/Services/Flight/src/Flight/Data/FlightDbContext.cs b/src/Services/Flight/src/Flight/Data/FlightDbContext.cs index 29dcb87..a895241 100644 --- a/src/Services/Flight/src/Flight/Data/FlightDbContext.cs +++ b/src/Services/Flight/src/Flight/Data/FlightDbContext.cs @@ -1,22 +1,18 @@ -using System.Reflection; using BuildingBlocks.EFCore; using BuildingBlocks.Utils; using Flight.Aircrafts.Models; using Flight.Airports.Models; using Flight.Seats.Models; -using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; namespace Flight.Data; public sealed class FlightDbContext : AppDbContextBase { - public const string DefaultSchema = "dbo"; public FlightDbContext(DbContextOptions options, ICurrentUserProvider currentUserProvider) : base( options, currentUserProvider) { } - public DbSet Flights => Set(); public DbSet Airports => Set(); public DbSet Aircraft => Set(); @@ -24,8 +20,8 @@ public sealed class FlightDbContext : AppDbContextBase protected override void OnModelCreating(ModelBuilder builder) { + base.OnModelCreating(builder); builder.FilterSoftDeletedProperties(); builder.ApplyConfigurationsFromAssembly(typeof(FlightRoot).Assembly); - base.OnModelCreating(builder); } } diff --git a/src/Services/Flight/src/Flight/Data/Migrations/20220728175834_Init.Designer.cs b/src/Services/Flight/src/Flight/Data/Migrations/20221203201848_Initial.Designer.cs similarity index 84% rename from src/Services/Flight/src/Flight/Data/Migrations/20220728175834_Init.Designer.cs rename to src/Services/Flight/src/Flight/Data/Migrations/20221203201848_Initial.Designer.cs index 349fc42..4a8b70f 100644 --- a/src/Services/Flight/src/Flight/Data/Migrations/20220728175834_Init.Designer.cs +++ b/src/Services/Flight/src/Flight/Data/Migrations/20221203201848_Initial.Designer.cs @@ -12,17 +12,52 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace Flight.Data.Migrations { [DbContext(typeof(FlightDbContext))] - [Migration("20220728175834_Init")] - partial class Init + [Migration("20221203201848_Initial")] + partial class Initial { + /// protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "6.0.1") + .HasAnnotation("ProductVersion", "7.0.0") .HasAnnotation("Relational:MaxIdentifierLength", 128); - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BuildingBlocks.PersistMessageProcessor.PersistMessage", b => + { + b.Property("Id") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Data") + .HasColumnType("nvarchar(max)"); + + b.Property("DataType") + .HasColumnType("nvarchar(max)"); + + b.Property("DeliveryType") + .IsRequired() + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnType("varchar(50)"); + + b.Property("MessageStatus") + .IsRequired() + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnType("varchar(50)"); + + b.Property("RetryCount") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("PersistMessage", "dbo"); + }); modelBuilder.Entity("Flight.Aircrafts.Models.Aircraft", b => { diff --git a/src/Services/Flight/src/Flight/Data/Migrations/20220728175834_Init.cs b/src/Services/Flight/src/Flight/Data/Migrations/20221203201848_Initial.cs similarity index 86% rename from src/Services/Flight/src/Flight/Data/Migrations/20220728175834_Init.cs rename to src/Services/Flight/src/Flight/Data/Migrations/20221203201848_Initial.cs index 5cd66bb..e314291 100644 --- a/src/Services/Flight/src/Flight/Data/Migrations/20220728175834_Init.cs +++ b/src/Services/Flight/src/Flight/Data/Migrations/20221203201848_Initial.cs @@ -5,8 +5,10 @@ using Microsoft.EntityFrameworkCore.Migrations; namespace Flight.Data.Migrations { - public partial class Init : Migration + /// + public partial class Initial : Migration { + /// protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.EnsureSchema( @@ -54,6 +56,24 @@ namespace Flight.Data.Migrations table.PrimaryKey("PK_Airport", x => x.Id); }); + migrationBuilder.CreateTable( + name: "PersistMessage", + schema: "dbo", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false), + DataType = table.Column(type: "nvarchar(max)", nullable: true), + Data = table.Column(type: "nvarchar(max)", nullable: true), + Created = table.Column(type: "datetime2", nullable: false), + RetryCount = table.Column(type: "int", nullable: false), + MessageStatus = table.Column(type: "varchar(50)", unicode: false, maxLength: 50, nullable: false), + DeliveryType = table.Column(type: "varchar(50)", unicode: false, maxLength: 50, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PersistMessage", x => x.Id); + }); + migrationBuilder.CreateTable( name: "Flight", schema: "dbo", @@ -144,8 +164,13 @@ namespace Flight.Data.Migrations column: "FlightId"); } + /// protected override void Down(MigrationBuilder migrationBuilder) { + migrationBuilder.DropTable( + name: "PersistMessage", + schema: "dbo"); + migrationBuilder.DropTable( name: "Seat", schema: "dbo"); diff --git a/src/Services/Flight/src/Flight/Data/Migrations/FlightDbContextModelSnapshot.cs b/src/Services/Flight/src/Flight/Data/Migrations/FlightDbContextModelSnapshot.cs index de7d19c..3acd661 100644 --- a/src/Services/Flight/src/Flight/Data/Migrations/FlightDbContextModelSnapshot.cs +++ b/src/Services/Flight/src/Flight/Data/Migrations/FlightDbContextModelSnapshot.cs @@ -17,10 +17,44 @@ namespace Flight.Data.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "6.0.1") + .HasAnnotation("ProductVersion", "7.0.0") .HasAnnotation("Relational:MaxIdentifierLength", 128); - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BuildingBlocks.PersistMessageProcessor.PersistMessage", b => + { + b.Property("Id") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Data") + .HasColumnType("nvarchar(max)"); + + b.Property("DataType") + .HasColumnType("nvarchar(max)"); + + b.Property("DeliveryType") + .IsRequired() + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnType("varchar(50)"); + + b.Property("MessageStatus") + .IsRequired() + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnType("varchar(50)"); + + b.Property("RetryCount") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("PersistMessage", "dbo"); + }); modelBuilder.Entity("Flight.Aircrafts.Models.Aircraft", b => { diff --git a/src/Services/Flight/src/Flight/Extensions/Infrastructure/InfrastructureExtensions.cs b/src/Services/Flight/src/Flight/Extensions/Infrastructure/InfrastructureExtensions.cs index bdca307..cd163e6 100644 --- a/src/Services/Flight/src/Flight/Extensions/Infrastructure/InfrastructureExtensions.cs +++ b/src/Services/Flight/src/Flight/Extensions/Infrastructure/InfrastructureExtensions.cs @@ -52,7 +52,7 @@ public static class InfrastructureExtensions builder.Services.AddCustomMediatR(); builder.Services.AddCustomProblemDetails(); - var appOptions = builder.Services.GetOptions("AppOptions"); + var appOptions = builder.Services.GetOptions(nameof(AppOptions)); Console.WriteLine(FiggleFonts.Standard.Render(appOptions.Name)); builder.Services.AddRateLimiter(options => @@ -66,11 +66,11 @@ public static class InfrastructureExtensions })); }); + builder.Services.AddPersistMessageProcessor(); builder.Services.AddCustomDbContext(configuration); builder.Services.AddScoped(); - builder.Services.AddMongoDbContext(configuration); - builder.Services.AddPersistMessage(configuration); + builder.AddCustomSerilog(env); builder.Services.AddJwt(); @@ -99,7 +99,7 @@ public static class InfrastructureExtensions public static WebApplication UseInfrastructure(this WebApplication app) { var env = app.Environment; - var appOptions = app.GetOptions("AppOptions"); + var appOptions = app.GetOptions(nameof(AppOptions)); app.UseProblemDetails(); app.UseSerilogRequestLogging(); diff --git a/src/Services/Identity/src/Identity.Api/appsettings.docker.json b/src/Services/Identity/src/Identity.Api/appsettings.docker.json index 58232c8..1423441 100644 --- a/src/Services/Identity/src/Identity.Api/appsettings.docker.json +++ b/src/Services/Identity/src/Identity.Api/appsettings.docker.json @@ -1,9 +1,9 @@ { "App": "Identity-Service", - "ConnectionStrings": { + "DatabaseOptions": { "DefaultConnection": "Server=db;Database=IdentityDB;User ID=sa;Password=@Aa123456" }, - "RabbitMq": { + "RabbitMqOptions": { "HostName": "rabbitmq", "ExchangeName": "identity", "UserName": "guest", diff --git a/src/Services/Identity/src/Identity.Api/appsettings.json b/src/Services/Identity/src/Identity.Api/appsettings.json index 548ed48..75bd768 100644 --- a/src/Services/Identity/src/Identity.Api/appsettings.json +++ b/src/Services/Identity/src/Identity.Api/appsettings.json @@ -2,10 +2,10 @@ "AppOptions": { "Name": "Identity-Service" }, - "ConnectionStrings": { + "DatabaseOptions": { "DefaultConnection": "Server=.\\sqlexpress;Database=IdentityDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" }, - "RabbitMq": { + "RabbitMqOptions": { "HostName": "localhost", "ExchangeName": "identity", "UserName": "guest", @@ -31,8 +31,7 @@ }, "PersistMessageOptions": { "Interval": 30, - "Enabled": true, - "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" + "Enabled": true }, "AllowedHosts": "*" } diff --git a/src/Services/Identity/src/Identity.Api/appsettings.test.json b/src/Services/Identity/src/Identity.Api/appsettings.test.json index 92b31cc..a434a7c 100644 --- a/src/Services/Identity/src/Identity.Api/appsettings.test.json +++ b/src/Services/Identity/src/Identity.Api/appsettings.test.json @@ -1,8 +1,8 @@ { - "ConnectionStrings": { + "DatabaseOptions": { "DefaultConnection": "Server=.\\sqlexpress;Database=IdentityDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" }, - "RabbitMq": { + "RabbitMqOptions": { "HostName": "localhost", "ExchangeName": "identity", "UserName": "guest", @@ -19,7 +19,6 @@ }, "PersistMessageOptions": { "Interval": 1, - "Enabled": true, - "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageTestDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" + "Enabled": true } } diff --git a/src/Services/Identity/src/Identity/Data/Configurations/PersistMessageConfiguration.cs b/src/Services/Identity/src/Identity/Data/Configurations/PersistMessageConfiguration.cs new file mode 100644 index 0000000..18c7c3b --- /dev/null +++ b/src/Services/Identity/src/Identity/Data/Configurations/PersistMessageConfiguration.cs @@ -0,0 +1,44 @@ +using System; +using BuildingBlocks.EFCore; +using BuildingBlocks.PersistMessageProcessor; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace Identity.Data.Configurations; + +public class PersistMessageConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("PersistMessage", AppDbContextBase.DefaultSchema); + + builder.HasKey(x => x.Id); + + builder.Property(x => x.Id) + .IsRequired(); + + builder.Property(x => x.DeliveryType) + .HasMaxLength(50) + .HasConversion( + v => v.ToString(), + v => (MessageDeliveryType)Enum.Parse(typeof(MessageDeliveryType), v)) + .IsRequired() + .IsUnicode(false); + + builder.Property(x => x.DeliveryType) + .HasMaxLength(50) + .HasConversion( + v => v.ToString(), + v => (MessageDeliveryType)Enum.Parse(typeof(MessageDeliveryType), v)) + .IsRequired() + .IsUnicode(false); + + builder.Property(x => x.MessageStatus) + .HasMaxLength(50) + .HasConversion( + v => v.ToString(), + v => (MessageStatus)Enum.Parse(typeof(MessageStatus), v)) + .IsRequired() + .IsUnicode(false); + } +} diff --git a/src/Services/Identity/src/Identity/Data/DesignTimeDbContextFactory.cs b/src/Services/Identity/src/Identity/Data/DesignTimeDbContextFactory.cs index a9645a9..007590a 100644 --- a/src/Services/Identity/src/Identity/Data/DesignTimeDbContextFactory.cs +++ b/src/Services/Identity/src/Identity/Data/DesignTimeDbContextFactory.cs @@ -9,7 +9,7 @@ public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory(); - builder.UseSqlServer("Server=.\\sqlexpress;Database=IdentityDB;Trusted_Connection=True;MultipleActiveResultSets=true"); + builder.UseSqlServer("Server=.\\sqlexpress;Database=IdentityDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"); return new IdentityContext(builder.Options, null); } } diff --git a/src/Services/Identity/src/Identity/Data/IdentityContext.cs b/src/Services/Identity/src/Identity/Data/IdentityContext.cs index 8dda0f3..e512e2f 100644 --- a/src/Services/Identity/src/Identity/Data/IdentityContext.cs +++ b/src/Services/Identity/src/Identity/Data/IdentityContext.cs @@ -8,11 +8,13 @@ using System.Threading.Tasks; using BuildingBlocks.Core.Event; using BuildingBlocks.Core.Model; using BuildingBlocks.EFCore; +using Humanizer; using Identity.Identity.Models; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Storage; namespace Identity.Data; @@ -21,8 +23,6 @@ public sealed class IdentityContext : IdentityDbContext, IdentityUserRole, IdentityUserLogin, IdentityRoleClaim, IdentityUserToken>, IDbContext { - public const string DefaultSchema = "dbo"; - private IDbContextTransaction _currentTransaction; public IdentityContext(DbContextOptions options, IHttpContextAccessor httpContextAccessor) : @@ -35,6 +35,13 @@ public sealed class IdentityContext : IdentityDbContext protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "6.0.1") + .HasAnnotation("ProductVersion", "7.0.0") .HasAnnotation("Relational:MaxIdentifierLength", 128); - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BuildingBlocks.PersistMessageProcessor.PersistMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Data") + .HasColumnType("nvarchar(max)"); + + b.Property("DataType") + .HasColumnType("nvarchar(max)"); + + b.Property("DeliveryType") + .IsRequired() + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnType("varchar(50)"); + + b.Property("MessageStatus") + .IsRequired() + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnType("varchar(50)"); + + b.Property("RetryCount") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("PersistMessage", "dbo"); + }); modelBuilder.Entity("Identity.Identity.Models.ApplicationUser", b => { @@ -30,7 +68,7 @@ namespace Identity.Data.Migrations .ValueGeneratedOnAdd() .HasColumnType("bigint"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); b.Property("AccessFailedCount") .HasColumnType("int"); @@ -98,7 +136,7 @@ namespace Identity.Data.Migrations .HasDatabaseName("UserNameIndex") .HasFilter("[NormalizedUserName] IS NOT NULL"); - b.ToTable("AspNetUsers", (string)null); + b.ToTable("AspNetUsers", "dbo"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => @@ -107,7 +145,7 @@ namespace Identity.Data.Migrations .ValueGeneratedOnAdd() .HasColumnType("bigint"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); b.Property("ConcurrencyStamp") .IsConcurrencyToken() @@ -128,7 +166,7 @@ namespace Identity.Data.Migrations .HasDatabaseName("RoleNameIndex") .HasFilter("[NormalizedName] IS NOT NULL"); - b.ToTable("AspNetRoles", (string)null); + b.ToTable("AspNetRoles", "dbo"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => @@ -137,7 +175,7 @@ namespace Identity.Data.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); b.Property("ClaimType") .HasColumnType("nvarchar(max)"); @@ -152,7 +190,7 @@ namespace Identity.Data.Migrations b.HasIndex("RoleId"); - b.ToTable("AspNetRoleClaims", (string)null); + b.ToTable("AspNetRoleClaims", "dbo"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => @@ -161,7 +199,7 @@ namespace Identity.Data.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); b.Property("ClaimType") .HasColumnType("nvarchar(max)"); @@ -176,7 +214,7 @@ namespace Identity.Data.Migrations b.HasIndex("UserId"); - b.ToTable("AspNetUserClaims", (string)null); + b.ToTable("AspNetUserClaims", "dbo"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => @@ -197,7 +235,7 @@ namespace Identity.Data.Migrations b.HasIndex("UserId"); - b.ToTable("AspNetUserLogins", (string)null); + b.ToTable("AspNetUserLogins", "dbo"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => @@ -212,7 +250,7 @@ namespace Identity.Data.Migrations b.HasIndex("RoleId"); - b.ToTable("AspNetUserRoles", (string)null); + b.ToTable("AspNetUserRoles", "dbo"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => @@ -231,7 +269,7 @@ namespace Identity.Data.Migrations b.HasKey("UserId", "LoginProvider", "Name"); - b.ToTable("AspNetUserTokens", (string)null); + b.ToTable("AspNetUserTokens", "dbo"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => diff --git a/src/Services/Identity/src/Identity/Data/Migrations/20220728175937_initial.cs b/src/Services/Identity/src/Identity/Data/Migrations/20221203211306_initial.cs similarity index 79% rename from src/Services/Identity/src/Identity/Data/Migrations/20220728175937_initial.cs rename to src/Services/Identity/src/Identity/Data/Migrations/20221203211306_initial.cs index a056fed..df434c0 100644 --- a/src/Services/Identity/src/Identity/Data/Migrations/20220728175937_initial.cs +++ b/src/Services/Identity/src/Identity/Data/Migrations/20221203211306_initial.cs @@ -5,12 +5,18 @@ using Microsoft.EntityFrameworkCore.Migrations; namespace Identity.Data.Migrations { + /// public partial class initial : Migration { + /// protected override void Up(MigrationBuilder migrationBuilder) { + migrationBuilder.EnsureSchema( + name: "dbo"); + migrationBuilder.CreateTable( name: "AspNetRoles", + schema: "dbo", columns: table => new { Id = table.Column(type: "bigint", nullable: false) @@ -26,6 +32,7 @@ namespace Identity.Data.Migrations migrationBuilder.CreateTable( name: "AspNetUsers", + schema: "dbo", columns: table => new { Id = table.Column(type: "bigint", nullable: false) @@ -53,8 +60,28 @@ namespace Identity.Data.Migrations table.PrimaryKey("PK_AspNetUsers", x => x.Id); }); + migrationBuilder.CreateTable( + name: "PersistMessage", + schema: "dbo", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + DataType = table.Column(type: "nvarchar(max)", nullable: true), + Data = table.Column(type: "nvarchar(max)", nullable: true), + Created = table.Column(type: "datetime2", nullable: false), + RetryCount = table.Column(type: "int", nullable: false), + MessageStatus = table.Column(type: "varchar(50)", unicode: false, maxLength: 50, nullable: false), + DeliveryType = table.Column(type: "varchar(50)", unicode: false, maxLength: 50, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PersistMessage", x => x.Id); + }); + migrationBuilder.CreateTable( name: "AspNetRoleClaims", + schema: "dbo", columns: table => new { Id = table.Column(type: "int", nullable: false) @@ -69,6 +96,7 @@ namespace Identity.Data.Migrations table.ForeignKey( name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", column: x => x.RoleId, + principalSchema: "dbo", principalTable: "AspNetRoles", principalColumn: "Id", onDelete: ReferentialAction.Cascade); @@ -76,6 +104,7 @@ namespace Identity.Data.Migrations migrationBuilder.CreateTable( name: "AspNetUserClaims", + schema: "dbo", columns: table => new { Id = table.Column(type: "int", nullable: false) @@ -90,6 +119,7 @@ namespace Identity.Data.Migrations table.ForeignKey( name: "FK_AspNetUserClaims_AspNetUsers_UserId", column: x => x.UserId, + principalSchema: "dbo", principalTable: "AspNetUsers", principalColumn: "Id", onDelete: ReferentialAction.Cascade); @@ -97,6 +127,7 @@ namespace Identity.Data.Migrations migrationBuilder.CreateTable( name: "AspNetUserLogins", + schema: "dbo", columns: table => new { LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), @@ -110,6 +141,7 @@ namespace Identity.Data.Migrations table.ForeignKey( name: "FK_AspNetUserLogins_AspNetUsers_UserId", column: x => x.UserId, + principalSchema: "dbo", principalTable: "AspNetUsers", principalColumn: "Id", onDelete: ReferentialAction.Cascade); @@ -117,6 +149,7 @@ namespace Identity.Data.Migrations migrationBuilder.CreateTable( name: "AspNetUserRoles", + schema: "dbo", columns: table => new { UserId = table.Column(type: "bigint", nullable: false), @@ -128,12 +161,14 @@ namespace Identity.Data.Migrations table.ForeignKey( name: "FK_AspNetUserRoles_AspNetRoles_RoleId", column: x => x.RoleId, + principalSchema: "dbo", principalTable: "AspNetRoles", principalColumn: "Id", onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "FK_AspNetUserRoles_AspNetUsers_UserId", column: x => x.UserId, + principalSchema: "dbo", principalTable: "AspNetUsers", principalColumn: "Id", onDelete: ReferentialAction.Cascade); @@ -141,6 +176,7 @@ namespace Identity.Data.Migrations migrationBuilder.CreateTable( name: "AspNetUserTokens", + schema: "dbo", columns: table => new { UserId = table.Column(type: "bigint", nullable: false), @@ -154,6 +190,7 @@ namespace Identity.Data.Migrations table.ForeignKey( name: "FK_AspNetUserTokens_AspNetUsers_UserId", column: x => x.UserId, + principalSchema: "dbo", principalTable: "AspNetUsers", principalColumn: "Id", onDelete: ReferentialAction.Cascade); @@ -161,11 +198,13 @@ namespace Identity.Data.Migrations migrationBuilder.CreateIndex( name: "IX_AspNetRoleClaims_RoleId", + schema: "dbo", table: "AspNetRoleClaims", column: "RoleId"); migrationBuilder.CreateIndex( name: "RoleNameIndex", + schema: "dbo", table: "AspNetRoles", column: "NormalizedName", unique: true, @@ -173,54 +212,71 @@ namespace Identity.Data.Migrations migrationBuilder.CreateIndex( name: "IX_AspNetUserClaims_UserId", + schema: "dbo", table: "AspNetUserClaims", column: "UserId"); migrationBuilder.CreateIndex( name: "IX_AspNetUserLogins_UserId", + schema: "dbo", table: "AspNetUserLogins", column: "UserId"); migrationBuilder.CreateIndex( name: "IX_AspNetUserRoles_RoleId", + schema: "dbo", table: "AspNetUserRoles", column: "RoleId"); migrationBuilder.CreateIndex( name: "EmailIndex", + schema: "dbo", table: "AspNetUsers", column: "NormalizedEmail"); migrationBuilder.CreateIndex( name: "UserNameIndex", + schema: "dbo", table: "AspNetUsers", column: "NormalizedUserName", unique: true, filter: "[NormalizedUserName] IS NOT NULL"); } + /// protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable( - name: "AspNetRoleClaims"); + name: "AspNetRoleClaims", + schema: "dbo"); migrationBuilder.DropTable( - name: "AspNetUserClaims"); + name: "AspNetUserClaims", + schema: "dbo"); migrationBuilder.DropTable( - name: "AspNetUserLogins"); + name: "AspNetUserLogins", + schema: "dbo"); migrationBuilder.DropTable( - name: "AspNetUserRoles"); + name: "AspNetUserRoles", + schema: "dbo"); migrationBuilder.DropTable( - name: "AspNetUserTokens"); + name: "AspNetUserTokens", + schema: "dbo"); migrationBuilder.DropTable( - name: "AspNetRoles"); + name: "PersistMessage", + schema: "dbo"); migrationBuilder.DropTable( - name: "AspNetUsers"); + name: "AspNetRoles", + schema: "dbo"); + + migrationBuilder.DropTable( + name: "AspNetUsers", + schema: "dbo"); } } } diff --git a/src/Services/Identity/src/Identity/Data/Migrations/IdentityContextModelSnapshot.cs b/src/Services/Identity/src/Identity/Data/Migrations/IdentityContextModelSnapshot.cs index 29e7d27..73f4b8d 100644 --- a/src/Services/Identity/src/Identity/Data/Migrations/IdentityContextModelSnapshot.cs +++ b/src/Services/Identity/src/Identity/Data/Migrations/IdentityContextModelSnapshot.cs @@ -17,10 +17,47 @@ namespace Identity.Data.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "6.0.1") + .HasAnnotation("ProductVersion", "7.0.0") .HasAnnotation("Relational:MaxIdentifierLength", 128); - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BuildingBlocks.PersistMessageProcessor.PersistMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Data") + .HasColumnType("nvarchar(max)"); + + b.Property("DataType") + .HasColumnType("nvarchar(max)"); + + b.Property("DeliveryType") + .IsRequired() + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnType("varchar(50)"); + + b.Property("MessageStatus") + .IsRequired() + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnType("varchar(50)"); + + b.Property("RetryCount") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("PersistMessage", "dbo"); + }); modelBuilder.Entity("Identity.Identity.Models.ApplicationUser", b => { @@ -28,7 +65,7 @@ namespace Identity.Data.Migrations .ValueGeneratedOnAdd() .HasColumnType("bigint"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); b.Property("AccessFailedCount") .HasColumnType("int"); @@ -96,7 +133,7 @@ namespace Identity.Data.Migrations .HasDatabaseName("UserNameIndex") .HasFilter("[NormalizedUserName] IS NOT NULL"); - b.ToTable("AspNetUsers", (string)null); + b.ToTable("AspNetUsers", "dbo"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => @@ -105,7 +142,7 @@ namespace Identity.Data.Migrations .ValueGeneratedOnAdd() .HasColumnType("bigint"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); b.Property("ConcurrencyStamp") .IsConcurrencyToken() @@ -126,7 +163,7 @@ namespace Identity.Data.Migrations .HasDatabaseName("RoleNameIndex") .HasFilter("[NormalizedName] IS NOT NULL"); - b.ToTable("AspNetRoles", (string)null); + b.ToTable("AspNetRoles", "dbo"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => @@ -135,7 +172,7 @@ namespace Identity.Data.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); b.Property("ClaimType") .HasColumnType("nvarchar(max)"); @@ -150,7 +187,7 @@ namespace Identity.Data.Migrations b.HasIndex("RoleId"); - b.ToTable("AspNetRoleClaims", (string)null); + b.ToTable("AspNetRoleClaims", "dbo"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => @@ -159,7 +196,7 @@ namespace Identity.Data.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); b.Property("ClaimType") .HasColumnType("nvarchar(max)"); @@ -174,7 +211,7 @@ namespace Identity.Data.Migrations b.HasIndex("UserId"); - b.ToTable("AspNetUserClaims", (string)null); + b.ToTable("AspNetUserClaims", "dbo"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => @@ -195,7 +232,7 @@ namespace Identity.Data.Migrations b.HasIndex("UserId"); - b.ToTable("AspNetUserLogins", (string)null); + b.ToTable("AspNetUserLogins", "dbo"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => @@ -210,7 +247,7 @@ namespace Identity.Data.Migrations b.HasIndex("RoleId"); - b.ToTable("AspNetUserRoles", (string)null); + b.ToTable("AspNetUserRoles", "dbo"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => @@ -229,7 +266,7 @@ namespace Identity.Data.Migrations b.HasKey("UserId", "LoginProvider", "Name"); - b.ToTable("AspNetUserTokens", (string)null); + b.ToTable("AspNetUserTokens", "dbo"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => diff --git a/src/Services/Identity/src/Identity/Extensions/Infrastructure/InfrastructureExtensions.cs b/src/Services/Identity/src/Identity/Extensions/Infrastructure/InfrastructureExtensions.cs index 48283e3..84886ee 100644 --- a/src/Services/Identity/src/Identity/Extensions/Infrastructure/InfrastructureExtensions.cs +++ b/src/Services/Identity/src/Identity/Extensions/Infrastructure/InfrastructureExtensions.cs @@ -41,7 +41,7 @@ public static class InfrastructureExtensions options.SuppressModelStateInvalidFilter = true; }); - var appOptions = builder.Services.GetOptions("AppOptions"); + var appOptions = builder.Services.GetOptions(nameof(AppOptions)); Console.WriteLine(FiggleFonts.Standard.Render(appOptions.Name)); builder.Services.AddRateLimiter(options => @@ -56,7 +56,7 @@ public static class InfrastructureExtensions }); builder.Services.AddControllers(); - builder.Services.AddPersistMessage(configuration); + builder.Services.AddPersistMessageProcessor(); builder.Services.AddCustomDbContext(configuration); builder.Services.AddScoped(); builder.AddCustomSerilog(env); @@ -82,7 +82,7 @@ public static class InfrastructureExtensions public static WebApplication UseInfrastructure(this WebApplication app) { var env = app.Environment; - var appOptions = app.GetOptions("AppOptions"); + var appOptions = app.GetOptions(nameof(AppOptions)); app.UseProblemDetails(); app.UseSerilogRequestLogging(); diff --git a/src/Services/Passenger/src/Passenger.Api/appsettings.docker.json b/src/Services/Passenger/src/Passenger.Api/appsettings.docker.json index 2b748ff..0b29709 100644 --- a/src/Services/Passenger/src/Passenger.Api/appsettings.docker.json +++ b/src/Services/Passenger/src/Passenger.Api/appsettings.docker.json @@ -1,13 +1,13 @@ { "App": "Passenger-Service", - "ConnectionStrings": { + "DatabaseOptions": { "DefaultConnection": "Server=db;Database=PassengerDB;User ID=sa;Password=@Aa123456" }, "Jwt": { "Authority": "https://localhost:5005", "Audience": "passenger-api" }, - "RabbitMq": { + "RabbitMqOptions": { "HostName": "rabbitmq", "ExchangeName": "passenger", "UserName": "guest", diff --git a/src/Services/Passenger/src/Passenger.Api/appsettings.json b/src/Services/Passenger/src/Passenger.Api/appsettings.json index f2d6d95..3726597 100644 --- a/src/Services/Passenger/src/Passenger.Api/appsettings.json +++ b/src/Services/Passenger/src/Passenger.Api/appsettings.json @@ -2,7 +2,7 @@ "AppOptions": { "Name": "Passenger-Service" }, - "ConnectionStrings": { + "DatabaseOptions": { "DefaultConnection": "Server=.\\sqlexpress;Database=PassengerDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" }, "MongoOptions": { @@ -13,7 +13,7 @@ "Authority": "https://localhost:5005", "Audience": "passenger-api" }, - "RabbitMq": { + "RabbitMqOptions": { "HostName": "localhost", "ExchangeName": "passenger", "UserName": "guest", @@ -35,8 +35,7 @@ }, "PersistMessageOptions": { "Interval": 30, - "Enabled": true, - "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" + "Enabled": true }, "AllowedHosts": "*" } diff --git a/src/Services/Passenger/src/Passenger.Api/appsettings.test.json b/src/Services/Passenger/src/Passenger.Api/appsettings.test.json index 15db2aa..5df0a35 100644 --- a/src/Services/Passenger/src/Passenger.Api/appsettings.test.json +++ b/src/Services/Passenger/src/Passenger.Api/appsettings.test.json @@ -1,8 +1,8 @@ { - "ConnectionStrings": { - "DefaultConnection": "Server=.\\sqlexpress;Database=PassengerDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" + "DatabaseOptions": { + "DefaultConnection": "Server=.\\sqlexpress;Database=PassengerDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" }, - "RabbitMq": { + "RabbitMqOptions": { "HostName": "localhost", "ExchangeName": "passenger", "UserName": "guest", @@ -19,7 +19,6 @@ }, "PersistMessageOptions": { "Interval": 1, - "Enabled": true, - "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageTestDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" + "Enabled": true } } diff --git a/src/Services/Passenger/src/Passenger/Data/Configurations/PassengerConfiguration.cs b/src/Services/Passenger/src/Passenger/Data/Configurations/PassengerConfiguration.cs index 5899f26..83733cc 100644 --- a/src/Services/Passenger/src/Passenger/Data/Configurations/PassengerConfiguration.cs +++ b/src/Services/Passenger/src/Passenger/Data/Configurations/PassengerConfiguration.cs @@ -1,3 +1,4 @@ +using BuildingBlocks.EFCore; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; @@ -7,9 +8,9 @@ public class PassengerConfiguration: IEntityTypeConfiguration builder) { - builder.ToTable("Passenger", "dbo"); + builder.ToTable("Passenger", AppDbContextBase.DefaultSchema); builder.HasKey(r => r.Id); builder.Property(r => r.Id).ValueGeneratedNever(); } -} \ No newline at end of file +} diff --git a/src/BuildingBlocks/PersistMessageProcessor/Data/Configurations/PersistMessageConfiguration.cs b/src/Services/Passenger/src/Passenger/Data/Configurations/PersistMessageConfiguration.cs similarity index 83% rename from src/BuildingBlocks/PersistMessageProcessor/Data/Configurations/PersistMessageConfiguration.cs rename to src/Services/Passenger/src/Passenger/Data/Configurations/PersistMessageConfiguration.cs index 60d2566..a823fb9 100644 --- a/src/BuildingBlocks/PersistMessageProcessor/Data/Configurations/PersistMessageConfiguration.cs +++ b/src/Services/Passenger/src/Passenger/Data/Configurations/PersistMessageConfiguration.cs @@ -1,13 +1,15 @@ -using Microsoft.EntityFrameworkCore; +using BuildingBlocks.EFCore; +using BuildingBlocks.PersistMessageProcessor; +using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; -namespace BuildingBlocks.PersistMessageProcessor.Data.Configurations; +namespace Passenger.Data.Configurations; public class PersistMessageConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { - builder.ToTable("PersistMessage", PersistMessageDbContext.DefaultSchema); + builder.ToTable("PersistMessage", AppDbContextBase.DefaultSchema); builder.HasKey(x => x.Id); diff --git a/src/Services/Passenger/src/Passenger/Data/DesignTimeDbContextFactory.cs b/src/Services/Passenger/src/Passenger/Data/DesignTimeDbContextFactory.cs index 92da9b2..e875be8 100644 --- a/src/Services/Passenger/src/Passenger/Data/DesignTimeDbContextFactory.cs +++ b/src/Services/Passenger/src/Passenger/Data/DesignTimeDbContextFactory.cs @@ -10,7 +10,7 @@ public class DesignTimeDbContextFactory: IDesignTimeDbContextFactory(); builder.UseSqlServer( - "Data Source=.\\sqlexpress;Initial Catalog=PassengerDB;Persist Security Info=False;Integrated Security=SSPI"); + "Data Source=.\\sqlexpress;Initial Catalog=PassengerDB;Persist Security Info=False;Integrated Security=SSPI;TrustServerCertificate=True"); return new PassengerDbContext(builder.Options, null); } } diff --git a/src/Services/Passenger/src/Passenger/Data/Migrations/20220728180020_initial.Designer.cs b/src/Services/Passenger/src/Passenger/Data/Migrations/20221203211633_initial.Designer.cs similarity index 58% rename from src/Services/Passenger/src/Passenger/Data/Migrations/20220728180020_initial.Designer.cs rename to src/Services/Passenger/src/Passenger/Data/Migrations/20221203211633_initial.Designer.cs index aa6b184..0a67156 100644 --- a/src/Services/Passenger/src/Passenger/Data/Migrations/20220728180020_initial.Designer.cs +++ b/src/Services/Passenger/src/Passenger/Data/Migrations/20221203211633_initial.Designer.cs @@ -12,17 +12,55 @@ using Passenger.Data; namespace Passenger.Data.Migrations { [DbContext(typeof(PassengerDbContext))] - [Migration("20220728180020_initial")] + [Migration("20221203211633_initial")] partial class initial { + /// protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "6.0.1") + .HasAnnotation("ProductVersion", "7.0.0") .HasAnnotation("Relational:MaxIdentifierLength", 128); - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BuildingBlocks.PersistMessageProcessor.PersistMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Data") + .HasColumnType("nvarchar(max)"); + + b.Property("DataType") + .HasColumnType("nvarchar(max)"); + + b.Property("DeliveryType") + .IsRequired() + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnType("varchar(50)"); + + b.Property("MessageStatus") + .IsRequired() + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnType("varchar(50)"); + + b.Property("RetryCount") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("PersistMessage", "dbo"); + }); modelBuilder.Entity("Passenger.Passengers.Models.Passenger", b => { diff --git a/src/Services/Passenger/src/Passenger/Data/Migrations/20220728180020_initial.cs b/src/Services/Passenger/src/Passenger/Data/Migrations/20221203211633_initial.cs similarity index 58% rename from src/Services/Passenger/src/Passenger/Data/Migrations/20220728180020_initial.cs rename to src/Services/Passenger/src/Passenger/Data/Migrations/20221203211633_initial.cs index cf5759c..121afb4 100644 --- a/src/Services/Passenger/src/Passenger/Data/Migrations/20220728180020_initial.cs +++ b/src/Services/Passenger/src/Passenger/Data/Migrations/20221203211633_initial.cs @@ -5,8 +5,10 @@ using Microsoft.EntityFrameworkCore.Migrations; namespace Passenger.Data.Migrations { + /// public partial class initial : Migration { + /// protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.EnsureSchema( @@ -33,13 +35,37 @@ namespace Passenger.Data.Migrations { table.PrimaryKey("PK_Passenger", x => x.Id); }); + + migrationBuilder.CreateTable( + name: "PersistMessage", + schema: "dbo", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + DataType = table.Column(type: "nvarchar(max)", nullable: true), + Data = table.Column(type: "nvarchar(max)", nullable: true), + Created = table.Column(type: "datetime2", nullable: false), + RetryCount = table.Column(type: "int", nullable: false), + MessageStatus = table.Column(type: "varchar(50)", unicode: false, maxLength: 50, nullable: false), + DeliveryType = table.Column(type: "varchar(50)", unicode: false, maxLength: 50, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PersistMessage", x => x.Id); + }); } + /// protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable( name: "Passenger", schema: "dbo"); + + migrationBuilder.DropTable( + name: "PersistMessage", + schema: "dbo"); } } } diff --git a/src/Services/Passenger/src/Passenger/Data/Migrations/PassengerDbContextModelSnapshot.cs b/src/Services/Passenger/src/Passenger/Data/Migrations/PassengerDbContextModelSnapshot.cs index df21933..aba9f86 100644 --- a/src/Services/Passenger/src/Passenger/Data/Migrations/PassengerDbContextModelSnapshot.cs +++ b/src/Services/Passenger/src/Passenger/Data/Migrations/PassengerDbContextModelSnapshot.cs @@ -17,10 +17,47 @@ namespace Passenger.Data.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "6.0.1") + .HasAnnotation("ProductVersion", "7.0.0") .HasAnnotation("Relational:MaxIdentifierLength", 128); - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BuildingBlocks.PersistMessageProcessor.PersistMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Data") + .HasColumnType("nvarchar(max)"); + + b.Property("DataType") + .HasColumnType("nvarchar(max)"); + + b.Property("DeliveryType") + .IsRequired() + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnType("varchar(50)"); + + b.Property("MessageStatus") + .IsRequired() + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnType("varchar(50)"); + + b.Property("RetryCount") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("PersistMessage", "dbo"); + }); modelBuilder.Entity("Passenger.Passengers.Models.Passenger", b => { diff --git a/src/Services/Passenger/src/Passenger/Extensions/Infrastructure/InfrastructureExtensions.cs b/src/Services/Passenger/src/Passenger/Extensions/Infrastructure/InfrastructureExtensions.cs index 1899bf0..4b91048 100644 --- a/src/Services/Passenger/src/Passenger/Extensions/Infrastructure/InfrastructureExtensions.cs +++ b/src/Services/Passenger/src/Passenger/Extensions/Infrastructure/InfrastructureExtensions.cs @@ -45,7 +45,7 @@ public static class InfrastructureExtensions options.SuppressModelStateInvalidFilter = true; }); - var appOptions = builder.Services.GetOptions("AppOptions"); + var appOptions = builder.Services.GetOptions(nameof(AppOptions)); Console.WriteLine(FiggleFonts.Standard.Render(appOptions.Name)); builder.Services.AddRateLimiter(options => @@ -59,9 +59,9 @@ public static class InfrastructureExtensions })); }); + builder.Services.AddPersistMessageProcessor(); builder.Services.AddCustomDbContext(configuration); builder.Services.AddMongoDbContext(configuration); - builder.Services.AddPersistMessage(configuration); builder.AddCustomSerilog(env); builder.Services.AddJwt(); @@ -89,7 +89,7 @@ public static class InfrastructureExtensions public static WebApplication UseInfrastructure(this WebApplication app) { var env = app.Environment; - var appOptions = app.GetOptions("AppOptions"); + var appOptions = app.GetOptions(nameof(AppOptions)); app.UseProblemDetails(); app.UseSerilogRequestLogging();