diff --git a/TimetableDesigner.Backend.Services.Authentication.DTO.Events/RegisterEvent.cs b/TimetableDesigner.Backend.Services.Authentication.DTO.Events/RegisterEvent.cs new file mode 100644 index 0000000..b6fd7eb --- /dev/null +++ b/TimetableDesigner.Backend.Services.Authentication.DTO.Events/RegisterEvent.cs @@ -0,0 +1,6 @@ +namespace TimetableDesigner.Backend.Services.Authentication.DTO.Events; + +public record RegisterEvent( + long Id, + string Email +); \ No newline at end of file diff --git a/TimetableDesigner.Backend.Services.Authentication.DTO.Events/TimetableDesigner.Backend.Services.Authentication.DTO.Events.csproj b/TimetableDesigner.Backend.Services.Authentication.DTO.Events/TimetableDesigner.Backend.Services.Authentication.DTO.Events.csproj new file mode 100644 index 0000000..237d661 --- /dev/null +++ b/TimetableDesigner.Backend.Services.Authentication.DTO.Events/TimetableDesigner.Backend.Services.Authentication.DTO.Events.csproj @@ -0,0 +1,9 @@ + + + + net10.0 + enable + enable + + + diff --git a/TimetableDesigner.Backend.Services.Authentication.slnx b/TimetableDesigner.Backend.Services.Authentication.slnx index 733c0df..cd3af9e 100644 --- a/TimetableDesigner.Backend.Services.Authentication.slnx +++ b/TimetableDesigner.Backend.Services.Authentication.slnx @@ -1,4 +1,5 @@ + diff --git a/TimetableDesigner.Backend.Services.Authentication/Application/Commands/Register/RegisterHandler.cs b/TimetableDesigner.Backend.Services.Authentication/Application/Commands/Register/RegisterHandler.cs index 3021ec4..f5cbd9f 100644 --- a/TimetableDesigner.Backend.Services.Authentication/Application/Commands/Register/RegisterHandler.cs +++ b/TimetableDesigner.Backend.Services.Authentication/Application/Commands/Register/RegisterHandler.cs @@ -1,7 +1,9 @@ using MediatR; +using TimetableDesigner.Backend.Events; using TimetableDesigner.Backend.Services.Authentication.Application.Helpers; using TimetableDesigner.Backend.Services.Authentication.Database; using TimetableDesigner.Backend.Services.Authentication.Database.Model; +using TimetableDesigner.Backend.Services.Authentication.DTO.Events; namespace TimetableDesigner.Backend.Services.Authentication.Application.Commands.Register; @@ -9,11 +11,13 @@ public class RegisterHandler : IRequestHandler { private readonly DatabaseContext _databaseContext; private readonly IPasswordHasher _passwordHasher; + private readonly IEventQueuePublisher _eventQueuePublisher; - public RegisterHandler(DatabaseContext databaseContext, IPasswordHasher passwordHasher) + public RegisterHandler(DatabaseContext databaseContext, IPasswordHasher passwordHasher, IEventQueuePublisher eventQueuePublisher) { _databaseContext = databaseContext; _passwordHasher = passwordHasher; + _eventQueuePublisher = eventQueuePublisher; } public async Task Handle(RegisterCommand command, CancellationToken cancellationToken) @@ -28,8 +32,9 @@ public class RegisterHandler : IRequestHandler }; await _databaseContext.Accounts.AddAsync(account, cancellationToken); await _databaseContext.SaveChangesAsync(cancellationToken); - - // Publish event (probably in transaction) + + RegisterEvent eventData = account.ToEvent(); + await _eventQueuePublisher.PublishAsync(eventData); RegisterResult result = account.ToResult(); return result; diff --git a/TimetableDesigner.Backend.Services.Authentication/Application/Commands/Register/RegisterMappers.cs b/TimetableDesigner.Backend.Services.Authentication/Application/Commands/Register/RegisterMappers.cs index 813e8d5..5fc87f7 100644 --- a/TimetableDesigner.Backend.Services.Authentication/Application/Commands/Register/RegisterMappers.cs +++ b/TimetableDesigner.Backend.Services.Authentication/Application/Commands/Register/RegisterMappers.cs @@ -1,4 +1,5 @@ using TimetableDesigner.Backend.Services.Authentication.Database.Model; +using TimetableDesigner.Backend.Services.Authentication.DTO.Events; using TimetableDesigner.Backend.Services.Authentication.DTO.WebAPI; namespace TimetableDesigner.Backend.Services.Authentication.Application.Commands.Register; @@ -13,4 +14,7 @@ public static class RegisterMappers public static RegisterResponse ToResponse(this RegisterResult result) => new RegisterResponse(result.Id, result.Email); + + public static RegisterEvent ToEvent(this Account account) => + new RegisterEvent(account.Id, account.Email); } \ No newline at end of file diff --git a/TimetableDesigner.Backend.Services.Authentication/Program.cs b/TimetableDesigner.Backend.Services.Authentication/Program.cs index abff260..1274bb9 100644 --- a/TimetableDesigner.Backend.Services.Authentication/Program.cs +++ b/TimetableDesigner.Backend.Services.Authentication/Program.cs @@ -17,14 +17,19 @@ public static class Program { public static void Main(string[] args) { - WebApplication app = WebApplication.CreateBuilder(args) - .SetupOpenApi() - .SetupSecurity() - .SetupDatabase() - .SetupHelpers() - .SetupValidation() - .SetupMediatR() - .Build(); + WebApplicationBuilder builder = WebApplication.CreateBuilder(args); + + string databaseConnectionString = builder.Configuration.GetConnectionString("Database")!; + string eventQueueConnectionString = builder.Configuration.GetConnectionString("EventQueue")!; + + builder.Services.AddOpenApi(); + builder.Services.AddDbContext(x => x.UseNpgsql(databaseConnectionString), ServiceLifetime.Transient); + builder.Services.AddEventQueue(eventQueueConnectionString); + builder.Services.AddHelpers(); + builder.Services.AddValidators(); + builder.Services.AddMediatR(x => x.RegisterServicesFromAssembly(typeof(Program).Assembly)); + + WebApplication app = builder.Build(); if (app.Environment.IsDevelopment()) app.MapOpenApi(); @@ -35,50 +40,17 @@ public static class Program app.Run(); } - - private static WebApplicationBuilder SetupOpenApi(this WebApplicationBuilder builder) - { - builder.Services.AddEventQueue(cfg => - { - cfg.Hostname = "localhost"; - cfg.Port = 5672; - cfg.Username = "user"; - cfg.Password = "l4JxOIuSoyod86N"; - cfg.ExchangeName = "events"; - cfg.QueuePrefix = "authentication"; - }); - builder.Services.AddOpenApi(); - return builder; - } - private static WebApplicationBuilder SetupSecurity(this WebApplicationBuilder builder) + private static IServiceCollection AddHelpers(this IServiceCollection services) { - //builder.Services.AddAuthorization(); - return builder; + services.AddSingleton(); + return services; } - private static WebApplicationBuilder SetupDatabase(this WebApplicationBuilder builder) + private static IServiceCollection AddValidators(this IServiceCollection services) { - builder.Services.AddDbContext(x => x.UseNpgsql(builder.Configuration.GetConnectionString("Database")), ServiceLifetime.Transient); - return builder; - } - - private static WebApplicationBuilder SetupHelpers(this WebApplicationBuilder builder) - { - builder.Services.AddSingleton(); - return builder; - } - - private static WebApplicationBuilder SetupValidation(this WebApplicationBuilder builder) - { - builder.Services.AddScoped, RegisterRequestValidator>(); - return builder; - } - - private static WebApplicationBuilder SetupMediatR(this WebApplicationBuilder builder) - { - builder.Services.AddMediatR(x => x.RegisterServicesFromAssembly(typeof(Program).Assembly)); - return builder; + services.AddScoped, RegisterRequestValidator>(); + return services; } private static WebApplication InitializeDatabase(this WebApplication app) diff --git a/TimetableDesigner.Backend.Services.Authentication/TimetableDesigner.Backend.Services.Authentication.csproj b/TimetableDesigner.Backend.Services.Authentication/TimetableDesigner.Backend.Services.Authentication.csproj index 7b69a71..51d4d15 100644 --- a/TimetableDesigner.Backend.Services.Authentication/TimetableDesigner.Backend.Services.Authentication.csproj +++ b/TimetableDesigner.Backend.Services.Authentication/TimetableDesigner.Backend.Services.Authentication.csproj @@ -18,11 +18,12 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - + + + diff --git a/TimetableDesigner.Backend.Services.Authentication/WebAPI/Endpoints.cs b/TimetableDesigner.Backend.Services.Authentication/WebAPI/Endpoints.cs index a52532b..7cf031b 100644 --- a/TimetableDesigner.Backend.Services.Authentication/WebAPI/Endpoints.cs +++ b/TimetableDesigner.Backend.Services.Authentication/WebAPI/Endpoints.cs @@ -29,7 +29,7 @@ public static class Endpoints return app; } - private static async Task, ValidationProblem>> Register(IMediator mediator, IValidator validator, RegisterRequest request) + private static async Task, ValidationProblem>> Register(IMediator mediator, IValidator validator, RegisterRequest request, CancellationToken cancellationToken) { ValidationResult validationResult = await validator.ValidateAsync(request); if (!validationResult.IsValid) @@ -38,7 +38,7 @@ public static class Endpoints } RegisterCommand registerCommand = request.ToCommand(); - RegisterResult result = await mediator.Send(registerCommand); + RegisterResult result = await mediator.Send(registerCommand, cancellationToken); RegisterResponse response = result.ToResponse(); return TypedResults.Created($"accounts/{response.Id}", response); diff --git a/TimetableDesigner.Backend.Services.Authentication/appsettings.json b/TimetableDesigner.Backend.Services.Authentication/appsettings.json index 65ac104..05d2018 100644 --- a/TimetableDesigner.Backend.Services.Authentication/appsettings.json +++ b/TimetableDesigner.Backend.Services.Authentication/appsettings.json @@ -7,6 +7,7 @@ }, "AllowedHosts": "*", "ConnectionStrings": { - "Database": "Host=localhost;Port=5433;Database=ttd_authentication;Username=postgres;Password=l4JxOIuSoyod86N;Include Error Detail=True" + "Database": "Host=localhost;Port=5433;Database=ttd_authentication;Username=postgres;Password=l4JxOIuSoyod86N;Include Error Detail=True", + "EventQueue": "Hostname=localhost;Port=5672;Username=user;Password=l4JxOIuSoyod86N;ExchangeName=events;QueuePrefix=authentication" } }