diff --git a/deployments/docker-compose/docker-compose.yaml b/deployments/docker-compose/docker-compose.yaml index e61ddf5..e2f1632 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,29 +229,29 @@ 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 ####################################################### # Mongo ####################################################### mongo: - image: mongo + image: mongo:4 container_name: mongo restart: unless-stopped # environment: @@ -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..2558920 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 ####################################################### @@ -76,7 +91,7 @@ services: # Mongo ####################################################### mongo: - image: mongo + image: mongo:4 container_name: mongo restart: unless-stopped # environment: @@ -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..e773b06 100644 --- a/src/BuildingBlocks/BuildingBlocks.csproj +++ b/src/BuildingBlocks/BuildingBlocks.csproj @@ -20,6 +20,7 @@ + @@ -27,6 +28,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + @@ -123,7 +128,7 @@ - + @@ -145,6 +150,7 @@ + diff --git a/src/BuildingBlocks/EFCore/AppDbContextBase.cs b/src/BuildingBlocks/EFCore/AppDbContextBase.cs index 9a0852a..a2719ec 100644 --- a/src/BuildingBlocks/EFCore/AppDbContextBase.cs +++ b/src/BuildingBlocks/EFCore/AppDbContextBase.cs @@ -3,7 +3,7 @@ using System.Data; using BuildingBlocks.Core.Event; using BuildingBlocks.Core.Model; using BuildingBlocks.Utils; -using JetBrains.Annotations; +using BuildingBlocks.Web; 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; @@ -117,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/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..b3474e2 100644 --- a/src/BuildingBlocks/EFCore/Extensions.cs +++ b/src/BuildingBlocks/EFCore/Extensions.cs @@ -1,11 +1,11 @@ using System.Linq.Expressions; using BuildingBlocks.Core.Model; 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; @@ -14,18 +14,24 @@ 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(ConnectionStrings))) + + services.AddOptions() + .BindConfiguration(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()); diff --git a/src/BuildingBlocks/EFCore/IDbContext.cs b/src/BuildingBlocks/EFCore/IDbContext.cs index 186d1b2..af53ad3 100644 --- a/src/BuildingBlocks/EFCore/IDbContext.cs +++ b/src/BuildingBlocks/EFCore/IDbContext.cs @@ -5,9 +5,7 @@ namespace BuildingBlocks.EFCore; public interface IDbContext { - DbSet Set() - where TEntity : class; - + DbSet Set() where TEntity : class; IReadOnlyList GetDomainEvents(); Task BeginTransactionAsync(CancellationToken cancellationToken = default); Task CommitTransactionAsync(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..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 => @@ -46,13 +50,14 @@ 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 => { - 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/BuildingBlocks/PersistMessageProcessor/Data/Configurations/PersistMessageConfiguration.cs b/src/BuildingBlocks/PersistMessageProcessor/Data/Configurations/PersistMessageConfiguration.cs index 60d2566..18c1281 100644 --- a/src/BuildingBlocks/PersistMessageProcessor/Data/Configurations/PersistMessageConfiguration.cs +++ b/src/BuildingBlocks/PersistMessageProcessor/Data/Configurations/PersistMessageConfiguration.cs @@ -1,4 +1,5 @@ -using Microsoft.EntityFrameworkCore; +using BuildingBlocks.EFCore; +using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; namespace BuildingBlocks.PersistMessageProcessor.Data.Configurations; @@ -7,12 +8,12 @@ public class PersistMessageConfiguration : IEntityTypeConfiguration builder) { - builder.ToTable("PersistMessage", PersistMessageDbContext.DefaultSchema); + builder.ToTable("PersistMessage", AppDbContextBase.DefaultSchema); builder.HasKey(x => 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 index 538c51f..91a4279 100644 --- a/src/BuildingBlocks/PersistMessageProcessor/Data/DesignTimeDbContextFactory.cs +++ b/src/BuildingBlocks/PersistMessageProcessor/Data/DesignTimeDbContextFactory.cs @@ -1,4 +1,4 @@ -using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Design; namespace BuildingBlocks.PersistMessageProcessor.Data; @@ -10,7 +10,7 @@ public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory(); builder.UseSqlServer( - "Data Source=.\\sqlexpress;Initial Catalog=PersistMessageDB;Persist Security Info=False;Integrated Security=SSPI"); + "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/20220728155556_initial.Designer.cs b/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20221206184130_initial.Designer.cs similarity index 79% rename from src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20220728155556_initial.Designer.cs rename to src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20221206184130_initial.Designer.cs index fbe223d..4d44436 100644 --- a/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20220728155556_initial.Designer.cs +++ b/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20221206184130_initial.Designer.cs @@ -1,6 +1,5 @@ // using System; -using Booking.Data; using BuildingBlocks.PersistMessageProcessor.Data; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; @@ -10,30 +9,26 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; #nullable disable -namespace Booking.Data.Migrations +namespace BuildingBlocks.PersistMessageProcessor.Data.Migrations { [DbContext(typeof(PersistMessageDbContext))] - [Migration("20220728155556_initial")] + [Migration("20221206184130_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("uniqueidentifier"); - - b.Property("ApplicationName") - .IsRequired() - .HasColumnType("nvarchar(max)"); + b.Property("Id") + .HasColumnType("bigint"); b.Property("Created") .HasColumnType("datetime2"); diff --git a/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20220728155556_initial.cs b/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20221206184130_initial.cs similarity index 91% rename from src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20220728155556_initial.cs rename to src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20221206184130_initial.cs index b2ddd42..3d3f92b 100644 --- a/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20220728155556_initial.cs +++ b/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/20221206184130_initial.cs @@ -3,10 +3,12 @@ using Microsoft.EntityFrameworkCore.Migrations; #nullable disable -namespace Booking.Data.Migrations +namespace BuildingBlocks.PersistMessageProcessor.Data.Migrations { + /// public partial class initial : Migration { + /// protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.EnsureSchema( @@ -31,6 +33,7 @@ namespace Booking.Data.Migrations }); } + /// protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable( diff --git a/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/PersistMessageDbContextModelSnapshot.cs b/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/PersistMessageDbContextModelSnapshot.cs index 5c56774..df9a1fb 100644 --- a/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/PersistMessageDbContextModelSnapshot.cs +++ b/src/BuildingBlocks/PersistMessageProcessor/Data/Migrations/PersistMessageDbContextModelSnapshot.cs @@ -1,6 +1,5 @@ // using System; -using Booking.Data; using BuildingBlocks.PersistMessageProcessor.Data; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; @@ -9,7 +8,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; #nullable disable -namespace Booking.Data.Migrations +namespace BuildingBlocks.PersistMessageProcessor.Data.Migrations { [DbContext(typeof(PersistMessageDbContext))] partial class PersistMessageDbContextModelSnapshot : ModelSnapshot @@ -18,15 +17,14 @@ namespace Booking.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"); b.Property("Created") diff --git a/src/BuildingBlocks/PersistMessageProcessor/Data/PersistMessageDbContext.cs b/src/BuildingBlocks/PersistMessageProcessor/Data/PersistMessageDbContext.cs index 8aa3528..19d94b7 100644 --- a/src/BuildingBlocks/PersistMessageProcessor/Data/PersistMessageDbContext.cs +++ b/src/BuildingBlocks/PersistMessageProcessor/Data/PersistMessageDbContext.cs @@ -1,15 +1,11 @@ -using BuildingBlocks.EFCore; +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) { diff --git a/src/BuildingBlocks/PersistMessageProcessor/Data/readme.md b/src/BuildingBlocks/PersistMessageProcessor/Data/readme.md index b7f4097..062e4d3 100644 --- a/src/BuildingBlocks/PersistMessageProcessor/Data/readme.md +++ b/src/BuildingBlocks/PersistMessageProcessor/Data/readme.md @@ -1,2 +1,2 @@ -dotnet ef migrations add initial --context PersistMessageDbContext -o "Data\Migrations" +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 2a6b0f5..b30b68d 100644 --- a/src/BuildingBlocks/PersistMessageProcessor/Extensions.cs +++ b/src/BuildingBlocks/PersistMessageProcessor/Extensions.cs @@ -1,25 +1,25 @@ -using BuildingBlocks.Core; -using BuildingBlocks.PersistMessageProcessor.Data; +using BuildingBlocks.PersistMessageProcessor.Data; using BuildingBlocks.Web; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; 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))) + .BindConfiguration(nameof(PersistMessageOptions)) .ValidateDataAnnotations(); - var persistMessageOptions = services.GetOptions("PersistMessageOptions"); - services.AddDbContext(options => + { + var persistMessageOptions = services.GetOptions(nameof(PersistMessageOptions)); + options.UseSqlServer(persistMessageOptions.ConnectionString, - x => x.MigrationsAssembly(typeof(PersistMessageDbContext).Assembly.GetName().Name))); + x => x.MigrationsAssembly(typeof(PersistMessageDbContext).Assembly.GetName().Name)); + }); services.AddScoped(provider => provider.GetService()); 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/TestBase/IntegrationTestBase.cs b/src/BuildingBlocks/TestBase/IntegrationTestBase.cs index 83dd3fc..2afdc07 100644 --- a/src/BuildingBlocks/TestBase/IntegrationTestBase.cs +++ b/src/BuildingBlocks/TestBase/IntegrationTestBase.cs @@ -7,6 +7,7 @@ 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; @@ -14,46 +15,49 @@ 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; using Microsoft.Extensions.Options; -using Mongo2Go; +using MongoDB.Driver; using NSubstitute; using Respawn; +using Respawn.Graph; using Serilog; using Xunit; using Xunit.Abstractions; namespace BuildingBlocks.TestBase; -public class IntegrationTestFixture : IDisposable +public class IntegrationTestFactory : IAsyncLifetime where TEntryPoint : class { private readonly WebApplicationFactory _factory; + private int Timeout => 120; // Second + public MsSqlTestcontainer MsSqlTestContainer; + public MsSqlTestcontainer MsSqlPersistTestContainer; + public RabbitMqTestcontainer RabbitMqTestContainer; + public MongoDbTestcontainer MongoDbTestContainer; - private int Timeout => 60; // Second - private ITestHarness TestHarness => ServiceProvider.GetTestHarness(); - public HttpClient HttpClient => _factory.CreateClient(); + 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 IServiceProvider ServiceProvider => _factory?.Services; + public IConfiguration Configuration => _factory?.Services.GetRequiredService(); + public ILogger Logger { get; set; } - public MsSqlTestcontainer SqlTestContainer; - public MsSqlTestcontainer SqlPersistTestContainer; - public MongoDbTestcontainer MongoTestContainer; - public RabbitMqTestcontainer RabbitMqTestContainer; - - public IntegrationTestFixture() + public IntegrationTestFactory() { _factory = new WebApplicationFactory() .WithWebHostBuilder(builder => { + builder.ConfigureAppConfiguration(AddCustomAppSettings); + builder.UseEnvironment("test"); builder.ConfigureServices(services => { @@ -63,9 +67,15 @@ public class IntegrationTestFixture : IDisposable }); } - 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) @@ -127,32 +137,35 @@ public class IntegrationTestFixture : IDisposable 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; @@ -161,18 +174,20 @@ public class IntegrationTestFixture : IDisposable 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 => { @@ -188,13 +203,52 @@ public class IntegrationTestFixture : IDisposable 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) + { + 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("MongoOptions:ConnectionString", MongoDbTestContainer.ConnectionString), + new("MongoOptions:DatabaseName", MongoDbTestContainer.Database) + }); } 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"; @@ -203,7 +257,7 @@ public class IntegrationTestFixture : IDisposable } } -public class IntegrationTestFixture : IntegrationTestFixture +public class IntegrationTestFactory : IntegrationTestFactory where TEntryPoint : class where TWContext : DbContext { @@ -310,7 +364,7 @@ public class IntegrationTestFixture : IntegrationTestFix } } -public class IntegrationTestFixture : IntegrationTestFixture +public class IntegrationTestFactory : IntegrationTestFactory where TEntryPoint : class where TWContext : DbContext where TRContext : MongoDbContext @@ -329,106 +383,100 @@ public class IntegrationTestFixture : Integra public class IntegrationTestFixtureCore : IAsyncLifetime where TEntryPoint : class { - private Checkpoint _checkpointDefaultDB; - private Checkpoint _checkpointPersistMessageDB; - private MongoDbRunner _mongoRunner; + private Respawner _reSpawnerDefaultDb; + private Respawner _reSpawnerPersistDb; + private SqlConnection DefaultDbConnection { get; set; } + private SqlConnection PersistDbConnection { get; set; } - 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) + 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() { - _checkpointDefaultDB = new Checkpoint {TablesToIgnore = new[] {"__EFMigrationsHistory"}}; - _checkpointPersistMessageDB = new Checkpoint {TablesToIgnore = new[] {"__EFMigrationsHistory"}}; + var databaseOptions = Fixture.ServiceProvider.GetRequiredService>()?.Value; + var persistOptions = Fixture.ServiceProvider.GetRequiredService>()?.Value; - if (!string.IsNullOrEmpty(DefaultConnectionString)) - await _checkpointDefaultDB.Reset(DefaultConnectionString); + if (!string.IsNullOrEmpty(persistOptions?.ConnectionString)) + { + PersistDbConnection = new SqlConnection(persistOptions?.ConnectionString); + await PersistDbConnection.OpenAsync(); - if (!string.IsNullOrEmpty(PersistConnectionString)) - await _checkpointPersistMessageDB.Reset(PersistConnectionString); + _reSpawnerPersistDb = await Respawner.CreateAsync(PersistDbConnection, + new RespawnerOptions { TablesToIgnore = new Table[] { "__EFMigrationsHistory" }, }); - _mongoRunner = MongoDbRunner.Start(); + await _reSpawnerPersistDb.ResetAsync(PersistDbConnection); + } - if (MongoConnectionString != null) - MongoConnectionString = _mongoRunner.ConnectionString; + if (!string.IsNullOrEmpty(databaseOptions?.DefaultConnection)) + { + DefaultDbConnection = new SqlConnection(databaseOptions.DefaultConnection); + await DefaultDbConnection.OpenAsync(); - //await StartTestContainerAsync(); + _reSpawnerDefaultDb = await Respawner.CreateAsync(DefaultDbConnection, + new RespawnerOptions { TablesToIgnore = new Table[] { "__EFMigrationsHistory" }, }); - await SeedDataAsync(); + await _reSpawnerDefaultDb.ResetAsync(DefaultDbConnection); + + await SeedDataAsync(); + } } public async Task DisposeAsync() { - if (!string.IsNullOrEmpty(PersistConnectionString)) - _mongoRunner.Dispose(); + await ResetMongoAsync(); + await ResetRabbitMqAsync(); + } - //await StopTestContainerAsync(); + 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) { } - 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(); @@ -438,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 0044487..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; @@ -6,34 +7,52 @@ 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") + .WithCleanUp(true) .Build(); - public static MsSqlTestcontainer SqlPersistTestContainer => new TestcontainersBuilder() - .WithDatabase(new MsSqlTestcontainerConfiguration + + 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") + .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(); + + public static MongoDbTestcontainer MongoTestContainer => new TestcontainersBuilder() .WithDatabase(new MongoDbTestcontainerConfiguration() { 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() { @@ -41,5 +60,10 @@ public static class TestContainers 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 c1d2f8f..06769cf 100644 --- a/src/Services/Booking/src/Booking.Api/appsettings.docker.json +++ b/src/Services/Booking/src/Booking.Api/appsettings.docker.json @@ -6,7 +6,12 @@ "Microsoft.AspNetCore": "Warning" } }, - "RabbitMq": { + "PersistMessageOptions": { + "Interval": 30, + "Enabled": true, + "ConnectionString": "Server=db;Database=PersistMessageDB;User ID=sa;Password=@Aa123456" + }, + "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..a794e5e 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", diff --git a/src/Services/Booking/src/Booking.Api/appsettings.test.json b/src/Services/Booking/src/Booking.Api/appsettings.test.json index 1c2df13..cb72535 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", @@ -14,16 +14,16 @@ "Microsoft.EntityFrameworkCore.Database.Command": "Debug" } }, - "PersistMessageOptions": { - "Interval": 1, - "Enabled": true, - "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageTestDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=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 3328456..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; @@ -43,7 +44,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 +59,7 @@ public static class InfrastructureExtensions })); }); - builder.Services.AddPersistMessage(configuration); + builder.Services.AddPersistMessageProcessor(); builder.Services.AddMongoDbContext(configuration); builder.AddCustomSerilog(env); @@ -90,13 +91,14 @@ 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(); 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 c77f594..30fe75c 100644 --- a/src/Services/Booking/tests/IntegrationTest/Booking/Features/CreateBookingTests.cs +++ b/src/Services/Booking/tests/IntegrationTest/Booking/Features/CreateBookingTests.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Threading.Tasks; using Booking.Api; using Booking.Data; @@ -11,8 +10,6 @@ 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,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) { } @@ -49,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 ef2d916..4b77b07 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", diff --git a/src/Services/Flight/src/Flight.Api/appsettings.test.json b/src/Services/Flight/src/Flight.Api/appsettings.test.json index 5ec0530..c78fbb4 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", @@ -18,8 +18,8 @@ } }, "PersistMessageOptions": { - "Interval": 1, + "Interval": 2, "Enabled": true, - "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageTestDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" + "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=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/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..1ee6f11 100644 --- a/src/Services/Flight/src/Flight/Data/FlightDbContext.cs +++ b/src/Services/Flight/src/Flight/Data/FlightDbContext.cs @@ -1,22 +1,19 @@ -using System.Reflection; using BuildingBlocks.EFCore; using BuildingBlocks.Utils; +using BuildingBlocks.Web; 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 +21,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/20221206180723_Initial.Designer.cs similarity index 97% rename from src/Services/Flight/src/Flight/Data/Migrations/20220728175834_Init.Designer.cs rename to src/Services/Flight/src/Flight/Data/Migrations/20221206180723_Initial.Designer.cs index 349fc42..ba1c044 100644 --- a/src/Services/Flight/src/Flight/Data/Migrations/20220728175834_Init.Designer.cs +++ b/src/Services/Flight/src/Flight/Data/Migrations/20221206180723_Initial.Designer.cs @@ -12,17 +12,18 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace Flight.Data.Migrations { [DbContext(typeof(FlightDbContext))] - [Migration("20220728175834_Init")] - partial class Init + [Migration("20221206180723_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("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/20221206180723_Initial.cs similarity index 98% rename from src/Services/Flight/src/Flight/Data/Migrations/20220728175834_Init.cs rename to src/Services/Flight/src/Flight/Data/Migrations/20221206180723_Initial.cs index 5cd66bb..576d26f 100644 --- a/src/Services/Flight/src/Flight/Data/Migrations/20220728175834_Init.cs +++ b/src/Services/Flight/src/Flight/Data/Migrations/20221206180723_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( @@ -144,6 +146,7 @@ namespace Flight.Data.Migrations column: "FlightId"); } + /// protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable( diff --git a/src/Services/Flight/src/Flight/Data/Migrations/FlightDbContextModelSnapshot.cs b/src/Services/Flight/src/Flight/Data/Migrations/FlightDbContextModelSnapshot.cs index de7d19c..3c2ccf0 100644 --- a/src/Services/Flight/src/Flight/Data/Migrations/FlightDbContextModelSnapshot.cs +++ b/src/Services/Flight/src/Flight/Data/Migrations/FlightDbContextModelSnapshot.cs @@ -17,10 +17,10 @@ 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("Flight.Aircrafts.Models.Aircraft", b => { 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 bdca307..dd53410 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,10 @@ public static class InfrastructureExtensions })); }); - builder.Services.AddCustomDbContext(configuration); + builder.Services.AddCustomDbContext(); builder.Services.AddScoped(); - builder.Services.AddMongoDbContext(configuration); - builder.Services.AddPersistMessage(configuration); + builder.Services.AddPersistMessageProcessor(); builder.AddCustomSerilog(env); builder.Services.AddJwt(); @@ -99,7 +98,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/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 58232c8..f05529b 100644 --- a/src/Services/Identity/src/Identity.Api/appsettings.docker.json +++ b/src/Services/Identity/src/Identity.Api/appsettings.docker.json @@ -1,9 +1,14 @@ { "App": "Identity-Service", - "ConnectionStrings": { + "DatabaseOptions": { "DefaultConnection": "Server=db;Database=IdentityDB;User ID=sa;Password=@Aa123456" }, - "RabbitMq": { + "PersistMessageOptions": { + "Interval": 30, + "Enabled": true, + "ConnectionString": "Server=db;Database=PersistMessageDB;User ID=sa;Password=@Aa123456" + }, + "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..b76b8e3 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", diff --git a/src/Services/Identity/src/Identity.Api/appsettings.test.json b/src/Services/Identity/src/Identity.Api/appsettings.test.json index 92b31cc..08307a2 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", @@ -18,8 +18,8 @@ } }, "PersistMessageOptions": { - "Interval": 1, + "Interval": 30, "Enabled": true, - "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageTestDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" + "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" } } 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("Identity.Identity.Models.ApplicationUser", b => { @@ -30,7 +31,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 +99,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 +108,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 +129,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 +138,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 +153,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 +162,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 +177,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 +198,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 +213,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 +232,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/20221206180831_initial.cs similarity index 88% rename from src/Services/Identity/src/Identity/Data/Migrations/20220728175937_initial.cs rename to src/Services/Identity/src/Identity/Data/Migrations/20221206180831_initial.cs index a056fed..1c533e3 100644 --- a/src/Services/Identity/src/Identity/Data/Migrations/20220728175937_initial.cs +++ b/src/Services/Identity/src/Identity/Data/Migrations/20221206180831_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) @@ -55,6 +62,7 @@ namespace Identity.Data.Migrations migrationBuilder.CreateTable( name: "AspNetRoleClaims", + schema: "dbo", columns: table => new { Id = table.Column(type: "int", nullable: false) @@ -69,6 +77,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 +85,7 @@ namespace Identity.Data.Migrations migrationBuilder.CreateTable( name: "AspNetUserClaims", + schema: "dbo", columns: table => new { Id = table.Column(type: "int", nullable: false) @@ -90,6 +100,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 +108,7 @@ namespace Identity.Data.Migrations migrationBuilder.CreateTable( name: "AspNetUserLogins", + schema: "dbo", columns: table => new { LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), @@ -110,6 +122,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 +130,7 @@ namespace Identity.Data.Migrations migrationBuilder.CreateTable( name: "AspNetUserRoles", + schema: "dbo", columns: table => new { UserId = table.Column(type: "bigint", nullable: false), @@ -128,12 +142,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 +157,7 @@ namespace Identity.Data.Migrations migrationBuilder.CreateTable( name: "AspNetUserTokens", + schema: "dbo", columns: table => new { UserId = table.Column(type: "bigint", nullable: false), @@ -154,6 +171,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 +179,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 +193,67 @@ 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: "AspNetRoles", + schema: "dbo"); migrationBuilder.DropTable( - name: "AspNetUsers"); + 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..fdf3fdf 100644 --- a/src/Services/Identity/src/Identity/Data/Migrations/IdentityContextModelSnapshot.cs +++ b/src/Services/Identity/src/Identity/Data/Migrations/IdentityContextModelSnapshot.cs @@ -17,10 +17,10 @@ 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("Identity.Identity.Models.ApplicationUser", b => { @@ -28,7 +28,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 +96,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 +105,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 +126,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 +135,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 +150,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 +159,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 +174,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 +195,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 +210,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 +229,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..4737933 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,8 +56,8 @@ public static class InfrastructureExtensions }); builder.Services.AddControllers(); - builder.Services.AddPersistMessage(configuration); - builder.Services.AddCustomDbContext(configuration); + builder.Services.AddPersistMessageProcessor(); + builder.Services.AddCustomDbContext(); builder.Services.AddScoped(); builder.AddCustomSerilog(env); builder.Services.AddCustomSwagger(configuration, typeof(IdentityRoot).Assembly); @@ -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/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 2b748ff..2af01bc 100644 --- a/src/Services/Passenger/src/Passenger.Api/appsettings.docker.json +++ b/src/Services/Passenger/src/Passenger.Api/appsettings.docker.json @@ -1,13 +1,18 @@ { "App": "Passenger-Service", - "ConnectionStrings": { + "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" }, - "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..d7cbb30 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", diff --git a/src/Services/Passenger/src/Passenger.Api/appsettings.test.json b/src/Services/Passenger/src/Passenger.Api/appsettings.test.json index 15db2aa..194eb82 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", @@ -18,8 +18,8 @@ } }, "PersistMessageOptions": { - "Interval": 1, + "Interval": 30, "Enabled": true, - "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageTestDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" + "ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=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/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/20221206180929_initial.Designer.cs similarity index 93% rename from src/Services/Passenger/src/Passenger/Data/Migrations/20220728180020_initial.Designer.cs rename to src/Services/Passenger/src/Passenger/Data/Migrations/20221206180929_initial.Designer.cs index aa6b184..64ec17a 100644 --- a/src/Services/Passenger/src/Passenger/Data/Migrations/20220728180020_initial.Designer.cs +++ b/src/Services/Passenger/src/Passenger/Data/Migrations/20221206180929_initial.Designer.cs @@ -12,17 +12,18 @@ using Passenger.Data; namespace Passenger.Data.Migrations { [DbContext(typeof(PassengerDbContext))] - [Migration("20220728180020_initial")] + [Migration("20221206180929_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("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/20221206180929_initial.cs similarity index 95% rename from src/Services/Passenger/src/Passenger/Data/Migrations/20220728180020_initial.cs rename to src/Services/Passenger/src/Passenger/Data/Migrations/20221206180929_initial.cs index cf5759c..8730fb3 100644 --- a/src/Services/Passenger/src/Passenger/Data/Migrations/20220728180020_initial.cs +++ b/src/Services/Passenger/src/Passenger/Data/Migrations/20221206180929_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( @@ -35,6 +37,7 @@ namespace Passenger.Data.Migrations }); } + /// protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable( diff --git a/src/Services/Passenger/src/Passenger/Data/Migrations/PassengerDbContextModelSnapshot.cs b/src/Services/Passenger/src/Passenger/Data/Migrations/PassengerDbContextModelSnapshot.cs index df21933..c5bb3b6 100644 --- a/src/Services/Passenger/src/Passenger/Data/Migrations/PassengerDbContextModelSnapshot.cs +++ b/src/Services/Passenger/src/Passenger/Data/Migrations/PassengerDbContextModelSnapshot.cs @@ -17,10 +17,10 @@ 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("Passenger.Passengers.Models.Passenger", b => { 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 1899bf0..f902d7a 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.AddCustomDbContext(configuration); + builder.Services.AddPersistMessageProcessor(); + builder.Services.AddCustomDbContext(); 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(); 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"; +}