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