From 27c63a4efa7f5e02c4ab78e1e5a2847f8808bb4d Mon Sep 17 00:00:00 2001 From: meysamhadeli Date: Sun, 4 Dec 2022 00:54:19 +0330 Subject: [PATCH 1/2] - 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(); From cfab34e3ae2ce5603b6b9cd731b64c8cebdc7ee2 Mon Sep 17 00:00:00 2001 From: meysamhadeli Date: Fri, 9 Dec 2022 17:12:13 +0330 Subject: [PATCH 2/2] - use test-container for integration-test - improvement test base --- .../docker-compose/docker-compose.yaml | 2 +- .../docker-compose/infrastracture.yaml | 2 +- src/BuildingBlocks/BuildingBlocks.csproj | 2 + src/BuildingBlocks/EFCore/AppDbContextBase.cs | 5 +- src/BuildingBlocks/EFCore/Extensions.cs | 18 +- src/BuildingBlocks/EFCore/IDbContext.cs | 3 - src/BuildingBlocks/MassTransit/Extensions.cs | 9 +- .../PersistMessageConfiguration.cs | 7 +- .../Data/DesignTimeDbContextFactory.cs | 16 ++ .../20221206184130_initial.Designer.cs | 64 +++++++ .../Data/Migrations/20221206184130_initial.cs | 44 +++++ .../PersistMessageDbContextModelSnapshot.cs | 61 ++++++ .../Data/PersistMessageDbContext.cs | 19 ++ .../PersistMessageProcessor/Data/readme.md | 2 + .../PersistMessageProcessor/Extensions.cs | 19 +- .../IPersistMessageDbContext.cs | 9 + .../PersistMessageBackgroundService.cs | 15 +- .../PersistMessageProcessor.cs | 25 ++- .../TestBase/IntegrationTestBase.cs | 176 ++++++++++++------ src/BuildingBlocks/TestBase/TestContainers.cs | 35 +++- .../{Utils => Web}/CurrentUserProvider.cs | 2 +- .../Web/ServiceProviderExtensions.cs | 30 +++ .../SlugifyParameterTransformer.cs | 2 +- .../Booking.Api/appsettings.Development.json | 6 - .../src/Booking.Api/appsettings.docker.json | 5 + .../Booking/src/Booking.Api/appsettings.json | 2 +- .../src/Booking.Api/appsettings.test.json | 10 +- .../V1/CreateBookingCommandHandler.cs | 2 +- .../InfrastructureExtensions.cs | 4 +- .../Booking/Features/CreateBookingTests.cs | 10 +- .../BookingIntegrationTestBase.cs | 21 +++ .../Flight.Api/appsettings.Development.json | 6 - .../src/Flight.Api/appsettings.docker.json | 7 +- .../Flight/src/Flight.Api/appsettings.json | 3 +- .../src/Flight.Api/appsettings.test.json | 5 +- .../PersistMessageConfiguration.cs | 45 ----- .../Flight/src/Flight/Data/FlightDbContext.cs | 1 + ....cs => 20221206180723_Initial.Designer.cs} | 36 +--- ...8_Initial.cs => 20221206180723_Initial.cs} | 22 --- .../FlightDbContextModelSnapshot.cs | 34 ---- .../src/Flight/Data/Seed/FlightDataSeeder.cs | 2 - .../InfrastructureExtensions.cs | 5 +- .../Aircraft/Features/CreateAircraftTests.cs | 9 +- .../Airport/Features/CreateAirportTests.cs | 9 +- .../Flight/Features/CreateFlightTests.cs | 16 +- .../Flight/Features/DeleteFlightTests.cs | 9 +- .../Features/GetAvailableFlightsTests.cs | 7 +- .../Flight/Features/GetFlightByIdTests.cs | 15 +- .../Flight/Features/UpdateFlightTests.cs | 9 +- .../FlightIntegrationTestBase.cs | 20 ++ .../Seat/Features/GetAvailableSeatsTests.cs | 15 +- .../Seat/Features/ReserveSeatTests.cs | 15 +- .../src/Identity.Api/appsettings.docker.json | 5 + .../src/Identity.Api/appsettings.json | 3 +- .../src/Identity.Api/appsettings.test.json | 5 +- .../PersistMessageConfiguration.cs | 44 ----- ....cs => 20221206180831_initial.Designer.cs} | 39 +--- ...6_initial.cs => 20221206180831_initial.cs} | 23 --- .../IdentityContextModelSnapshot.cs | 37 ---- .../InfrastructureExtensions.cs | 2 +- .../Identity/src/Identity/Identity.csproj | 1 + .../Identity/Features/RegisterNewUserTests.cs | 10 +- .../IdentityIntegrationTestBase.cs | 21 +++ .../src/Passenger.Api/appsettings.docker.json | 5 + .../src/Passenger.Api/appsettings.json | 3 +- .../src/Passenger.Api/appsettings.test.json | 5 +- ....cs => 20221206180929_initial.Designer.cs} | 39 +--- ...3_initial.cs => 20221206180929_initial.cs} | 23 --- .../PassengerDbContextModelSnapshot.cs | 37 ---- .../src/Passenger/Data/PassengerDbContext.cs | 5 +- .../InfrastructureExtensions.cs | 2 +- .../IntegrationTest/Fakes/FakeUserCreated.cs | 4 +- .../CompleteRegisterPassengerTests.cs | 8 +- .../Features/GetPassengerByIdTests.cs | 16 +- .../PassengerIntegrationTestBase.cs | 21 +++ 75 files changed, 651 insertions(+), 624 deletions(-) rename src/{Services/Passenger/src/Passenger => BuildingBlocks/PersistMessageProcessor}/Data/Configurations/PersistMessageConfiguration.cs (88%) create mode 100644 src/BuildingBlocks/PersistMessageProcessor/Data/DesignTimeDbContextFactory.cs create mode 100644 src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20221206184130_initial.Designer.cs create mode 100644 src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20221206184130_initial.cs create mode 100644 src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/PersistMessageDbContextModelSnapshot.cs create mode 100644 src/BuildingBlocks/PersistMessageProcessor/Data/PersistMessageDbContext.cs create mode 100644 src/BuildingBlocks/PersistMessageProcessor/Data/readme.md create mode 100644 src/BuildingBlocks/PersistMessageProcessor/IPersistMessageDbContext.cs rename src/BuildingBlocks/{Utils => Web}/CurrentUserProvider.cs (95%) create mode 100644 src/BuildingBlocks/Web/ServiceProviderExtensions.cs rename src/BuildingBlocks/{Utils => Web}/SlugifyParameterTransformer.cs (92%) create mode 100644 src/Services/Booking/tests/IntegrationTest/BookingIntegrationTestBase.cs delete mode 100644 src/Services/Flight/src/Flight/Data/Configurations/PersistMessageConfiguration.cs rename src/Services/Flight/src/Flight/Data/Migrations/{20221203201848_Initial.Designer.cs => 20221206180723_Initial.Designer.cs} (86%) rename src/Services/Flight/src/Flight/Data/Migrations/{20221203201848_Initial.cs => 20221206180723_Initial.cs} (87%) create mode 100644 src/Services/Flight/tests/IntegrationTest/FlightIntegrationTestBase.cs delete mode 100644 src/Services/Identity/src/Identity/Data/Configurations/PersistMessageConfiguration.cs rename src/Services/Identity/src/Identity/Data/Migrations/{20221203211306_initial.Designer.cs => 20221206180831_initial.Designer.cs} (88%) rename src/Services/Identity/src/Identity/Data/Migrations/{20221203211306_initial.cs => 20221206180831_initial.cs} (90%) create mode 100644 src/Services/Identity/tests/IntegrationTest/IdentityIntegrationTestBase.cs rename src/Services/Passenger/src/Passenger/Data/Migrations/{20221203211633_initial.Designer.cs => 20221206180929_initial.Designer.cs} (61%) rename src/Services/Passenger/src/Passenger/Data/Migrations/{20221203211633_initial.cs => 20221206180929_initial.cs} (61%) create mode 100644 src/Services/Passenger/tests/IntegrationTest/PassengerIntegrationTestBase.cs diff --git a/deployments/docker-compose/docker-compose.yaml b/deployments/docker-compose/docker-compose.yaml index 0ba167e..e2f1632 100644 --- a/deployments/docker-compose/docker-compose.yaml +++ b/deployments/docker-compose/docker-compose.yaml @@ -251,7 +251,7 @@ services: # Mongo ####################################################### mongo: - image: mongo + image: mongo:4 container_name: mongo restart: unless-stopped # environment: diff --git a/deployments/docker-compose/infrastracture.yaml b/deployments/docker-compose/infrastracture.yaml index d219836..2558920 100644 --- a/deployments/docker-compose/infrastracture.yaml +++ b/deployments/docker-compose/infrastracture.yaml @@ -91,7 +91,7 @@ services: # Mongo ####################################################### mongo: - image: mongo + image: mongo:4 container_name: mongo restart: unless-stopped # environment: diff --git a/src/BuildingBlocks/BuildingBlocks.csproj b/src/BuildingBlocks/BuildingBlocks.csproj index 430ff9c..e773b06 100644 --- a/src/BuildingBlocks/BuildingBlocks.csproj +++ b/src/BuildingBlocks/BuildingBlocks.csproj @@ -20,6 +20,7 @@ + @@ -149,6 +150,7 @@ + diff --git a/src/BuildingBlocks/EFCore/AppDbContextBase.cs b/src/BuildingBlocks/EFCore/AppDbContextBase.cs index 220c992..a2719ec 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 BuildingBlocks.Web; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Storage; @@ -71,7 +71,7 @@ public abstract class AppDbContextBase : DbContext, IDbContext OnBeforeSaving(); return base.SaveChangesAsync(cancellationToken); } - + public IReadOnlyList GetDomainEvents() { var domainEntities = ChangeTracker @@ -119,6 +119,7 @@ public abstract class AppDbContextBase : DbContext, IDbContext entry.Entity.LastModifiedBy = userId; entry.Entity.LastModified = DateTime.Now; entry.Entity.IsDeleted = true; + entry.Entity.Version++; break; } } diff --git a/src/BuildingBlocks/EFCore/Extensions.cs b/src/BuildingBlocks/EFCore/Extensions.cs index 7b22142..b3474e2 100644 --- a/src/BuildingBlocks/EFCore/Extensions.cs +++ b/src/BuildingBlocks/EFCore/Extensions.cs @@ -1,12 +1,11 @@ using System.Linq.Expressions; using BuildingBlocks.Core.Model; -using BuildingBlocks.PersistMessageProcessor; +using BuildingBlocks.PersistMessageProcessor.Data; using BuildingBlocks.Web; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Query; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -15,12 +14,12 @@ namespace BuildingBlocks.EFCore; public static class Extensions { public static IServiceCollection AddCustomDbContext( - this IServiceCollection services, - IConfiguration configuration) + this IServiceCollection services) where TContext : DbContext, IDbContext { + services.AddOptions() - .Bind(configuration.GetSection(nameof(DatabaseOptions))) + .BindConfiguration(nameof(DatabaseOptions)) .ValidateDataAnnotations(); services.AddDbContext((sp, options) => @@ -28,7 +27,10 @@ public static class Extensions var databaseOptions = services.GetOptions(nameof(DatabaseOptions)); options.UseSqlServer(databaseOptions?.DefaultConnection, - dbOptions => dbOptions.MigrationsAssembly(typeof(TContext).Assembly.GetName().Name)); + dbOptions => + { + dbOptions.MigrationsAssembly(typeof(TContext).Assembly.GetName().Name); + }); }); services.AddScoped(provider => provider.GetService()); @@ -71,8 +73,10 @@ public static class Extensions { using var scope = serviceProvider.CreateScope(); - var context = scope.ServiceProvider.GetRequiredService(); + 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 473626e..af53ad3 100644 --- a/src/BuildingBlocks/EFCore/IDbContext.cs +++ b/src/BuildingBlocks/EFCore/IDbContext.cs @@ -1,5 +1,4 @@ using BuildingBlocks.Core.Event; -using BuildingBlocks.PersistMessageProcessor; using Microsoft.EntityFrameworkCore; namespace BuildingBlocks.EFCore; @@ -7,8 +6,6 @@ namespace BuildingBlocks.EFCore; public interface IDbContext { DbSet Set() where TEntity : class; - DbSet PersistMessages => Set(); - IReadOnlyList GetDomainEvents(); Task BeginTransactionAsync(CancellationToken cancellationToken = default); Task CommitTransactionAsync(CancellationToken cancellationToken = default); diff --git a/src/BuildingBlocks/MassTransit/Extensions.cs b/src/BuildingBlocks/MassTransit/Extensions.cs index d6af590..e56d18a 100644 --- a/src/BuildingBlocks/MassTransit/Extensions.cs +++ b/src/BuildingBlocks/MassTransit/Extensions.cs @@ -21,6 +21,10 @@ public static class Extensions public static IServiceCollection AddCustomMassTransit(this IServiceCollection services, Assembly assembly, IWebHostEnvironment env) { + services.AddOptions() + .BindConfiguration(nameof(RabbitMqOptions)) + .ValidateDataAnnotations(); + if (env.IsEnvironment("test")) { services.AddMassTransitTestHarness(configure => @@ -47,12 +51,13 @@ public static class Extensions configure.UsingRabbitMq((context, configurator) => { var rabbitMqOptions = services.GetOptions(nameof(RabbitMqOptions)); + var host = IsRunningInContainer ? "rabbitmq" : rabbitMqOptions.HostName; configurator.Host(host, rabbitMqOptions?.Port ?? 5672, "/", h => { - h.Username(rabbitMqOptions.UserName); - h.Password(rabbitMqOptions.Password); + h.Username(rabbitMqOptions?.UserName); + h.Password(rabbitMqOptions?.Password); }); var types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes()) diff --git a/src/Services/Passenger/src/Passenger/Data/Configurations/PersistMessageConfiguration.cs b/src/BuildingBlocks/PersistMessageProcessor/Data/Configurations/PersistMessageConfiguration.cs similarity index 88% rename from src/Services/Passenger/src/Passenger/Data/Configurations/PersistMessageConfiguration.cs rename to src/BuildingBlocks/PersistMessageProcessor/Data/Configurations/PersistMessageConfiguration.cs index a823fb9..18c1281 100644 --- a/src/Services/Passenger/src/Passenger/Data/Configurations/PersistMessageConfiguration.cs +++ b/src/BuildingBlocks/PersistMessageProcessor/Data/Configurations/PersistMessageConfiguration.cs @@ -1,9 +1,8 @@ using BuildingBlocks.EFCore; -using BuildingBlocks.PersistMessageProcessor; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; -namespace Passenger.Data.Configurations; +namespace BuildingBlocks.PersistMessageProcessor.Data.Configurations; public class PersistMessageConfiguration : IEntityTypeConfiguration { @@ -13,8 +12,8 @@ public class PersistMessageConfiguration : IEntityTypeConfiguration x.Id); - builder.Property(x => x.Id) - .IsRequired(); + builder.Property(r => r.Id) + .IsRequired().ValueGeneratedNever(); builder.Property(x => x.DeliveryType) .HasMaxLength(50) diff --git a/src/BuildingBlocks/PersistMessageProcessor/Data/DesignTimeDbContextFactory.cs b/src/BuildingBlocks/PersistMessageProcessor/Data/DesignTimeDbContextFactory.cs new file mode 100644 index 0000000..91a4279 --- /dev/null +++ b/src/BuildingBlocks/PersistMessageProcessor/Data/DesignTimeDbContextFactory.cs @@ -0,0 +1,16 @@ +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;TrustServerCertificate=True"); + return new PersistMessageDbContext(builder.Options); + } +} diff --git a/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20221206184130_initial.Designer.cs b/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20221206184130_initial.Designer.cs new file mode 100644 index 0000000..4d44436 --- /dev/null +++ b/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20221206184130_initial.Designer.cs @@ -0,0 +1,64 @@ +// +using System; +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 BuildingBlocks.PersistMessageProcessor.Data.Migrations +{ + [DbContext(typeof(PersistMessageDbContext))] + [Migration("20221206184130_initial")] + partial class initial + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + 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"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20221206184130_initial.cs b/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20221206184130_initial.cs new file mode 100644 index 0000000..3d3f92b --- /dev/null +++ b/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20221206184130_initial.cs @@ -0,0 +1,44 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BuildingBlocks.PersistMessageProcessor.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 new file mode 100644 index 0000000..df9a1fb --- /dev/null +++ b/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/PersistMessageDbContextModelSnapshot.cs @@ -0,0 +1,61 @@ +// +using System; +using BuildingBlocks.PersistMessageProcessor.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace BuildingBlocks.PersistMessageProcessor.Data.Migrations +{ + [DbContext(typeof(PersistMessageDbContext))] + partial class PersistMessageDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + 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"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/BuildingBlocks/PersistMessageProcessor/Data/PersistMessageDbContext.cs b/src/BuildingBlocks/PersistMessageProcessor/Data/PersistMessageDbContext.cs new file mode 100644 index 0000000..19d94b7 --- /dev/null +++ b/src/BuildingBlocks/PersistMessageProcessor/Data/PersistMessageDbContext.cs @@ -0,0 +1,19 @@ +using BuildingBlocks.EFCore; +using BuildingBlocks.PersistMessageProcessor.Data.Configurations; +using Microsoft.EntityFrameworkCore; + +namespace BuildingBlocks.PersistMessageProcessor.Data; + +public class PersistMessageDbContext : AppDbContextBase, IPersistMessageDbContext +{ + 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 new file mode 100644 index 0000000..062e4d3 --- /dev/null +++ b/src/BuildingBlocks/PersistMessageProcessor/Data/readme.md @@ -0,0 +1,2 @@ +dotnet ef migrations add initial --context PersistMessageDbContext -o "PersistMessageProcessor\Data\Migrations" +dotnet ef database update --context PersistMessageDbContext diff --git a/src/BuildingBlocks/PersistMessageProcessor/Extensions.cs b/src/BuildingBlocks/PersistMessageProcessor/Extensions.cs index 21dcc01..b30b68d 100644 --- a/src/BuildingBlocks/PersistMessageProcessor/Extensions.cs +++ b/src/BuildingBlocks/PersistMessageProcessor/Extensions.cs @@ -1,4 +1,7 @@ -using Microsoft.Extensions.DependencyInjection; +using BuildingBlocks.PersistMessageProcessor.Data; +using BuildingBlocks.Web; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; namespace BuildingBlocks.PersistMessageProcessor; @@ -6,6 +9,20 @@ public static class Extensions { public static IServiceCollection AddPersistMessageProcessor(this IServiceCollection services) { + services.AddOptions() + .BindConfiguration(nameof(PersistMessageOptions)) + .ValidateDataAnnotations(); + + services.AddDbContext(options => + { + var persistMessageOptions = services.GetOptions(nameof(PersistMessageOptions)); + + 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 new file mode 100644 index 0000000..2552126 --- /dev/null +++ b/src/BuildingBlocks/PersistMessageProcessor/IPersistMessageDbContext.cs @@ -0,0 +1,9 @@ +using BuildingBlocks.EFCore; +using Microsoft.EntityFrameworkCore; + +namespace BuildingBlocks.PersistMessageProcessor; + +public interface IPersistMessageDbContext : IDbContext +{ + DbSet PersistMessages => Set(); +} diff --git a/src/BuildingBlocks/PersistMessageProcessor/PersistMessageBackgroundService.cs b/src/BuildingBlocks/PersistMessageProcessor/PersistMessageBackgroundService.cs index 09527f9..5fc37d6 100644 --- a/src/BuildingBlocks/PersistMessageProcessor/PersistMessageBackgroundService.cs +++ b/src/BuildingBlocks/PersistMessageProcessor/PersistMessageBackgroundService.cs @@ -1,5 +1,4 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -8,18 +7,18 @@ namespace BuildingBlocks.PersistMessageProcessor; public class PersistMessageBackgroundService : BackgroundService { private readonly ILogger _logger; - private readonly IServiceProvider _serviceProvider; + private readonly IPersistMessageProcessor _persistMessageProcessor; private PersistMessageOptions _options; private Task? _executingTask; public PersistMessageBackgroundService( ILogger logger, - IServiceProvider serviceProvider, + IPersistMessageProcessor persistMessageProcessor, IOptions options) { _logger = logger; - _serviceProvider = serviceProvider; + _persistMessageProcessor = persistMessageProcessor; _options = options.Value; } @@ -45,11 +44,7 @@ public class PersistMessageBackgroundService : BackgroundService { try { - await using (var scope = _serviceProvider.CreateAsyncScope()) - { - var service = scope.ServiceProvider.GetRequiredService(); - await service.ProcessAllAsync(stoppingToken); - } + await _persistMessageProcessor.ProcessAllAsync(stoppingToken); var delay = _options.Interval is { } ? TimeSpan.FromSeconds((int)_options.Interval) diff --git a/src/BuildingBlocks/PersistMessageProcessor/PersistMessageProcessor.cs b/src/BuildingBlocks/PersistMessageProcessor/PersistMessageProcessor.cs index 72bafad..f1815a6 100644 --- a/src/BuildingBlocks/PersistMessageProcessor/PersistMessageProcessor.cs +++ b/src/BuildingBlocks/PersistMessageProcessor/PersistMessageProcessor.cs @@ -2,7 +2,6 @@ using System.Text.Json; using Ardalis.GuardClauses; using BuildingBlocks.Core.Event; -using BuildingBlocks.EFCore; using BuildingBlocks.IdsGenerator; using BuildingBlocks.Utils; using MassTransit; @@ -16,18 +15,18 @@ public class PersistMessageProcessor : IPersistMessageProcessor { private readonly ILogger _logger; private readonly IMediator _mediator; - private readonly IDbContext _dbContext; + private readonly IPersistMessageDbContext _persistMessageDbContext; private readonly IPublishEndpoint _publishEndpoint; public PersistMessageProcessor( ILogger logger, IMediator mediator, - IDbContext dbContext, + IPersistMessageDbContext persistMessageDbContext, IPublishEndpoint publishEndpoint) { _logger = logger; _mediator = mediator; - _dbContext = dbContext; + _persistMessageDbContext = persistMessageDbContext; _publishEndpoint = publishEndpoint; } @@ -55,13 +54,13 @@ public class PersistMessageProcessor : IPersistMessageProcessor public async Task> GetByFilterAsync(Expression> predicate, CancellationToken cancellationToken = default) { - return (await _dbContext.PersistMessages.Where(predicate).ToListAsync(cancellationToken)) + return (await _persistMessageDbContext.PersistMessages.Where(predicate).ToListAsync(cancellationToken)) .AsReadOnly(); } public Task ExistMessageAsync(long messageId, CancellationToken cancellationToken = default) { - return _dbContext.PersistMessages.FirstOrDefaultAsync(x => + return _persistMessageDbContext.PersistMessages.FirstOrDefaultAsync(x => x.Id == messageId && x.DeliveryType == MessageDeliveryType.Inbox && x.MessageStatus == MessageStatus.Processed, @@ -74,7 +73,7 @@ public class PersistMessageProcessor : IPersistMessageProcessor CancellationToken cancellationToken = default) { var message = - await _dbContext.PersistMessages.FirstOrDefaultAsync( + await _persistMessageDbContext.PersistMessages.FirstOrDefaultAsync( x => x.Id == messageId && x.DeliveryType == deliveryType, cancellationToken); if (message is null) @@ -111,7 +110,7 @@ public class PersistMessageProcessor : IPersistMessageProcessor public async Task ProcessAllAsync(CancellationToken cancellationToken = default) { - var messages = await _dbContext.PersistMessages + var messages = await _persistMessageDbContext.PersistMessages .Where(x => x.MessageStatus != MessageStatus.Processed) .ToListAsync(cancellationToken); @@ -120,7 +119,7 @@ public class PersistMessageProcessor : IPersistMessageProcessor public async Task ProcessInboxAsync(long messageId, CancellationToken cancellationToken = default) { - var message = await _dbContext.PersistMessages.FirstOrDefaultAsync( + var message = await _persistMessageDbContext.PersistMessages.FirstOrDefaultAsync( x => x.Id == messageId && x.DeliveryType == MessageDeliveryType.Inbox && x.MessageStatus == MessageStatus.InProgress, @@ -191,7 +190,7 @@ public class PersistMessageProcessor : IPersistMessageProcessor else id = SnowFlakIdGenerator.NewId(); - await _dbContext.PersistMessages.AddAsync( + await _persistMessageDbContext.PersistMessages.AddAsync( new PersistMessage( id, messageEnvelope.Message.GetType().ToString(), @@ -199,7 +198,7 @@ public class PersistMessageProcessor : IPersistMessageProcessor deliveryType), cancellationToken); - await _dbContext.SaveChangesAsync(cancellationToken); + await _persistMessageDbContext.SaveChangesAsync(cancellationToken); _logger.LogInformation( "Message with id: {MessageID} and delivery type: {DeliveryType} saved in persistence message store.", @@ -213,8 +212,8 @@ public class PersistMessageProcessor : IPersistMessageProcessor { message.ChangeState(MessageStatus.Processed); - _dbContext.PersistMessages.Update(message); + _persistMessageDbContext.PersistMessages.Update(message); - await _dbContext.SaveChangesAsync(cancellationToken); + await _persistMessageDbContext.SaveChangesAsync(cancellationToken); } } diff --git a/src/BuildingBlocks/TestBase/IntegrationTestBase.cs b/src/BuildingBlocks/TestBase/IntegrationTestBase.cs index d6a5ddb..2afdc07 100644 --- a/src/BuildingBlocks/TestBase/IntegrationTestBase.cs +++ b/src/BuildingBlocks/TestBase/IntegrationTestBase.cs @@ -2,10 +2,12 @@ using BuildingBlocks.Core.Event; using BuildingBlocks.Core.Model; using BuildingBlocks.EFCore; +using BuildingBlocks.MassTransit; using BuildingBlocks.Mongo; using BuildingBlocks.PersistMessageProcessor; using BuildingBlocks.Web; using DotNet.Testcontainers.Containers; +using EasyNetQ.Management.Client; using Grpc.Net.Client; using MassTransit; using MassTransit.Testing; @@ -18,7 +20,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -using Mongo2Go; +using MongoDB.Driver; using NSubstitute; using Respawn; using Respawn.Graph; @@ -28,42 +30,43 @@ using Xunit.Abstractions; namespace BuildingBlocks.TestBase; -public class IntegrationTestFixture : IAsyncLifetime +public class IntegrationTestFactory : IAsyncLifetime where TEntryPoint : class { private readonly WebApplicationFactory _factory; - private int Timeout => 60; // Second + private int Timeout => 120; // Second public MsSqlTestcontainer MsSqlTestContainer; + public MsSqlTestcontainer MsSqlPersistTestContainer; public RabbitMqTestcontainer RabbitMqTestContainer; + public MongoDbTestcontainer MongoDbTestContainer; private ITestHarness TestHarness => ServiceProvider?.GetTestHarness(); public HttpClient HttpClient => _factory?.CreateClient(); - public GrpcChannel Channel => - GrpcChannel.ForAddress(HttpClient.BaseAddress!, new GrpcChannelOptions { HttpClient = HttpClient }); + public GrpcChannel Channel => 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 ILogger Logger { get; set; } - public IntegrationTestFixture() + public IntegrationTestFactory() { _factory = new WebApplicationFactory() .WithWebHostBuilder(builder => { + builder.ConfigureAppConfiguration(AddCustomAppSettings); + builder.UseEnvironment("test"); builder.ConfigureServices(services => { TestRegistrationServices?.Invoke(services); services.ReplaceSingleton(AddHttpContextAccessorMock); }); - - builder.ConfigureAppConfiguration(AddCustomAppSettings); }); } - public async Task InitializeAsync() { await StartTestContainerAsync(); @@ -134,32 +137,35 @@ public class IntegrationTestFixture : IAsyncLifetime await TestHarness.Bus.Publish(message, cancellationToken); } - public async Task WaitForPublishing(CancellationToken cancellationToken = default) + public async Task WaitForPublishing(CancellationToken cancellationToken = default) where TMessage : class, IEvent { - await WaitUntilConditionMet(async () => + var result = await WaitUntilConditionMet(async () => { var published = await TestHarness.Published.Any(cancellationToken); var faulty = await TestHarness.Published.Any>(cancellationToken); return published && faulty == false; }); + return result; } - public async Task WaitForConsuming(CancellationToken cancellationToken = default) + public async Task WaitForConsuming(CancellationToken cancellationToken = default) where TMessage : class, IEvent { - await WaitUntilConditionMet(async () => + var result = await WaitUntilConditionMet(async () => { var consumed = await TestHarness.Consumed.Any(cancellationToken); var faulty = await TestHarness.Consumed.Any>(cancellationToken); return consumed && faulty == false; }); + + return result; } // Ref: https://tech.energyhelpline.com/in-memory-testing-with-masstransit/ - public async ValueTask WaitUntilConditionMet(Func> conditionToMet, int? timeoutSecond = null) + public async Task WaitUntilConditionMet(Func> conditionToMet, int? timeoutSecond = null) { var time = timeoutSecond ?? Timeout; @@ -168,18 +174,20 @@ public class IntegrationTestFixture : IAsyncLifetime var meet = await conditionToMet.Invoke(); while (!meet) { - if (timeoutExpired) throw new TimeoutException("Condition not met for the test."); + if (timeoutExpired) return false; await Task.Delay(100); meet = await conditionToMet.Invoke(); timeoutExpired = DateTime.Now - startTime > TimeSpan.FromSeconds(time); } + + return true; } - public async ValueTask ShouldProcessedPersistInternalCommand() + public async Task ShouldProcessedPersistInternalCommand() where TInternalCommand : class, IInternalCommand { - await WaitUntilConditionMet(async () => + var result = await WaitUntilConditionMet(async () => { return await ExecuteScopeAsync(async sp => { @@ -195,22 +203,30 @@ public class IntegrationTestFixture : IAsyncLifetime return res; }); }); + + return result; } private async Task StartTestContainerAsync() { MsSqlTestContainer = TestContainers.MsSqlTestContainer; + MsSqlPersistTestContainer = TestContainers.MsSqlPersistTestContainer; RabbitMqTestContainer = TestContainers.RabbitMqTestContainer; + MongoDbTestContainer = TestContainers.MongoTestContainer; + await MongoDbTestContainer.StartAsync(); await MsSqlTestContainer.StartAsync(); + await MsSqlPersistTestContainer.StartAsync(); await RabbitMqTestContainer.StartAsync(); } private async Task StopTestContainerAsync() { await MsSqlTestContainer.StopAsync(); + await MsSqlPersistTestContainer.StopAsync(); await RabbitMqTestContainer.StopAsync(); + await MongoDbTestContainer.StopAsync(); } private void AddCustomAppSettings(IConfigurationBuilder configuration) @@ -218,10 +234,13 @@ public class IntegrationTestFixture : IAsyncLifetime configuration.AddInMemoryCollection(new KeyValuePair[] { new("DatabaseOptions:DefaultConnection", MsSqlTestContainer.ConnectionString + "TrustServerCertificate=True"), + new("PersistMessageOptions:ConnectionString", MsSqlPersistTestContainer.ConnectionString + "TrustServerCertificate=True"), new("RabbitMqOptions:HostName", RabbitMqTestContainer.Hostname), new("RabbitMqOptions:UserName", RabbitMqTestContainer.Username), new("RabbitMqOptions:Password", RabbitMqTestContainer.Password), - new("RabbitMqOptions:Port", RabbitMqTestContainer.Port.ToString()) + new("RabbitMqOptions:Port", RabbitMqTestContainer.Port.ToString()), + new("MongoOptions:ConnectionString", MongoDbTestContainer.ConnectionString), + new("MongoOptions:DatabaseName", MongoDbTestContainer.Database) }); } @@ -238,7 +257,7 @@ public class IntegrationTestFixture : IAsyncLifetime } } -public class IntegrationTestFixture : IntegrationTestFixture +public class IntegrationTestFactory : IntegrationTestFactory where TEntryPoint : class where TWContext : DbContext { @@ -345,7 +364,7 @@ public class IntegrationTestFixture : IntegrationTestFix } } -public class IntegrationTestFixture : IntegrationTestFixture +public class IntegrationTestFactory : IntegrationTestFactory where TEntryPoint : class where TWContext : DbContext where TRContext : MongoDbContext @@ -365,48 +384,93 @@ public class IntegrationTestFixtureCore : IAsyncLifetime where TEntryPoint : class { private Respawner _reSpawnerDefaultDb; - private MongoDbRunner _mongoRunner; + private Respawner _reSpawnerPersistDb; + private SqlConnection DefaultDbConnection { get; set; } + private SqlConnection PersistDbConnection { get; set; } - - public IntegrationTestFixtureCore(IntegrationTestFixture integrationTestFixture) + public IntegrationTestFixtureCore(IntegrationTestFactory integrationTestFixture, ITestOutputHelper outputHelper) { Fixture = integrationTestFixture; integrationTestFixture.RegisterServices(services => RegisterTestsServices(services)); + integrationTestFixture.Logger = integrationTestFixture.CreateLogger(outputHelper); } - public IntegrationTestFixture Fixture { get; } + public IntegrationTestFactory Fixture { get; } public async Task InitializeAsync() { var databaseOptions = Fixture.ServiceProvider.GetRequiredService>()?.Value; - var mongoOptions = Fixture.ServiceProvider.GetRequiredService>()?.Value; + var persistOptions = Fixture.ServiceProvider.GetRequiredService>()?.Value; + + if (!string.IsNullOrEmpty(persistOptions?.ConnectionString)) + { + PersistDbConnection = new SqlConnection(persistOptions?.ConnectionString); + await PersistDbConnection.OpenAsync(); + + _reSpawnerPersistDb = await Respawner.CreateAsync(PersistDbConnection, + new RespawnerOptions { TablesToIgnore = new Table[] { "__EFMigrationsHistory" }, }); + + await _reSpawnerPersistDb.ResetAsync(PersistDbConnection); + } if (!string.IsNullOrEmpty(databaseOptions?.DefaultConnection)) { - var dbConnection = new SqlConnection(databaseOptions.DefaultConnection); - await dbConnection.OpenAsync(); + DefaultDbConnection = new SqlConnection(databaseOptions.DefaultConnection); + await DefaultDbConnection.OpenAsync(); - _reSpawnerDefaultDb = await Respawner.CreateAsync(dbConnection, - new RespawnerOptions - { - TablesToIgnore = new Table[] { "__EFMigrationsHistory" }, - }); + _reSpawnerDefaultDb = await Respawner.CreateAsync(DefaultDbConnection, + new RespawnerOptions { TablesToIgnore = new Table[] { "__EFMigrationsHistory" }, }); - await _reSpawnerDefaultDb.ResetAsync(dbConnection); + await _reSpawnerDefaultDb.ResetAsync(DefaultDbConnection); + + await SeedDataAsync(); } - - _mongoRunner = MongoDbRunner.Start(); - - if (!string.IsNullOrEmpty(mongoOptions?.ConnectionString)) - mongoOptions.ConnectionString = _mongoRunner.ConnectionString; - - await SeedDataAsync(); } public async Task DisposeAsync() { - _mongoRunner.Dispose(); + await ResetMongoAsync(); + await ResetRabbitMqAsync(); + } + + private async Task ResetMongoAsync(CancellationToken cancellationToken = default) + { + //https://stackoverflow.com/questions/3366397/delete-everything-in-a-mongodb-database + MongoClient dbClient = new MongoClient(Fixture.MongoDbTestContainer?.ConnectionString); + var collections = await dbClient.GetDatabase(Fixture.MongoDbTestContainer?.Database) + .ListCollectionsAsync(cancellationToken: cancellationToken); + + foreach (var collection in collections.ToList()) + { + await dbClient.GetDatabase(Fixture.MongoDbTestContainer?.Database) + .DropCollectionAsync(collection["name"].AsString, cancellationToken); + } + } + + private async Task ResetRabbitMqAsync(CancellationToken cancellationToken = default) + { + var port = Fixture.RabbitMqTestContainer?.GetMappedPublicPort(15672) ?? 15672; + + var rabbitmqOptions = Fixture.ServiceProvider.GetRequiredService>()?.Value; + + var managementClient = new ManagementClient(rabbitmqOptions?.HostName, rabbitmqOptions?.UserName, + rabbitmqOptions?.Password, port); + + var bd = await managementClient.GetBindingsAsync(cancellationToken); + var bindings = bd.Where(x => !string.IsNullOrEmpty(x.Source) && !string.IsNullOrEmpty(x.Destination)); + + foreach (var binding in bindings) + { + await managementClient.DeleteBindingAsync(binding, cancellationToken); + } + + var queues = await managementClient.GetQueuesAsync(cancellationToken); + + foreach (var queue in queues) + { + await managementClient.DeleteQueueAsync(queue, cancellationToken); + } } protected virtual void RegisterTestsServices(IServiceCollection services) @@ -422,44 +486,32 @@ public class IntegrationTestFixtureCore : IAsyncLifetime } } -public abstract class IntegrationTestBase : IntegrationTestFixtureCore, - IClassFixture> - where TEntryPoint : class -{ - protected IntegrationTestBase( - IntegrationTestFixture integrationTestFixture) : base(integrationTestFixture) - { - Fixture = integrationTestFixture; - } - - public IntegrationTestFixture Fixture { get; } -} - -public abstract class IntegrationTestBase : IntegrationTestFixtureCore, - IClassFixture> +public abstract class IntegrationTestBase : IntegrationTestFixtureCore + //,IClassFixture> where TEntryPoint : class where TWContext : DbContext { protected IntegrationTestBase( - IntegrationTestFixture integrationTestFixture) : base(integrationTestFixture) + IntegrationTestFactory integrationTestFixture, ITestOutputHelper outputHelper = null) : base(integrationTestFixture, outputHelper) { Fixture = integrationTestFixture; } - public IntegrationTestFixture Fixture { get; } + public IntegrationTestFactory Fixture { get; } } -public abstract class IntegrationTestBase : IntegrationTestFixtureCore, - IClassFixture> +public abstract class IntegrationTestBase : IntegrationTestFixtureCore + //,IClassFixture> where TEntryPoint : class where TWContext : DbContext where TRContext : MongoDbContext { protected IntegrationTestBase( - IntegrationTestFixture integrationTestFixture) : base(integrationTestFixture) + IntegrationTestFactory integrationTestFixture, ITestOutputHelper outputHelper = null) : base(integrationTestFixture, outputHelper) { Fixture = integrationTestFixture; } - public IntegrationTestFixture Fixture { get; } + public IntegrationTestFactory Fixture { get; } } + diff --git a/src/BuildingBlocks/TestBase/TestContainers.cs b/src/BuildingBlocks/TestBase/TestContainers.cs index 3d3fdae..19ef810 100644 --- a/src/BuildingBlocks/TestBase/TestContainers.cs +++ b/src/BuildingBlocks/TestBase/TestContainers.cs @@ -1,4 +1,5 @@ -using DotNet.Testcontainers.Builders; +using System; +using DotNet.Testcontainers.Builders; using DotNet.Testcontainers.Configurations; using DotNet.Testcontainers.Containers; @@ -15,18 +16,28 @@ public static class TestContainers Username = Guid.NewGuid().ToString("D") }) .WithImage("postgres:latest") + .WithCleanUp(true) .Build(); - // issue ref: https://github.com/testcontainers/testcontainers-dotnet/discussions/533 public static MsSqlTestcontainer MsSqlTestContainer = new TestcontainersBuilder() .WithDatabase(new MsSqlTestcontainerConfiguration() { Password = Guid.NewGuid().ToString("D") }) .WithImage("mcr.microsoft.com/mssql/server:2022-latest") - .WithExposedPort(1433) - .WithPortBinding(1433, true) // Add this line for issue in hangup MsSqlTestContainer in docker desktop + .WithPortBinding(1433, true) + .WithCleanUp(true) + .Build(); + + public static MsSqlTestcontainer MsSqlPersistTestContainer = new TestcontainersBuilder() + .WithDatabase(new MsSqlTestcontainerConfiguration() + { + Password = Guid.NewGuid().ToString("D") + }) + .WithImage("mcr.microsoft.com/mssql/server:2022-latest") + .WithPortBinding(1433, true) + .WithCleanUp(true) .Build(); @@ -35,14 +46,24 @@ public static class TestContainers { Database = Guid.NewGuid().ToString("D"), Username = Guid.NewGuid().ToString("D"), - Password = Guid.NewGuid().ToString("D") + Password = Guid.NewGuid().ToString("D"), }) - .WithImage("mongo") + .WithImage("mongo:4") + .WithCleanUp(true) .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") + .WithPortBinding(15672, true) + .WithPortBinding(5672, true) + .WithCleanUp(true) .Build(); + + } diff --git a/src/BuildingBlocks/Utils/CurrentUserProvider.cs b/src/BuildingBlocks/Web/CurrentUserProvider.cs similarity index 95% rename from src/BuildingBlocks/Utils/CurrentUserProvider.cs rename to src/BuildingBlocks/Web/CurrentUserProvider.cs index 385d393..0796c16 100644 --- a/src/BuildingBlocks/Utils/CurrentUserProvider.cs +++ b/src/BuildingBlocks/Web/CurrentUserProvider.cs @@ -1,7 +1,7 @@ using System.Security.Claims; using Microsoft.AspNetCore.Http; -namespace BuildingBlocks.Utils; +namespace BuildingBlocks.Web; public interface ICurrentUserProvider { diff --git a/src/BuildingBlocks/Web/ServiceProviderExtensions.cs b/src/BuildingBlocks/Web/ServiceProviderExtensions.cs new file mode 100644 index 0000000..1ab0d8b --- /dev/null +++ b/src/BuildingBlocks/Web/ServiceProviderExtensions.cs @@ -0,0 +1,30 @@ +using Microsoft.Extensions.Hosting; + +namespace BuildingBlocks.Web; + +public static class ServiceProviderExtensions +{ + public static async Task StartTestHostedServices( + this IServiceProvider serviceProvider, + Type[] hostedServiceTypes, + CancellationToken cancellationToken = default) + { + foreach (var hostedServiceType in hostedServiceTypes) + { + if (serviceProvider.GetService(hostedServiceType) is IHostedService hostedService) + await hostedService.StartAsync(cancellationToken); + } + } + + public static async Task StopTestHostedServices( + this IServiceProvider serviceProvider, + Type[] hostedServiceTypes, + CancellationToken cancellationToken = default) + { + foreach (var hostedServiceType in hostedServiceTypes) + { + if (serviceProvider.GetService(hostedServiceType) is IHostedService hostedService) + await hostedService.StopAsync(cancellationToken); + } + } +} diff --git a/src/BuildingBlocks/Utils/SlugifyParameterTransformer.cs b/src/BuildingBlocks/Web/SlugifyParameterTransformer.cs similarity index 92% rename from src/BuildingBlocks/Utils/SlugifyParameterTransformer.cs rename to src/BuildingBlocks/Web/SlugifyParameterTransformer.cs index e0a7612..9aecf77 100644 --- a/src/BuildingBlocks/Utils/SlugifyParameterTransformer.cs +++ b/src/BuildingBlocks/Web/SlugifyParameterTransformer.cs @@ -1,7 +1,7 @@ using System.Text.RegularExpressions; using Microsoft.AspNetCore.Routing; -namespace BuildingBlocks.Utils; +namespace BuildingBlocks.Web; public class SlugifyParameterTransformer : IOutboundParameterTransformer { diff --git a/src/Services/Booking/src/Booking.Api/appsettings.Development.json b/src/Services/Booking/src/Booking.Api/appsettings.Development.json index 0c208ae..2c63c08 100644 --- a/src/Services/Booking/src/Booking.Api/appsettings.Development.json +++ b/src/Services/Booking/src/Booking.Api/appsettings.Development.json @@ -1,8 +1,2 @@ { - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - } } diff --git a/src/Services/Booking/src/Booking.Api/appsettings.docker.json b/src/Services/Booking/src/Booking.Api/appsettings.docker.json index 6d567d2..06769cf 100644 --- a/src/Services/Booking/src/Booking.Api/appsettings.docker.json +++ b/src/Services/Booking/src/Booking.Api/appsettings.docker.json @@ -6,6 +6,11 @@ "Microsoft.AspNetCore": "Warning" } }, + "PersistMessageOptions": { + "Interval": 30, + "Enabled": true, + "ConnectionString": "Server=db;Database=PersistMessageDB;User ID=sa;Password=@Aa123456" + }, "RabbitMqOptions": { "HostName": "rabbitmq", "ExchangeName": "booking", diff --git a/src/Services/Booking/src/Booking.Api/appsettings.json b/src/Services/Booking/src/Booking.Api/appsettings.json index fe9a66f..a794e5e 100644 --- a/src/Services/Booking/src/Booking.Api/appsettings.json +++ b/src/Services/Booking/src/Booking.Api/appsettings.json @@ -40,7 +40,7 @@ "PersistMessageOptions": { "Interval": 30, "Enabled": true, - "ConnectionString": "Server=localhost;Port=5432;Database=persist_message_db;User Id=postgres;Password=postgres;Include Error Detail=true" + "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=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 e6a2c63..cb72535 100644 --- a/src/Services/Booking/src/Booking.Api/appsettings.test.json +++ b/src/Services/Booking/src/Booking.Api/appsettings.test.json @@ -14,16 +14,16 @@ "Microsoft.EntityFrameworkCore.Database.Command": "Debug" } }, - "PersistMessageOptions": { - "Interval": 1, - "Enabled": 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", "DatabaseName": "booking-db-test" }, "EventStore": { "ConnectionString": "esdb://localhost:2113?tls=false" + }, + "PersistMessageOptions": { + "Interval": 30, + "Enabled": true, + "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" } } diff --git a/src/Services/Booking/src/Booking/Booking/Features/CreateBooking/Commands/V1/CreateBookingCommandHandler.cs b/src/Services/Booking/src/Booking/Booking/Features/CreateBooking/Commands/V1/CreateBookingCommandHandler.cs index 0f91a85..05c1ca9 100644 --- a/src/Services/Booking/src/Booking/Booking/Features/CreateBooking/Commands/V1/CreateBookingCommandHandler.cs +++ b/src/Services/Booking/src/Booking/Booking/Features/CreateBooking/Commands/V1/CreateBookingCommandHandler.cs @@ -4,7 +4,7 @@ using Booking.Booking.Models.ValueObjects; using BuildingBlocks.Core; using BuildingBlocks.Core.CQRS; using BuildingBlocks.EventStoreDB.Repository; -using BuildingBlocks.Utils; +using BuildingBlocks.Web; using Flight; using Passenger; diff --git a/src/Services/Booking/src/Booking/Extensions/Infrastructure/InfrastructureExtensions.cs b/src/Services/Booking/src/Booking/Extensions/Infrastructure/InfrastructureExtensions.cs index 34e5a85..c0d7dde 100644 --- a/src/Services/Booking/src/Booking/Extensions/Infrastructure/InfrastructureExtensions.cs +++ b/src/Services/Booking/src/Booking/Extensions/Infrastructure/InfrastructureExtensions.cs @@ -1,6 +1,7 @@ using System.Threading.RateLimiting; using Booking.Data; using BuildingBlocks.Core; +using BuildingBlocks.EFCore; using BuildingBlocks.EventStoreDB; using BuildingBlocks.HealthCheck; using BuildingBlocks.IdsGenerator; @@ -11,8 +12,8 @@ using BuildingBlocks.MassTransit; using BuildingBlocks.Mongo; using BuildingBlocks.OpenTelemetry; using BuildingBlocks.PersistMessageProcessor; +using BuildingBlocks.PersistMessageProcessor.Data; using BuildingBlocks.Swagger; -using BuildingBlocks.Utils; using BuildingBlocks.Web; using Figgle; using FluentValidation; @@ -97,6 +98,7 @@ public static class InfrastructureExtensions app.UseCorrelationId(); app.UseRouting(); app.UseHttpMetrics(); + app.UseMigration(env); app.UseHttpsRedirection(); app.UseCustomHealthCheck(); app.MapMetrics(); diff --git a/src/Services/Booking/tests/IntegrationTest/Booking/Features/CreateBookingTests.cs b/src/Services/Booking/tests/IntegrationTest/Booking/Features/CreateBookingTests.cs index ac8d1a1..30fe75c 100644 --- a/src/Services/Booking/tests/IntegrationTest/Booking/Features/CreateBookingTests.cs +++ b/src/Services/Booking/tests/IntegrationTest/Booking/Features/CreateBookingTests.cs @@ -3,7 +3,7 @@ using System.Threading.Tasks; using Booking.Api; using Booking.Data; using BuildingBlocks.Contracts.EventBus.Messages; -using BuildingBlocks.EFCore; +using BuildingBlocks.PersistMessageProcessor.Data; using BuildingBlocks.TestBase; using Flight; using FluentAssertions; @@ -19,11 +19,9 @@ using GetByIdRequest = Flight.GetByIdRequest; namespace Integration.Test.Booking.Features; -public class CreateBookingTests : IntegrationTestBase +public class CreateBookingTests : BookingIntegrationTestBase { - public CreateBookingTests( - IntegrationTestFixture integrationTestFixture) : base( - integrationTestFixture) + public CreateBookingTests(IntegrationTestFactory integrationTestFixture) : base(integrationTestFixture) { } @@ -46,7 +44,7 @@ public class CreateBookingTests : IntegrationTestBase(); + (await Fixture.WaitForPublishing()).Should().Be(true); } diff --git a/src/Services/Booking/tests/IntegrationTest/BookingIntegrationTestBase.cs b/src/Services/Booking/tests/IntegrationTest/BookingIntegrationTestBase.cs new file mode 100644 index 0000000..7e8dc96 --- /dev/null +++ b/src/Services/Booking/tests/IntegrationTest/BookingIntegrationTestBase.cs @@ -0,0 +1,21 @@ +using Booking.Api; +using Booking.Data; +using BuildingBlocks.PersistMessageProcessor.Data; +using BuildingBlocks.TestBase; +using Xunit; + +namespace Integration.Test; + +[Collection(IntegrationTestCollection.Name)] +public class BookingIntegrationTestBase: IntegrationTestBase +{ + public BookingIntegrationTestBase(IntegrationTestFactory integrationTestFixture) : base(integrationTestFixture) + { + } +} + +[CollectionDefinition(Name)] +public class IntegrationTestCollection : ICollectionFixture> +{ + public const string Name = "Booking Integration Test"; +} diff --git a/src/Services/Flight/src/Flight.Api/appsettings.Development.json b/src/Services/Flight/src/Flight.Api/appsettings.Development.json index a6e86ac..2c63c08 100644 --- a/src/Services/Flight/src/Flight.Api/appsettings.Development.json +++ b/src/Services/Flight/src/Flight.Api/appsettings.Development.json @@ -1,8 +1,2 @@ { - "Logging": { - "LogLevel": { - "Default": "Debug", - "Microsoft.AspNetCore": "Warning" - } - } } diff --git a/src/Services/Flight/src/Flight.Api/appsettings.docker.json b/src/Services/Flight/src/Flight.Api/appsettings.docker.json index 485ca97..3e97e65 100644 --- a/src/Services/Flight/src/Flight.Api/appsettings.docker.json +++ b/src/Services/Flight/src/Flight.Api/appsettings.docker.json @@ -6,7 +6,7 @@ "Microsoft.AspNetCore": "Warning" } }, - "ConnectionStrings": { + "DatabaseOptions": { "DefaultConnection": "Server=db;Database=FlightDB;User ID=sa;Password=@Aa123456" }, "Jwt": { @@ -20,5 +20,10 @@ "Password": "guest", "Port": 5672 }, + "PersistMessageOptions": { + "Interval": 30, + "Enabled": true, + "ConnectionString": "Server=db;Database=PersistMessageDB;User ID=sa;Password=@Aa123456" + }, "AllowedHosts": "*" } diff --git a/src/Services/Flight/src/Flight.Api/appsettings.json b/src/Services/Flight/src/Flight.Api/appsettings.json index c9d9000..4b77b07 100644 --- a/src/Services/Flight/src/Flight.Api/appsettings.json +++ b/src/Services/Flight/src/Flight.Api/appsettings.json @@ -35,7 +35,8 @@ }, "PersistMessageOptions": { "Interval": 30, - "Enabled": true + "Enabled": true, + "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=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 620d0fc..c78fbb4 100644 --- a/src/Services/Flight/src/Flight.Api/appsettings.test.json +++ b/src/Services/Flight/src/Flight.Api/appsettings.test.json @@ -18,7 +18,8 @@ } }, "PersistMessageOptions": { - "Interval": 1, - "Enabled": true + "Interval": 2, + "Enabled": true, + "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" } } diff --git a/src/Services/Flight/src/Flight/Data/Configurations/PersistMessageConfiguration.cs b/src/Services/Flight/src/Flight/Data/Configurations/PersistMessageConfiguration.cs deleted file mode 100644 index 2d0ffc1..0000000 --- a/src/Services/Flight/src/Flight/Data/Configurations/PersistMessageConfiguration.cs +++ /dev/null @@ -1,45 +0,0 @@ -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/FlightDbContext.cs b/src/Services/Flight/src/Flight/Data/FlightDbContext.cs index a895241..1ee6f11 100644 --- a/src/Services/Flight/src/Flight/Data/FlightDbContext.cs +++ b/src/Services/Flight/src/Flight/Data/FlightDbContext.cs @@ -1,5 +1,6 @@ using BuildingBlocks.EFCore; using BuildingBlocks.Utils; +using BuildingBlocks.Web; using Flight.Aircrafts.Models; using Flight.Airports.Models; using Flight.Seats.Models; diff --git a/src/Services/Flight/src/Flight/Data/Migrations/20221203201848_Initial.Designer.cs b/src/Services/Flight/src/Flight/Data/Migrations/20221206180723_Initial.Designer.cs similarity index 86% rename from src/Services/Flight/src/Flight/Data/Migrations/20221203201848_Initial.Designer.cs rename to src/Services/Flight/src/Flight/Data/Migrations/20221206180723_Initial.Designer.cs index 4a8b70f..ba1c044 100644 --- a/src/Services/Flight/src/Flight/Data/Migrations/20221203201848_Initial.Designer.cs +++ b/src/Services/Flight/src/Flight/Data/Migrations/20221206180723_Initial.Designer.cs @@ -12,7 +12,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace Flight.Data.Migrations { [DbContext(typeof(FlightDbContext))] - [Migration("20221203201848_Initial")] + [Migration("20221206180723_Initial")] partial class Initial { /// @@ -25,40 +25,6 @@ namespace Flight.Data.Migrations 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 => { b.Property("Id") diff --git a/src/Services/Flight/src/Flight/Data/Migrations/20221203201848_Initial.cs b/src/Services/Flight/src/Flight/Data/Migrations/20221206180723_Initial.cs similarity index 87% rename from src/Services/Flight/src/Flight/Data/Migrations/20221203201848_Initial.cs rename to src/Services/Flight/src/Flight/Data/Migrations/20221206180723_Initial.cs index e314291..576d26f 100644 --- a/src/Services/Flight/src/Flight/Data/Migrations/20221203201848_Initial.cs +++ b/src/Services/Flight/src/Flight/Data/Migrations/20221206180723_Initial.cs @@ -56,24 +56,6 @@ 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", @@ -167,10 +149,6 @@ namespace Flight.Data.Migrations /// 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 3acd661..3c2ccf0 100644 --- a/src/Services/Flight/src/Flight/Data/Migrations/FlightDbContextModelSnapshot.cs +++ b/src/Services/Flight/src/Flight/Data/Migrations/FlightDbContextModelSnapshot.cs @@ -22,40 +22,6 @@ namespace Flight.Data.Migrations 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 => { b.Property("Id") diff --git a/src/Services/Flight/src/Flight/Data/Seed/FlightDataSeeder.cs b/src/Services/Flight/src/Flight/Data/Seed/FlightDataSeeder.cs index acc6b8b..8c64322 100644 --- a/src/Services/Flight/src/Flight/Data/Seed/FlightDataSeeder.cs +++ b/src/Services/Flight/src/Flight/Data/Seed/FlightDataSeeder.cs @@ -1,13 +1,11 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using BuildingBlocks.EFCore; using Flight.Aircrafts.Models; using Flight.Aircrafts.Models.Reads; using Flight.Airports.Models; using Flight.Airports.Models.Reads; -using Flight.Flights.Models; using Flight.Flights.Models.Reads; using Flight.Seats.Models; using Flight.Seats.Models.Reads; diff --git a/src/Services/Flight/src/Flight/Extensions/Infrastructure/InfrastructureExtensions.cs b/src/Services/Flight/src/Flight/Extensions/Infrastructure/InfrastructureExtensions.cs index cd163e6..dd53410 100644 --- a/src/Services/Flight/src/Flight/Extensions/Infrastructure/InfrastructureExtensions.cs +++ b/src/Services/Flight/src/Flight/Extensions/Infrastructure/InfrastructureExtensions.cs @@ -66,11 +66,10 @@ public static class InfrastructureExtensions })); }); - builder.Services.AddPersistMessageProcessor(); - builder.Services.AddCustomDbContext(configuration); + builder.Services.AddCustomDbContext(); builder.Services.AddScoped(); builder.Services.AddMongoDbContext(configuration); - + builder.Services.AddPersistMessageProcessor(); builder.AddCustomSerilog(env); builder.Services.AddJwt(); diff --git a/src/Services/Flight/tests/IntegrationTest/Aircraft/Features/CreateAircraftTests.cs b/src/Services/Flight/tests/IntegrationTest/Aircraft/Features/CreateAircraftTests.cs index 2006d7d..940b910 100644 --- a/src/Services/Flight/tests/IntegrationTest/Aircraft/Features/CreateAircraftTests.cs +++ b/src/Services/Flight/tests/IntegrationTest/Aircraft/Features/CreateAircraftTests.cs @@ -10,11 +10,10 @@ using Xunit; namespace Integration.Test.Aircraft.Features; -public class CreateAircraftTests : IntegrationTestBase +public class CreateAircraftTests : FlightIntegrationTestBase { public CreateAircraftTests( - IntegrationTestFixture integrationTestFixture) : base( - integrationTestFixture) + IntegrationTestFactory integrationTestFactory) : base(integrationTestFactory) { } @@ -31,8 +30,8 @@ public class CreateAircraftTests : IntegrationTestBase(); + (await Fixture.WaitForPublishing()).Should().Be(true); - await Fixture.ShouldProcessedPersistInternalCommand(); + (await Fixture.ShouldProcessedPersistInternalCommand()).Should().Be(true); } } diff --git a/src/Services/Flight/tests/IntegrationTest/Airport/Features/CreateAirportTests.cs b/src/Services/Flight/tests/IntegrationTest/Airport/Features/CreateAirportTests.cs index 6d54704..53c0964 100644 --- a/src/Services/Flight/tests/IntegrationTest/Airport/Features/CreateAirportTests.cs +++ b/src/Services/Flight/tests/IntegrationTest/Airport/Features/CreateAirportTests.cs @@ -10,11 +10,10 @@ using Xunit; namespace Integration.Test.Airport.Features; -public class CreateAirportTests : IntegrationTestBase +public class CreateAirportTests : FlightIntegrationTestBase { public CreateAirportTests( - IntegrationTestFixture integrationTestFixture) : base( - integrationTestFixture) + IntegrationTestFactory integrationTestFactory) : base(integrationTestFactory) { } @@ -31,8 +30,8 @@ public class CreateAirportTests : IntegrationTestBase(); + (await Fixture.WaitForPublishing()).Should().Be(true); - await Fixture.ShouldProcessedPersistInternalCommand(); + (await Fixture.ShouldProcessedPersistInternalCommand()).Should().Be(true); } } diff --git a/src/Services/Flight/tests/IntegrationTest/Flight/Features/CreateFlightTests.cs b/src/Services/Flight/tests/IntegrationTest/Flight/Features/CreateFlightTests.cs index 8c9d092..0c52ea4 100644 --- a/src/Services/Flight/tests/IntegrationTest/Flight/Features/CreateFlightTests.cs +++ b/src/Services/Flight/tests/IntegrationTest/Flight/Features/CreateFlightTests.cs @@ -10,17 +10,17 @@ using Xunit; namespace Integration.Test.Flight.Features; -public class CreateFlightTests : IntegrationTestBase +public class CreateFlightTests : FlightIntegrationTestBase { public CreateFlightTests( - IntegrationTestFixture integrationTestFixture) : base( - integrationTestFixture) - { } + IntegrationTestFactory integrationTestFactory) : base(integrationTestFactory) + { + } [Fact] public async Task should_create_new_flight_to_db_and_publish_message_to_broker() { - // Arrange + //Arrange var command = new FakeCreateFlightCommand().Generate(); // Act @@ -30,9 +30,9 @@ public class CreateFlightTests : IntegrationTestBase(); - await Fixture.WaitForConsuming(); + (await Fixture.WaitForPublishing()).Should().Be(true); + (await Fixture.WaitForConsuming()).Should().Be(true); - await Fixture.ShouldProcessedPersistInternalCommand(); + (await Fixture.ShouldProcessedPersistInternalCommand()).Should().Be(true); } } diff --git a/src/Services/Flight/tests/IntegrationTest/Flight/Features/DeleteFlightTests.cs b/src/Services/Flight/tests/IntegrationTest/Flight/Features/DeleteFlightTests.cs index d5299f6..0242aa8 100644 --- a/src/Services/Flight/tests/IntegrationTest/Flight/Features/DeleteFlightTests.cs +++ b/src/Services/Flight/tests/IntegrationTest/Flight/Features/DeleteFlightTests.cs @@ -12,11 +12,10 @@ using Xunit; namespace Integration.Test.Flight.Features; -public class DeleteFlightTests : IntegrationTestBase +public class DeleteFlightTests : FlightIntegrationTestBase { public DeleteFlightTests( - IntegrationTestFixture integrationTestFixture) : base( - integrationTestFixture) + IntegrationTestFactory integrationTestFactory) : base(integrationTestFactory) { } @@ -38,8 +37,8 @@ public class DeleteFlightTests : IntegrationTestBase(); + (await Fixture.WaitForPublishing()).Should().Be(true); - await Fixture.ShouldProcessedPersistInternalCommand(); + (await Fixture.ShouldProcessedPersistInternalCommand()).Should().Be(true); } } diff --git a/src/Services/Flight/tests/IntegrationTest/Flight/Features/GetAvailableFlightsTests.cs b/src/Services/Flight/tests/IntegrationTest/Flight/Features/GetAvailableFlightsTests.cs index 293a16b..83b7c6f 100644 --- a/src/Services/Flight/tests/IntegrationTest/Flight/Features/GetAvailableFlightsTests.cs +++ b/src/Services/Flight/tests/IntegrationTest/Flight/Features/GetAvailableFlightsTests.cs @@ -11,11 +11,10 @@ using Xunit; namespace Integration.Test.Flight.Features; -public class GetAvailableFlightsTests : IntegrationTestBase +public class GetAvailableFlightsTests : FlightIntegrationTestBase { public GetAvailableFlightsTests( - IntegrationTestFixture integrationTestFixture) - : base(integrationTestFixture) + IntegrationTestFactory integrationTestFactory) : base(integrationTestFactory) { } @@ -27,7 +26,7 @@ public class GetAvailableFlightsTests : IntegrationTestBase(); + (await Fixture.ShouldProcessedPersistInternalCommand()).Should().Be(true); var query = new GetAvailableFlightsQuery(); diff --git a/src/Services/Flight/tests/IntegrationTest/Flight/Features/GetFlightByIdTests.cs b/src/Services/Flight/tests/IntegrationTest/Flight/Features/GetFlightByIdTests.cs index 1711133..39880ae 100644 --- a/src/Services/Flight/tests/IntegrationTest/Flight/Features/GetFlightByIdTests.cs +++ b/src/Services/Flight/tests/IntegrationTest/Flight/Features/GetFlightByIdTests.cs @@ -6,21 +6,16 @@ using Flight.Data; using Flight.Flights.Features.CreateFlight.Commands.V1.Reads; using Flight.Flights.Features.GetFlightById.Queries.V1; using FluentAssertions; -using Grpc.Net.Client; using Integration.Test.Fakes; using Xunit; namespace Integration.Test.Flight.Features; -public class GetFlightByIdTests : IntegrationTestBase +public class GetFlightByIdTests : FlightIntegrationTestBase { - private readonly GrpcChannel _channel; - public GetFlightByIdTests( - IntegrationTestFixture integrationTestFixture) : base( - integrationTestFixture) + IntegrationTestFactory integrationTestFactory) : base(integrationTestFactory) { - _channel = Fixture.Channel; } [Fact] @@ -30,7 +25,7 @@ public class GetFlightByIdTests : IntegrationTestBase(); + (await Fixture.ShouldProcessedPersistInternalCommand()).Should().Be(true); var query = new GetFlightByIdQuery(command.Id); @@ -49,9 +44,9 @@ public class GetFlightByIdTests : IntegrationTestBase(); + (await Fixture.ShouldProcessedPersistInternalCommand()).Should().Be(true); - var flightGrpcClient = new FlightGrpcService.FlightGrpcServiceClient(_channel); + var flightGrpcClient = new FlightGrpcService.FlightGrpcServiceClient(Fixture.Channel); // Act var response = await flightGrpcClient.GetByIdAsync(new GetByIdRequest {Id = command.Id}); diff --git a/src/Services/Flight/tests/IntegrationTest/Flight/Features/UpdateFlightTests.cs b/src/Services/Flight/tests/IntegrationTest/Flight/Features/UpdateFlightTests.cs index c794a81..18184d1 100644 --- a/src/Services/Flight/tests/IntegrationTest/Flight/Features/UpdateFlightTests.cs +++ b/src/Services/Flight/tests/IntegrationTest/Flight/Features/UpdateFlightTests.cs @@ -10,11 +10,10 @@ using Xunit; namespace Integration.Test.Flight.Features; -public class UpdateFlightTests : IntegrationTestBase +public class UpdateFlightTests : FlightIntegrationTestBase { public UpdateFlightTests( - IntegrationTestFixture integrationTestFixture) : base( - integrationTestFixture) + IntegrationTestFactory integrationTestFactory) : base(integrationTestFactory) { } @@ -33,8 +32,8 @@ public class UpdateFlightTests : IntegrationTestBase(); + (await Fixture.WaitForPublishing()).Should().Be(true); - await Fixture.ShouldProcessedPersistInternalCommand(); + (await Fixture.ShouldProcessedPersistInternalCommand()).Should().Be(true); } } diff --git a/src/Services/Flight/tests/IntegrationTest/FlightIntegrationTestBase.cs b/src/Services/Flight/tests/IntegrationTest/FlightIntegrationTestBase.cs new file mode 100644 index 0000000..6743eb7 --- /dev/null +++ b/src/Services/Flight/tests/IntegrationTest/FlightIntegrationTestBase.cs @@ -0,0 +1,20 @@ +using BuildingBlocks.TestBase; +using Flight.Api; +using Flight.Data; +using Xunit; + +namespace Integration.Test; + +[Collection(IntegrationTestCollection.Name)] +public class FlightIntegrationTestBase: IntegrationTestBase +{ + public FlightIntegrationTestBase(IntegrationTestFactory integrationTestFixture) : base(integrationTestFixture) + { + } +} + +[CollectionDefinition(Name)] +public class IntegrationTestCollection : ICollectionFixture> +{ + public const string Name = "Flight Integration Test"; +} diff --git a/src/Services/Flight/tests/IntegrationTest/Seat/Features/GetAvailableSeatsTests.cs b/src/Services/Flight/tests/IntegrationTest/Seat/Features/GetAvailableSeatsTests.cs index 7276158..05e671b 100644 --- a/src/Services/Flight/tests/IntegrationTest/Seat/Features/GetAvailableSeatsTests.cs +++ b/src/Services/Flight/tests/IntegrationTest/Seat/Features/GetAvailableSeatsTests.cs @@ -6,19 +6,16 @@ using Flight.Data; using Flight.Flights.Features.CreateFlight.Commands.V1.Reads; using Flight.Seats.Features.CreateSeat.Commands.V1.Reads; using FluentAssertions; -using Grpc.Net.Client; using Integration.Test.Fakes; using Xunit; namespace Integration.Test.Seat.Features; -public class GetAvailableSeatsTests : IntegrationTestBase +public class GetAvailableSeatsTests : FlightIntegrationTestBase { - private readonly GrpcChannel _channel; - - public GetAvailableSeatsTests(IntegrationTestFixture integrationTestFixture) : base(integrationTestFixture) + public GetAvailableSeatsTests( + IntegrationTestFactory integrationTestFactory) : base(integrationTestFactory) { - _channel = Fixture.Channel; } [Fact] @@ -29,15 +26,15 @@ public class GetAvailableSeatsTests : IntegrationTestBase(); + (await Fixture.ShouldProcessedPersistInternalCommand()).Should().Be(true); var seatCommand = new FakeCreateSeatCommand(flightCommand.Id).Generate(); await Fixture.SendAsync(seatCommand); - await Fixture.ShouldProcessedPersistInternalCommand(); + (await Fixture.ShouldProcessedPersistInternalCommand()).Should().Be(true); - var flightGrpcClient = new FlightGrpcService.FlightGrpcServiceClient(_channel); + var flightGrpcClient = new FlightGrpcService.FlightGrpcServiceClient(Fixture.Channel); // Act var response = await flightGrpcClient.GetAvailableSeatsAsync(new GetAvailableSeatsRequest{FlightId = flightCommand.Id}); diff --git a/src/Services/Flight/tests/IntegrationTest/Seat/Features/ReserveSeatTests.cs b/src/Services/Flight/tests/IntegrationTest/Seat/Features/ReserveSeatTests.cs index be2da07..b6c6ce9 100644 --- a/src/Services/Flight/tests/IntegrationTest/Seat/Features/ReserveSeatTests.cs +++ b/src/Services/Flight/tests/IntegrationTest/Seat/Features/ReserveSeatTests.cs @@ -6,21 +6,16 @@ using Flight.Data; using Flight.Flights.Features.CreateFlight.Commands.V1.Reads; using Flight.Seats.Features.CreateSeat.Commands.V1.Reads; using FluentAssertions; -using Grpc.Net.Client; using Integration.Test.Fakes; using Xunit; namespace Integration.Test.Seat.Features; -public class ReserveSeatTests : IntegrationTestBase +public class ReserveSeatTests : FlightIntegrationTestBase { - private readonly GrpcChannel _channel; - public ReserveSeatTests( - IntegrationTestFixture integrationTestFixture) : base( - integrationTestFixture) + IntegrationTestFactory integrationTestFactory) : base(integrationTestFactory) { - _channel = Fixture.Channel; } [Fact] @@ -31,15 +26,15 @@ public class ReserveSeatTests : IntegrationTestBase(); + (await Fixture.ShouldProcessedPersistInternalCommand()).Should().Be(true); var seatCommand = new FakeCreateSeatCommand(flightCommand.Id).Generate(); await Fixture.SendAsync(seatCommand); - await Fixture.ShouldProcessedPersistInternalCommand(); + (await Fixture.ShouldProcessedPersistInternalCommand()).Should().Be(true); - var flightGrpcClient = new FlightGrpcService.FlightGrpcServiceClient(_channel); + var flightGrpcClient = new FlightGrpcService.FlightGrpcServiceClient(Fixture.Channel); // Act var response = await flightGrpcClient.ReserveSeatAsync(new ReserveSeatRequest() diff --git a/src/Services/Identity/src/Identity.Api/appsettings.docker.json b/src/Services/Identity/src/Identity.Api/appsettings.docker.json index 1423441..f05529b 100644 --- a/src/Services/Identity/src/Identity.Api/appsettings.docker.json +++ b/src/Services/Identity/src/Identity.Api/appsettings.docker.json @@ -3,6 +3,11 @@ "DatabaseOptions": { "DefaultConnection": "Server=db;Database=IdentityDB;User ID=sa;Password=@Aa123456" }, + "PersistMessageOptions": { + "Interval": 30, + "Enabled": true, + "ConnectionString": "Server=db;Database=PersistMessageDB;User ID=sa;Password=@Aa123456" + }, "RabbitMqOptions": { "HostName": "rabbitmq", "ExchangeName": "identity", diff --git a/src/Services/Identity/src/Identity.Api/appsettings.json b/src/Services/Identity/src/Identity.Api/appsettings.json index 75bd768..b76b8e3 100644 --- a/src/Services/Identity/src/Identity.Api/appsettings.json +++ b/src/Services/Identity/src/Identity.Api/appsettings.json @@ -31,7 +31,8 @@ }, "PersistMessageOptions": { "Interval": 30, - "Enabled": true + "Enabled": true, + "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=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 a434a7c..08307a2 100644 --- a/src/Services/Identity/src/Identity.Api/appsettings.test.json +++ b/src/Services/Identity/src/Identity.Api/appsettings.test.json @@ -18,7 +18,8 @@ } }, "PersistMessageOptions": { - "Interval": 1, - "Enabled": true + "Interval": 30, + "Enabled": true, + "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" } } diff --git a/src/Services/Identity/src/Identity/Data/Configurations/PersistMessageConfiguration.cs b/src/Services/Identity/src/Identity/Data/Configurations/PersistMessageConfiguration.cs deleted file mode 100644 index 18c7c3b..0000000 --- a/src/Services/Identity/src/Identity/Data/Configurations/PersistMessageConfiguration.cs +++ /dev/null @@ -1,44 +0,0 @@ -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/Migrations/20221203211306_initial.Designer.cs b/src/Services/Identity/src/Identity/Data/Migrations/20221206180831_initial.Designer.cs similarity index 88% rename from src/Services/Identity/src/Identity/Data/Migrations/20221203211306_initial.Designer.cs rename to src/Services/Identity/src/Identity/Data/Migrations/20221206180831_initial.Designer.cs index 4a30d4a..8f9e108 100644 --- a/src/Services/Identity/src/Identity/Data/Migrations/20221203211306_initial.Designer.cs +++ b/src/Services/Identity/src/Identity/Data/Migrations/20221206180831_initial.Designer.cs @@ -12,7 +12,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace Identity.Data.Migrations { [DbContext(typeof(IdentityContext))] - [Migration("20221203211306_initial")] + [Migration("20221206180831_initial")] partial class initial { /// @@ -25,43 +25,6 @@ namespace Identity.Data.Migrations 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 => { b.Property("Id") diff --git a/src/Services/Identity/src/Identity/Data/Migrations/20221203211306_initial.cs b/src/Services/Identity/src/Identity/Data/Migrations/20221206180831_initial.cs similarity index 90% rename from src/Services/Identity/src/Identity/Data/Migrations/20221203211306_initial.cs rename to src/Services/Identity/src/Identity/Data/Migrations/20221206180831_initial.cs index df434c0..1c533e3 100644 --- a/src/Services/Identity/src/Identity/Data/Migrations/20221203211306_initial.cs +++ b/src/Services/Identity/src/Identity/Data/Migrations/20221206180831_initial.cs @@ -60,25 +60,6 @@ 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", @@ -266,10 +247,6 @@ namespace Identity.Data.Migrations name: "AspNetUserTokens", schema: "dbo"); - migrationBuilder.DropTable( - name: "PersistMessage", - schema: "dbo"); - migrationBuilder.DropTable( name: "AspNetRoles", 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 73f4b8d..fdf3fdf 100644 --- a/src/Services/Identity/src/Identity/Data/Migrations/IdentityContextModelSnapshot.cs +++ b/src/Services/Identity/src/Identity/Data/Migrations/IdentityContextModelSnapshot.cs @@ -22,43 +22,6 @@ namespace Identity.Data.Migrations 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 => { b.Property("Id") diff --git a/src/Services/Identity/src/Identity/Extensions/Infrastructure/InfrastructureExtensions.cs b/src/Services/Identity/src/Identity/Extensions/Infrastructure/InfrastructureExtensions.cs index 84886ee..4737933 100644 --- a/src/Services/Identity/src/Identity/Extensions/Infrastructure/InfrastructureExtensions.cs +++ b/src/Services/Identity/src/Identity/Extensions/Infrastructure/InfrastructureExtensions.cs @@ -57,7 +57,7 @@ public static class InfrastructureExtensions builder.Services.AddControllers(); builder.Services.AddPersistMessageProcessor(); - builder.Services.AddCustomDbContext(configuration); + builder.Services.AddCustomDbContext(); builder.Services.AddScoped(); builder.AddCustomSerilog(env); builder.Services.AddCustomSwagger(configuration, typeof(IdentityRoot).Assembly); diff --git a/src/Services/Identity/src/Identity/Identity.csproj b/src/Services/Identity/src/Identity/Identity.csproj index 57491c9..a5f9f70 100644 --- a/src/Services/Identity/src/Identity/Identity.csproj +++ b/src/Services/Identity/src/Identity/Identity.csproj @@ -16,6 +16,7 @@ + diff --git a/src/Services/Identity/tests/IntegrationTest/Identity/Features/RegisterNewUserTests.cs b/src/Services/Identity/tests/IntegrationTest/Identity/Features/RegisterNewUserTests.cs index c7386f3..374d9b4 100644 --- a/src/Services/Identity/tests/IntegrationTest/Identity/Features/RegisterNewUserTests.cs +++ b/src/Services/Identity/tests/IntegrationTest/Identity/Features/RegisterNewUserTests.cs @@ -5,16 +5,14 @@ using FluentAssertions; using Identity.Api; using Identity.Data; using Integration.Test.Fakes; -using MassTransit; -using MassTransit.Testing; using Xunit; namespace Integration.Test.Identity.Features; -public class RegisterNewUserTests : IntegrationTestBase +public class RegisterNewUserTests : IdentityIntegrationTestBase { - public RegisterNewUserTests(IntegrationTestFixture integrationTestFixture) : base( - integrationTestFixture) + public RegisterNewUserTests( + IntegrationTestFactory integrationTestFactory) : base(integrationTestFactory) { } @@ -31,6 +29,6 @@ public class RegisterNewUserTests : IntegrationTestBase(); + (await Fixture.WaitForPublishing()).Should().Be(true); } } diff --git a/src/Services/Identity/tests/IntegrationTest/IdentityIntegrationTestBase.cs b/src/Services/Identity/tests/IntegrationTest/IdentityIntegrationTestBase.cs new file mode 100644 index 0000000..61df267 --- /dev/null +++ b/src/Services/Identity/tests/IntegrationTest/IdentityIntegrationTestBase.cs @@ -0,0 +1,21 @@ +using BuildingBlocks.TestBase; +using Identity.Api; +using Identity.Data; +using Xunit; + +namespace Integration.Test; + +[Collection(IntegrationTestCollection.Name)] +public class IdentityIntegrationTestBase: IntegrationTestBase +{ + public IdentityIntegrationTestBase(IntegrationTestFactory integrationTestFactory) + : base(integrationTestFactory) + { + } +} + +[CollectionDefinition(Name)] +public class IntegrationTestCollection : ICollectionFixture> +{ + public const string Name = "Identity Integration Test"; +} diff --git a/src/Services/Passenger/src/Passenger.Api/appsettings.docker.json b/src/Services/Passenger/src/Passenger.Api/appsettings.docker.json index 0b29709..2af01bc 100644 --- a/src/Services/Passenger/src/Passenger.Api/appsettings.docker.json +++ b/src/Services/Passenger/src/Passenger.Api/appsettings.docker.json @@ -3,6 +3,11 @@ "DatabaseOptions": { "DefaultConnection": "Server=db;Database=PassengerDB;User ID=sa;Password=@Aa123456" }, + "PersistMessageOptions": { + "Interval": 30, + "Enabled": true, + "ConnectionString": "Server=db;Database=PersistMessageDB;User ID=sa;Password=@Aa123456" + }, "Jwt": { "Authority": "https://localhost:5005", "Audience": "passenger-api" diff --git a/src/Services/Passenger/src/Passenger.Api/appsettings.json b/src/Services/Passenger/src/Passenger.Api/appsettings.json index 3726597..d7cbb30 100644 --- a/src/Services/Passenger/src/Passenger.Api/appsettings.json +++ b/src/Services/Passenger/src/Passenger.Api/appsettings.json @@ -35,7 +35,8 @@ }, "PersistMessageOptions": { "Interval": 30, - "Enabled": true + "Enabled": true, + "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=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 5df0a35..194eb82 100644 --- a/src/Services/Passenger/src/Passenger.Api/appsettings.test.json +++ b/src/Services/Passenger/src/Passenger.Api/appsettings.test.json @@ -18,7 +18,8 @@ } }, "PersistMessageOptions": { - "Interval": 1, - "Enabled": true + "Interval": 30, + "Enabled": true, + "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" } } diff --git a/src/Services/Passenger/src/Passenger/Data/Migrations/20221203211633_initial.Designer.cs b/src/Services/Passenger/src/Passenger/Data/Migrations/20221206180929_initial.Designer.cs similarity index 61% rename from src/Services/Passenger/src/Passenger/Data/Migrations/20221203211633_initial.Designer.cs rename to src/Services/Passenger/src/Passenger/Data/Migrations/20221206180929_initial.Designer.cs index 0a67156..64ec17a 100644 --- a/src/Services/Passenger/src/Passenger/Data/Migrations/20221203211633_initial.Designer.cs +++ b/src/Services/Passenger/src/Passenger/Data/Migrations/20221206180929_initial.Designer.cs @@ -12,7 +12,7 @@ using Passenger.Data; namespace Passenger.Data.Migrations { [DbContext(typeof(PassengerDbContext))] - [Migration("20221203211633_initial")] + [Migration("20221206180929_initial")] partial class initial { /// @@ -25,43 +25,6 @@ namespace Passenger.Data.Migrations 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 => { b.Property("Id") diff --git a/src/Services/Passenger/src/Passenger/Data/Migrations/20221203211633_initial.cs b/src/Services/Passenger/src/Passenger/Data/Migrations/20221206180929_initial.cs similarity index 61% rename from src/Services/Passenger/src/Passenger/Data/Migrations/20221203211633_initial.cs rename to src/Services/Passenger/src/Passenger/Data/Migrations/20221206180929_initial.cs index 121afb4..8730fb3 100644 --- a/src/Services/Passenger/src/Passenger/Data/Migrations/20221203211633_initial.cs +++ b/src/Services/Passenger/src/Passenger/Data/Migrations/20221206180929_initial.cs @@ -35,25 +35,6 @@ 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); - }); } /// @@ -62,10 +43,6 @@ namespace Passenger.Data.Migrations 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 aba9f86..c5bb3b6 100644 --- a/src/Services/Passenger/src/Passenger/Data/Migrations/PassengerDbContextModelSnapshot.cs +++ b/src/Services/Passenger/src/Passenger/Data/Migrations/PassengerDbContextModelSnapshot.cs @@ -22,43 +22,6 @@ namespace Passenger.Data.Migrations 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 => { b.Property("Id") diff --git a/src/Services/Passenger/src/Passenger/Data/PassengerDbContext.cs b/src/Services/Passenger/src/Passenger/Data/PassengerDbContext.cs index 7a80a04..f0bfd18 100644 --- a/src/Services/Passenger/src/Passenger/Data/PassengerDbContext.cs +++ b/src/Services/Passenger/src/Passenger/Data/PassengerDbContext.cs @@ -1,15 +1,12 @@ using System.Reflection; using BuildingBlocks.EFCore; -using BuildingBlocks.Utils; -using Microsoft.AspNetCore.Http; +using BuildingBlocks.Web; using Microsoft.EntityFrameworkCore; namespace Passenger.Data; public sealed class PassengerDbContext : AppDbContextBase { - public const string DefaultSchema = "dbo"; - public PassengerDbContext(DbContextOptions options, ICurrentUserProvider currentUserProvider) : base(options, currentUserProvider) { } diff --git a/src/Services/Passenger/src/Passenger/Extensions/Infrastructure/InfrastructureExtensions.cs b/src/Services/Passenger/src/Passenger/Extensions/Infrastructure/InfrastructureExtensions.cs index 4b91048..f902d7a 100644 --- a/src/Services/Passenger/src/Passenger/Extensions/Infrastructure/InfrastructureExtensions.cs +++ b/src/Services/Passenger/src/Passenger/Extensions/Infrastructure/InfrastructureExtensions.cs @@ -60,7 +60,7 @@ public static class InfrastructureExtensions }); builder.Services.AddPersistMessageProcessor(); - builder.Services.AddCustomDbContext(configuration); + builder.Services.AddCustomDbContext(); builder.Services.AddMongoDbContext(configuration); builder.AddCustomSerilog(env); diff --git a/src/Services/Passenger/tests/IntegrationTest/Fakes/FakeUserCreated.cs b/src/Services/Passenger/tests/IntegrationTest/Fakes/FakeUserCreated.cs index f53739e..0ff69d0 100644 --- a/src/Services/Passenger/tests/IntegrationTest/Fakes/FakeUserCreated.cs +++ b/src/Services/Passenger/tests/IntegrationTest/Fakes/FakeUserCreated.cs @@ -9,7 +9,7 @@ public class FakeUserCreated : AutoFaker public FakeUserCreated() { RuleFor(r => r.Id, _ => SnowFlakIdGenerator.NewId()); - RuleFor(r => r.Name, _ => "Meysam"); - RuleFor(r => r.PassportNumber, _ => "1299878"); + RuleFor(r => r.Name, _ => "Sam"); + RuleFor(r => r.PassportNumber, _ => "123456789"); } } diff --git a/src/Services/Passenger/tests/IntegrationTest/Passenger/Features/CompleteRegisterPassengerTests.cs b/src/Services/Passenger/tests/IntegrationTest/Passenger/Features/CompleteRegisterPassengerTests.cs index fd22476..41879c9 100644 --- a/src/Services/Passenger/tests/IntegrationTest/Passenger/Features/CompleteRegisterPassengerTests.cs +++ b/src/Services/Passenger/tests/IntegrationTest/Passenger/Features/CompleteRegisterPassengerTests.cs @@ -3,18 +3,16 @@ using BuildingBlocks.Contracts.EventBus.Messages; using BuildingBlocks.TestBase; using FluentAssertions; using Integration.Test.Fakes; -using MassTransit.Testing; using Passenger.Api; using Passenger.Data; -using Passenger.Passengers.Features.CompleteRegisterPassenger.Commands.V1.Reads; using Xunit; namespace Integration.Test.Passenger.Features; -public class CompleteRegisterPassengerTests : IntegrationTestBase +public class CompleteRegisterPassengerTests : PassengerIntegrationTestBase { - public CompleteRegisterPassengerTests(IntegrationTestFixture integrationTestFixture) : - base(integrationTestFixture) + public CompleteRegisterPassengerTests( + IntegrationTestFactory integrationTestFactory) : base(integrationTestFactory) { } diff --git a/src/Services/Passenger/tests/IntegrationTest/Passenger/Features/GetPassengerByIdTests.cs b/src/Services/Passenger/tests/IntegrationTest/Passenger/Features/GetPassengerByIdTests.cs index 1758051..dec0350 100644 --- a/src/Services/Passenger/tests/IntegrationTest/Passenger/Features/GetPassengerByIdTests.cs +++ b/src/Services/Passenger/tests/IntegrationTest/Passenger/Features/GetPassengerByIdTests.cs @@ -1,11 +1,7 @@ using System.Threading.Tasks; -using BuildingBlocks.Contracts.EventBus.Messages; using BuildingBlocks.TestBase; using FluentAssertions; -using Grpc.Net.Client; using Integration.Test.Fakes; -using MassTransit.Testing; -using Microsoft.Extensions.DependencyInjection; using Passenger; using Passenger.Api; using Passenger.Data; @@ -14,17 +10,13 @@ using Xunit; namespace Integration.Test.Passenger.Features; -public class GetPassengerByIdTests : IntegrationTestBase +public class GetPassengerByIdTests : PassengerIntegrationTestBase { - private readonly GrpcChannel _channel; - - public GetPassengerByIdTests(IntegrationTestFixture integrationTestFixture) : base( - integrationTestFixture) + public GetPassengerByIdTests( + IntegrationTestFactory integrationTestFactory) : base(integrationTestFactory) { - _channel = Fixture.Channel; } - [Fact] public async Task should_retrive_a_passenger_by_id_currectly() { @@ -53,7 +45,7 @@ public class GetPassengerByIdTests : IntegrationTestBase +{ + public PassengerIntegrationTestBase(IntegrationTestFactory integrationTestFactory) + : base(integrationTestFactory) + { + } +} + +[CollectionDefinition(Name)] +public class IntegrationTestCollection : ICollectionFixture> +{ + public const string Name = "Passenger Integration Test"; +}