Merge pull request #239 from meysamhadeli/refactor/refactor-id-genrator

Refactor/refactor id genrator
This commit is contained in:
Meysam Hadeli 2023-03-30 12:20:09 +03:30 committed by GitHub
commit 021e218671
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 67 additions and 70 deletions

View File

@ -163,8 +163,7 @@ docker-compose -f ./deployments/docker-compose/docker-compose.yaml up -d
``` ```
> ### Kubernetes > ### Kubernetes
For Configure TLS in kubernetes cluster we need install `cert-manager` base on [docs](https://cert-manager.io/docs/installation) and run the following commands for apply TLS in our application For Configure TLS in kubernetes cluster we need install `cert-manager` base on [docs](https://cert-manager.io/docs/installation) and run the following commands for apply TLS in our application. Here we use [LetsEncrypt](https://letsencrypt.org/) for encryption our certificate.
Here we use [LetsEncrypt](https://letsencrypt.org/) for encrypt our certificate.
```bash ```bash
kubectl apply -f ./deployments/kubernetes/booking-cert-manager.yml kubectl apply -f ./deployments/kubernetes/booking-cert-manager.yml

View File

@ -18,6 +18,7 @@
<PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="6.0.2" /> <PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="6.0.2" />
<PackageReference Include="AspNetCore.HealthChecks.UI.SQLite.Storage" Version="6.0.5" /> <PackageReference Include="AspNetCore.HealthChecks.UI.SQLite.Storage" Version="6.0.5" />
<PackageReference Include="Ben.BlockingDetector" Version="0.0.4" /> <PackageReference Include="Ben.BlockingDetector" Version="0.0.4" />
<PackageReference Include="DotNetEnv" Version="2.5.0" />
<PackageReference Include="EasyCaching.Core" Version="1.8.0" /> <PackageReference Include="EasyCaching.Core" Version="1.8.0" />
<PackageReference Include="EasyCaching.InMemory" Version="1.8.0" /> <PackageReference Include="EasyCaching.InMemory" Version="1.8.0" />
<PackageReference Include="EasyNetQ.Management.Client" Version="1.4.2" /> <PackageReference Include="EasyNetQ.Management.Client" Version="1.4.2" />

View File

@ -5,7 +5,7 @@ namespace BuildingBlocks.Core.Event;
public interface IEvent : INotification public interface IEvent : INotification
{ {
long EventId => SnowFlakIdGenerator.NewId(); long EventId => SnowflakeIdGenerator.NewId();
public DateTime OccurredOn => DateTime.Now; public DateTime OccurredOn => DateTime.Now;
public string EventType => GetType().AssemblyQualifiedName; public string EventType => GetType().AssemblyQualifiedName;
} }

View File

@ -1,4 +1,3 @@
using Ardalis.GuardClauses;
using IdGen; using IdGen;
namespace BuildingBlocks.IdsGenerator; namespace BuildingBlocks.IdsGenerator;
@ -6,16 +5,16 @@ namespace BuildingBlocks.IdsGenerator;
// Ref: https://github.com/RobThree/IdGen // Ref: https://github.com/RobThree/IdGen
// https://github.com/RobThree/IdGen/issues/34 // https://github.com/RobThree/IdGen/issues/34
// https://www.callicoder.com/distributed-unique-id-sequence-number-generator/ // https://www.callicoder.com/distributed-unique-id-sequence-number-generator/
public static class SnowFlakIdGenerator public static class SnowflakeIdGenerator
{ {
private static IdGenerator _generator; private static readonly IdGenerator Generator;
static SnowflakeIdGenerator()
public static void Configure(int generatorId)
{ {
Guard.Against.NegativeOrZero(generatorId, nameof(generatorId)); // Read `GENERATOR_ID` from .env file in service root folder or system environment variables
var generatorId = DotNetEnv.Env.GetInt("GENERATOR_ID", 0);
// Let's say we take jan 17st 2022 as our epoch // Let's say we take current time as our epoch
var epoch = new DateTime(2022, 1, 1, 0, 0, 0, DateTimeKind.Local); var epoch = DateTime.Now;
// Create an ID with 45 bits for timestamp, 2 for generator-id // Create an ID with 45 bits for timestamp, 2 for generator-id
// and 16 for sequence // and 16 for sequence
@ -26,8 +25,11 @@ public static class SnowFlakIdGenerator
// Create an IdGenerator with it's generator-id set to 0, our custom epoch // Create an IdGenerator with it's generator-id set to 0, our custom epoch
// and id-structure // and id-structure
_generator = new IdGenerator(0, options); Generator = new IdGenerator(generatorId, options);
} }
public static long NewId() => _generator.CreateId(); public static long NewId()
{
return Generator.CreateId();
}
} }

View File

@ -202,7 +202,7 @@ public class PersistMessageProcessor : IPersistMessageProcessor
if (messageEnvelope.Message is IEvent message) if (messageEnvelope.Message is IEvent message)
id = message.EventId; id = message.EventId;
else else
id = SnowFlakIdGenerator.NewId(); id = SnowflakeIdGenerator.NewId();
await _persistMessageDbContext.PersistMessages.AddAsync( await _persistMessageDbContext.PersistMessages.AddAsync(
new PersistMessage( new PersistMessage(

View File

@ -0,0 +1 @@
GENERATOR_ID=4

View File

@ -15,7 +15,7 @@ using Passenger;
public record CreateBooking(long PassengerId, long FlightId, string Description) : ICommand<CreateBookingResult>, IInternalCommand public record CreateBooking(long PassengerId, long FlightId, string Description) : ICommand<CreateBookingResult>, IInternalCommand
{ {
public long Id { get; init; } = SnowFlakIdGenerator.NewId(); public long Id { get; init; } = SnowflakeIdGenerator.NewId();
} }
public record CreateBookingResult(ulong Id); public record CreateBookingResult(ulong Id);

View File

@ -41,7 +41,7 @@ public class BookingProjection : IProjectionProcessor
{ {
var bookingReadModel = new BookingReadModel var bookingReadModel = new BookingReadModel
{ {
Id = SnowFlakIdGenerator.NewId(), Id = SnowflakeIdGenerator.NewId(),
Trip = @event.Trip, Trip = @event.Trip,
BookId = @event.Id, BookId = @event.Id,
PassengerInfo = @event.PassengerInfo, PassengerInfo = @event.PassengerInfo,

View File

@ -35,6 +35,9 @@ public static class InfrastructureExtensions
var configuration = builder.Configuration; var configuration = builder.Configuration;
var env = builder.Environment; var env = builder.Environment;
// https://github.com/tonerdo/dotnet-env
DotNetEnv.Env.TraversePath().Load();
builder.Services.AddScoped<ICurrentUserProvider, CurrentUserProvider>(); builder.Services.AddScoped<ICurrentUserProvider, CurrentUserProvider>();
builder.Services.AddScoped<IEventMapper, EventMapper>(); builder.Services.AddScoped<IEventMapper, EventMapper>();
builder.Services.AddScoped<IEventDispatcher, EventDispatcher>(); builder.Services.AddScoped<IEventDispatcher, EventDispatcher>();
@ -76,8 +79,6 @@ public static class InfrastructureExtensions
builder.Services.AddCustomOpenTelemetry(); builder.Services.AddCustomOpenTelemetry();
builder.Services.AddTransient<AuthHeaderHandler>(); builder.Services.AddTransient<AuthHeaderHandler>();
SnowFlakIdGenerator.Configure(3);
// ref: https://github.com/oskardudycz/EventSourcing.NetCore/tree/main/Sample/EventStoreDB/ECommerce // ref: https://github.com/oskardudycz/EventSourcing.NetCore/tree/main/Sample/EventStoreDB/ECommerce
builder.Services.AddEventStore(configuration, typeof(BookingRoot).Assembly) builder.Services.AddEventStore(configuration, typeof(BookingRoot).Assembly)
.AddEventStoreDBSubscriptionToAll(); .AddEventStoreDBSubscriptionToAll();

View File

@ -9,7 +9,7 @@ public sealed class FakeCreateBookingCommand : AutoFaker<CreateBooking>
{ {
public FakeCreateBookingCommand() public FakeCreateBookingCommand()
{ {
RuleFor(r => r.Id, _ => SnowFlakIdGenerator.NewId()); RuleFor(r => r.Id, _ => SnowflakeIdGenerator.NewId());
RuleFor(r => r.FlightId, _ => 1); RuleFor(r => r.FlightId, _ => 1);
RuleFor(r => r.PassengerId, _ => 1); RuleFor(r => r.PassengerId, _ => 1);
} }

View File

@ -8,6 +8,6 @@ public class FakePassengerResponse : AutoFaker<PassengerResponse>
{ {
public FakePassengerResponse() public FakePassengerResponse()
{ {
RuleFor(r => r.Id, _ => SnowFlakIdGenerator.NewId()); RuleFor(r => r.Id, _ => SnowflakeIdGenerator.NewId());
} }
} }

View File

@ -0,0 +1 @@
GENERATOR_ID=1

View File

@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Flight\Flight.csproj"/> <ProjectReference Include="..\Flight\Flight.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -11,11 +11,11 @@ public class AircraftMappings : IRegister
public void Register(TypeAdapterConfig config) public void Register(TypeAdapterConfig config)
{ {
config.NewConfig<CreateAircraftMongo, AircraftReadModel>() config.NewConfig<CreateAircraftMongo, AircraftReadModel>()
.Map(d => d.Id, s => SnowFlakIdGenerator.NewId()) .Map(d => d.Id, s => SnowflakeIdGenerator.NewId())
.Map(d => d.AircraftId, s => s.Id); .Map(d => d.AircraftId, s => s.Id);
config.NewConfig<Aircraft, AircraftReadModel>() config.NewConfig<Aircraft, AircraftReadModel>()
.Map(d => d.Id, s => SnowFlakIdGenerator.NewId()) .Map(d => d.Id, s => SnowflakeIdGenerator.NewId())
.Map(d => d.AircraftId, s => s.Id); .Map(d => d.AircraftId, s => s.Id);
config.NewConfig<CreateAircraftRequestDto, CreatingAircraft.V1.CreateAircraft>() config.NewConfig<CreateAircraftRequestDto, CreatingAircraft.V1.CreateAircraft>()

View File

@ -17,7 +17,7 @@ using Microsoft.EntityFrameworkCore;
public record CreateAircraft(string Name, string Model, int ManufacturingYear) : ICommand<CreateAircraftResult>, IInternalCommand public record CreateAircraft(string Name, string Model, int ManufacturingYear) : ICommand<CreateAircraftResult>, IInternalCommand
{ {
public long Id { get; init; } = SnowFlakIdGenerator.NewId(); public long Id { get; init; } = SnowflakeIdGenerator.NewId();
} }
public record CreateAircraftResult(long Id); public record CreateAircraftResult(long Id);

View File

@ -10,11 +10,11 @@ public class AirportMappings : IRegister
public void Register(TypeAdapterConfig config) public void Register(TypeAdapterConfig config)
{ {
config.NewConfig<CreateAirportMongo, AirportReadModel>() config.NewConfig<CreateAirportMongo, AirportReadModel>()
.Map(d => d.Id, s => SnowFlakIdGenerator.NewId()) .Map(d => d.Id, s => SnowflakeIdGenerator.NewId())
.Map(d => d.AirportId, s => s.Id); .Map(d => d.AirportId, s => s.Id);
config.NewConfig<Airport, AirportReadModel>() config.NewConfig<Airport, AirportReadModel>()
.Map(d => d.Id, s => SnowFlakIdGenerator.NewId()) .Map(d => d.Id, s => SnowflakeIdGenerator.NewId())
.Map(d => d.AirportId, s => s.Id); .Map(d => d.AirportId, s => s.Id);
config.NewConfig<CreateAirportRequestDto, CreateAirport>() config.NewConfig<CreateAirportRequestDto, CreateAirport>()

View File

@ -16,7 +16,7 @@ using Microsoft.EntityFrameworkCore;
public record CreateAirport(string Name, string Address, string Code) : ICommand<CreateAirportResult>, IInternalCommand public record CreateAirport(string Name, string Address, string Code) : ICommand<CreateAirportResult>, IInternalCommand
{ {
public long Id { get; init; } = SnowFlakIdGenerator.NewId(); public long Id { get; init; } = SnowflakeIdGenerator.NewId();
} }
public record CreateAirportResult(long Id); public record CreateAirportResult(long Id);

View File

@ -31,7 +31,6 @@ using Serilog;
namespace Flight.Extensions.Infrastructure; namespace Flight.Extensions.Infrastructure;
using BuildingBlocks.PersistMessageProcessor.Data; using BuildingBlocks.PersistMessageProcessor.Data;
using Microsoft.AspNetCore.HttpOverrides;
public static class InfrastructureExtensions public static class InfrastructureExtensions
{ {
@ -40,6 +39,9 @@ public static class InfrastructureExtensions
var configuration = builder.Configuration; var configuration = builder.Configuration;
var env = builder.Environment; var env = builder.Environment;
// https://github.com/tonerdo/dotnet-env
DotNetEnv.Env.TraversePath().Load();
builder.Services.AddScoped<ICurrentUserProvider, CurrentUserProvider>(); builder.Services.AddScoped<ICurrentUserProvider, CurrentUserProvider>();
builder.Services.AddScoped<IEventMapper, EventMapper>(); builder.Services.AddScoped<IEventMapper, EventMapper>();
builder.Services.AddScoped<IEventDispatcher, EventDispatcher>(); builder.Services.AddScoped<IEventDispatcher, EventDispatcher>();
@ -86,8 +88,6 @@ public static class InfrastructureExtensions
options.Interceptors.Add<GrpcExceptionInterceptor>(); options.Interceptors.Add<GrpcExceptionInterceptor>();
}); });
SnowFlakIdGenerator.Configure(1);
builder.Services.AddEasyCaching(options => { options.UseInMemory(configuration, "mem"); }); builder.Services.AddEasyCaching(options => { options.UseInMemory(configuration, "mem"); });
return builder; return builder;

View File

@ -19,7 +19,7 @@ public record CreateFlight(string FlightNumber, long AircraftId, long DepartureA
decimal DurationMinutes, DateTime FlightDate, Enums.FlightStatus Status, decimal DurationMinutes, DateTime FlightDate, Enums.FlightStatus Status,
decimal Price) : ICommand<CreateFlightResult>, IInternalCommand decimal Price) : ICommand<CreateFlightResult>, IInternalCommand
{ {
public long Id { get; init; } = SnowFlakIdGenerator.NewId(); public long Id { get; init; } = SnowflakeIdGenerator.NewId();
} }
public record CreateFlightResult(long Id); public record CreateFlightResult(long Id);

View File

@ -19,11 +19,11 @@ public class FlightMappings : IRegister
x.ArriveDate, x.ArriveAirportId, x.DurationMinutes, x.FlightDate, x.Status, x.Price)); x.ArriveDate, x.ArriveAirportId, x.DurationMinutes, x.FlightDate, x.Status, x.Price));
config.NewConfig<CreateFlightMongo, FlightReadModel>() config.NewConfig<CreateFlightMongo, FlightReadModel>()
.Map(d => d.Id, s => SnowFlakIdGenerator.NewId()) .Map(d => d.Id, s => SnowflakeIdGenerator.NewId())
.Map(d => d.FlightId, s => s.Id); .Map(d => d.FlightId, s => s.Id);
config.NewConfig<Models.Flight, FlightReadModel>() config.NewConfig<Models.Flight, FlightReadModel>()
.Map(d => d.Id, s => SnowFlakIdGenerator.NewId()) .Map(d => d.Id, s => SnowflakeIdGenerator.NewId())
.Map(d => d.FlightId, s => s.Id); .Map(d => d.FlightId, s => s.Id);
config.NewConfig<FlightReadModel, FlightDto>() config.NewConfig<FlightReadModel, FlightDto>()

View File

@ -17,7 +17,7 @@ using Microsoft.EntityFrameworkCore;
public record CreateSeat(string SeatNumber, Enums.SeatType Type, Enums.SeatClass Class, long FlightId) : ICommand<CreateSeatResult>, IInternalCommand public record CreateSeat(string SeatNumber, Enums.SeatType Type, Enums.SeatClass Class, long FlightId) : ICommand<CreateSeatResult>, IInternalCommand
{ {
public long Id { get; init; } = SnowFlakIdGenerator.NewId(); public long Id { get; init; } = SnowflakeIdGenerator.NewId();
} }
public record CreateSeatResult(long Id); public record CreateSeatResult(long Id);

View File

@ -16,11 +16,11 @@ public class SeatMappings : IRegister
.ConstructUsing(x => new SeatDto(x.Id, x.SeatNumber, x.Type, x.Class, x.FlightId)); .ConstructUsing(x => new SeatDto(x.Id, x.SeatNumber, x.Type, x.Class, x.FlightId));
config.NewConfig<CreateSeatMongo, SeatReadModel>() config.NewConfig<CreateSeatMongo, SeatReadModel>()
.Map(d => d.Id, s => SnowFlakIdGenerator.NewId()) .Map(d => d.Id, s => SnowflakeIdGenerator.NewId())
.Map(d => d.SeatId, s => s.Id); .Map(d => d.SeatId, s => s.Id);
config.NewConfig<Seat, SeatReadModel>() config.NewConfig<Seat, SeatReadModel>()
.Map(d => d.Id, s => SnowFlakIdGenerator.NewId()) .Map(d => d.Id, s => SnowflakeIdGenerator.NewId())
.Map(d => d.SeatId, s => s.Id); .Map(d => d.SeatId, s => s.Id);
config.NewConfig<ReserveSeatMongo, SeatReadModel>() config.NewConfig<ReserveSeatMongo, SeatReadModel>()

View File

@ -10,7 +10,7 @@ public sealed class FakeCreateFlightCommand : AutoFaker<CreateFlight>
{ {
public FakeCreateFlightCommand() public FakeCreateFlightCommand()
{ {
RuleFor(r => r.Id, _ => SnowFlakIdGenerator.NewId()); RuleFor(r => r.Id, _ => SnowflakeIdGenerator.NewId());
RuleFor(r => r.FlightNumber, r => "12FF"); RuleFor(r => r.FlightNumber, r => "12FF");
RuleFor(r => r.DepartureAirportId, _ => 1); RuleFor(r => r.DepartureAirportId, _ => 1);
RuleFor(r => r.ArriveAirportId, _ => 2); RuleFor(r => r.ArriveAirportId, _ => 2);

View File

@ -9,6 +9,6 @@ public class FakeCreateAircraftCommand : AutoFaker<CreateAircraft>
{ {
public FakeCreateAircraftCommand() public FakeCreateAircraftCommand()
{ {
RuleFor(r => r.Id, _ => SnowFlakIdGenerator.NewId()); RuleFor(r => r.Id, _ => SnowflakeIdGenerator.NewId());
} }
} }

View File

@ -9,6 +9,6 @@ public class FakeCreateAirportCommand : AutoFaker<CreateAirport>
{ {
public FakeCreateAirportCommand() public FakeCreateAirportCommand()
{ {
RuleFor(r => r.Id, _ => SnowFlakIdGenerator.NewId()); RuleFor(r => r.Id, _ => SnowflakeIdGenerator.NewId());
} }
} }

View File

@ -10,7 +10,7 @@ public sealed class FakeCreateFlightCommand : AutoFaker<CreateFlight>
{ {
public FakeCreateFlightCommand() public FakeCreateFlightCommand()
{ {
RuleFor(r => r.Id, _ => SnowFlakIdGenerator.NewId()); RuleFor(r => r.Id, _ => SnowflakeIdGenerator.NewId());
RuleFor(r => r.FlightNumber, r => r.Random.Number(1000, 2000).ToString()); RuleFor(r => r.FlightNumber, r => r.Random.Number(1000, 2000).ToString());
RuleFor(r => r.DepartureAirportId, _ => 1); RuleFor(r => r.DepartureAirportId, _ => 1);
RuleFor(r => r.ArriveAirportId, _ => 2); RuleFor(r => r.ArriveAirportId, _ => 2);

View File

@ -10,7 +10,7 @@ public class FakeCreateSeatCommand : AutoFaker<CreateSeat>
{ {
public FakeCreateSeatCommand(long flightId) public FakeCreateSeatCommand(long flightId)
{ {
RuleFor(r => r.Id, _ => SnowFlakIdGenerator.NewId()); RuleFor(r => r.Id, _ => SnowflakeIdGenerator.NewId());
RuleFor(r => r.FlightId, _ => flightId); RuleFor(r => r.FlightId, _ => flightId);
RuleFor(r => r.Class, _ => SeatClass.Economy); RuleFor(r => r.Class, _ => SeatClass.Economy);
RuleFor(r => r.Type, _ => SeatType.Middle); RuleFor(r => r.Type, _ => SeatType.Middle);

View File

@ -1,11 +0,0 @@
using BuildingBlocks.IdsGenerator;
namespace Unit.Test.Common;
public static class SnowFlakIdGeneratorFactory
{
public static void Create()
{
SnowFlakIdGenerator.Configure(1);
}
}

View File

@ -13,7 +13,6 @@ namespace Unit.Test.Common
{ {
public UnitTestFixture() public UnitTestFixture()
{ {
SnowFlakIdGeneratorFactory.Create();
Mapper = MapperFactory.Create(); Mapper = MapperFactory.Create();
DbContext = DbContextFactory.Create(); DbContext = DbContextFactory.Create();
} }

View File

@ -9,6 +9,6 @@ public class FakeCreateAircraftCommand : AutoFaker<CreateAircraft>
{ {
public FakeCreateAircraftCommand() public FakeCreateAircraftCommand()
{ {
RuleFor(r => r.Id, _ => SnowFlakIdGenerator.NewId()); RuleFor(r => r.Id, _ => SnowflakeIdGenerator.NewId());
} }
} }

View File

@ -9,6 +9,6 @@ public class FakeCreateAirportCommand : AutoFaker<CreateAirport>
{ {
public FakeCreateAirportCommand() public FakeCreateAirportCommand()
{ {
RuleFor(r => r.Id, _ => SnowFlakIdGenerator.NewId()); RuleFor(r => r.Id, _ => SnowflakeIdGenerator.NewId());
} }
} }

View File

@ -9,7 +9,7 @@ public sealed class FakeCreateFlightCommand : AutoFaker<CreateFlight>
{ {
public FakeCreateFlightCommand() public FakeCreateFlightCommand()
{ {
RuleFor(r => r.Id, _ => SnowFlakIdGenerator.NewId()); RuleFor(r => r.Id, _ => SnowflakeIdGenerator.NewId());
RuleFor(r => r.FlightNumber, r => r.Random.Number(1000, 2000).ToString()); RuleFor(r => r.FlightNumber, r => r.Random.Number(1000, 2000).ToString());
RuleFor(r => r.DepartureAirportId, _ => 1); RuleFor(r => r.DepartureAirportId, _ => 1);
RuleFor(r => r.ArriveAirportId, _ => 2); RuleFor(r => r.ArriveAirportId, _ => 2);

View File

@ -10,7 +10,7 @@ public class FakeCreateSeatCommand : AutoFaker<CreateSeat>
{ {
public FakeCreateSeatCommand() public FakeCreateSeatCommand()
{ {
RuleFor(r => r.Id, _ => SnowFlakIdGenerator.NewId()); RuleFor(r => r.Id, _ => SnowflakeIdGenerator.NewId());
RuleFor(r => r.FlightId, _ => 1); RuleFor(r => r.FlightId, _ => 1);
RuleFor(r => r.SeatNumber, _ => "F99"); RuleFor(r => r.SeatNumber, _ => "F99");
RuleFor(r => r.Type, _ => SeatType.Window); RuleFor(r => r.Type, _ => SeatType.Window);

View File

@ -0,0 +1 @@
GENERATOR_ID=2

View File

@ -37,6 +37,9 @@ public static class InfrastructureExtensions
var configuration = builder.Configuration; var configuration = builder.Configuration;
var env = builder.Environment; var env = builder.Environment;
// https://github.com/tonerdo/dotnet-env
DotNetEnv.Env.TraversePath().Load();
builder.Services.AddScoped<ICurrentUserProvider, CurrentUserProvider>(); builder.Services.AddScoped<ICurrentUserProvider, CurrentUserProvider>();
builder.Services.AddScoped<IEventMapper, EventMapper>(); builder.Services.AddScoped<IEventMapper, EventMapper>();
builder.Services.AddScoped<IEventDispatcher, EventDispatcher>(); builder.Services.AddScoped<IEventDispatcher, EventDispatcher>();
@ -76,8 +79,6 @@ public static class InfrastructureExtensions
builder.Services.AddCustomMassTransit(env, typeof(IdentityRoot).Assembly); builder.Services.AddCustomMassTransit(env, typeof(IdentityRoot).Assembly);
builder.Services.AddCustomOpenTelemetry(); builder.Services.AddCustomOpenTelemetry();
SnowFlakIdGenerator.Configure(4);
builder.AddCustomIdentityServer(); builder.AddCustomIdentityServer();
builder.Services.Configure<ForwardedHeadersOptions>(options => builder.Services.Configure<ForwardedHeadersOptions>(options =>

View File

@ -0,0 +1 @@
GENERATOR_ID=3

View File

@ -6,7 +6,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Passenger\Passenger.csproj"/> <ProjectReference Include="..\Passenger\Passenger.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -37,6 +37,9 @@ public static class InfrastructureExtensions
var configuration = builder.Configuration; var configuration = builder.Configuration;
var env = builder.Environment; var env = builder.Environment;
// https://github.com/tonerdo/dotnet-env
DotNetEnv.Env.TraversePath().Load();
builder.Services.AddScoped<ICurrentUserProvider, CurrentUserProvider>(); builder.Services.AddScoped<ICurrentUserProvider, CurrentUserProvider>();
builder.Services.AddScoped<IEventMapper, EventMapper>(); builder.Services.AddScoped<IEventMapper, EventMapper>();
builder.Services.AddScoped<IEventDispatcher, EventDispatcher>(); builder.Services.AddScoped<IEventDispatcher, EventDispatcher>();
@ -81,8 +84,6 @@ public static class InfrastructureExtensions
options.Interceptors.Add<GrpcExceptionInterceptor>(); options.Interceptors.Add<GrpcExceptionInterceptor>();
}); });
SnowFlakIdGenerator.Configure(2);
return builder; return builder;
} }

View File

@ -45,7 +45,7 @@ public class RegisterNewUserHandler : IConsumer<UserCreated>
return; return;
} }
var passenger = Passengers.Models.Passenger.Create(SnowFlakIdGenerator.NewId(), context.Message.Name, var passenger = Passengers.Models.Passenger.Create(SnowflakeIdGenerator.NewId(), context.Message.Name,
context.Message.PassportNumber); context.Message.PassportNumber);
await _passengerDbContext.AddAsync(passenger); await _passengerDbContext.AddAsync(passenger);

View File

@ -13,7 +13,7 @@ using Dtos;
public record CompleteRegisterPassenger(string PassportNumber, Enums.PassengerType PassengerType, int Age) : ICommand<CompleteRegisterPassengerResult>, IInternalCommand public record CompleteRegisterPassenger(string PassportNumber, Enums.PassengerType PassengerType, int Age) : ICommand<CompleteRegisterPassengerResult>, IInternalCommand
{ {
public long Id { get; init; } = SnowFlakIdGenerator.NewId(); public long Id { get; init; } = SnowflakeIdGenerator.NewId();
} }
public record CompleteRegisterPassengerResult(PassengerDto PassengerDto); public record CompleteRegisterPassengerResult(PassengerDto PassengerDto);

View File

@ -11,7 +11,7 @@ public class PassengerMappings : IRegister
public void Register(TypeAdapterConfig config) public void Register(TypeAdapterConfig config)
{ {
config.NewConfig<CompleteRegisterPassengerMongoCommand, PassengerReadModel>() config.NewConfig<CompleteRegisterPassengerMongoCommand, PassengerReadModel>()
.Map(d => d.Id, s => SnowFlakIdGenerator.NewId()) .Map(d => d.Id, s => SnowflakeIdGenerator.NewId())
.Map(d => d.PassengerId, s => s.Id); .Map(d => d.PassengerId, s => s.Id);
config.NewConfig<CompleteRegisterPassengerRequestDto, CompleteRegisterPassenger>() config.NewConfig<CompleteRegisterPassengerRequestDto, CompleteRegisterPassenger>()

View File

@ -10,7 +10,7 @@ public sealed class FakeCompleteRegisterPassengerCommand : AutoFaker<CompleteReg
{ {
public FakeCompleteRegisterPassengerCommand(string passportNumber) public FakeCompleteRegisterPassengerCommand(string passportNumber)
{ {
RuleFor(r => r.Id, _ => SnowFlakIdGenerator.NewId()); RuleFor(r => r.Id, _ => SnowflakeIdGenerator.NewId());
RuleFor(r => r.PassportNumber, _ => passportNumber); RuleFor(r => r.PassportNumber, _ => passportNumber);
RuleFor(r => r.PassengerType, _ => PassengerType.Male); RuleFor(r => r.PassengerType, _ => PassengerType.Male);
RuleFor(r => r.Age, _ => 30); RuleFor(r => r.Age, _ => 30);

View File

@ -7,6 +7,6 @@ public static class FakePassengerCreated
{ {
public static global::Passenger.Passengers.Models.Passenger Generate(UserCreated userCreated) public static global::Passenger.Passengers.Models.Passenger Generate(UserCreated userCreated)
{ {
return global::Passenger.Passengers.Models.Passenger.Create(SnowFlakIdGenerator.NewId(), userCreated.Name, userCreated.PassportNumber); return global::Passenger.Passengers.Models.Passenger.Create(SnowflakeIdGenerator.NewId(), userCreated.Name, userCreated.PassportNumber);
} }
} }

View File

@ -8,6 +8,6 @@ public class FakePassengerResponse : AutoFaker<PassengerResponse>
{ {
public FakePassengerResponse() public FakePassengerResponse()
{ {
RuleFor(r => r.Id, _ => SnowFlakIdGenerator.NewId()); RuleFor(r => r.Id, _ => SnowflakeIdGenerator.NewId());
} }
} }

View File

@ -8,7 +8,7 @@ public class FakeUserCreated : AutoFaker<UserCreated>
{ {
public FakeUserCreated() public FakeUserCreated()
{ {
RuleFor(r => r.Id, _ => SnowFlakIdGenerator.NewId()); RuleFor(r => r.Id, _ => SnowflakeIdGenerator.NewId());
RuleFor(r => r.Name, _ => "Sam"); RuleFor(r => r.Name, _ => "Sam");
RuleFor(r => r.PassportNumber, _ => "123456789"); RuleFor(r => r.PassportNumber, _ => "123456789");
} }