mirror of
https://github.com/meysamhadeli/booking-microservices.git
synced 2026-05-03 03:11:51 +08:00
commit
9031043c78
@ -19,10 +19,8 @@ services:
|
|||||||
- db
|
- db
|
||||||
- rabbitmq
|
- rabbitmq
|
||||||
- jaeger
|
- jaeger
|
||||||
- eventstore.db
|
|
||||||
- elasticsearch
|
- elasticsearch
|
||||||
- kibana
|
- kibana
|
||||||
# - mongo
|
|
||||||
volumes:
|
volumes:
|
||||||
- '${USERPROFILE}\.aspnet\https:/https/'
|
- '${USERPROFILE}\.aspnet\https:/https/'
|
||||||
environment:
|
environment:
|
||||||
@ -52,10 +50,9 @@ services:
|
|||||||
- db
|
- db
|
||||||
- rabbitmq
|
- rabbitmq
|
||||||
- jaeger
|
- jaeger
|
||||||
- eventstore.db
|
|
||||||
- elasticsearch
|
- elasticsearch
|
||||||
- kibana
|
- kibana
|
||||||
# - mongo
|
- mongo
|
||||||
volumes:
|
volumes:
|
||||||
- '${USERPROFILE}\.aspnet\https:/https/'
|
- '${USERPROFILE}\.aspnet\https:/https/'
|
||||||
environment:
|
environment:
|
||||||
@ -85,10 +82,8 @@ services:
|
|||||||
- db
|
- db
|
||||||
- rabbitmq
|
- rabbitmq
|
||||||
- jaeger
|
- jaeger
|
||||||
- eventstore.db
|
|
||||||
- elasticsearch
|
- elasticsearch
|
||||||
- kibana
|
- kibana
|
||||||
# - mongo
|
|
||||||
volumes:
|
volumes:
|
||||||
- '${USERPROFILE}\.aspnet\https:/https/'
|
- '${USERPROFILE}\.aspnet\https:/https/'
|
||||||
environment:
|
environment:
|
||||||
@ -118,10 +113,9 @@ services:
|
|||||||
- db
|
- db
|
||||||
- rabbitmq
|
- rabbitmq
|
||||||
- jaeger
|
- jaeger
|
||||||
- eventstore.db
|
|
||||||
- elasticsearch
|
- elasticsearch
|
||||||
- kibana
|
- kibana
|
||||||
# - mongo
|
- mongo
|
||||||
volumes:
|
volumes:
|
||||||
- '${USERPROFILE}\.aspnet\https:/https/'
|
- '${USERPROFILE}\.aspnet\https:/https/'
|
||||||
environment:
|
environment:
|
||||||
@ -154,7 +148,7 @@ services:
|
|||||||
- eventstore.db
|
- eventstore.db
|
||||||
- elasticsearch
|
- elasticsearch
|
||||||
- kibana
|
- kibana
|
||||||
# - mongo
|
- mongo
|
||||||
volumes:
|
volumes:
|
||||||
- '${USERPROFILE}\.aspnet\https:/https/'
|
- '${USERPROFILE}\.aspnet\https:/https/'
|
||||||
environment:
|
environment:
|
||||||
@ -166,6 +160,37 @@ services:
|
|||||||
- booking
|
- booking
|
||||||
|
|
||||||
|
|
||||||
|
#######################################################
|
||||||
|
# SqlServer
|
||||||
|
#######################################################
|
||||||
|
db:
|
||||||
|
container_name: sqldb
|
||||||
|
image: mcr.microsoft.com/mssql/server:2022-latest
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "1433:1433"
|
||||||
|
environment:
|
||||||
|
SA_PASSWORD: "@Aa123456"
|
||||||
|
ACCEPT_EULA: "Y"
|
||||||
|
networks:
|
||||||
|
- booking
|
||||||
|
|
||||||
|
|
||||||
|
# ######################################################
|
||||||
|
# # Postgres
|
||||||
|
# ######################################################
|
||||||
|
# postgres:
|
||||||
|
# image: postgres:latest
|
||||||
|
# container_name: postgres
|
||||||
|
# restart: on-failure
|
||||||
|
# ports:
|
||||||
|
# - '5432:5432'
|
||||||
|
# environment:
|
||||||
|
# - POSTGRES_USER=postgres
|
||||||
|
# - POSTGRES_PASSWORD=postgres
|
||||||
|
# networks:
|
||||||
|
# - booking
|
||||||
|
|
||||||
|
|
||||||
#######################################################
|
#######################################################
|
||||||
# Rabbitmq
|
# Rabbitmq
|
||||||
@ -181,22 +206,6 @@ services:
|
|||||||
- booking
|
- booking
|
||||||
|
|
||||||
|
|
||||||
#######################################################
|
|
||||||
# SqlServer
|
|
||||||
#######################################################
|
|
||||||
db:
|
|
||||||
container_name: sqldb
|
|
||||||
image: mcr.microsoft.com/mssql/server:2017-latest
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "1433:1433"
|
|
||||||
environment:
|
|
||||||
SA_PASSWORD: "@Aa123456"
|
|
||||||
ACCEPT_EULA: "Y"
|
|
||||||
networks:
|
|
||||||
- booking
|
|
||||||
|
|
||||||
|
|
||||||
#######################################################
|
#######################################################
|
||||||
# Jaeger
|
# Jaeger
|
||||||
#######################################################
|
#######################################################
|
||||||
@ -242,7 +251,7 @@ services:
|
|||||||
# Mongo
|
# Mongo
|
||||||
#######################################################
|
#######################################################
|
||||||
mongo:
|
mongo:
|
||||||
image: mongo
|
image: mongo:4
|
||||||
container_name: mongo
|
container_name: mongo
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
# environment:
|
# environment:
|
||||||
|
|||||||
@ -20,7 +20,7 @@ services:
|
|||||||
#######################################################
|
#######################################################
|
||||||
db:
|
db:
|
||||||
container_name: sqldb
|
container_name: sqldb
|
||||||
image: mcr.microsoft.com/mssql/server:2017-latest
|
image: mcr.microsoft.com/mssql/server:2022-latest
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
- "1433:1433"
|
- "1433:1433"
|
||||||
@ -31,6 +31,21 @@ services:
|
|||||||
- booking
|
- booking
|
||||||
|
|
||||||
|
|
||||||
|
# #######################################################
|
||||||
|
# # Postgres
|
||||||
|
# ######################################################
|
||||||
|
# postgres:
|
||||||
|
# image: postgres:latest
|
||||||
|
# container_name: postgres
|
||||||
|
# restart: on-failure
|
||||||
|
# ports:
|
||||||
|
# - '5432:5432'
|
||||||
|
# environment:
|
||||||
|
# - POSTGRES_USER=postgres
|
||||||
|
# - POSTGRES_PASSWORD=postgres
|
||||||
|
# networks:
|
||||||
|
# - booking
|
||||||
|
|
||||||
#######################################################
|
#######################################################
|
||||||
# Jaeger
|
# Jaeger
|
||||||
#######################################################
|
#######################################################
|
||||||
@ -76,7 +91,7 @@ services:
|
|||||||
# Mongo
|
# Mongo
|
||||||
#######################################################
|
#######################################################
|
||||||
mongo:
|
mongo:
|
||||||
image: mongo
|
image: mongo:4
|
||||||
container_name: mongo
|
container_name: mongo
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
# environment:
|
# environment:
|
||||||
@ -125,6 +140,18 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- booking
|
- booking
|
||||||
|
|
||||||
|
#######################################################
|
||||||
|
# Redis
|
||||||
|
#######################################################
|
||||||
|
redis:
|
||||||
|
image: redis
|
||||||
|
container_name: redis
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- booking
|
||||||
|
ports:
|
||||||
|
- 6379:6379
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
@ -141,3 +168,4 @@ volumes:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
<PackageReference Include="Ben.BlockingDetector" Version="0.0.4" />
|
<PackageReference Include="Ben.BlockingDetector" Version="0.0.4" />
|
||||||
<PackageReference Include="EasyCaching.Core" Version="1.7.0" />
|
<PackageReference Include="EasyCaching.Core" Version="1.7.0" />
|
||||||
<PackageReference Include="EasyCaching.InMemory" Version="1.7.0" />
|
<PackageReference Include="EasyCaching.InMemory" Version="1.7.0" />
|
||||||
|
<PackageReference Include="EasyNetQ.Management.Client" Version="1.4.2" />
|
||||||
<PackageReference Include="EFCore.NamingConventions" Version="7.0.0" />
|
<PackageReference Include="EFCore.NamingConventions" Version="7.0.0" />
|
||||||
<PackageReference Include="EntityFrameworkCore.Triggered" Version="3.2.1" />
|
<PackageReference Include="EntityFrameworkCore.Triggered" Version="3.2.1" />
|
||||||
<PackageReference Include="Figgle" Version="0.4.1" />
|
<PackageReference Include="Figgle" Version="0.4.1" />
|
||||||
@ -27,6 +28,10 @@
|
|||||||
<PackageReference Include="FluentValidation.AspNetCore" Version="11.2.2" />
|
<PackageReference Include="FluentValidation.AspNetCore" Version="11.2.2" />
|
||||||
<PackageReference Include="Grpc.Core.Testing" Version="2.46.5" />
|
<PackageReference Include="Grpc.Core.Testing" Version="2.46.5" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.0">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="7.0.0" />
|
||||||
<PackageReference Include="Mongo2Go" Version="3.1.3" />
|
<PackageReference Include="Mongo2Go" Version="3.1.3" />
|
||||||
@ -123,7 +128,7 @@
|
|||||||
<PackageReference Include="Bogus" Version="34.0.2" />
|
<PackageReference Include="Bogus" Version="34.0.2" />
|
||||||
<PackageReference Include="FluentAssertions" Version="6.8.0" />
|
<PackageReference Include="FluentAssertions" Version="6.8.0" />
|
||||||
<PackageReference Include="MediatR" Version="9.0.0" />
|
<PackageReference Include="MediatR" Version="9.0.0" />
|
||||||
<PackageReference Include="Respawn" Version="4.0.0" />
|
<PackageReference Include="Respawn" Version="6.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="7.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="7.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.0" />
|
||||||
<PackageReference Include="Moq" Version="4.18.2" />
|
<PackageReference Include="Moq" Version="4.18.2" />
|
||||||
@ -145,6 +150,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Contracts" />
|
<Folder Include="Contracts" />
|
||||||
<Folder Include="EventStoreDB\BackgroundWorkers" />
|
<Folder Include="EventStoreDB\BackgroundWorkers" />
|
||||||
|
<Folder Include="PersistMessageProcessor\Data\Migrations" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -3,7 +3,7 @@ using System.Data;
|
|||||||
using BuildingBlocks.Core.Event;
|
using BuildingBlocks.Core.Event;
|
||||||
using BuildingBlocks.Core.Model;
|
using BuildingBlocks.Core.Model;
|
||||||
using BuildingBlocks.Utils;
|
using BuildingBlocks.Utils;
|
||||||
using JetBrains.Annotations;
|
using BuildingBlocks.Web;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Storage;
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
|
|
||||||
@ -11,6 +11,8 @@ namespace BuildingBlocks.EFCore;
|
|||||||
|
|
||||||
public abstract class AppDbContextBase : DbContext, IDbContext
|
public abstract class AppDbContextBase : DbContext, IDbContext
|
||||||
{
|
{
|
||||||
|
public const string DefaultSchema = "dbo";
|
||||||
|
|
||||||
private readonly ICurrentUserProvider _currentUserProvider;
|
private readonly ICurrentUserProvider _currentUserProvider;
|
||||||
|
|
||||||
private IDbContextTransaction _currentTransaction;
|
private IDbContextTransaction _currentTransaction;
|
||||||
@ -117,6 +119,7 @@ public abstract class AppDbContextBase : DbContext, IDbContext
|
|||||||
entry.Entity.LastModifiedBy = userId;
|
entry.Entity.LastModifiedBy = userId;
|
||||||
entry.Entity.LastModified = DateTime.Now;
|
entry.Entity.LastModified = DateTime.Now;
|
||||||
entry.Entity.IsDeleted = true;
|
entry.Entity.IsDeleted = true;
|
||||||
|
entry.Entity.Version++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
namespace BuildingBlocks.EFCore;
|
namespace BuildingBlocks.EFCore;
|
||||||
|
|
||||||
public class ConnectionStrings
|
public class DatabaseOptions
|
||||||
{
|
{
|
||||||
public string DefaultConnection { get; set; }
|
public string DefaultConnection { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using BuildingBlocks.Core.Model;
|
using BuildingBlocks.Core.Model;
|
||||||
using BuildingBlocks.PersistMessageProcessor.Data;
|
using BuildingBlocks.PersistMessageProcessor.Data;
|
||||||
|
using BuildingBlocks.Web;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Query;
|
using Microsoft.EntityFrameworkCore.Query;
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
@ -14,18 +14,24 @@ namespace BuildingBlocks.EFCore;
|
|||||||
public static class Extensions
|
public static class Extensions
|
||||||
{
|
{
|
||||||
public static IServiceCollection AddCustomDbContext<TContext>(
|
public static IServiceCollection AddCustomDbContext<TContext>(
|
||||||
this IServiceCollection services,
|
this IServiceCollection services)
|
||||||
IConfiguration configuration)
|
|
||||||
where TContext : DbContext, IDbContext
|
where TContext : DbContext, IDbContext
|
||||||
{
|
{
|
||||||
services.AddOptions<ConnectionStrings>()
|
|
||||||
.Bind(configuration.GetSection(nameof(ConnectionStrings)))
|
services.AddOptions<DatabaseOptions>()
|
||||||
|
.BindConfiguration(nameof(DatabaseOptions))
|
||||||
.ValidateDataAnnotations();
|
.ValidateDataAnnotations();
|
||||||
|
|
||||||
services.AddDbContext<TContext>(options =>
|
services.AddDbContext<TContext>((sp, options) =>
|
||||||
options.UseSqlServer(
|
{
|
||||||
configuration.GetConnectionString("DefaultConnection"),
|
var databaseOptions = services.GetOptions<DatabaseOptions>(nameof(DatabaseOptions));
|
||||||
x => x.MigrationsAssembly(typeof(TContext).Assembly.GetName().Name)));
|
|
||||||
|
options.UseSqlServer(databaseOptions?.DefaultConnection,
|
||||||
|
dbOptions =>
|
||||||
|
{
|
||||||
|
dbOptions.MigrationsAssembly(typeof(TContext).Assembly.GetName().Name);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
services.AddScoped<IDbContext>(provider => provider.GetService<TContext>());
|
services.AddScoped<IDbContext>(provider => provider.GetService<TContext>());
|
||||||
|
|
||||||
|
|||||||
@ -5,9 +5,7 @@ namespace BuildingBlocks.EFCore;
|
|||||||
|
|
||||||
public interface IDbContext
|
public interface IDbContext
|
||||||
{
|
{
|
||||||
DbSet<TEntity> Set<TEntity>()
|
DbSet<TEntity> Set<TEntity>() where TEntity : class;
|
||||||
where TEntity : class;
|
|
||||||
|
|
||||||
IReadOnlyList<IDomainEvent> GetDomainEvents();
|
IReadOnlyList<IDomainEvent> GetDomainEvents();
|
||||||
Task BeginTransactionAsync(CancellationToken cancellationToken = default);
|
Task BeginTransactionAsync(CancellationToken cancellationToken = default);
|
||||||
Task CommitTransactionAsync(CancellationToken cancellationToken = default);
|
Task CommitTransactionAsync(CancellationToken cancellationToken = default);
|
||||||
|
|||||||
@ -3,7 +3,6 @@ using BuildingBlocks.Logging;
|
|||||||
using BuildingBlocks.MassTransit;
|
using BuildingBlocks.MassTransit;
|
||||||
using BuildingBlocks.Mongo;
|
using BuildingBlocks.Mongo;
|
||||||
using BuildingBlocks.Web;
|
using BuildingBlocks.Web;
|
||||||
using DotNetCore.CAP.MongoDB;
|
|
||||||
using HealthChecks.UI.Client;
|
using HealthChecks.UI.Client;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
|
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
|
||||||
@ -17,11 +16,11 @@ public static class Extensions
|
|||||||
{
|
{
|
||||||
public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services)
|
public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
var appOptions = services.GetOptions<AppOptions>("AppOptions");
|
var appOptions = services.GetOptions<AppOptions>(nameof(AppOptions));
|
||||||
var sqlOptions = services.GetOptions<ConnectionStrings>("ConnectionStrings");
|
var sqlOptions = services.GetOptions<DatabaseOptions>(nameof(DatabaseOptions));
|
||||||
var rabbitMqOptions = services.GetOptions<RabbitMqOptions>("RabbitMq");
|
var rabbitMqOptions = services.GetOptions<RabbitMqOptions>(nameof(RabbitMqOptions));
|
||||||
var mongoOptions = services.GetOptions<MongoOptions>("MongoOptions");
|
var mongoOptions = services.GetOptions<MongoOptions>(nameof(MongoOptions));
|
||||||
var logOptions = services.GetOptions<LogOptions>("LogOptions");
|
var logOptions = services.GetOptions<LogOptions>(nameof(LogOptions));
|
||||||
|
|
||||||
var healthChecksBuilder = services.AddHealthChecks()
|
var healthChecksBuilder = services.AddHealthChecks()
|
||||||
.AddRabbitMQ(rabbitConnectionString: $"amqp://{rabbitMqOptions.UserName}:{rabbitMqOptions.Password}@{rabbitMqOptions.HostName}")
|
.AddRabbitMQ(rabbitConnectionString: $"amqp://{rabbitMqOptions.UserName}:{rabbitMqOptions.Password}@{rabbitMqOptions.HostName}")
|
||||||
|
|||||||
@ -21,6 +21,10 @@ public static class Extensions
|
|||||||
public static IServiceCollection AddCustomMassTransit(this IServiceCollection services, Assembly assembly,
|
public static IServiceCollection AddCustomMassTransit(this IServiceCollection services, Assembly assembly,
|
||||||
IWebHostEnvironment env)
|
IWebHostEnvironment env)
|
||||||
{
|
{
|
||||||
|
services.AddOptions<RabbitMqOptions>()
|
||||||
|
.BindConfiguration(nameof(RabbitMqOptions))
|
||||||
|
.ValidateDataAnnotations();
|
||||||
|
|
||||||
if (env.IsEnvironment("test"))
|
if (env.IsEnvironment("test"))
|
||||||
{
|
{
|
||||||
services.AddMassTransitTestHarness(configure =>
|
services.AddMassTransitTestHarness(configure =>
|
||||||
@ -46,13 +50,14 @@ public static class Extensions
|
|||||||
|
|
||||||
configure.UsingRabbitMq((context, configurator) =>
|
configure.UsingRabbitMq((context, configurator) =>
|
||||||
{
|
{
|
||||||
var rabbitMqOptions = services.GetOptions<RabbitMqOptions>("RabbitMq");
|
var rabbitMqOptions = services.GetOptions<RabbitMqOptions>(nameof(RabbitMqOptions));
|
||||||
|
|
||||||
var host = IsRunningInContainer ? "rabbitmq" : rabbitMqOptions.HostName;
|
var host = IsRunningInContainer ? "rabbitmq" : rabbitMqOptions.HostName;
|
||||||
|
|
||||||
configurator.Host(host, rabbitMqOptions?.Port ?? 5672, "/", h =>
|
configurator.Host(host, rabbitMqOptions?.Port ?? 5672, "/", h =>
|
||||||
{
|
{
|
||||||
h.Username(rabbitMqOptions.UserName);
|
h.Username(rabbitMqOptions?.UserName);
|
||||||
h.Password(rabbitMqOptions.Password);
|
h.Password(rabbitMqOptions?.Password);
|
||||||
});
|
});
|
||||||
|
|
||||||
var types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes())
|
var types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes())
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using BuildingBlocks.EFCore;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
|
|
||||||
namespace BuildingBlocks.PersistMessageProcessor.Data.Configurations;
|
namespace BuildingBlocks.PersistMessageProcessor.Data.Configurations;
|
||||||
@ -7,12 +8,12 @@ public class PersistMessageConfiguration : IEntityTypeConfiguration<PersistMessa
|
|||||||
{
|
{
|
||||||
public void Configure(EntityTypeBuilder<PersistMessage> builder)
|
public void Configure(EntityTypeBuilder<PersistMessage> builder)
|
||||||
{
|
{
|
||||||
builder.ToTable("PersistMessage", PersistMessageDbContext.DefaultSchema);
|
builder.ToTable("PersistMessage", AppDbContextBase.DefaultSchema);
|
||||||
|
|
||||||
builder.HasKey(x => x.Id);
|
builder.HasKey(x => x.Id);
|
||||||
|
|
||||||
builder.Property(x => x.Id)
|
builder.Property(r => r.Id)
|
||||||
.IsRequired();
|
.IsRequired().ValueGeneratedNever();
|
||||||
|
|
||||||
builder.Property(x => x.DeliveryType)
|
builder.Property(x => x.DeliveryType)
|
||||||
.HasMaxLength(50)
|
.HasMaxLength(50)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Design;
|
using Microsoft.EntityFrameworkCore.Design;
|
||||||
|
|
||||||
namespace BuildingBlocks.PersistMessageProcessor.Data;
|
namespace BuildingBlocks.PersistMessageProcessor.Data;
|
||||||
@ -10,7 +10,7 @@ public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<PersistMes
|
|||||||
var builder = new DbContextOptionsBuilder<PersistMessageDbContext>();
|
var builder = new DbContextOptionsBuilder<PersistMessageDbContext>();
|
||||||
|
|
||||||
builder.UseSqlServer(
|
builder.UseSqlServer(
|
||||||
"Data Source=.\\sqlexpress;Initial Catalog=PersistMessageDB;Persist Security Info=False;Integrated Security=SSPI");
|
"Data Source=.\\sqlexpress;Initial Catalog=PersistMessageDB;Persist Security Info=False;Integrated Security=SSPI;TrustServerCertificate=True");
|
||||||
return new PersistMessageDbContext(builder.Options);
|
return new PersistMessageDbContext(builder.Options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
// <auto-generated />
|
// <auto-generated />
|
||||||
using System;
|
using System;
|
||||||
using Booking.Data;
|
|
||||||
using BuildingBlocks.PersistMessageProcessor.Data;
|
using BuildingBlocks.PersistMessageProcessor.Data;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
@ -10,30 +9,26 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
namespace Booking.Data.Migrations
|
namespace BuildingBlocks.PersistMessageProcessor.Data.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(PersistMessageDbContext))]
|
[DbContext(typeof(PersistMessageDbContext))]
|
||||||
[Migration("20220728155556_initial")]
|
[Migration("20221206184130_initial")]
|
||||||
partial class initial
|
partial class initial
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "6.0.1")
|
.HasAnnotation("ProductVersion", "7.0.0")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
modelBuilder.Entity("BuildingBlocks.PersistMessageProcessor.PersistMessage", b =>
|
modelBuilder.Entity("BuildingBlocks.PersistMessageProcessor.PersistMessage", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<long>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.HasColumnType("bigint");
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<string>("ApplicationName")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("Created")
|
b.Property<DateTime>("Created")
|
||||||
.HasColumnType("datetime2");
|
.HasColumnType("datetime2");
|
||||||
@ -3,10 +3,12 @@ using Microsoft.EntityFrameworkCore.Migrations;
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
namespace Booking.Data.Migrations
|
namespace BuildingBlocks.PersistMessageProcessor.Data.Migrations
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
public partial class initial : Migration
|
public partial class initial : Migration
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
migrationBuilder.EnsureSchema(
|
migrationBuilder.EnsureSchema(
|
||||||
@ -31,6 +33,7 @@ namespace Booking.Data.Migrations
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
@ -1,6 +1,5 @@
|
|||||||
// <auto-generated />
|
// <auto-generated />
|
||||||
using System;
|
using System;
|
||||||
using Booking.Data;
|
|
||||||
using BuildingBlocks.PersistMessageProcessor.Data;
|
using BuildingBlocks.PersistMessageProcessor.Data;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
@ -9,7 +8,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
namespace Booking.Data.Migrations
|
namespace BuildingBlocks.PersistMessageProcessor.Data.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(PersistMessageDbContext))]
|
[DbContext(typeof(PersistMessageDbContext))]
|
||||||
partial class PersistMessageDbContextModelSnapshot : ModelSnapshot
|
partial class PersistMessageDbContextModelSnapshot : ModelSnapshot
|
||||||
@ -18,15 +17,14 @@ namespace Booking.Data.Migrations
|
|||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "6.0.1")
|
.HasAnnotation("ProductVersion", "7.0.0")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
modelBuilder.Entity("BuildingBlocks.PersistMessageProcessor.PersistMessage", b =>
|
modelBuilder.Entity("BuildingBlocks.PersistMessageProcessor.PersistMessage", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("Id")
|
b.Property<long>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
b.Property<DateTime>("Created")
|
b.Property<DateTime>("Created")
|
||||||
|
|||||||
@ -1,15 +1,11 @@
|
|||||||
using BuildingBlocks.EFCore;
|
using BuildingBlocks.EFCore;
|
||||||
using BuildingBlocks.PersistMessageProcessor.Data.Configurations;
|
using BuildingBlocks.PersistMessageProcessor.Data.Configurations;
|
||||||
using BuildingBlocks.Utils;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace BuildingBlocks.PersistMessageProcessor.Data;
|
namespace BuildingBlocks.PersistMessageProcessor.Data;
|
||||||
|
|
||||||
public class PersistMessageDbContext : AppDbContextBase, IPersistMessageDbContext
|
public class PersistMessageDbContext : AppDbContextBase, IPersistMessageDbContext
|
||||||
{
|
{
|
||||||
public const string DefaultSchema = "dbo";
|
|
||||||
|
|
||||||
public PersistMessageDbContext(DbContextOptions<PersistMessageDbContext> options)
|
public PersistMessageDbContext(DbContextOptions<PersistMessageDbContext> options)
|
||||||
: base(options)
|
: base(options)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
dotnet ef migrations add initial --context PersistMessageDbContext -o "Data\Migrations"
|
dotnet ef migrations add initial --context PersistMessageDbContext -o "PersistMessageProcessor\Data\Migrations"
|
||||||
dotnet ef database update --context PersistMessageDbContext
|
dotnet ef database update --context PersistMessageDbContext
|
||||||
|
|||||||
@ -1,25 +1,25 @@
|
|||||||
using BuildingBlocks.Core;
|
using BuildingBlocks.PersistMessageProcessor.Data;
|
||||||
using BuildingBlocks.PersistMessageProcessor.Data;
|
|
||||||
using BuildingBlocks.Web;
|
using BuildingBlocks.Web;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace BuildingBlocks.PersistMessageProcessor;
|
namespace BuildingBlocks.PersistMessageProcessor;
|
||||||
|
|
||||||
public static class Extensions
|
public static class Extensions
|
||||||
{
|
{
|
||||||
public static IServiceCollection AddPersistMessage(this IServiceCollection services, IConfiguration configuration)
|
public static IServiceCollection AddPersistMessageProcessor(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddOptions<PersistMessageOptions>()
|
services.AddOptions<PersistMessageOptions>()
|
||||||
.Bind(configuration.GetSection(nameof(PersistMessageOptions)))
|
.BindConfiguration(nameof(PersistMessageOptions))
|
||||||
.ValidateDataAnnotations();
|
.ValidateDataAnnotations();
|
||||||
|
|
||||||
var persistMessageOptions = services.GetOptions<PersistMessageOptions>("PersistMessageOptions");
|
|
||||||
|
|
||||||
services.AddDbContext<PersistMessageDbContext>(options =>
|
services.AddDbContext<PersistMessageDbContext>(options =>
|
||||||
|
{
|
||||||
|
var persistMessageOptions = services.GetOptions<PersistMessageOptions>(nameof(PersistMessageOptions));
|
||||||
|
|
||||||
options.UseSqlServer(persistMessageOptions.ConnectionString,
|
options.UseSqlServer(persistMessageOptions.ConnectionString,
|
||||||
x => x.MigrationsAssembly(typeof(PersistMessageDbContext).Assembly.GetName().Name)));
|
x => x.MigrationsAssembly(typeof(PersistMessageDbContext).Assembly.GetName().Name));
|
||||||
|
});
|
||||||
|
|
||||||
services.AddScoped<IPersistMessageDbContext>(provider => provider.GetService<PersistMessageDbContext>());
|
services.AddScoped<IPersistMessageDbContext>(provider => provider.GetService<PersistMessageDbContext>());
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
@ -8,18 +7,18 @@ namespace BuildingBlocks.PersistMessageProcessor;
|
|||||||
public class PersistMessageBackgroundService : BackgroundService
|
public class PersistMessageBackgroundService : BackgroundService
|
||||||
{
|
{
|
||||||
private readonly ILogger<PersistMessageBackgroundService> _logger;
|
private readonly ILogger<PersistMessageBackgroundService> _logger;
|
||||||
private readonly IServiceProvider _serviceProvider;
|
private readonly IPersistMessageProcessor _persistMessageProcessor;
|
||||||
private PersistMessageOptions _options;
|
private PersistMessageOptions _options;
|
||||||
|
|
||||||
private Task? _executingTask;
|
private Task? _executingTask;
|
||||||
|
|
||||||
public PersistMessageBackgroundService(
|
public PersistMessageBackgroundService(
|
||||||
ILogger<PersistMessageBackgroundService> logger,
|
ILogger<PersistMessageBackgroundService> logger,
|
||||||
IServiceProvider serviceProvider,
|
IPersistMessageProcessor persistMessageProcessor,
|
||||||
IOptions<PersistMessageOptions> options)
|
IOptions<PersistMessageOptions> options)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_serviceProvider = serviceProvider;
|
_persistMessageProcessor = persistMessageProcessor;
|
||||||
_options = options.Value;
|
_options = options.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,11 +44,7 @@ public class PersistMessageBackgroundService : BackgroundService
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await using (var scope = _serviceProvider.CreateAsyncScope())
|
await _persistMessageProcessor.ProcessAllAsync(stoppingToken);
|
||||||
{
|
|
||||||
var service = scope.ServiceProvider.GetRequiredService<IPersistMessageProcessor>();
|
|
||||||
await service.ProcessAllAsync(stoppingToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
var delay = _options.Interval is { }
|
var delay = _options.Interval is { }
|
||||||
? TimeSpan.FromSeconds((int)_options.Interval)
|
? TimeSpan.FromSeconds((int)_options.Interval)
|
||||||
|
|||||||
@ -7,6 +7,7 @@ using BuildingBlocks.Mongo;
|
|||||||
using BuildingBlocks.PersistMessageProcessor;
|
using BuildingBlocks.PersistMessageProcessor;
|
||||||
using BuildingBlocks.Web;
|
using BuildingBlocks.Web;
|
||||||
using DotNet.Testcontainers.Containers;
|
using DotNet.Testcontainers.Containers;
|
||||||
|
using EasyNetQ.Management.Client;
|
||||||
using Grpc.Net.Client;
|
using Grpc.Net.Client;
|
||||||
using MassTransit;
|
using MassTransit;
|
||||||
using MassTransit.Testing;
|
using MassTransit.Testing;
|
||||||
@ -14,46 +15,49 @@ using MediatR;
|
|||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc.Testing;
|
using Microsoft.AspNetCore.Mvc.Testing;
|
||||||
|
using Microsoft.Data.SqlClient;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Mongo2Go;
|
using MongoDB.Driver;
|
||||||
using NSubstitute;
|
using NSubstitute;
|
||||||
using Respawn;
|
using Respawn;
|
||||||
|
using Respawn.Graph;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Xunit.Abstractions;
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
namespace BuildingBlocks.TestBase;
|
namespace BuildingBlocks.TestBase;
|
||||||
|
|
||||||
public class IntegrationTestFixture<TEntryPoint> : IDisposable
|
public class IntegrationTestFactory<TEntryPoint> : IAsyncLifetime
|
||||||
where TEntryPoint : class
|
where TEntryPoint : class
|
||||||
{
|
{
|
||||||
private readonly WebApplicationFactory<TEntryPoint> _factory;
|
private readonly WebApplicationFactory<TEntryPoint> _factory;
|
||||||
|
private int Timeout => 120; // Second
|
||||||
|
|
||||||
|
public MsSqlTestcontainer MsSqlTestContainer;
|
||||||
|
public MsSqlTestcontainer MsSqlPersistTestContainer;
|
||||||
|
public RabbitMqTestcontainer RabbitMqTestContainer;
|
||||||
|
public MongoDbTestcontainer MongoDbTestContainer;
|
||||||
|
|
||||||
private int Timeout => 60; // Second
|
private ITestHarness TestHarness => ServiceProvider?.GetTestHarness();
|
||||||
private ITestHarness TestHarness => ServiceProvider.GetTestHarness();
|
public HttpClient HttpClient => _factory?.CreateClient();
|
||||||
public HttpClient HttpClient => _factory.CreateClient();
|
|
||||||
|
|
||||||
public GrpcChannel Channel =>
|
public GrpcChannel Channel => GrpcChannel.ForAddress(HttpClient.BaseAddress!, new GrpcChannelOptions { HttpClient = HttpClient });
|
||||||
GrpcChannel.ForAddress(HttpClient.BaseAddress!, new GrpcChannelOptions {HttpClient = HttpClient});
|
|
||||||
|
|
||||||
public Action<IServiceCollection> TestRegistrationServices { get; set; }
|
public Action<IServiceCollection> TestRegistrationServices { get; set; }
|
||||||
public IServiceProvider ServiceProvider => _factory.Services;
|
public IServiceProvider ServiceProvider => _factory?.Services;
|
||||||
public IConfiguration Configuration => _factory.Services.GetRequiredService<IConfiguration>();
|
public IConfiguration Configuration => _factory?.Services.GetRequiredService<IConfiguration>();
|
||||||
|
public ILogger Logger { get; set; }
|
||||||
|
|
||||||
public MsSqlTestcontainer SqlTestContainer;
|
public IntegrationTestFactory()
|
||||||
public MsSqlTestcontainer SqlPersistTestContainer;
|
|
||||||
public MongoDbTestcontainer MongoTestContainer;
|
|
||||||
public RabbitMqTestcontainer RabbitMqTestContainer;
|
|
||||||
|
|
||||||
public IntegrationTestFixture()
|
|
||||||
{
|
{
|
||||||
_factory = new WebApplicationFactory<TEntryPoint>()
|
_factory = new WebApplicationFactory<TEntryPoint>()
|
||||||
.WithWebHostBuilder(builder =>
|
.WithWebHostBuilder(builder =>
|
||||||
{
|
{
|
||||||
|
builder.ConfigureAppConfiguration(AddCustomAppSettings);
|
||||||
|
|
||||||
builder.UseEnvironment("test");
|
builder.UseEnvironment("test");
|
||||||
builder.ConfigureServices(services =>
|
builder.ConfigureServices(services =>
|
||||||
{
|
{
|
||||||
@ -63,9 +67,15 @@ public class IntegrationTestFixture<TEntryPoint> : IDisposable
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public async Task InitializeAsync()
|
||||||
{
|
{
|
||||||
_factory.Dispose();
|
await StartTestContainerAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DisposeAsync()
|
||||||
|
{
|
||||||
|
await StopTestContainerAsync();
|
||||||
|
_factory?.DisposeAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void RegisterServices(Action<IServiceCollection> services)
|
public virtual void RegisterServices(Action<IServiceCollection> services)
|
||||||
@ -127,32 +137,35 @@ public class IntegrationTestFixture<TEntryPoint> : IDisposable
|
|||||||
await TestHarness.Bus.Publish<TMessage>(message, cancellationToken);
|
await TestHarness.Bus.Publish<TMessage>(message, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task WaitForPublishing<TMessage>(CancellationToken cancellationToken = default)
|
public async Task<bool> WaitForPublishing<TMessage>(CancellationToken cancellationToken = default)
|
||||||
where TMessage : class, IEvent
|
where TMessage : class, IEvent
|
||||||
{
|
{
|
||||||
await WaitUntilConditionMet(async () =>
|
var result = await WaitUntilConditionMet(async () =>
|
||||||
{
|
{
|
||||||
var published = await TestHarness.Published.Any<TMessage>(cancellationToken);
|
var published = await TestHarness.Published.Any<TMessage>(cancellationToken);
|
||||||
var faulty = await TestHarness.Published.Any<Fault<TMessage>>(cancellationToken);
|
var faulty = await TestHarness.Published.Any<Fault<TMessage>>(cancellationToken);
|
||||||
|
|
||||||
return published && faulty == false;
|
return published && faulty == false;
|
||||||
});
|
});
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task WaitForConsuming<TMessage>(CancellationToken cancellationToken = default)
|
public async Task<bool> WaitForConsuming<TMessage>(CancellationToken cancellationToken = default)
|
||||||
where TMessage : class, IEvent
|
where TMessage : class, IEvent
|
||||||
{
|
{
|
||||||
await WaitUntilConditionMet(async () =>
|
var result = await WaitUntilConditionMet(async () =>
|
||||||
{
|
{
|
||||||
var consumed = await TestHarness.Consumed.Any<TMessage>(cancellationToken);
|
var consumed = await TestHarness.Consumed.Any<TMessage>(cancellationToken);
|
||||||
var faulty = await TestHarness.Consumed.Any<Fault<TMessage>>(cancellationToken);
|
var faulty = await TestHarness.Consumed.Any<Fault<TMessage>>(cancellationToken);
|
||||||
|
|
||||||
return consumed && faulty == false;
|
return consumed && faulty == false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ref: https://tech.energyhelpline.com/in-memory-testing-with-masstransit/
|
// Ref: https://tech.energyhelpline.com/in-memory-testing-with-masstransit/
|
||||||
public async ValueTask WaitUntilConditionMet(Func<Task<bool>> conditionToMet, int? timeoutSecond = null)
|
public async Task<bool> WaitUntilConditionMet(Func<Task<bool>> conditionToMet, int? timeoutSecond = null)
|
||||||
{
|
{
|
||||||
var time = timeoutSecond ?? Timeout;
|
var time = timeoutSecond ?? Timeout;
|
||||||
|
|
||||||
@ -161,18 +174,20 @@ public class IntegrationTestFixture<TEntryPoint> : IDisposable
|
|||||||
var meet = await conditionToMet.Invoke();
|
var meet = await conditionToMet.Invoke();
|
||||||
while (!meet)
|
while (!meet)
|
||||||
{
|
{
|
||||||
if (timeoutExpired) throw new TimeoutException("Condition not met for the test.");
|
if (timeoutExpired) return false;
|
||||||
|
|
||||||
await Task.Delay(100);
|
await Task.Delay(100);
|
||||||
meet = await conditionToMet.Invoke();
|
meet = await conditionToMet.Invoke();
|
||||||
timeoutExpired = DateTime.Now - startTime > TimeSpan.FromSeconds(time);
|
timeoutExpired = DateTime.Now - startTime > TimeSpan.FromSeconds(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async ValueTask ShouldProcessedPersistInternalCommand<TInternalCommand>()
|
public async Task<bool> ShouldProcessedPersistInternalCommand<TInternalCommand>()
|
||||||
where TInternalCommand : class, IInternalCommand
|
where TInternalCommand : class, IInternalCommand
|
||||||
{
|
{
|
||||||
await WaitUntilConditionMet(async () =>
|
var result = await WaitUntilConditionMet(async () =>
|
||||||
{
|
{
|
||||||
return await ExecuteScopeAsync(async sp =>
|
return await ExecuteScopeAsync(async sp =>
|
||||||
{
|
{
|
||||||
@ -188,6 +203,45 @@ public class IntegrationTestFixture<TEntryPoint> : IDisposable
|
|||||||
return res;
|
return res;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async Task StartTestContainerAsync()
|
||||||
|
{
|
||||||
|
MsSqlTestContainer = TestContainers.MsSqlTestContainer;
|
||||||
|
MsSqlPersistTestContainer = TestContainers.MsSqlPersistTestContainer;
|
||||||
|
RabbitMqTestContainer = TestContainers.RabbitMqTestContainer;
|
||||||
|
MongoDbTestContainer = TestContainers.MongoTestContainer;
|
||||||
|
|
||||||
|
await MongoDbTestContainer.StartAsync();
|
||||||
|
await MsSqlTestContainer.StartAsync();
|
||||||
|
await MsSqlPersistTestContainer.StartAsync();
|
||||||
|
await RabbitMqTestContainer.StartAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task StopTestContainerAsync()
|
||||||
|
{
|
||||||
|
await MsSqlTestContainer.StopAsync();
|
||||||
|
await MsSqlPersistTestContainer.StopAsync();
|
||||||
|
await RabbitMqTestContainer.StopAsync();
|
||||||
|
await MongoDbTestContainer.StopAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddCustomAppSettings(IConfigurationBuilder configuration)
|
||||||
|
{
|
||||||
|
configuration.AddInMemoryCollection(new KeyValuePair<string, string>[]
|
||||||
|
{
|
||||||
|
new("DatabaseOptions:DefaultConnection", MsSqlTestContainer.ConnectionString + "TrustServerCertificate=True"),
|
||||||
|
new("PersistMessageOptions:ConnectionString", MsSqlPersistTestContainer.ConnectionString + "TrustServerCertificate=True"),
|
||||||
|
new("RabbitMqOptions:HostName", RabbitMqTestContainer.Hostname),
|
||||||
|
new("RabbitMqOptions:UserName", RabbitMqTestContainer.Username),
|
||||||
|
new("RabbitMqOptions:Password", RabbitMqTestContainer.Password),
|
||||||
|
new("RabbitMqOptions:Port", RabbitMqTestContainer.Port.ToString()),
|
||||||
|
new("MongoOptions:ConnectionString", MongoDbTestContainer.ConnectionString),
|
||||||
|
new("MongoOptions:DatabaseName", MongoDbTestContainer.Database)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private IHttpContextAccessor AddHttpContextAccessorMock(IServiceProvider serviceProvider)
|
private IHttpContextAccessor AddHttpContextAccessorMock(IServiceProvider serviceProvider)
|
||||||
@ -203,7 +257,7 @@ public class IntegrationTestFixture<TEntryPoint> : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class IntegrationTestFixture<TEntryPoint, TWContext> : IntegrationTestFixture<TEntryPoint>
|
public class IntegrationTestFactory<TEntryPoint, TWContext> : IntegrationTestFactory<TEntryPoint>
|
||||||
where TEntryPoint : class
|
where TEntryPoint : class
|
||||||
where TWContext : DbContext
|
where TWContext : DbContext
|
||||||
{
|
{
|
||||||
@ -310,7 +364,7 @@ public class IntegrationTestFixture<TEntryPoint, TWContext> : IntegrationTestFix
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class IntegrationTestFixture<TEntryPoint, TWContext, TRContext> : IntegrationTestFixture<TEntryPoint, TWContext>
|
public class IntegrationTestFactory<TEntryPoint, TWContext, TRContext> : IntegrationTestFactory<TEntryPoint, TWContext>
|
||||||
where TEntryPoint : class
|
where TEntryPoint : class
|
||||||
where TWContext : DbContext
|
where TWContext : DbContext
|
||||||
where TRContext : MongoDbContext
|
where TRContext : MongoDbContext
|
||||||
@ -329,106 +383,100 @@ public class IntegrationTestFixture<TEntryPoint, TWContext, TRContext> : Integra
|
|||||||
public class IntegrationTestFixtureCore<TEntryPoint> : IAsyncLifetime
|
public class IntegrationTestFixtureCore<TEntryPoint> : IAsyncLifetime
|
||||||
where TEntryPoint : class
|
where TEntryPoint : class
|
||||||
{
|
{
|
||||||
private Checkpoint _checkpointDefaultDB;
|
private Respawner _reSpawnerDefaultDb;
|
||||||
private Checkpoint _checkpointPersistMessageDB;
|
private Respawner _reSpawnerPersistDb;
|
||||||
private MongoDbRunner _mongoRunner;
|
private SqlConnection DefaultDbConnection { get; set; }
|
||||||
|
private SqlConnection PersistDbConnection { get; set; }
|
||||||
|
|
||||||
private string DefaultConnectionString
|
public IntegrationTestFixtureCore(IntegrationTestFactory<TEntryPoint> integrationTestFixture, ITestOutputHelper outputHelper)
|
||||||
{
|
|
||||||
get => Fixture.ServiceProvider.GetRequiredService<IOptions<ConnectionStrings>>()?.Value.DefaultConnection;
|
|
||||||
set => Fixture.ServiceProvider.GetRequiredService<IOptions<ConnectionStrings>>().Value.DefaultConnection =
|
|
||||||
value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string PersistConnectionString
|
|
||||||
{
|
|
||||||
get => Fixture.ServiceProvider.GetRequiredService<IOptions<PersistMessageOptions>>()?.Value.ConnectionString;
|
|
||||||
set => Fixture.ServiceProvider.GetRequiredService<IOptions<PersistMessageOptions>>().Value.ConnectionString =
|
|
||||||
value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string MongoConnectionString
|
|
||||||
{
|
|
||||||
get => Fixture.ServiceProvider.GetRequiredService<IOptions<MongoOptions>>()?.Value?.ConnectionString;
|
|
||||||
set => Fixture.ServiceProvider.GetRequiredService<IOptions<MongoOptions>>().Value.ConnectionString = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private RabbitMqOptions RabbitMqOptions =>
|
|
||||||
Fixture.ServiceProvider.GetRequiredService<IOptions<RabbitMqOptions>>()?.Value;
|
|
||||||
|
|
||||||
public IntegrationTestFixtureCore(IntegrationTestFixture<TEntryPoint> integrationTestFixture)
|
|
||||||
{
|
{
|
||||||
Fixture = integrationTestFixture;
|
Fixture = integrationTestFixture;
|
||||||
integrationTestFixture.RegisterServices(services => RegisterTestsServices(services));
|
integrationTestFixture.RegisterServices(services => RegisterTestsServices(services));
|
||||||
|
integrationTestFixture.Logger = integrationTestFixture.CreateLogger(outputHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IntegrationTestFixture<TEntryPoint> Fixture { get; }
|
public IntegrationTestFactory<TEntryPoint> Fixture { get; }
|
||||||
|
|
||||||
|
|
||||||
public async Task InitializeAsync()
|
public async Task InitializeAsync()
|
||||||
{
|
{
|
||||||
_checkpointDefaultDB = new Checkpoint {TablesToIgnore = new[] {"__EFMigrationsHistory"}};
|
var databaseOptions = Fixture.ServiceProvider.GetRequiredService<IOptions<DatabaseOptions>>()?.Value;
|
||||||
_checkpointPersistMessageDB = new Checkpoint {TablesToIgnore = new[] {"__EFMigrationsHistory"}};
|
var persistOptions = Fixture.ServiceProvider.GetRequiredService<IOptions<PersistMessageOptions>>()?.Value;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(DefaultConnectionString))
|
if (!string.IsNullOrEmpty(persistOptions?.ConnectionString))
|
||||||
await _checkpointDefaultDB.Reset(DefaultConnectionString);
|
{
|
||||||
|
PersistDbConnection = new SqlConnection(persistOptions?.ConnectionString);
|
||||||
|
await PersistDbConnection.OpenAsync();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(PersistConnectionString))
|
_reSpawnerPersistDb = await Respawner.CreateAsync(PersistDbConnection,
|
||||||
await _checkpointPersistMessageDB.Reset(PersistConnectionString);
|
new RespawnerOptions { TablesToIgnore = new Table[] { "__EFMigrationsHistory" }, });
|
||||||
|
|
||||||
_mongoRunner = MongoDbRunner.Start();
|
await _reSpawnerPersistDb.ResetAsync(PersistDbConnection);
|
||||||
|
}
|
||||||
|
|
||||||
if (MongoConnectionString != null)
|
if (!string.IsNullOrEmpty(databaseOptions?.DefaultConnection))
|
||||||
MongoConnectionString = _mongoRunner.ConnectionString;
|
{
|
||||||
|
DefaultDbConnection = new SqlConnection(databaseOptions.DefaultConnection);
|
||||||
|
await DefaultDbConnection.OpenAsync();
|
||||||
|
|
||||||
//await StartTestContainerAsync();
|
_reSpawnerDefaultDb = await Respawner.CreateAsync(DefaultDbConnection,
|
||||||
|
new RespawnerOptions { TablesToIgnore = new Table[] { "__EFMigrationsHistory" }, });
|
||||||
|
|
||||||
|
await _reSpawnerDefaultDb.ResetAsync(DefaultDbConnection);
|
||||||
|
|
||||||
await SeedDataAsync();
|
await SeedDataAsync();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task DisposeAsync()
|
public async Task DisposeAsync()
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(PersistConnectionString))
|
await ResetMongoAsync();
|
||||||
_mongoRunner.Dispose();
|
await ResetRabbitMqAsync();
|
||||||
|
}
|
||||||
|
|
||||||
//await StopTestContainerAsync();
|
private async Task ResetMongoAsync(CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
//https://stackoverflow.com/questions/3366397/delete-everything-in-a-mongodb-database
|
||||||
|
MongoClient dbClient = new MongoClient(Fixture.MongoDbTestContainer?.ConnectionString);
|
||||||
|
var collections = await dbClient.GetDatabase(Fixture.MongoDbTestContainer?.Database)
|
||||||
|
.ListCollectionsAsync(cancellationToken: cancellationToken);
|
||||||
|
|
||||||
|
foreach (var collection in collections.ToList())
|
||||||
|
{
|
||||||
|
await dbClient.GetDatabase(Fixture.MongoDbTestContainer?.Database)
|
||||||
|
.DropCollectionAsync(collection["name"].AsString, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ResetRabbitMqAsync(CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var port = Fixture.RabbitMqTestContainer?.GetMappedPublicPort(15672) ?? 15672;
|
||||||
|
|
||||||
|
var rabbitmqOptions = Fixture.ServiceProvider.GetRequiredService<IOptions<RabbitMqOptions>>()?.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)
|
protected virtual void RegisterTestsServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task StartTestContainerAsync()
|
|
||||||
{
|
|
||||||
// <<For using test-container base>>
|
|
||||||
Fixture.SqlTestContainer = TestContainers.SqlTestContainer;
|
|
||||||
Fixture.SqlPersistTestContainer = TestContainers.SqlPersistTestContainer;
|
|
||||||
Fixture.MongoTestContainer = TestContainers.MongoTestContainer;
|
|
||||||
Fixture.RabbitMqTestContainer = TestContainers.RabbitMqTestContainer;
|
|
||||||
|
|
||||||
await Fixture.SqlTestContainer.StartAsync();
|
|
||||||
await Fixture.SqlPersistTestContainer.StartAsync();
|
|
||||||
await Fixture.MongoTestContainer.StartAsync();
|
|
||||||
await Fixture.RabbitMqTestContainer.StartAsync();
|
|
||||||
|
|
||||||
DefaultConnectionString = Fixture.SqlTestContainer?.ConnectionString;
|
|
||||||
PersistConnectionString = Fixture.SqlPersistTestContainer?.ConnectionString;
|
|
||||||
MongoConnectionString = Fixture.MongoTestContainer?.ConnectionString;
|
|
||||||
|
|
||||||
RabbitMqOptions.Password = Fixture.RabbitMqTestContainer.Password;
|
|
||||||
RabbitMqOptions.UserName = Fixture.RabbitMqTestContainer.Username;
|
|
||||||
RabbitMqOptions.HostName = Fixture.RabbitMqTestContainer.Hostname;
|
|
||||||
RabbitMqOptions.Port = (ushort)Fixture.RabbitMqTestContainer.Port;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task StopTestContainerAsync()
|
|
||||||
{
|
|
||||||
// <<For using test-container base>>
|
|
||||||
await Fixture.SqlTestContainer.StopAsync();
|
|
||||||
await Fixture.SqlPersistTestContainer.StopAsync();
|
|
||||||
await Fixture.MongoTestContainer.StopAsync();
|
|
||||||
await Fixture.RabbitMqTestContainer.StopAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SeedDataAsync()
|
private async Task SeedDataAsync()
|
||||||
{
|
{
|
||||||
using var scope = Fixture.ServiceProvider.CreateScope();
|
using var scope = Fixture.ServiceProvider.CreateScope();
|
||||||
@ -438,44 +486,32 @@ public class IntegrationTestFixtureCore<TEntryPoint> : IAsyncLifetime
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class IntegrationTestBase<TEntryPoint> : IntegrationTestFixtureCore<TEntryPoint>,
|
public abstract class IntegrationTestBase<TEntryPoint, TWContext> : IntegrationTestFixtureCore<TEntryPoint>
|
||||||
IClassFixture<IntegrationTestFixture<TEntryPoint>>
|
//,IClassFixture<IntegrationTestFactory<TEntryPoint, TWContext>>
|
||||||
where TEntryPoint : class
|
|
||||||
{
|
|
||||||
protected IntegrationTestBase(
|
|
||||||
IntegrationTestFixture<TEntryPoint> integrationTestFixture) : base(integrationTestFixture)
|
|
||||||
{
|
|
||||||
Fixture = integrationTestFixture;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IntegrationTestFixture<TEntryPoint> Fixture { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class IntegrationTestBase<TEntryPoint, TWContext> : IntegrationTestFixtureCore<TEntryPoint>,
|
|
||||||
IClassFixture<IntegrationTestFixture<TEntryPoint, TWContext>>
|
|
||||||
where TEntryPoint : class
|
where TEntryPoint : class
|
||||||
where TWContext : DbContext
|
where TWContext : DbContext
|
||||||
{
|
{
|
||||||
protected IntegrationTestBase(
|
protected IntegrationTestBase(
|
||||||
IntegrationTestFixture<TEntryPoint, TWContext> integrationTestFixture) : base(integrationTestFixture)
|
IntegrationTestFactory<TEntryPoint, TWContext> integrationTestFixture, ITestOutputHelper outputHelper = null) : base(integrationTestFixture, outputHelper)
|
||||||
{
|
{
|
||||||
Fixture = integrationTestFixture;
|
Fixture = integrationTestFixture;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IntegrationTestFixture<TEntryPoint, TWContext> Fixture { get; }
|
public IntegrationTestFactory<TEntryPoint, TWContext> Fixture { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class IntegrationTestBase<TEntryPoint, TWContext, TRContext> : IntegrationTestFixtureCore<TEntryPoint>,
|
public abstract class IntegrationTestBase<TEntryPoint, TWContext, TRContext> : IntegrationTestFixtureCore<TEntryPoint>
|
||||||
IClassFixture<IntegrationTestFixture<TEntryPoint, TWContext, TRContext>>
|
//,IClassFixture<IntegrationTestFactory<TEntryPoint, TWContext, TRContext>>
|
||||||
where TEntryPoint : class
|
where TEntryPoint : class
|
||||||
where TWContext : DbContext
|
where TWContext : DbContext
|
||||||
where TRContext : MongoDbContext
|
where TRContext : MongoDbContext
|
||||||
{
|
{
|
||||||
protected IntegrationTestBase(
|
protected IntegrationTestBase(
|
||||||
IntegrationTestFixture<TEntryPoint, TWContext, TRContext> integrationTestFixture) : base(integrationTestFixture)
|
IntegrationTestFactory<TEntryPoint, TWContext, TRContext> integrationTestFixture, ITestOutputHelper outputHelper = null) : base(integrationTestFixture, outputHelper)
|
||||||
{
|
{
|
||||||
Fixture = integrationTestFixture;
|
Fixture = integrationTestFixture;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IntegrationTestFixture<TEntryPoint, TWContext, TRContext> Fixture { get; }
|
public IntegrationTestFactory<TEntryPoint, TWContext, TRContext> Fixture { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using DotNet.Testcontainers.Builders;
|
using System;
|
||||||
|
using DotNet.Testcontainers.Builders;
|
||||||
using DotNet.Testcontainers.Configurations;
|
using DotNet.Testcontainers.Configurations;
|
||||||
using DotNet.Testcontainers.Containers;
|
using DotNet.Testcontainers.Containers;
|
||||||
|
|
||||||
@ -6,34 +7,52 @@ namespace BuildingBlocks.TestBase;
|
|||||||
|
|
||||||
public static class TestContainers
|
public static class TestContainers
|
||||||
{
|
{
|
||||||
public static MsSqlTestcontainer SqlTestContainer => new TestcontainersBuilder<MsSqlTestcontainer>()
|
public static PostgreSqlTestcontainer PostgresTestContainer => new TestcontainersBuilder<PostgreSqlTestcontainer>()
|
||||||
.WithDatabase(
|
.WithDatabase(
|
||||||
new MsSqlTestcontainerConfiguration
|
new PostgreSqlTestcontainerConfiguration
|
||||||
{
|
{
|
||||||
Database = Guid.NewGuid().ToString("D"),
|
Database = Guid.NewGuid().ToString("D"),
|
||||||
Password = Guid.NewGuid().ToString("D")
|
Password = Guid.NewGuid().ToString("D"),
|
||||||
|
Username = Guid.NewGuid().ToString("D")
|
||||||
})
|
})
|
||||||
.WithImage("mcr.microsoft.com/mssql/server:2017-latest")
|
.WithImage("postgres:latest")
|
||||||
|
.WithCleanUp(true)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
public static MsSqlTestcontainer SqlPersistTestContainer => new TestcontainersBuilder<MsSqlTestcontainer>()
|
|
||||||
.WithDatabase(new MsSqlTestcontainerConfiguration
|
public static MsSqlTestcontainer MsSqlTestContainer = new TestcontainersBuilder<MsSqlTestcontainer>()
|
||||||
|
.WithDatabase(new MsSqlTestcontainerConfiguration()
|
||||||
{
|
{
|
||||||
Database = Guid.NewGuid().ToString("D"), Password = Guid.NewGuid().ToString("D")
|
Password = Guid.NewGuid().ToString("D")
|
||||||
})
|
})
|
||||||
.WithImage("mcr.microsoft.com/mssql/server:2017-latest")
|
.WithImage("mcr.microsoft.com/mssql/server:2022-latest")
|
||||||
|
.WithPortBinding(1433, true)
|
||||||
|
.WithCleanUp(true)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
public static MsSqlTestcontainer MsSqlPersistTestContainer = new TestcontainersBuilder<MsSqlTestcontainer>()
|
||||||
|
.WithDatabase(new MsSqlTestcontainerConfiguration()
|
||||||
|
{
|
||||||
|
Password = Guid.NewGuid().ToString("D")
|
||||||
|
})
|
||||||
|
.WithImage("mcr.microsoft.com/mssql/server:2022-latest")
|
||||||
|
.WithPortBinding(1433, true)
|
||||||
|
.WithCleanUp(true)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
|
||||||
public static MongoDbTestcontainer MongoTestContainer => new TestcontainersBuilder<MongoDbTestcontainer>()
|
public static MongoDbTestcontainer MongoTestContainer => new TestcontainersBuilder<MongoDbTestcontainer>()
|
||||||
.WithDatabase(new MongoDbTestcontainerConfiguration()
|
.WithDatabase(new MongoDbTestcontainerConfiguration()
|
||||||
{
|
{
|
||||||
Database = Guid.NewGuid().ToString("D"),
|
Database = Guid.NewGuid().ToString("D"),
|
||||||
Username = 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();
|
.Build();
|
||||||
|
|
||||||
|
|
||||||
public static RabbitMqTestcontainer RabbitMqTestContainer => new TestcontainersBuilder<RabbitMqTestcontainer>()
|
public static RabbitMqTestcontainer RabbitMqTestContainer => new TestcontainersBuilder<RabbitMqTestcontainer>()
|
||||||
.WithMessageBroker(new RabbitMqTestcontainerConfiguration()
|
.WithMessageBroker(new RabbitMqTestcontainerConfiguration()
|
||||||
{
|
{
|
||||||
@ -41,5 +60,10 @@ public static class TestContainers
|
|||||||
Username = "guest"
|
Username = "guest"
|
||||||
})
|
})
|
||||||
.WithImage("rabbitmq:3-management")
|
.WithImage("rabbitmq:3-management")
|
||||||
|
.WithPortBinding(15672, true)
|
||||||
|
.WithPortBinding(5672, true)
|
||||||
|
.WithCleanUp(true)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace BuildingBlocks.Utils;
|
namespace BuildingBlocks.Web;
|
||||||
|
|
||||||
public interface ICurrentUserProvider
|
public interface ICurrentUserProvider
|
||||||
{
|
{
|
||||||
30
src/BuildingBlocks/Web/ServiceProviderExtensions.cs
Normal file
30
src/BuildingBlocks/Web/ServiceProviderExtensions.cs
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
|
|
||||||
namespace BuildingBlocks.Utils;
|
namespace BuildingBlocks.Web;
|
||||||
|
|
||||||
public class SlugifyParameterTransformer : IOutboundParameterTransformer
|
public class SlugifyParameterTransformer : IOutboundParameterTransformer
|
||||||
{
|
{
|
||||||
@ -1,8 +1,2 @@
|
|||||||
{
|
{
|
||||||
"Logging": {
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Information",
|
|
||||||
"Microsoft.AspNetCore": "Warning"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,12 @@
|
|||||||
"Microsoft.AspNetCore": "Warning"
|
"Microsoft.AspNetCore": "Warning"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"RabbitMq": {
|
"PersistMessageOptions": {
|
||||||
|
"Interval": 30,
|
||||||
|
"Enabled": true,
|
||||||
|
"ConnectionString": "Server=db;Database=PersistMessageDB;User ID=sa;Password=@Aa123456"
|
||||||
|
},
|
||||||
|
"RabbitMqOptions": {
|
||||||
"HostName": "rabbitmq",
|
"HostName": "rabbitmq",
|
||||||
"ExchangeName": "booking",
|
"ExchangeName": "booking",
|
||||||
"UserName": "guest",
|
"UserName": "guest",
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
"Authority": "https://localhost:5005",
|
"Authority": "https://localhost:5005",
|
||||||
"Audience": "booking-api"
|
"Audience": "booking-api"
|
||||||
},
|
},
|
||||||
"RabbitMq": {
|
"RabbitMqOptions": {
|
||||||
"HostName": "localhost",
|
"HostName": "localhost",
|
||||||
"ExchangeName": "booking",
|
"ExchangeName": "booking",
|
||||||
"UserName": "guest",
|
"UserName": "guest",
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"RabbitMq": {
|
"RabbitMqOptions": {
|
||||||
"HostName": "localhost",
|
"HostName": "localhost",
|
||||||
"ExchangeName": "booking",
|
"ExchangeName": "booking",
|
||||||
"UserName": "guest",
|
"UserName": "guest",
|
||||||
@ -14,16 +14,16 @@
|
|||||||
"Microsoft.EntityFrameworkCore.Database.Command": "Debug"
|
"Microsoft.EntityFrameworkCore.Database.Command": "Debug"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"PersistMessageOptions": {
|
|
||||||
"Interval": 1,
|
|
||||||
"Enabled": true,
|
|
||||||
"ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageTestDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
|
||||||
},
|
|
||||||
"MongoOptions": {
|
"MongoOptions": {
|
||||||
"ConnectionString": "mongodb://localhost:27017",
|
"ConnectionString": "mongodb://localhost:27017",
|
||||||
"DatabaseName": "booking-db-test"
|
"DatabaseName": "booking-db-test"
|
||||||
},
|
},
|
||||||
"EventStore": {
|
"EventStore": {
|
||||||
"ConnectionString": "esdb://localhost:2113?tls=false"
|
"ConnectionString": "esdb://localhost:2113?tls=false"
|
||||||
|
},
|
||||||
|
"PersistMessageOptions": {
|
||||||
|
"Interval": 30,
|
||||||
|
"Enabled": true,
|
||||||
|
"ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ using Booking.Booking.Models.ValueObjects;
|
|||||||
using BuildingBlocks.Core;
|
using BuildingBlocks.Core;
|
||||||
using BuildingBlocks.Core.CQRS;
|
using BuildingBlocks.Core.CQRS;
|
||||||
using BuildingBlocks.EventStoreDB.Repository;
|
using BuildingBlocks.EventStoreDB.Repository;
|
||||||
using BuildingBlocks.Utils;
|
using BuildingBlocks.Web;
|
||||||
using Flight;
|
using Flight;
|
||||||
using Passenger;
|
using Passenger;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using System.Threading.RateLimiting;
|
using System.Threading.RateLimiting;
|
||||||
using Booking.Data;
|
using Booking.Data;
|
||||||
using BuildingBlocks.Core;
|
using BuildingBlocks.Core;
|
||||||
|
using BuildingBlocks.EFCore;
|
||||||
using BuildingBlocks.EventStoreDB;
|
using BuildingBlocks.EventStoreDB;
|
||||||
using BuildingBlocks.HealthCheck;
|
using BuildingBlocks.HealthCheck;
|
||||||
using BuildingBlocks.IdsGenerator;
|
using BuildingBlocks.IdsGenerator;
|
||||||
@ -11,8 +12,8 @@ using BuildingBlocks.MassTransit;
|
|||||||
using BuildingBlocks.Mongo;
|
using BuildingBlocks.Mongo;
|
||||||
using BuildingBlocks.OpenTelemetry;
|
using BuildingBlocks.OpenTelemetry;
|
||||||
using BuildingBlocks.PersistMessageProcessor;
|
using BuildingBlocks.PersistMessageProcessor;
|
||||||
|
using BuildingBlocks.PersistMessageProcessor.Data;
|
||||||
using BuildingBlocks.Swagger;
|
using BuildingBlocks.Swagger;
|
||||||
using BuildingBlocks.Utils;
|
|
||||||
using BuildingBlocks.Web;
|
using BuildingBlocks.Web;
|
||||||
using Figgle;
|
using Figgle;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
@ -43,7 +44,7 @@ public static class InfrastructureExtensions
|
|||||||
options.SuppressModelStateInvalidFilter = true;
|
options.SuppressModelStateInvalidFilter = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
var appOptions = builder.Services.GetOptions<AppOptions>("AppOptions");
|
var appOptions = builder.Services.GetOptions<AppOptions>(nameof(AppOptions));
|
||||||
|
|
||||||
Console.WriteLine(FiggleFonts.Standard.Render(appOptions.Name));
|
Console.WriteLine(FiggleFonts.Standard.Render(appOptions.Name));
|
||||||
|
|
||||||
@ -58,7 +59,7 @@ public static class InfrastructureExtensions
|
|||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Services.AddPersistMessage(configuration);
|
builder.Services.AddPersistMessageProcessor();
|
||||||
builder.Services.AddMongoDbContext<BookingReadDbContext>(configuration);
|
builder.Services.AddMongoDbContext<BookingReadDbContext>(configuration);
|
||||||
|
|
||||||
builder.AddCustomSerilog(env);
|
builder.AddCustomSerilog(env);
|
||||||
@ -90,13 +91,14 @@ public static class InfrastructureExtensions
|
|||||||
public static WebApplication UseInfrastructure(this WebApplication app)
|
public static WebApplication UseInfrastructure(this WebApplication app)
|
||||||
{
|
{
|
||||||
var env = app.Environment;
|
var env = app.Environment;
|
||||||
var appOptions = app.GetOptions<AppOptions>("AppOptions");
|
var appOptions = app.GetOptions<AppOptions>(nameof(AppOptions));
|
||||||
|
|
||||||
app.UseProblemDetails();
|
app.UseProblemDetails();
|
||||||
app.UseSerilogRequestLogging();
|
app.UseSerilogRequestLogging();
|
||||||
app.UseCorrelationId();
|
app.UseCorrelationId();
|
||||||
app.UseRouting();
|
app.UseRouting();
|
||||||
app.UseHttpMetrics();
|
app.UseHttpMetrics();
|
||||||
|
app.UseMigration<PersistMessageDbContext>(env);
|
||||||
app.UseHttpsRedirection();
|
app.UseHttpsRedirection();
|
||||||
app.UseCustomHealthCheck();
|
app.UseCustomHealthCheck();
|
||||||
app.MapMetrics();
|
app.MapMetrics();
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Linq;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Booking.Api;
|
using Booking.Api;
|
||||||
using Booking.Data;
|
using Booking.Data;
|
||||||
@ -11,8 +10,6 @@ using FluentAssertions;
|
|||||||
using Grpc.Core;
|
using Grpc.Core;
|
||||||
using Grpc.Core.Testing;
|
using Grpc.Core.Testing;
|
||||||
using Integration.Test.Fakes;
|
using Integration.Test.Fakes;
|
||||||
using MassTransit;
|
|
||||||
using MassTransit.Testing;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
using NSubstitute;
|
using NSubstitute;
|
||||||
@ -22,11 +19,9 @@ using GetByIdRequest = Flight.GetByIdRequest;
|
|||||||
|
|
||||||
namespace Integration.Test.Booking.Features;
|
namespace Integration.Test.Booking.Features;
|
||||||
|
|
||||||
public class CreateBookingTests : IntegrationTestBase<Program, PersistMessageDbContext, BookingReadDbContext>
|
public class CreateBookingTests : BookingIntegrationTestBase
|
||||||
{
|
{
|
||||||
public CreateBookingTests(
|
public CreateBookingTests(IntegrationTestFactory<Program, PersistMessageDbContext, BookingReadDbContext> integrationTestFixture) : base(integrationTestFixture)
|
||||||
IntegrationTestFixture<Program, PersistMessageDbContext, BookingReadDbContext> integrationTestFixture) : base(
|
|
||||||
integrationTestFixture)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +44,7 @@ public class CreateBookingTests : IntegrationTestBase<Program, PersistMessageDbC
|
|||||||
// Assert
|
// Assert
|
||||||
response.Should().BeGreaterOrEqualTo(0);
|
response.Should().BeGreaterOrEqualTo(0);
|
||||||
|
|
||||||
await Fixture.WaitForPublishing<BookingCreated>();
|
(await Fixture.WaitForPublishing<BookingCreated>()).Should().Be(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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<Program, PersistMessageDbContext, BookingReadDbContext>
|
||||||
|
{
|
||||||
|
public BookingIntegrationTestBase(IntegrationTestFactory<Program, PersistMessageDbContext, BookingReadDbContext> integrationTestFixture) : base(integrationTestFixture)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CollectionDefinition(Name)]
|
||||||
|
public class IntegrationTestCollection : ICollectionFixture<IntegrationTestFactory<Program, PersistMessageDbContext, BookingReadDbContext>>
|
||||||
|
{
|
||||||
|
public const string Name = "Booking Integration Test";
|
||||||
|
}
|
||||||
@ -1,8 +1,2 @@
|
|||||||
{
|
{
|
||||||
"Logging": {
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Debug",
|
|
||||||
"Microsoft.AspNetCore": "Warning"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
"Microsoft.AspNetCore": "Warning"
|
"Microsoft.AspNetCore": "Warning"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"DatabaseOptions": {
|
||||||
"DefaultConnection": "Server=db;Database=FlightDB;User ID=sa;Password=@Aa123456"
|
"DefaultConnection": "Server=db;Database=FlightDB;User ID=sa;Password=@Aa123456"
|
||||||
},
|
},
|
||||||
"Jwt": {
|
"Jwt": {
|
||||||
@ -20,5 +20,10 @@
|
|||||||
"Password": "guest",
|
"Password": "guest",
|
||||||
"Port": 5672
|
"Port": 5672
|
||||||
},
|
},
|
||||||
|
"PersistMessageOptions": {
|
||||||
|
"Interval": 30,
|
||||||
|
"Enabled": true,
|
||||||
|
"ConnectionString": "Server=db;Database=PersistMessageDB;User ID=sa;Password=@Aa123456"
|
||||||
|
},
|
||||||
"AllowedHosts": "*"
|
"AllowedHosts": "*"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
"interval": "day"
|
"interval": "day"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"DatabaseOptions": {
|
||||||
"DefaultConnection": "Server=.\\sqlexpress;Database=FlightDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
"DefaultConnection": "Server=.\\sqlexpress;Database=FlightDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
||||||
},
|
},
|
||||||
"MongoOptions": {
|
"MongoOptions": {
|
||||||
@ -26,7 +26,7 @@
|
|||||||
"Authority": "https://localhost:5005",
|
"Authority": "https://localhost:5005",
|
||||||
"Audience": "flight-api"
|
"Audience": "flight-api"
|
||||||
},
|
},
|
||||||
"RabbitMq": {
|
"RabbitMqOptions": {
|
||||||
"HostName": "localhost",
|
"HostName": "localhost",
|
||||||
"ExchangeName": "flight",
|
"ExchangeName": "flight",
|
||||||
"UserName": "guest",
|
"UserName": "guest",
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"ConnectionStrings": {
|
"DatabaseOptions": {
|
||||||
"DefaultConnection": "Server=.\\sqlexpress;Database=FlightDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
"DefaultConnection": "Server=.\\sqlexpress;Database=FlightDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
||||||
},
|
},
|
||||||
"RabbitMq": {
|
"RabbitMqOptions": {
|
||||||
"HostName": "localhost",
|
"HostName": "localhost",
|
||||||
"ExchangeName": "flight",
|
"ExchangeName": "flight",
|
||||||
"UserName": "guest",
|
"UserName": "guest",
|
||||||
@ -18,8 +18,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"PersistMessageOptions": {
|
"PersistMessageOptions": {
|
||||||
"Interval": 1,
|
"Interval": 2,
|
||||||
"Enabled": true,
|
"Enabled": true,
|
||||||
"ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageTestDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
"ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
using BuildingBlocks.EFCore;
|
||||||
using Flight.Aircrafts.Models;
|
using Flight.Aircrafts.Models;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
@ -8,7 +9,7 @@ public class AircraftConfiguration : IEntityTypeConfiguration<Aircraft>
|
|||||||
{
|
{
|
||||||
public void Configure(EntityTypeBuilder<Aircraft> builder)
|
public void Configure(EntityTypeBuilder<Aircraft> builder)
|
||||||
{
|
{
|
||||||
builder.ToTable("Aircraft", FlightDbContext.DefaultSchema);
|
builder.ToTable("Aircraft", AppDbContextBase.DefaultSchema);
|
||||||
builder.HasKey(r => r.Id);
|
builder.HasKey(r => r.Id);
|
||||||
builder.Property(r => r.Id).ValueGeneratedNever();
|
builder.Property(r => r.Id).ValueGeneratedNever();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
using BuildingBlocks.EFCore;
|
||||||
using Flight.Airports.Models;
|
using Flight.Airports.Models;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
@ -8,7 +9,7 @@ public class AirportConfiguration: IEntityTypeConfiguration<Airport>
|
|||||||
{
|
{
|
||||||
public void Configure(EntityTypeBuilder<Airport> builder)
|
public void Configure(EntityTypeBuilder<Airport> builder)
|
||||||
{
|
{
|
||||||
builder.ToTable("Airport", FlightDbContext.DefaultSchema);
|
builder.ToTable("Airport", AppDbContextBase.DefaultSchema);
|
||||||
|
|
||||||
builder.HasKey(r => r.Id);
|
builder.HasKey(r => r.Id);
|
||||||
builder.Property(r => r.Id).ValueGeneratedNever();
|
builder.Property(r => r.Id).ValueGeneratedNever();
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
using BuildingBlocks.EFCore;
|
||||||
using Flight.Aircrafts.Models;
|
using Flight.Aircrafts.Models;
|
||||||
using Flight.Airports.Models;
|
using Flight.Airports.Models;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
@ -9,7 +10,7 @@ public class FlightConfiguration : IEntityTypeConfiguration<Flights.Models.Fligh
|
|||||||
{
|
{
|
||||||
public void Configure(EntityTypeBuilder<Flights.Models.Flight> builder)
|
public void Configure(EntityTypeBuilder<Flights.Models.Flight> builder)
|
||||||
{
|
{
|
||||||
builder.ToTable("Flight", FlightDbContext.DefaultSchema);
|
builder.ToTable("Flight", AppDbContextBase.DefaultSchema);
|
||||||
|
|
||||||
builder.HasKey(r => r.Id);
|
builder.HasKey(r => r.Id);
|
||||||
builder.Property(r => r.Id).ValueGeneratedNever();
|
builder.Property(r => r.Id).ValueGeneratedNever();
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
using BuildingBlocks.EFCore;
|
||||||
using Flight.Seats.Models;
|
using Flight.Seats.Models;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
@ -8,7 +9,7 @@ public class SeatConfiguration : IEntityTypeConfiguration<Seat>
|
|||||||
{
|
{
|
||||||
public void Configure(EntityTypeBuilder<Seat> builder)
|
public void Configure(EntityTypeBuilder<Seat> builder)
|
||||||
{
|
{
|
||||||
builder.ToTable("Seat", FlightDbContext.DefaultSchema);
|
builder.ToTable("Seat", AppDbContextBase.DefaultSchema);
|
||||||
|
|
||||||
builder.HasKey(r => r.Id);
|
builder.HasKey(r => r.Id);
|
||||||
builder.Property(r => r.Id).ValueGeneratedNever();
|
builder.Property(r => r.Id).ValueGeneratedNever();
|
||||||
|
|||||||
@ -9,8 +9,7 @@ namespace Flight.Data
|
|||||||
{
|
{
|
||||||
var builder = new DbContextOptionsBuilder<FlightDbContext>();
|
var builder = new DbContextOptionsBuilder<FlightDbContext>();
|
||||||
|
|
||||||
builder.UseSqlServer(
|
builder.UseSqlServer("Data Source=.\\sqlexpress;Initial Catalog=FlightDB;Persist Security Info=False;Integrated Security=SSPI;TrustServerCertificate=True");
|
||||||
"Data Source=.\\sqlexpress;Initial Catalog=FlightDB;Persist Security Info=False;Integrated Security=SSPI");
|
|
||||||
return new FlightDbContext(builder.Options, null);
|
return new FlightDbContext(builder.Options, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,22 +1,19 @@
|
|||||||
using System.Reflection;
|
|
||||||
using BuildingBlocks.EFCore;
|
using BuildingBlocks.EFCore;
|
||||||
using BuildingBlocks.Utils;
|
using BuildingBlocks.Utils;
|
||||||
|
using BuildingBlocks.Web;
|
||||||
using Flight.Aircrafts.Models;
|
using Flight.Aircrafts.Models;
|
||||||
using Flight.Airports.Models;
|
using Flight.Airports.Models;
|
||||||
using Flight.Seats.Models;
|
using Flight.Seats.Models;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace Flight.Data;
|
namespace Flight.Data;
|
||||||
|
|
||||||
public sealed class FlightDbContext : AppDbContextBase
|
public sealed class FlightDbContext : AppDbContextBase
|
||||||
{
|
{
|
||||||
public const string DefaultSchema = "dbo";
|
|
||||||
public FlightDbContext(DbContextOptions<FlightDbContext> options, ICurrentUserProvider currentUserProvider) : base(
|
public FlightDbContext(DbContextOptions<FlightDbContext> options, ICurrentUserProvider currentUserProvider) : base(
|
||||||
options, currentUserProvider)
|
options, currentUserProvider)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public DbSet<Flights.Models.Flight> Flights => Set<Flights.Models.Flight>();
|
public DbSet<Flights.Models.Flight> Flights => Set<Flights.Models.Flight>();
|
||||||
public DbSet<Airport> Airports => Set<Airport>();
|
public DbSet<Airport> Airports => Set<Airport>();
|
||||||
public DbSet<Aircraft> Aircraft => Set<Aircraft>();
|
public DbSet<Aircraft> Aircraft => Set<Aircraft>();
|
||||||
@ -24,8 +21,8 @@ public sealed class FlightDbContext : AppDbContextBase
|
|||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder builder)
|
protected override void OnModelCreating(ModelBuilder builder)
|
||||||
{
|
{
|
||||||
|
base.OnModelCreating(builder);
|
||||||
builder.FilterSoftDeletedProperties();
|
builder.FilterSoftDeletedProperties();
|
||||||
builder.ApplyConfigurationsFromAssembly(typeof(FlightRoot).Assembly);
|
builder.ApplyConfigurationsFromAssembly(typeof(FlightRoot).Assembly);
|
||||||
base.OnModelCreating(builder);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,17 +12,18 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|||||||
namespace Flight.Data.Migrations
|
namespace Flight.Data.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(FlightDbContext))]
|
[DbContext(typeof(FlightDbContext))]
|
||||||
[Migration("20220728175834_Init")]
|
[Migration("20221206180723_Initial")]
|
||||||
partial class Init
|
partial class Initial
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "6.0.1")
|
.HasAnnotation("ProductVersion", "7.0.0")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
modelBuilder.Entity("Flight.Aircrafts.Models.Aircraft", b =>
|
modelBuilder.Entity("Flight.Aircrafts.Models.Aircraft", b =>
|
||||||
{
|
{
|
||||||
@ -5,8 +5,10 @@ using Microsoft.EntityFrameworkCore.Migrations;
|
|||||||
|
|
||||||
namespace Flight.Data.Migrations
|
namespace Flight.Data.Migrations
|
||||||
{
|
{
|
||||||
public partial class Init : Migration
|
/// <inheritdoc />
|
||||||
|
public partial class Initial : Migration
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
migrationBuilder.EnsureSchema(
|
migrationBuilder.EnsureSchema(
|
||||||
@ -144,6 +146,7 @@ namespace Flight.Data.Migrations
|
|||||||
column: "FlightId");
|
column: "FlightId");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
@ -17,10 +17,10 @@ namespace Flight.Data.Migrations
|
|||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "6.0.1")
|
.HasAnnotation("ProductVersion", "7.0.0")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
modelBuilder.Entity("Flight.Aircrafts.Models.Aircraft", b =>
|
modelBuilder.Entity("Flight.Aircrafts.Models.Aircraft", b =>
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,13 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BuildingBlocks.EFCore;
|
using BuildingBlocks.EFCore;
|
||||||
using Flight.Aircrafts.Models;
|
using Flight.Aircrafts.Models;
|
||||||
using Flight.Aircrafts.Models.Reads;
|
using Flight.Aircrafts.Models.Reads;
|
||||||
using Flight.Airports.Models;
|
using Flight.Airports.Models;
|
||||||
using Flight.Airports.Models.Reads;
|
using Flight.Airports.Models.Reads;
|
||||||
using Flight.Flights.Models;
|
|
||||||
using Flight.Flights.Models.Reads;
|
using Flight.Flights.Models.Reads;
|
||||||
using Flight.Seats.Models;
|
using Flight.Seats.Models;
|
||||||
using Flight.Seats.Models.Reads;
|
using Flight.Seats.Models.Reads;
|
||||||
|
|||||||
@ -52,7 +52,7 @@ public static class InfrastructureExtensions
|
|||||||
builder.Services.AddCustomMediatR();
|
builder.Services.AddCustomMediatR();
|
||||||
builder.Services.AddCustomProblemDetails();
|
builder.Services.AddCustomProblemDetails();
|
||||||
|
|
||||||
var appOptions = builder.Services.GetOptions<AppOptions>("AppOptions");
|
var appOptions = builder.Services.GetOptions<AppOptions>(nameof(AppOptions));
|
||||||
Console.WriteLine(FiggleFonts.Standard.Render(appOptions.Name));
|
Console.WriteLine(FiggleFonts.Standard.Render(appOptions.Name));
|
||||||
|
|
||||||
builder.Services.AddRateLimiter(options =>
|
builder.Services.AddRateLimiter(options =>
|
||||||
@ -66,11 +66,10 @@ public static class InfrastructureExtensions
|
|||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Services.AddCustomDbContext<FlightDbContext>(configuration);
|
builder.Services.AddCustomDbContext<FlightDbContext>();
|
||||||
builder.Services.AddScoped<IDataSeeder, FlightDataSeeder>();
|
builder.Services.AddScoped<IDataSeeder, FlightDataSeeder>();
|
||||||
|
|
||||||
builder.Services.AddMongoDbContext<FlightReadDbContext>(configuration);
|
builder.Services.AddMongoDbContext<FlightReadDbContext>(configuration);
|
||||||
builder.Services.AddPersistMessage(configuration);
|
builder.Services.AddPersistMessageProcessor();
|
||||||
|
|
||||||
builder.AddCustomSerilog(env);
|
builder.AddCustomSerilog(env);
|
||||||
builder.Services.AddJwt();
|
builder.Services.AddJwt();
|
||||||
@ -99,7 +98,7 @@ public static class InfrastructureExtensions
|
|||||||
public static WebApplication UseInfrastructure(this WebApplication app)
|
public static WebApplication UseInfrastructure(this WebApplication app)
|
||||||
{
|
{
|
||||||
var env = app.Environment;
|
var env = app.Environment;
|
||||||
var appOptions = app.GetOptions<AppOptions>("AppOptions");
|
var appOptions = app.GetOptions<AppOptions>(nameof(AppOptions));
|
||||||
|
|
||||||
app.UseProblemDetails();
|
app.UseProblemDetails();
|
||||||
app.UseSerilogRequestLogging();
|
app.UseSerilogRequestLogging();
|
||||||
|
|||||||
@ -10,11 +10,10 @@ using Xunit;
|
|||||||
|
|
||||||
namespace Integration.Test.Aircraft.Features;
|
namespace Integration.Test.Aircraft.Features;
|
||||||
|
|
||||||
public class CreateAircraftTests : IntegrationTestBase<Program, FlightDbContext, FlightReadDbContext>
|
public class CreateAircraftTests : FlightIntegrationTestBase
|
||||||
{
|
{
|
||||||
public CreateAircraftTests(
|
public CreateAircraftTests(
|
||||||
IntegrationTestFixture<Program, FlightDbContext, FlightReadDbContext> integrationTestFixture) : base(
|
IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
integrationTestFixture)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,8 +30,8 @@ public class CreateAircraftTests : IntegrationTestBase<Program, FlightDbContext,
|
|||||||
response?.Should().NotBeNull();
|
response?.Should().NotBeNull();
|
||||||
response?.Name.Should().Be(command.Name);
|
response?.Name.Should().Be(command.Name);
|
||||||
|
|
||||||
await Fixture.WaitForPublishing<AircraftCreated>();
|
(await Fixture.WaitForPublishing<AircraftCreated>()).Should().Be(true);
|
||||||
|
|
||||||
await Fixture.ShouldProcessedPersistInternalCommand<CreateAircraftMongoCommand>();
|
(await Fixture.ShouldProcessedPersistInternalCommand<CreateAircraftMongoCommand>()).Should().Be(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,11 +10,10 @@ using Xunit;
|
|||||||
|
|
||||||
namespace Integration.Test.Airport.Features;
|
namespace Integration.Test.Airport.Features;
|
||||||
|
|
||||||
public class CreateAirportTests : IntegrationTestBase<Program, FlightDbContext, FlightReadDbContext>
|
public class CreateAirportTests : FlightIntegrationTestBase
|
||||||
{
|
{
|
||||||
public CreateAirportTests(
|
public CreateAirportTests(
|
||||||
IntegrationTestFixture<Program, FlightDbContext, FlightReadDbContext> integrationTestFixture) : base(
|
IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
integrationTestFixture)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,8 +30,8 @@ public class CreateAirportTests : IntegrationTestBase<Program, FlightDbContext,
|
|||||||
response?.Should().NotBeNull();
|
response?.Should().NotBeNull();
|
||||||
response?.Name.Should().Be(command.Name);
|
response?.Name.Should().Be(command.Name);
|
||||||
|
|
||||||
await Fixture.WaitForPublishing<AirportCreated>();
|
(await Fixture.WaitForPublishing<AirportCreated>()).Should().Be(true);
|
||||||
|
|
||||||
await Fixture.ShouldProcessedPersistInternalCommand<CreateAirportMongoCommand>();
|
(await Fixture.ShouldProcessedPersistInternalCommand<CreateAirportMongoCommand>()).Should().Be(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,12 +10,12 @@ using Xunit;
|
|||||||
|
|
||||||
namespace Integration.Test.Flight.Features;
|
namespace Integration.Test.Flight.Features;
|
||||||
|
|
||||||
public class CreateFlightTests : IntegrationTestBase<Program, FlightDbContext, FlightReadDbContext>
|
public class CreateFlightTests : FlightIntegrationTestBase
|
||||||
{
|
{
|
||||||
public CreateFlightTests(
|
public CreateFlightTests(
|
||||||
IntegrationTestFixture<Program, FlightDbContext, FlightReadDbContext> integrationTestFixture) : base(
|
IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
integrationTestFixture)
|
{
|
||||||
{ }
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task should_create_new_flight_to_db_and_publish_message_to_broker()
|
public async Task should_create_new_flight_to_db_and_publish_message_to_broker()
|
||||||
@ -30,9 +30,9 @@ public class CreateFlightTests : IntegrationTestBase<Program, FlightDbContext, F
|
|||||||
response.Should().NotBeNull();
|
response.Should().NotBeNull();
|
||||||
response?.FlightNumber.Should().Be(command.FlightNumber);
|
response?.FlightNumber.Should().Be(command.FlightNumber);
|
||||||
|
|
||||||
await Fixture.WaitForPublishing<FlightCreated>();
|
(await Fixture.WaitForPublishing<FlightCreated>()).Should().Be(true);
|
||||||
await Fixture.WaitForConsuming<FlightCreated>();
|
(await Fixture.WaitForConsuming<FlightCreated>()).Should().Be(true);
|
||||||
|
|
||||||
await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongoCommand>();
|
(await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongoCommand>()).Should().Be(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,11 +12,10 @@ using Xunit;
|
|||||||
|
|
||||||
namespace Integration.Test.Flight.Features;
|
namespace Integration.Test.Flight.Features;
|
||||||
|
|
||||||
public class DeleteFlightTests : IntegrationTestBase<Program, FlightDbContext, FlightReadDbContext>
|
public class DeleteFlightTests : FlightIntegrationTestBase
|
||||||
{
|
{
|
||||||
public DeleteFlightTests(
|
public DeleteFlightTests(
|
||||||
IntegrationTestFixture<Program, FlightDbContext, FlightReadDbContext> integrationTestFixture) : base(
|
IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
integrationTestFixture)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,8 +37,8 @@ public class DeleteFlightTests : IntegrationTestBase<Program, FlightDbContext, F
|
|||||||
// Assert
|
// Assert
|
||||||
deletedFlight?.IsDeleted.Should().BeTrue();
|
deletedFlight?.IsDeleted.Should().BeTrue();
|
||||||
|
|
||||||
await Fixture.WaitForPublishing<FlightDeleted>();
|
(await Fixture.WaitForPublishing<FlightDeleted>()).Should().Be(true);
|
||||||
|
|
||||||
await Fixture.ShouldProcessedPersistInternalCommand<DeleteFlightMongoCommand>();
|
(await Fixture.ShouldProcessedPersistInternalCommand<DeleteFlightMongoCommand>()).Should().Be(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,11 +11,10 @@ using Xunit;
|
|||||||
|
|
||||||
namespace Integration.Test.Flight.Features;
|
namespace Integration.Test.Flight.Features;
|
||||||
|
|
||||||
public class GetAvailableFlightsTests : IntegrationTestBase<Program, FlightDbContext, FlightReadDbContext>
|
public class GetAvailableFlightsTests : FlightIntegrationTestBase
|
||||||
{
|
{
|
||||||
public GetAvailableFlightsTests(
|
public GetAvailableFlightsTests(
|
||||||
IntegrationTestFixture<Program, FlightDbContext, FlightReadDbContext> integrationTestFixture)
|
IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
: base(integrationTestFixture)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,7 +26,7 @@ public class GetAvailableFlightsTests : IntegrationTestBase<Program, FlightDbCon
|
|||||||
|
|
||||||
await Fixture.SendAsync(flightCommand);
|
await Fixture.SendAsync(flightCommand);
|
||||||
|
|
||||||
await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongoCommand>();
|
(await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongoCommand>()).Should().Be(true);
|
||||||
|
|
||||||
var query = new GetAvailableFlightsQuery();
|
var query = new GetAvailableFlightsQuery();
|
||||||
|
|
||||||
|
|||||||
@ -6,21 +6,16 @@ using Flight.Data;
|
|||||||
using Flight.Flights.Features.CreateFlight.Commands.V1.Reads;
|
using Flight.Flights.Features.CreateFlight.Commands.V1.Reads;
|
||||||
using Flight.Flights.Features.GetFlightById.Queries.V1;
|
using Flight.Flights.Features.GetFlightById.Queries.V1;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Grpc.Net.Client;
|
|
||||||
using Integration.Test.Fakes;
|
using Integration.Test.Fakes;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Integration.Test.Flight.Features;
|
namespace Integration.Test.Flight.Features;
|
||||||
|
|
||||||
public class GetFlightByIdTests : IntegrationTestBase<Program, FlightDbContext, FlightReadDbContext>
|
public class GetFlightByIdTests : FlightIntegrationTestBase
|
||||||
{
|
{
|
||||||
private readonly GrpcChannel _channel;
|
|
||||||
|
|
||||||
public GetFlightByIdTests(
|
public GetFlightByIdTests(
|
||||||
IntegrationTestFixture<Program, FlightDbContext, FlightReadDbContext> integrationTestFixture) : base(
|
IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
integrationTestFixture)
|
|
||||||
{
|
{
|
||||||
_channel = Fixture.Channel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -30,7 +25,7 @@ public class GetFlightByIdTests : IntegrationTestBase<Program, FlightDbContext,
|
|||||||
var command = new FakeCreateFlightCommand().Generate();
|
var command = new FakeCreateFlightCommand().Generate();
|
||||||
await Fixture.SendAsync(command);
|
await Fixture.SendAsync(command);
|
||||||
|
|
||||||
await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongoCommand>();
|
(await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongoCommand>()).Should().Be(true);
|
||||||
|
|
||||||
var query = new GetFlightByIdQuery(command.Id);
|
var query = new GetFlightByIdQuery(command.Id);
|
||||||
|
|
||||||
@ -49,9 +44,9 @@ public class GetFlightByIdTests : IntegrationTestBase<Program, FlightDbContext,
|
|||||||
var command = new FakeCreateFlightCommand().Generate();
|
var command = new FakeCreateFlightCommand().Generate();
|
||||||
await Fixture.SendAsync(command);
|
await Fixture.SendAsync(command);
|
||||||
|
|
||||||
await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongoCommand>();
|
(await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongoCommand>()).Should().Be(true);
|
||||||
|
|
||||||
var flightGrpcClient = new FlightGrpcService.FlightGrpcServiceClient(_channel);
|
var flightGrpcClient = new FlightGrpcService.FlightGrpcServiceClient(Fixture.Channel);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await flightGrpcClient.GetByIdAsync(new GetByIdRequest {Id = command.Id});
|
var response = await flightGrpcClient.GetByIdAsync(new GetByIdRequest {Id = command.Id});
|
||||||
|
|||||||
@ -10,11 +10,10 @@ using Xunit;
|
|||||||
|
|
||||||
namespace Integration.Test.Flight.Features;
|
namespace Integration.Test.Flight.Features;
|
||||||
|
|
||||||
public class UpdateFlightTests : IntegrationTestBase<Program, FlightDbContext, FlightReadDbContext>
|
public class UpdateFlightTests : FlightIntegrationTestBase
|
||||||
{
|
{
|
||||||
public UpdateFlightTests(
|
public UpdateFlightTests(
|
||||||
IntegrationTestFixture<Program, FlightDbContext, FlightReadDbContext> integrationTestFixture) : base(
|
IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
integrationTestFixture)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,8 +32,8 @@ public class UpdateFlightTests : IntegrationTestBase<Program, FlightDbContext, F
|
|||||||
response?.Id.Should().Be(flightEntity?.Id);
|
response?.Id.Should().Be(flightEntity?.Id);
|
||||||
response?.Price.Should().NotBe(flightEntity?.Price);
|
response?.Price.Should().NotBe(flightEntity?.Price);
|
||||||
|
|
||||||
await Fixture.WaitForPublishing<FlightUpdated>();
|
(await Fixture.WaitForPublishing<FlightUpdated>()).Should().Be(true);
|
||||||
|
|
||||||
await Fixture.ShouldProcessedPersistInternalCommand<UpdateFlightMongoCommand>();
|
(await Fixture.ShouldProcessedPersistInternalCommand<UpdateFlightMongoCommand>()).Should().Be(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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<Program, FlightDbContext, FlightReadDbContext>
|
||||||
|
{
|
||||||
|
public FlightIntegrationTestBase(IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFixture) : base(integrationTestFixture)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CollectionDefinition(Name)]
|
||||||
|
public class IntegrationTestCollection : ICollectionFixture<IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext>>
|
||||||
|
{
|
||||||
|
public const string Name = "Flight Integration Test";
|
||||||
|
}
|
||||||
@ -6,19 +6,16 @@ using Flight.Data;
|
|||||||
using Flight.Flights.Features.CreateFlight.Commands.V1.Reads;
|
using Flight.Flights.Features.CreateFlight.Commands.V1.Reads;
|
||||||
using Flight.Seats.Features.CreateSeat.Commands.V1.Reads;
|
using Flight.Seats.Features.CreateSeat.Commands.V1.Reads;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Grpc.Net.Client;
|
|
||||||
using Integration.Test.Fakes;
|
using Integration.Test.Fakes;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Integration.Test.Seat.Features;
|
namespace Integration.Test.Seat.Features;
|
||||||
|
|
||||||
public class GetAvailableSeatsTests : IntegrationTestBase<Program, FlightDbContext, FlightReadDbContext>
|
public class GetAvailableSeatsTests : FlightIntegrationTestBase
|
||||||
{
|
{
|
||||||
private readonly GrpcChannel _channel;
|
public GetAvailableSeatsTests(
|
||||||
|
IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
public GetAvailableSeatsTests(IntegrationTestFixture<Program, FlightDbContext, FlightReadDbContext> integrationTestFixture) : base(integrationTestFixture)
|
|
||||||
{
|
{
|
||||||
_channel = Fixture.Channel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -29,15 +26,15 @@ public class GetAvailableSeatsTests : IntegrationTestBase<Program, FlightDbConte
|
|||||||
|
|
||||||
await Fixture.SendAsync(flightCommand);
|
await Fixture.SendAsync(flightCommand);
|
||||||
|
|
||||||
await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongoCommand>();
|
(await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongoCommand>()).Should().Be(true);
|
||||||
|
|
||||||
var seatCommand = new FakeCreateSeatCommand(flightCommand.Id).Generate();
|
var seatCommand = new FakeCreateSeatCommand(flightCommand.Id).Generate();
|
||||||
|
|
||||||
await Fixture.SendAsync(seatCommand);
|
await Fixture.SendAsync(seatCommand);
|
||||||
|
|
||||||
await Fixture.ShouldProcessedPersistInternalCommand<CreateSeatMongoCommand>();
|
(await Fixture.ShouldProcessedPersistInternalCommand<CreateSeatMongoCommand>()).Should().Be(true);
|
||||||
|
|
||||||
var flightGrpcClient = new FlightGrpcService.FlightGrpcServiceClient(_channel);
|
var flightGrpcClient = new FlightGrpcService.FlightGrpcServiceClient(Fixture.Channel);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await flightGrpcClient.GetAvailableSeatsAsync(new GetAvailableSeatsRequest{FlightId = flightCommand.Id});
|
var response = await flightGrpcClient.GetAvailableSeatsAsync(new GetAvailableSeatsRequest{FlightId = flightCommand.Id});
|
||||||
|
|||||||
@ -6,21 +6,16 @@ using Flight.Data;
|
|||||||
using Flight.Flights.Features.CreateFlight.Commands.V1.Reads;
|
using Flight.Flights.Features.CreateFlight.Commands.V1.Reads;
|
||||||
using Flight.Seats.Features.CreateSeat.Commands.V1.Reads;
|
using Flight.Seats.Features.CreateSeat.Commands.V1.Reads;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Grpc.Net.Client;
|
|
||||||
using Integration.Test.Fakes;
|
using Integration.Test.Fakes;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Integration.Test.Seat.Features;
|
namespace Integration.Test.Seat.Features;
|
||||||
|
|
||||||
public class ReserveSeatTests : IntegrationTestBase<Program, FlightDbContext, FlightReadDbContext>
|
public class ReserveSeatTests : FlightIntegrationTestBase
|
||||||
{
|
{
|
||||||
private readonly GrpcChannel _channel;
|
|
||||||
|
|
||||||
public ReserveSeatTests(
|
public ReserveSeatTests(
|
||||||
IntegrationTestFixture<Program, FlightDbContext, FlightReadDbContext> integrationTestFixture) : base(
|
IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
integrationTestFixture)
|
|
||||||
{
|
{
|
||||||
_channel = Fixture.Channel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -31,15 +26,15 @@ public class ReserveSeatTests : IntegrationTestBase<Program, FlightDbContext, Fl
|
|||||||
|
|
||||||
await Fixture.SendAsync(flightCommand);
|
await Fixture.SendAsync(flightCommand);
|
||||||
|
|
||||||
await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongoCommand>();
|
(await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongoCommand>()).Should().Be(true);
|
||||||
|
|
||||||
var seatCommand = new FakeCreateSeatCommand(flightCommand.Id).Generate();
|
var seatCommand = new FakeCreateSeatCommand(flightCommand.Id).Generate();
|
||||||
|
|
||||||
await Fixture.SendAsync(seatCommand);
|
await Fixture.SendAsync(seatCommand);
|
||||||
|
|
||||||
await Fixture.ShouldProcessedPersistInternalCommand<CreateSeatMongoCommand>();
|
(await Fixture.ShouldProcessedPersistInternalCommand<CreateSeatMongoCommand>()).Should().Be(true);
|
||||||
|
|
||||||
var flightGrpcClient = new FlightGrpcService.FlightGrpcServiceClient(_channel);
|
var flightGrpcClient = new FlightGrpcService.FlightGrpcServiceClient(Fixture.Channel);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await flightGrpcClient.ReserveSeatAsync(new ReserveSeatRequest()
|
var response = await flightGrpcClient.ReserveSeatAsync(new ReserveSeatRequest()
|
||||||
|
|||||||
@ -1,9 +1,14 @@
|
|||||||
{
|
{
|
||||||
"App": "Identity-Service",
|
"App": "Identity-Service",
|
||||||
"ConnectionStrings": {
|
"DatabaseOptions": {
|
||||||
"DefaultConnection": "Server=db;Database=IdentityDB;User ID=sa;Password=@Aa123456"
|
"DefaultConnection": "Server=db;Database=IdentityDB;User ID=sa;Password=@Aa123456"
|
||||||
},
|
},
|
||||||
"RabbitMq": {
|
"PersistMessageOptions": {
|
||||||
|
"Interval": 30,
|
||||||
|
"Enabled": true,
|
||||||
|
"ConnectionString": "Server=db;Database=PersistMessageDB;User ID=sa;Password=@Aa123456"
|
||||||
|
},
|
||||||
|
"RabbitMqOptions": {
|
||||||
"HostName": "rabbitmq",
|
"HostName": "rabbitmq",
|
||||||
"ExchangeName": "identity",
|
"ExchangeName": "identity",
|
||||||
"UserName": "guest",
|
"UserName": "guest",
|
||||||
|
|||||||
@ -2,10 +2,10 @@
|
|||||||
"AppOptions": {
|
"AppOptions": {
|
||||||
"Name": "Identity-Service"
|
"Name": "Identity-Service"
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"DatabaseOptions": {
|
||||||
"DefaultConnection": "Server=.\\sqlexpress;Database=IdentityDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
"DefaultConnection": "Server=.\\sqlexpress;Database=IdentityDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
||||||
},
|
},
|
||||||
"RabbitMq": {
|
"RabbitMqOptions": {
|
||||||
"HostName": "localhost",
|
"HostName": "localhost",
|
||||||
"ExchangeName": "identity",
|
"ExchangeName": "identity",
|
||||||
"UserName": "guest",
|
"UserName": "guest",
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"ConnectionStrings": {
|
"DatabaseOptions": {
|
||||||
"DefaultConnection": "Server=.\\sqlexpress;Database=IdentityDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
"DefaultConnection": "Server=.\\sqlexpress;Database=IdentityDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
||||||
},
|
},
|
||||||
"RabbitMq": {
|
"RabbitMqOptions": {
|
||||||
"HostName": "localhost",
|
"HostName": "localhost",
|
||||||
"ExchangeName": "identity",
|
"ExchangeName": "identity",
|
||||||
"UserName": "guest",
|
"UserName": "guest",
|
||||||
@ -18,8 +18,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"PersistMessageOptions": {
|
"PersistMessageOptions": {
|
||||||
"Interval": 1,
|
"Interval": 30,
|
||||||
"Enabled": true,
|
"Enabled": true,
|
||||||
"ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageTestDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
"ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<IdentityCo
|
|||||||
{
|
{
|
||||||
var builder = new DbContextOptionsBuilder<IdentityContext>();
|
var builder = new DbContextOptionsBuilder<IdentityContext>();
|
||||||
|
|
||||||
builder.UseSqlServer("Server=.\\sqlexpress;Database=IdentityDB;Trusted_Connection=True;MultipleActiveResultSets=true");
|
builder.UseSqlServer("Server=.\\sqlexpress;Database=IdentityDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True");
|
||||||
return new IdentityContext(builder.Options, null);
|
return new IdentityContext(builder.Options, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,11 +8,13 @@ using System.Threading.Tasks;
|
|||||||
using BuildingBlocks.Core.Event;
|
using BuildingBlocks.Core.Event;
|
||||||
using BuildingBlocks.Core.Model;
|
using BuildingBlocks.Core.Model;
|
||||||
using BuildingBlocks.EFCore;
|
using BuildingBlocks.EFCore;
|
||||||
|
using Humanizer;
|
||||||
using Identity.Identity.Models;
|
using Identity.Identity.Models;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
using Microsoft.EntityFrameworkCore.Storage;
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
|
|
||||||
namespace Identity.Data;
|
namespace Identity.Data;
|
||||||
@ -21,8 +23,6 @@ public sealed class IdentityContext : IdentityDbContext<ApplicationUser, Identit
|
|||||||
IdentityUserClaim<long>,
|
IdentityUserClaim<long>,
|
||||||
IdentityUserRole<long>, IdentityUserLogin<long>, IdentityRoleClaim<long>, IdentityUserToken<long>>, IDbContext
|
IdentityUserRole<long>, IdentityUserLogin<long>, IdentityRoleClaim<long>, IdentityUserToken<long>>, IDbContext
|
||||||
{
|
{
|
||||||
public const string DefaultSchema = "dbo";
|
|
||||||
|
|
||||||
private IDbContextTransaction _currentTransaction;
|
private IDbContextTransaction _currentTransaction;
|
||||||
|
|
||||||
public IdentityContext(DbContextOptions<IdentityContext> options, IHttpContextAccessor httpContextAccessor) :
|
public IdentityContext(DbContextOptions<IdentityContext> options, IHttpContextAccessor httpContextAccessor) :
|
||||||
@ -35,6 +35,13 @@ public sealed class IdentityContext : IdentityDbContext<ApplicationUser, Identit
|
|||||||
builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
|
builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
|
||||||
base.OnModelCreating(builder);
|
base.OnModelCreating(builder);
|
||||||
|
|
||||||
|
// https://andrewlock.net/customising-asp-net-core-identity-ef-core-naming-conventions-for-postgresql/
|
||||||
|
foreach (var entity in builder.Model.GetEntityTypes())
|
||||||
|
{
|
||||||
|
// Replace schema
|
||||||
|
entity.SetSchema(AppDbContextBase.DefaultSchema);
|
||||||
|
}
|
||||||
|
|
||||||
builder.FilterSoftDeletedProperties();
|
builder.FilterSoftDeletedProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,17 +12,18 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|||||||
namespace Identity.Data.Migrations
|
namespace Identity.Data.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(IdentityContext))]
|
[DbContext(typeof(IdentityContext))]
|
||||||
[Migration("20220728175937_initial")]
|
[Migration("20221206180831_initial")]
|
||||||
partial class initial
|
partial class initial
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "6.0.1")
|
.HasAnnotation("ProductVersion", "7.0.0")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
modelBuilder.Entity("Identity.Identity.Models.ApplicationUser", b =>
|
modelBuilder.Entity("Identity.Identity.Models.ApplicationUser", b =>
|
||||||
{
|
{
|
||||||
@ -30,7 +31,7 @@ namespace Identity.Data.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"), 1L, 1);
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
|
||||||
|
|
||||||
b.Property<int>("AccessFailedCount")
|
b.Property<int>("AccessFailedCount")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
@ -98,7 +99,7 @@ namespace Identity.Data.Migrations
|
|||||||
.HasDatabaseName("UserNameIndex")
|
.HasDatabaseName("UserNameIndex")
|
||||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
||||||
|
|
||||||
b.ToTable("AspNetUsers", (string)null);
|
b.ToTable("AspNetUsers", "dbo");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole<long>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole<long>", b =>
|
||||||
@ -107,7 +108,7 @@ namespace Identity.Data.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"), 1L, 1);
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
b.Property<string>("ConcurrencyStamp")
|
||||||
.IsConcurrencyToken()
|
.IsConcurrencyToken()
|
||||||
@ -128,7 +129,7 @@ namespace Identity.Data.Migrations
|
|||||||
.HasDatabaseName("RoleNameIndex")
|
.HasDatabaseName("RoleNameIndex")
|
||||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
.HasFilter("[NormalizedName] IS NOT NULL");
|
||||||
|
|
||||||
b.ToTable("AspNetRoles", (string)null);
|
b.ToTable("AspNetRoles", "dbo");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<long>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<long>", b =>
|
||||||
@ -137,7 +138,7 @@ namespace Identity.Data.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
b.Property<string>("ClaimType")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
@ -152,7 +153,7 @@ namespace Identity.Data.Migrations
|
|||||||
|
|
||||||
b.HasIndex("RoleId");
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
b.ToTable("AspNetRoleClaims", (string)null);
|
b.ToTable("AspNetRoleClaims", "dbo");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<long>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<long>", b =>
|
||||||
@ -161,7 +162,7 @@ namespace Identity.Data.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
b.Property<string>("ClaimType")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
@ -176,7 +177,7 @@ namespace Identity.Data.Migrations
|
|||||||
|
|
||||||
b.HasIndex("UserId");
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
b.ToTable("AspNetUserClaims", (string)null);
|
b.ToTable("AspNetUserClaims", "dbo");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<long>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<long>", b =>
|
||||||
@ -197,7 +198,7 @@ namespace Identity.Data.Migrations
|
|||||||
|
|
||||||
b.HasIndex("UserId");
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
b.ToTable("AspNetUserLogins", (string)null);
|
b.ToTable("AspNetUserLogins", "dbo");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<long>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<long>", b =>
|
||||||
@ -212,7 +213,7 @@ namespace Identity.Data.Migrations
|
|||||||
|
|
||||||
b.HasIndex("RoleId");
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
b.ToTable("AspNetUserRoles", (string)null);
|
b.ToTable("AspNetUserRoles", "dbo");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<long>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<long>", b =>
|
||||||
@ -231,7 +232,7 @@ namespace Identity.Data.Migrations
|
|||||||
|
|
||||||
b.HasKey("UserId", "LoginProvider", "Name");
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
b.ToTable("AspNetUserTokens", (string)null);
|
b.ToTable("AspNetUserTokens", "dbo");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<long>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<long>", b =>
|
||||||
@ -5,12 +5,18 @@ using Microsoft.EntityFrameworkCore.Migrations;
|
|||||||
|
|
||||||
namespace Identity.Data.Migrations
|
namespace Identity.Data.Migrations
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
public partial class initial : Migration
|
public partial class initial : Migration
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
|
migrationBuilder.EnsureSchema(
|
||||||
|
name: "dbo");
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "AspNetRoles",
|
name: "AspNetRoles",
|
||||||
|
schema: "dbo",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<long>(type: "bigint", nullable: false)
|
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||||
@ -26,6 +32,7 @@ namespace Identity.Data.Migrations
|
|||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "AspNetUsers",
|
name: "AspNetUsers",
|
||||||
|
schema: "dbo",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<long>(type: "bigint", nullable: false)
|
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||||
@ -55,6 +62,7 @@ namespace Identity.Data.Migrations
|
|||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "AspNetRoleClaims",
|
name: "AspNetRoleClaims",
|
||||||
|
schema: "dbo",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<int>(type: "int", nullable: false)
|
Id = table.Column<int>(type: "int", nullable: false)
|
||||||
@ -69,6 +77,7 @@ namespace Identity.Data.Migrations
|
|||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
|
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
|
||||||
column: x => x.RoleId,
|
column: x => x.RoleId,
|
||||||
|
principalSchema: "dbo",
|
||||||
principalTable: "AspNetRoles",
|
principalTable: "AspNetRoles",
|
||||||
principalColumn: "Id",
|
principalColumn: "Id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
@ -76,6 +85,7 @@ namespace Identity.Data.Migrations
|
|||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "AspNetUserClaims",
|
name: "AspNetUserClaims",
|
||||||
|
schema: "dbo",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<int>(type: "int", nullable: false)
|
Id = table.Column<int>(type: "int", nullable: false)
|
||||||
@ -90,6 +100,7 @@ namespace Identity.Data.Migrations
|
|||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
|
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
|
||||||
column: x => x.UserId,
|
column: x => x.UserId,
|
||||||
|
principalSchema: "dbo",
|
||||||
principalTable: "AspNetUsers",
|
principalTable: "AspNetUsers",
|
||||||
principalColumn: "Id",
|
principalColumn: "Id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
@ -97,6 +108,7 @@ namespace Identity.Data.Migrations
|
|||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "AspNetUserLogins",
|
name: "AspNetUserLogins",
|
||||||
|
schema: "dbo",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
LoginProvider = table.Column<string>(type: "nvarchar(450)", nullable: false),
|
LoginProvider = table.Column<string>(type: "nvarchar(450)", nullable: false),
|
||||||
@ -110,6 +122,7 @@ namespace Identity.Data.Migrations
|
|||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
|
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
|
||||||
column: x => x.UserId,
|
column: x => x.UserId,
|
||||||
|
principalSchema: "dbo",
|
||||||
principalTable: "AspNetUsers",
|
principalTable: "AspNetUsers",
|
||||||
principalColumn: "Id",
|
principalColumn: "Id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
@ -117,6 +130,7 @@ namespace Identity.Data.Migrations
|
|||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "AspNetUserRoles",
|
name: "AspNetUserRoles",
|
||||||
|
schema: "dbo",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
UserId = table.Column<long>(type: "bigint", nullable: false),
|
UserId = table.Column<long>(type: "bigint", nullable: false),
|
||||||
@ -128,12 +142,14 @@ namespace Identity.Data.Migrations
|
|||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
|
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
|
||||||
column: x => x.RoleId,
|
column: x => x.RoleId,
|
||||||
|
principalSchema: "dbo",
|
||||||
principalTable: "AspNetRoles",
|
principalTable: "AspNetRoles",
|
||||||
principalColumn: "Id",
|
principalColumn: "Id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
|
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
|
||||||
column: x => x.UserId,
|
column: x => x.UserId,
|
||||||
|
principalSchema: "dbo",
|
||||||
principalTable: "AspNetUsers",
|
principalTable: "AspNetUsers",
|
||||||
principalColumn: "Id",
|
principalColumn: "Id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
@ -141,6 +157,7 @@ namespace Identity.Data.Migrations
|
|||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "AspNetUserTokens",
|
name: "AspNetUserTokens",
|
||||||
|
schema: "dbo",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
UserId = table.Column<long>(type: "bigint", nullable: false),
|
UserId = table.Column<long>(type: "bigint", nullable: false),
|
||||||
@ -154,6 +171,7 @@ namespace Identity.Data.Migrations
|
|||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
|
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
|
||||||
column: x => x.UserId,
|
column: x => x.UserId,
|
||||||
|
principalSchema: "dbo",
|
||||||
principalTable: "AspNetUsers",
|
principalTable: "AspNetUsers",
|
||||||
principalColumn: "Id",
|
principalColumn: "Id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
@ -161,11 +179,13 @@ namespace Identity.Data.Migrations
|
|||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "IX_AspNetRoleClaims_RoleId",
|
name: "IX_AspNetRoleClaims_RoleId",
|
||||||
|
schema: "dbo",
|
||||||
table: "AspNetRoleClaims",
|
table: "AspNetRoleClaims",
|
||||||
column: "RoleId");
|
column: "RoleId");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "RoleNameIndex",
|
name: "RoleNameIndex",
|
||||||
|
schema: "dbo",
|
||||||
table: "AspNetRoles",
|
table: "AspNetRoles",
|
||||||
column: "NormalizedName",
|
column: "NormalizedName",
|
||||||
unique: true,
|
unique: true,
|
||||||
@ -173,54 +193,67 @@ namespace Identity.Data.Migrations
|
|||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "IX_AspNetUserClaims_UserId",
|
name: "IX_AspNetUserClaims_UserId",
|
||||||
|
schema: "dbo",
|
||||||
table: "AspNetUserClaims",
|
table: "AspNetUserClaims",
|
||||||
column: "UserId");
|
column: "UserId");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "IX_AspNetUserLogins_UserId",
|
name: "IX_AspNetUserLogins_UserId",
|
||||||
|
schema: "dbo",
|
||||||
table: "AspNetUserLogins",
|
table: "AspNetUserLogins",
|
||||||
column: "UserId");
|
column: "UserId");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "IX_AspNetUserRoles_RoleId",
|
name: "IX_AspNetUserRoles_RoleId",
|
||||||
|
schema: "dbo",
|
||||||
table: "AspNetUserRoles",
|
table: "AspNetUserRoles",
|
||||||
column: "RoleId");
|
column: "RoleId");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "EmailIndex",
|
name: "EmailIndex",
|
||||||
|
schema: "dbo",
|
||||||
table: "AspNetUsers",
|
table: "AspNetUsers",
|
||||||
column: "NormalizedEmail");
|
column: "NormalizedEmail");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "UserNameIndex",
|
name: "UserNameIndex",
|
||||||
|
schema: "dbo",
|
||||||
table: "AspNetUsers",
|
table: "AspNetUsers",
|
||||||
column: "NormalizedUserName",
|
column: "NormalizedUserName",
|
||||||
unique: true,
|
unique: true,
|
||||||
filter: "[NormalizedUserName] IS NOT NULL");
|
filter: "[NormalizedUserName] IS NOT NULL");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "AspNetRoleClaims");
|
name: "AspNetRoleClaims",
|
||||||
|
schema: "dbo");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "AspNetUserClaims");
|
name: "AspNetUserClaims",
|
||||||
|
schema: "dbo");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "AspNetUserLogins");
|
name: "AspNetUserLogins",
|
||||||
|
schema: "dbo");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "AspNetUserRoles");
|
name: "AspNetUserRoles",
|
||||||
|
schema: "dbo");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "AspNetUserTokens");
|
name: "AspNetUserTokens",
|
||||||
|
schema: "dbo");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "AspNetRoles");
|
name: "AspNetRoles",
|
||||||
|
schema: "dbo");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "AspNetUsers");
|
name: "AspNetUsers",
|
||||||
|
schema: "dbo");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -17,10 +17,10 @@ namespace Identity.Data.Migrations
|
|||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "6.0.1")
|
.HasAnnotation("ProductVersion", "7.0.0")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
modelBuilder.Entity("Identity.Identity.Models.ApplicationUser", b =>
|
modelBuilder.Entity("Identity.Identity.Models.ApplicationUser", b =>
|
||||||
{
|
{
|
||||||
@ -28,7 +28,7 @@ namespace Identity.Data.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"), 1L, 1);
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
|
||||||
|
|
||||||
b.Property<int>("AccessFailedCount")
|
b.Property<int>("AccessFailedCount")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
@ -96,7 +96,7 @@ namespace Identity.Data.Migrations
|
|||||||
.HasDatabaseName("UserNameIndex")
|
.HasDatabaseName("UserNameIndex")
|
||||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
||||||
|
|
||||||
b.ToTable("AspNetUsers", (string)null);
|
b.ToTable("AspNetUsers", "dbo");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole<long>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole<long>", b =>
|
||||||
@ -105,7 +105,7 @@ namespace Identity.Data.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"), 1L, 1);
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
b.Property<string>("ConcurrencyStamp")
|
||||||
.IsConcurrencyToken()
|
.IsConcurrencyToken()
|
||||||
@ -126,7 +126,7 @@ namespace Identity.Data.Migrations
|
|||||||
.HasDatabaseName("RoleNameIndex")
|
.HasDatabaseName("RoleNameIndex")
|
||||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
.HasFilter("[NormalizedName] IS NOT NULL");
|
||||||
|
|
||||||
b.ToTable("AspNetRoles", (string)null);
|
b.ToTable("AspNetRoles", "dbo");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<long>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<long>", b =>
|
||||||
@ -135,7 +135,7 @@ namespace Identity.Data.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
b.Property<string>("ClaimType")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
@ -150,7 +150,7 @@ namespace Identity.Data.Migrations
|
|||||||
|
|
||||||
b.HasIndex("RoleId");
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
b.ToTable("AspNetRoleClaims", (string)null);
|
b.ToTable("AspNetRoleClaims", "dbo");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<long>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<long>", b =>
|
||||||
@ -159,7 +159,7 @@ namespace Identity.Data.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
b.Property<string>("ClaimType")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
@ -174,7 +174,7 @@ namespace Identity.Data.Migrations
|
|||||||
|
|
||||||
b.HasIndex("UserId");
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
b.ToTable("AspNetUserClaims", (string)null);
|
b.ToTable("AspNetUserClaims", "dbo");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<long>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<long>", b =>
|
||||||
@ -195,7 +195,7 @@ namespace Identity.Data.Migrations
|
|||||||
|
|
||||||
b.HasIndex("UserId");
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
b.ToTable("AspNetUserLogins", (string)null);
|
b.ToTable("AspNetUserLogins", "dbo");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<long>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<long>", b =>
|
||||||
@ -210,7 +210,7 @@ namespace Identity.Data.Migrations
|
|||||||
|
|
||||||
b.HasIndex("RoleId");
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
b.ToTable("AspNetUserRoles", (string)null);
|
b.ToTable("AspNetUserRoles", "dbo");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<long>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<long>", b =>
|
||||||
@ -229,7 +229,7 @@ namespace Identity.Data.Migrations
|
|||||||
|
|
||||||
b.HasKey("UserId", "LoginProvider", "Name");
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
b.ToTable("AspNetUserTokens", (string)null);
|
b.ToTable("AspNetUserTokens", "dbo");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<long>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<long>", b =>
|
||||||
|
|||||||
@ -41,7 +41,7 @@ public static class InfrastructureExtensions
|
|||||||
options.SuppressModelStateInvalidFilter = true;
|
options.SuppressModelStateInvalidFilter = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
var appOptions = builder.Services.GetOptions<AppOptions>("AppOptions");
|
var appOptions = builder.Services.GetOptions<AppOptions>(nameof(AppOptions));
|
||||||
Console.WriteLine(FiggleFonts.Standard.Render(appOptions.Name));
|
Console.WriteLine(FiggleFonts.Standard.Render(appOptions.Name));
|
||||||
|
|
||||||
builder.Services.AddRateLimiter(options =>
|
builder.Services.AddRateLimiter(options =>
|
||||||
@ -56,8 +56,8 @@ public static class InfrastructureExtensions
|
|||||||
});
|
});
|
||||||
|
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
builder.Services.AddPersistMessage(configuration);
|
builder.Services.AddPersistMessageProcessor();
|
||||||
builder.Services.AddCustomDbContext<IdentityContext>(configuration);
|
builder.Services.AddCustomDbContext<IdentityContext>();
|
||||||
builder.Services.AddScoped<IDataSeeder, IdentityDataSeeder>();
|
builder.Services.AddScoped<IDataSeeder, IdentityDataSeeder>();
|
||||||
builder.AddCustomSerilog(env);
|
builder.AddCustomSerilog(env);
|
||||||
builder.Services.AddCustomSwagger(configuration, typeof(IdentityRoot).Assembly);
|
builder.Services.AddCustomSwagger(configuration, typeof(IdentityRoot).Assembly);
|
||||||
@ -82,7 +82,7 @@ public static class InfrastructureExtensions
|
|||||||
public static WebApplication UseInfrastructure(this WebApplication app)
|
public static WebApplication UseInfrastructure(this WebApplication app)
|
||||||
{
|
{
|
||||||
var env = app.Environment;
|
var env = app.Environment;
|
||||||
var appOptions = app.GetOptions<AppOptions>("AppOptions");
|
var appOptions = app.GetOptions<AppOptions>(nameof(AppOptions));
|
||||||
|
|
||||||
app.UseProblemDetails();
|
app.UseProblemDetails();
|
||||||
app.UseSerilogRequestLogging();
|
app.UseSerilogRequestLogging();
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Folder Include="Data\Configurations" />
|
||||||
<Folder Include="Data\Migrations" />
|
<Folder Include="Data\Migrations" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@ -5,16 +5,14 @@ using FluentAssertions;
|
|||||||
using Identity.Api;
|
using Identity.Api;
|
||||||
using Identity.Data;
|
using Identity.Data;
|
||||||
using Integration.Test.Fakes;
|
using Integration.Test.Fakes;
|
||||||
using MassTransit;
|
|
||||||
using MassTransit.Testing;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Integration.Test.Identity.Features;
|
namespace Integration.Test.Identity.Features;
|
||||||
|
|
||||||
public class RegisterNewUserTests : IntegrationTestBase<Program, IdentityContext>
|
public class RegisterNewUserTests : IdentityIntegrationTestBase
|
||||||
{
|
{
|
||||||
public RegisterNewUserTests(IntegrationTestFixture<Program, IdentityContext> integrationTestFixture) : base(
|
public RegisterNewUserTests(
|
||||||
integrationTestFixture)
|
IntegrationTestFactory<Program, IdentityContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,6 +29,6 @@ public class RegisterNewUserTests : IntegrationTestBase<Program, IdentityContext
|
|||||||
response?.Should().NotBeNull();
|
response?.Should().NotBeNull();
|
||||||
response?.Username.Should().Be(command.Username);
|
response?.Username.Should().Be(command.Username);
|
||||||
|
|
||||||
await Fixture.WaitForPublishing<UserCreated>();
|
(await Fixture.WaitForPublishing<UserCreated>()).Should().Be(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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<Program, IdentityContext>
|
||||||
|
{
|
||||||
|
public IdentityIntegrationTestBase(IntegrationTestFactory<Program, IdentityContext> integrationTestFactory)
|
||||||
|
: base(integrationTestFactory)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CollectionDefinition(Name)]
|
||||||
|
public class IntegrationTestCollection : ICollectionFixture<IntegrationTestFactory<Program, IdentityContext>>
|
||||||
|
{
|
||||||
|
public const string Name = "Identity Integration Test";
|
||||||
|
}
|
||||||
@ -1,13 +1,18 @@
|
|||||||
{
|
{
|
||||||
"App": "Passenger-Service",
|
"App": "Passenger-Service",
|
||||||
"ConnectionStrings": {
|
"DatabaseOptions": {
|
||||||
"DefaultConnection": "Server=db;Database=PassengerDB;User ID=sa;Password=@Aa123456"
|
"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": {
|
"Jwt": {
|
||||||
"Authority": "https://localhost:5005",
|
"Authority": "https://localhost:5005",
|
||||||
"Audience": "passenger-api"
|
"Audience": "passenger-api"
|
||||||
},
|
},
|
||||||
"RabbitMq": {
|
"RabbitMqOptions": {
|
||||||
"HostName": "rabbitmq",
|
"HostName": "rabbitmq",
|
||||||
"ExchangeName": "passenger",
|
"ExchangeName": "passenger",
|
||||||
"UserName": "guest",
|
"UserName": "guest",
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"AppOptions": {
|
"AppOptions": {
|
||||||
"Name": "Passenger-Service"
|
"Name": "Passenger-Service"
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"DatabaseOptions": {
|
||||||
"DefaultConnection": "Server=.\\sqlexpress;Database=PassengerDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
"DefaultConnection": "Server=.\\sqlexpress;Database=PassengerDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
||||||
},
|
},
|
||||||
"MongoOptions": {
|
"MongoOptions": {
|
||||||
@ -13,7 +13,7 @@
|
|||||||
"Authority": "https://localhost:5005",
|
"Authority": "https://localhost:5005",
|
||||||
"Audience": "passenger-api"
|
"Audience": "passenger-api"
|
||||||
},
|
},
|
||||||
"RabbitMq": {
|
"RabbitMqOptions": {
|
||||||
"HostName": "localhost",
|
"HostName": "localhost",
|
||||||
"ExchangeName": "passenger",
|
"ExchangeName": "passenger",
|
||||||
"UserName": "guest",
|
"UserName": "guest",
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"ConnectionStrings": {
|
"DatabaseOptions": {
|
||||||
"DefaultConnection": "Server=.\\sqlexpress;Database=PassengerDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
"DefaultConnection": "Server=.\\sqlexpress;Database=PassengerDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
||||||
},
|
},
|
||||||
"RabbitMq": {
|
"RabbitMqOptions": {
|
||||||
"HostName": "localhost",
|
"HostName": "localhost",
|
||||||
"ExchangeName": "passenger",
|
"ExchangeName": "passenger",
|
||||||
"UserName": "guest",
|
"UserName": "guest",
|
||||||
@ -18,8 +18,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"PersistMessageOptions": {
|
"PersistMessageOptions": {
|
||||||
"Interval": 1,
|
"Interval": 30,
|
||||||
"Enabled": true,
|
"Enabled": true,
|
||||||
"ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageTestDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
"ConnectionString": "Server=.\\sqlexpress;Database=PersistMessageDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
using BuildingBlocks.EFCore;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
|
|
||||||
@ -7,7 +8,7 @@ public class PassengerConfiguration: IEntityTypeConfiguration<Passengers.Models.
|
|||||||
{
|
{
|
||||||
public void Configure(EntityTypeBuilder<Passengers.Models.Passenger> builder)
|
public void Configure(EntityTypeBuilder<Passengers.Models.Passenger> builder)
|
||||||
{
|
{
|
||||||
builder.ToTable("Passenger", "dbo");
|
builder.ToTable("Passenger", AppDbContextBase.DefaultSchema);
|
||||||
|
|
||||||
builder.HasKey(r => r.Id);
|
builder.HasKey(r => r.Id);
|
||||||
builder.Property(r => r.Id).ValueGeneratedNever();
|
builder.Property(r => r.Id).ValueGeneratedNever();
|
||||||
|
|||||||
@ -10,7 +10,7 @@ public class DesignTimeDbContextFactory: IDesignTimeDbContextFactory<PassengerDb
|
|||||||
var builder = new DbContextOptionsBuilder<PassengerDbContext>();
|
var builder = new DbContextOptionsBuilder<PassengerDbContext>();
|
||||||
|
|
||||||
builder.UseSqlServer(
|
builder.UseSqlServer(
|
||||||
"Data Source=.\\sqlexpress;Initial Catalog=PassengerDB;Persist Security Info=False;Integrated Security=SSPI");
|
"Data Source=.\\sqlexpress;Initial Catalog=PassengerDB;Persist Security Info=False;Integrated Security=SSPI;TrustServerCertificate=True");
|
||||||
return new PassengerDbContext(builder.Options, null);
|
return new PassengerDbContext(builder.Options, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,17 +12,18 @@ using Passenger.Data;
|
|||||||
namespace Passenger.Data.Migrations
|
namespace Passenger.Data.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(PassengerDbContext))]
|
[DbContext(typeof(PassengerDbContext))]
|
||||||
[Migration("20220728180020_initial")]
|
[Migration("20221206180929_initial")]
|
||||||
partial class initial
|
partial class initial
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "6.0.1")
|
.HasAnnotation("ProductVersion", "7.0.0")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
modelBuilder.Entity("Passenger.Passengers.Models.Passenger", b =>
|
modelBuilder.Entity("Passenger.Passengers.Models.Passenger", b =>
|
||||||
{
|
{
|
||||||
@ -5,8 +5,10 @@ using Microsoft.EntityFrameworkCore.Migrations;
|
|||||||
|
|
||||||
namespace Passenger.Data.Migrations
|
namespace Passenger.Data.Migrations
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
public partial class initial : Migration
|
public partial class initial : Migration
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
migrationBuilder.EnsureSchema(
|
migrationBuilder.EnsureSchema(
|
||||||
@ -35,6 +37,7 @@ namespace Passenger.Data.Migrations
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
@ -17,10 +17,10 @@ namespace Passenger.Data.Migrations
|
|||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "6.0.1")
|
.HasAnnotation("ProductVersion", "7.0.0")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
modelBuilder.Entity("Passenger.Passengers.Models.Passenger", b =>
|
modelBuilder.Entity("Passenger.Passengers.Models.Passenger", b =>
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,15 +1,12 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using BuildingBlocks.EFCore;
|
using BuildingBlocks.EFCore;
|
||||||
using BuildingBlocks.Utils;
|
using BuildingBlocks.Web;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace Passenger.Data;
|
namespace Passenger.Data;
|
||||||
|
|
||||||
public sealed class PassengerDbContext : AppDbContextBase
|
public sealed class PassengerDbContext : AppDbContextBase
|
||||||
{
|
{
|
||||||
public const string DefaultSchema = "dbo";
|
|
||||||
|
|
||||||
public PassengerDbContext(DbContextOptions<PassengerDbContext> options, ICurrentUserProvider currentUserProvider) : base(options, currentUserProvider)
|
public PassengerDbContext(DbContextOptions<PassengerDbContext> options, ICurrentUserProvider currentUserProvider) : base(options, currentUserProvider)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,7 +45,7 @@ public static class InfrastructureExtensions
|
|||||||
options.SuppressModelStateInvalidFilter = true;
|
options.SuppressModelStateInvalidFilter = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
var appOptions = builder.Services.GetOptions<AppOptions>("AppOptions");
|
var appOptions = builder.Services.GetOptions<AppOptions>(nameof(AppOptions));
|
||||||
Console.WriteLine(FiggleFonts.Standard.Render(appOptions.Name));
|
Console.WriteLine(FiggleFonts.Standard.Render(appOptions.Name));
|
||||||
|
|
||||||
builder.Services.AddRateLimiter(options =>
|
builder.Services.AddRateLimiter(options =>
|
||||||
@ -59,9 +59,9 @@ public static class InfrastructureExtensions
|
|||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Services.AddCustomDbContext<PassengerDbContext>(configuration);
|
builder.Services.AddPersistMessageProcessor();
|
||||||
|
builder.Services.AddCustomDbContext<PassengerDbContext>();
|
||||||
builder.Services.AddMongoDbContext<PassengerReadDbContext>(configuration);
|
builder.Services.AddMongoDbContext<PassengerReadDbContext>(configuration);
|
||||||
builder.Services.AddPersistMessage(configuration);
|
|
||||||
|
|
||||||
builder.AddCustomSerilog(env);
|
builder.AddCustomSerilog(env);
|
||||||
builder.Services.AddJwt();
|
builder.Services.AddJwt();
|
||||||
@ -89,7 +89,7 @@ public static class InfrastructureExtensions
|
|||||||
public static WebApplication UseInfrastructure(this WebApplication app)
|
public static WebApplication UseInfrastructure(this WebApplication app)
|
||||||
{
|
{
|
||||||
var env = app.Environment;
|
var env = app.Environment;
|
||||||
var appOptions = app.GetOptions<AppOptions>("AppOptions");
|
var appOptions = app.GetOptions<AppOptions>(nameof(AppOptions));
|
||||||
|
|
||||||
app.UseProblemDetails();
|
app.UseProblemDetails();
|
||||||
app.UseSerilogRequestLogging();
|
app.UseSerilogRequestLogging();
|
||||||
|
|||||||
@ -9,7 +9,7 @@ public class FakeUserCreated : AutoFaker<UserCreated>
|
|||||||
public FakeUserCreated()
|
public FakeUserCreated()
|
||||||
{
|
{
|
||||||
RuleFor(r => r.Id, _ => SnowFlakIdGenerator.NewId());
|
RuleFor(r => r.Id, _ => SnowFlakIdGenerator.NewId());
|
||||||
RuleFor(r => r.Name, _ => "Meysam");
|
RuleFor(r => r.Name, _ => "Sam");
|
||||||
RuleFor(r => r.PassportNumber, _ => "1299878");
|
RuleFor(r => r.PassportNumber, _ => "123456789");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,18 +3,16 @@ using BuildingBlocks.Contracts.EventBus.Messages;
|
|||||||
using BuildingBlocks.TestBase;
|
using BuildingBlocks.TestBase;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Integration.Test.Fakes;
|
using Integration.Test.Fakes;
|
||||||
using MassTransit.Testing;
|
|
||||||
using Passenger.Api;
|
using Passenger.Api;
|
||||||
using Passenger.Data;
|
using Passenger.Data;
|
||||||
using Passenger.Passengers.Features.CompleteRegisterPassenger.Commands.V1.Reads;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Integration.Test.Passenger.Features;
|
namespace Integration.Test.Passenger.Features;
|
||||||
|
|
||||||
public class CompleteRegisterPassengerTests : IntegrationTestBase<Program, PassengerDbContext>
|
public class CompleteRegisterPassengerTests : PassengerIntegrationTestBase
|
||||||
{
|
{
|
||||||
public CompleteRegisterPassengerTests(IntegrationTestFixture<Program, PassengerDbContext> integrationTestFixture) :
|
public CompleteRegisterPassengerTests(
|
||||||
base(integrationTestFixture)
|
IntegrationTestFactory<Program, PassengerDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,7 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BuildingBlocks.Contracts.EventBus.Messages;
|
|
||||||
using BuildingBlocks.TestBase;
|
using BuildingBlocks.TestBase;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Grpc.Net.Client;
|
|
||||||
using Integration.Test.Fakes;
|
using Integration.Test.Fakes;
|
||||||
using MassTransit.Testing;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Passenger;
|
using Passenger;
|
||||||
using Passenger.Api;
|
using Passenger.Api;
|
||||||
using Passenger.Data;
|
using Passenger.Data;
|
||||||
@ -14,17 +10,13 @@ using Xunit;
|
|||||||
|
|
||||||
namespace Integration.Test.Passenger.Features;
|
namespace Integration.Test.Passenger.Features;
|
||||||
|
|
||||||
public class GetPassengerByIdTests : IntegrationTestBase<Program, PassengerDbContext>
|
public class GetPassengerByIdTests : PassengerIntegrationTestBase
|
||||||
{
|
{
|
||||||
private readonly GrpcChannel _channel;
|
public GetPassengerByIdTests(
|
||||||
|
IntegrationTestFactory<Program, PassengerDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
public GetPassengerByIdTests(IntegrationTestFixture<Program, PassengerDbContext> integrationTestFixture) : base(
|
|
||||||
integrationTestFixture)
|
|
||||||
{
|
{
|
||||||
_channel = Fixture.Channel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task should_retrive_a_passenger_by_id_currectly()
|
public async Task should_retrive_a_passenger_by_id_currectly()
|
||||||
{
|
{
|
||||||
@ -53,7 +45,7 @@ public class GetPassengerByIdTests : IntegrationTestBase<Program, PassengerDbCon
|
|||||||
var passengerEntity = FakePassengerCreated.Generate(userCreated);
|
var passengerEntity = FakePassengerCreated.Generate(userCreated);
|
||||||
await Fixture.InsertAsync(passengerEntity);
|
await Fixture.InsertAsync(passengerEntity);
|
||||||
|
|
||||||
var passengerGrpcClient = new PassengerGrpcService.PassengerGrpcServiceClient(_channel);
|
var passengerGrpcClient = new PassengerGrpcService.PassengerGrpcServiceClient(Fixture.Channel);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await passengerGrpcClient.GetByIdAsync(new GetByIdRequest {Id = passengerEntity.Id});
|
var response = await passengerGrpcClient.GetByIdAsync(new GetByIdRequest {Id = passengerEntity.Id});
|
||||||
|
|||||||
@ -0,0 +1,21 @@
|
|||||||
|
using BuildingBlocks.TestBase;
|
||||||
|
using Passenger.Api;
|
||||||
|
using Passenger.Data;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Integration.Test;
|
||||||
|
|
||||||
|
[Collection(IntegrationTestCollection.Name)]
|
||||||
|
public class PassengerIntegrationTestBase: IntegrationTestBase<Program, PassengerDbContext>
|
||||||
|
{
|
||||||
|
public PassengerIntegrationTestBase(IntegrationTestFactory<Program, PassengerDbContext> integrationTestFactory)
|
||||||
|
: base(integrationTestFactory)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CollectionDefinition(Name)]
|
||||||
|
public class IntegrationTestCollection : ICollectionFixture<IntegrationTestFactory<Program, PassengerDbContext>>
|
||||||
|
{
|
||||||
|
public const string Name = "Passenger Integration Test";
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user