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