diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml new file mode 100644 index 00000000..98ab7abb --- /dev/null +++ b/.github/workflows/build_test.yml @@ -0,0 +1,32 @@ +# This workflow will build a .NET project +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net + +name: Build and test + +on: + push: + branches: [ "avdeev/tests" ] + pull_request: + branches: [ "avdeev/tests" ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - name: Checkout avdeev/tests branch + uses: actions/checkout@v4 + with: + ref: 'avdeev/tests' + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + - name: Restore dependencies + run: dotnet restore Homeworks/UnitTests/src + - name: Build + run: dotnet build Homeworks/UnitTests/src --no-restore + - name: Test + run: dotnet test Homeworks/UnitTests/src --no-build --verbosity normal diff --git a/Homeworks/RabbitMQ/compose.bat b/Homeworks/RabbitMQ/compose.bat new file mode 100644 index 00000000..05fc00c9 --- /dev/null +++ b/Homeworks/RabbitMQ/compose.bat @@ -0,0 +1,3 @@ +cd D:\OTUS\ASP.NET\Homeworks\RabbitMQ +docker-compose -f compose.yml up +PAUSE \ No newline at end of file diff --git a/Homeworks/RabbitMQ/compose.yml b/Homeworks/RabbitMQ/compose.yml index 8ef772ad..e3644b6e 100644 --- a/Homeworks/RabbitMQ/compose.yml +++ b/Homeworks/RabbitMQ/compose.yml @@ -1,26 +1,22 @@ services: - #Administration Db - promocode-factory-administration-db: - image: "postgres:latest" - container_name: 'promocode-factory-administration-db' - restart: always - ports: - - 5433:5432 - environment: - - POSTGRES_PASSWORD=docker - - #Administration Api - promocode-factory-administration-api: - build: src/Pcf.Administration/ - container_name: 'promocode-factory-administration-api' + + rabbit: + image: rabbitmq:3-management restart: always - ports: - - "8091:8080" + hostname: rabbitmqhost environment: - - "ConnectionStrings:PromocodeFactoryAdministrationDb=Host=promocode-factory-administration-db;Database=promocode_factory_administration_db;Username=postgres;Password=docker" - depends_on: - - promocode-factory-administration-db - + RABBITMQ_DEFAULT_USER: myuser + RABBITMQ_DEFAULT_PASS: mypass + volumes: + - rabbitmq_data:/var/lib/rabbitmq + ports: + - "5672:5672" + - "15672:15672" + healthcheck: + test: [ "CMD", "rabbitmqctl", "status" ] + interval: 10s + timeout: 5s + retries: 5 #ReceivingFromPartner Db promocode-factory-receiving-from-partner-db: @@ -41,10 +37,16 @@ services: - "8092:8080" environment: - "ConnectionStrings:PromocodeFactoryReceivingFromPartnerDb=Host=promocode-factory-receiving-from-partner-db;Database=promocode_factory_receiving_from_partner_db;Username=postgres;Password=docker" - - "IntegrationSettings:GivingToCustomerApiUrl=http://promocode-factory-giving-to-customer-api" - - "IntegrationSettings:AdministrationApiUrl=http://promocode-factory-administration-api" + - "IntegrationSettings:GivingToCustomerApiUrl=http://promocode-factory-giving-to-customer-api:8080" + - "IntegrationSettings:AdministrationApiUrl=http://promocode-factory-administration-api:8080" + - "RmqSettings:Host=rabbit" + - "RmqSettings:Login=myuser" + - "RmqSettings:Password=mypass" depends_on: - - promocode-factory-receiving-from-partner-db + promocode-factory-receiving-from-partner-db: + condition: service_started + rabbit: + condition: service_healthy #GivingToCustomer Db promocode-factory-giving-to-customer-db: @@ -64,6 +66,48 @@ services: ports: - "8093:8080" environment: - - "ConnectionStrings:PromocodeFactoryGivingToCustomerDb=Host=promocode-factory-giving-to-customer-db;Database=promocode_factory_giving_to_customer_db;Username=postgres;Password=docker" + - "ConnectionStrings:PromocodeFactoryGivingToCustomerDb=Host=promocode-factory-giving-to-customer-db;Database=promocode_factory_giving_to_customer_db;Username=postgres;Password=docker" + - "RmqSettings:Host=rabbit" + - "RmqSettings:Login=myuser" + - "RmqSettings:Password=mypass" depends_on: - - promocode-factory-giving-to-customer-db \ No newline at end of file + promocode-factory-giving-to-customer-db: + condition: service_started + rabbit: + condition: service_healthy + + #Administration Db + promocode-factory-administration-db: + image: "postgres:latest" + container_name: 'promocode-factory-administration-db' + restart: always + ports: + - 5433:5432 + environment: + - POSTGRES_PASSWORD=docker + + #Administration Api + promocode-factory-administration-api: + build: src/Pcf.Administration/ + container_name: 'promocode-factory-administration-api' + restart: always + ports: + - "8091:8080" + environment: + - "ConnectionStrings:PromocodeFactoryAdministrationDb=Host=promocode-factory-administration-db;Database=promocode_factory_administration_db;Username=postgres;Password=docker" + - "RmqSettings:Host=rabbit" + - "RmqSettings:Login=myuser" + - "RmqSettings:Password=mypass" + depends_on: + promocode-factory-administration-db: + condition: service_started + rabbit: + condition: service_healthy + +volumes: + rabbitmq_data: + +#networks: +# default: +# name: myLocalNetwork # создана извне: docker network create --driver=bridge myLocalNetwork +# external: true \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.Administration/Dockerfile b/Homeworks/RabbitMQ/src/Pcf.Administration/Dockerfile index 4db9c88e..f8376925 100644 --- a/Homeworks/RabbitMQ/src/Pcf.Administration/Dockerfile +++ b/Homeworks/RabbitMQ/src/Pcf.Administration/Dockerfile @@ -5,6 +5,7 @@ WORKDIR /app # Copy the solution file and project files, then restore dependencies COPY *.sln . COPY */*.csproj ./ +COPY nuget.config . RUN for file in $(ls *.csproj); do mkdir -p ${file%.*} && mv $file ${file%.*}; done RUN dotnet restore diff --git a/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Controllers/EmployeesController.cs b/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Controllers/EmployeesController.cs index 03b7ddbc..f53c71ac 100644 --- a/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Controllers/EmployeesController.cs +++ b/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Controllers/EmployeesController.cs @@ -80,7 +80,6 @@ public async Task> GetEmployeeByIdAsync(Guid id) /// Id сотрудника, например 451533d5-d8d5-4a11-9c7b-eb9f14e1a32f /// [HttpPost("{id:guid}/appliedPromocodes")] - public async Task UpdateAppliedPromocodesAsync(Guid id) { var employee = await _employeeRepository.GetByIdAsync(id); diff --git a/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Pcf.Administration.WebHost.csproj b/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Pcf.Administration.WebHost.csproj index 761be6a3..01c224fd 100644 --- a/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Pcf.Administration.WebHost.csproj +++ b/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Pcf.Administration.WebHost.csproj @@ -13,6 +13,7 @@ + @@ -20,4 +21,8 @@ + + + + diff --git a/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Services/Employees/AdministrationDto.cs b/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Services/Employees/AdministrationDto.cs new file mode 100644 index 00000000..d5a0744d --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Services/Employees/AdministrationDto.cs @@ -0,0 +1,8 @@ +using System; + +namespace Pcf.Administration.WebHost.Services.Employees; + +public class AdministrationDto +{ + public Guid PartnerId { get; set; } +} \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Services/Employees/EmployeesService.cs b/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Services/Employees/EmployeesService.cs new file mode 100644 index 00000000..8bd78363 --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Services/Employees/EmployeesService.cs @@ -0,0 +1,34 @@ +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; +using Infrastructure.RabbitMq; +using Pcf.Administration.Core.Abstractions.Repositories; +using Pcf.Administration.Core.Domain.Administration; +using RabbitMQ.Client.Events; + +namespace Pcf.Administration.WebHost.Services.Employees; + +public class EmployeesService : RabbitMqConsumer, IEmployeesService +{ + private readonly IRepository _employeeRepository; + + public EmployeesService(IRepository employeeRepository) + { + _employeeRepository = employeeRepository; + } + + protected override async Task OnConsumerOnReceivedAsync(object sender, BasicDeliverEventArgs e) + { + var body = e.Body; + var message = JsonSerializer.Deserialize(Encoding.UTF8.GetString(body.ToArray())); + + var employee = await _employeeRepository.GetByIdAsync(message!.PartnerId); + + if (employee == null) + return; + + employee.AppliedPromocodesCount++; + + await _employeeRepository.UpdateAsync(employee); + } +} \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Services/Employees/IEmployeesService.cs b/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Services/Employees/IEmployeesService.cs new file mode 100644 index 00000000..d3ed1f0f --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Services/Employees/IEmployeesService.cs @@ -0,0 +1,8 @@ +using Infrastructure.RabbitMq; + +namespace Pcf.Administration.WebHost.Services.Employees; + +public interface IEmployeesService : IRabbitMqConsumer +{ + +} \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Settings/ApplicationSettings.cs b/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Settings/ApplicationSettings.cs new file mode 100644 index 00000000..2e1c499d --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Settings/ApplicationSettings.cs @@ -0,0 +1,9 @@ +using Infrastructure.RabbitMq; + +namespace Pcf.Administration.WebHost.Settings +{ + public class ApplicationSettings + { + public RmqSettings RmqSettings { get; set; } + } +} \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Startup.cs b/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Startup.cs index 2baa3996..992506f2 100644 --- a/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Startup.cs +++ b/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/Startup.cs @@ -10,6 +10,11 @@ using Pcf.Administration.DataAccess.Data; using Pcf.Administration.Core.Abstractions.Repositories; using System; +using System.Threading.Tasks; +using Infrastructure.RabbitMq; +using Pcf.Administration.WebHost.Services.Employees; +using Pcf.Administration.WebHost.Settings; +using RabbitMQ.Client; namespace Pcf.Administration.WebHost { @@ -28,7 +33,7 @@ public void ConfigureServices(IServiceCollection services) { services.AddControllers().AddMvcOptions(x => x.SuppressAsyncSuffixInActionNames = false); - services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>)); + services.AddSingleton(typeof(IRepository<>), typeof(EfRepository<>)); services.AddScoped(); services.AddDbContext(x => { @@ -38,6 +43,9 @@ public void ConfigureServices(IServiceCollection services) x.UseLazyLoadingProxies(); }); + ConfigureRabbitMq(services).Wait(); + services.AddSingleton(); + AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true); services.AddOpenApiDocument(options => @@ -48,7 +56,22 @@ public void ConfigureServices(IServiceCollection services) } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IDbInitializer dbInitializer) + private async Task ConfigureRabbitMq(IServiceCollection services) + { + var rmqSettings = Configuration.Get().RmqSettings; + var connection = await RabbitMqConfiguration.GetRabbitConnection(rmqSettings); + + var channel = await connection.CreateChannelAsync(); + + services.AddSingleton(_ => channel); + } + + public void Configure( + IApplicationBuilder app, + IWebHostEnvironment env, + IDbInitializer dbInitializer, + IEmployeesService employeesService, + IChannel channel) { if (env.IsDevelopment()) { @@ -73,7 +96,13 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IDbIniti { endpoints.MapControllers(); }); - + + employeesService.Register( + channel, + Configuration["AdministrationExchangeName"]!, + Configuration["AdministrationQueue"]!, + Configuration["AdministrationRoutingKey"]!); + dbInitializer.InitializeDb(); } } diff --git a/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/appsettings.json b/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/appsettings.json index 704547c6..55a21428 100644 --- a/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/appsettings.json +++ b/Homeworks/RabbitMQ/src/Pcf.Administration/Pcf.Administration.WebHost/appsettings.json @@ -9,5 +9,15 @@ "ConnectionStrings":{ "PromocodeFactoryAdministrationDb":"Host=localhost;Database=promocode_factory_administration_db;Username=postgres;Password=docker;Port=5433" }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "RmqSettings": { + "Host": "localhost", + "Port": 5672, + "VHost": "/", + "Login": "guest", + "Password": "guest" + }, + "AdministrationExchangeName": "exchange.administration", + "AdministrationRoutingKey": "routingKey.administration", + "AdministrationQueue": "queue.administration" } diff --git a/Homeworks/RabbitMQ/src/Pcf.Administration/nuget.config b/Homeworks/RabbitMQ/src/Pcf.Administration/nuget.config new file mode 100644 index 00000000..a48aae93 --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.Administration/nuget.config @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Dockerfile b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Dockerfile index e9a8bc8c..1dee44f6 100644 --- a/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Dockerfile +++ b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Dockerfile @@ -4,6 +4,7 @@ WORKDIR /app # Copy the solution file and project files, then restore dependencies COPY *.sln . +COPY nuget.config . COPY */*.csproj ./ RUN for file in $(ls *.csproj); do mkdir -p ${file%.*} && mv $file ${file%.*}; done RUN dotnet restore diff --git a/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Mappers/PromoCodeMapper.cs b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Mappers/PromoCodeMapper.cs index ef7eb235..bf0b8518 100644 --- a/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Mappers/PromoCodeMapper.cs +++ b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Mappers/PromoCodeMapper.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using Pcf.GivingToCustomer.Core.Domain; using Pcf.GivingToCustomer.WebHost.Models; +using Pcf.GivingToCustomer.WebHost.Services.Promocodes; namespace Pcf.GivingToCustomer.WebHost.Mappers { @@ -41,5 +42,37 @@ public static PromoCode MapFromModel(GivePromoCodeRequest request, Preference pr return promocode; } + + public static PromoCode MapFromModel(GivePromoCodeToCustomerDto dto, Preference preference, IEnumerable customers) + { + var promocode = new PromoCode(); + promocode.Id = dto.PromoCodeId; + + promocode.PartnerId = dto.PartnerId; + promocode.Code = dto.PromoCode; + promocode.ServiceInfo = dto.ServiceInfo; + + promocode.BeginDate = DateTime.Parse(dto.BeginDate); + promocode.EndDate = DateTime.Parse(dto.EndDate); + + promocode.Preference = preference; + promocode.PreferenceId = preference.Id; + + promocode.Customers = new List(); + + foreach (var item in customers) + { + promocode.Customers.Add(new PromoCodeCustomer() + { + + CustomerId = item.Id, + Customer = item, + PromoCodeId = promocode.Id, + PromoCode = promocode + }); + }; + + return promocode; + } } } diff --git a/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Pcf.GivingToCustomer.WebHost.csproj b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Pcf.GivingToCustomer.WebHost.csproj index 4fba074e..b56ca11e 100644 --- a/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Pcf.GivingToCustomer.WebHost.csproj +++ b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Pcf.GivingToCustomer.WebHost.csproj @@ -14,6 +14,7 @@ + diff --git a/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Services/Promocodes/GivePromoCodeToCustomerDto.cs b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Services/Promocodes/GivePromoCodeToCustomerDto.cs new file mode 100644 index 00000000..c0851ae4 --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Services/Promocodes/GivePromoCodeToCustomerDto.cs @@ -0,0 +1,23 @@ +using System; + +namespace Pcf.GivingToCustomer.WebHost.Services.Promocodes +{ + public class GivePromoCodeToCustomerDto + { + public string ServiceInfo { get; set; } + + public Guid PartnerId { get; set; } + + public Guid PromoCodeId { get; set; } + + public string PromoCode { get; set; } + + public Guid PreferenceId { get; set; } + + public string BeginDate { get; set; } + + public string EndDate { get; set; } + + public Guid? PartnerManagerId { get; set; } + } +} \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Services/Promocodes/IPromocodesService.cs b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Services/Promocodes/IPromocodesService.cs new file mode 100644 index 00000000..51ddce40 --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Services/Promocodes/IPromocodesService.cs @@ -0,0 +1,8 @@ +using Infrastructure.RabbitMq; + +namespace Pcf.GivingToCustomer.WebHost.Services.Promocodes; + +public interface IPromocodesService : IRabbitMqConsumer +{ + +} \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Services/Promocodes/PromocodesService.cs b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Services/Promocodes/PromocodesService.cs new file mode 100644 index 00000000..c1fdbbd5 --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Services/Promocodes/PromocodesService.cs @@ -0,0 +1,47 @@ +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; +using Infrastructure.RabbitMq; +using Pcf.GivingToCustomer.Core.Abstractions.Repositories; +using Pcf.GivingToCustomer.Core.Domain; +using Pcf.GivingToCustomer.WebHost.Mappers; +using RabbitMQ.Client.Events; + +namespace Pcf.GivingToCustomer.WebHost.Services.Promocodes; + +public class PromocodesService : RabbitMqConsumer, IPromocodesService +{ + private readonly IRepository _promoCodesRepository; + private readonly IRepository _preferencesRepository; + private readonly IRepository _customersRepository; + + public PromocodesService(IRepository promoCodesRepository, IRepository preferencesRepository, IRepository customersRepository) + { + _promoCodesRepository = promoCodesRepository; + _preferencesRepository = preferencesRepository; + _customersRepository = customersRepository; + } + + protected override async Task OnConsumerOnReceivedAsync(object sender, BasicDeliverEventArgs e) + { + var body = e.Body; + var message = JsonSerializer.Deserialize(Encoding.UTF8.GetString(body.ToArray())); + + var preference = await _preferencesRepository.GetByIdAsync(message!.PreferenceId); + + if (preference == null) + { + return; + } + + // Получаем клиентов с этим предпочтением: + var customers = await _customersRepository + .GetWhere(d => d.Preferences.Any(x => + x.Preference.Id == preference.Id)); + + PromoCode promoCode = PromoCodeMapper.MapFromModel(message, preference, customers); + + await _promoCodesRepository.AddAsync(promoCode); + } +} \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Settings/ApplicationSettings.cs b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Settings/ApplicationSettings.cs new file mode 100644 index 00000000..9c80a733 --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Settings/ApplicationSettings.cs @@ -0,0 +1,9 @@ +using Infrastructure.RabbitMq; + +namespace Pcf.GivingToCustomer.WebHost.Settings +{ + public class ApplicationSettings + { + public RmqSettings RmqSettings { get; set; } + } +} \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Startup.cs b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Startup.cs index aedacea7..890894ff 100644 --- a/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Startup.cs +++ b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/Startup.cs @@ -1,4 +1,6 @@ using System; +using System.Threading.Tasks; +using Infrastructure.RabbitMq; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; @@ -12,6 +14,9 @@ using Pcf.GivingToCustomer.DataAccess; using Pcf.GivingToCustomer.DataAccess.Repositories; using Pcf.GivingToCustomer.Integration; +using Pcf.GivingToCustomer.WebHost.Services.Promocodes; +using Pcf.GivingToCustomer.WebHost.Settings; +using RabbitMQ.Client; namespace Pcf.GivingToCustomer.WebHost { @@ -30,7 +35,7 @@ public void ConfigureServices(IServiceCollection services) { services.AddControllers().AddMvcOptions(x => x.SuppressAsyncSuffixInActionNames = false); - services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>)); + services.AddSingleton(typeof(IRepository<>), typeof(EfRepository<>)); services.AddScoped(); services.AddScoped(); services.AddDbContext(x => @@ -40,6 +45,9 @@ public void ConfigureServices(IServiceCollection services) x.UseSnakeCaseNamingConvention(); x.UseLazyLoadingProxies(); }); + + ConfigureRabbitMq(services).Wait(); + services.AddSingleton(); AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true); @@ -49,9 +57,24 @@ public void ConfigureServices(IServiceCollection services) options.Version = "1.0"; }); } + + private async Task ConfigureRabbitMq(IServiceCollection services) + { + var rmqSettings = Configuration.Get().RmqSettings; + var connection = await RabbitMqConfiguration.GetRabbitConnection(rmqSettings); + + var channel = await connection.CreateChannelAsync(); + + services.AddSingleton(_ => channel); + } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IDbInitializer dbInitializer) + public void Configure( + IApplicationBuilder app, + IWebHostEnvironment env, + IDbInitializer dbInitializer, + IPromocodesService promocodesService, + IChannel channel) { if (env.IsDevelopment()) { @@ -76,6 +99,12 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IDbIniti { endpoints.MapControllers(); }); + + promocodesService.Register( + channel, + Configuration["GivingPromoCodeToCustomerExchangeName"]!, + Configuration["GivingPromoCodeToCustomerQueue"]!, + Configuration["GivingPromoCodeToCustomerRoutingKey"]!); dbInitializer.InitializeDb(); } diff --git a/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/appsettings.json b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/appsettings.json index cfae3069..eb3c6bbf 100644 --- a/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/appsettings.json +++ b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/Pcf.GivingToCustomer.WebHost/appsettings.json @@ -9,5 +9,15 @@ "ConnectionStrings":{ "PromocodeFactoryGivingToCustomerDb":"Host=localhost;Database=promocode_factory_givingToCustomer_db;Username=postgres;Password=docker;Port=5435" }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "RmqSettings": { + "Host": "localhost", + "Port": 5672, + "VHost": "/", + "Login": "guest", + "Password": "guest" + }, + "GivingPromoCodeToCustomerExchangeName": "exchange.giving-promocode", + "GivingPromoCodeToCustomerRoutingKey": "routingKey.giving-promocode", + "GivingPromoCodeToCustomerQueue": "queue.giving-promocode" } diff --git a/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/nuget.config b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/nuget.config new file mode 100644 index 00000000..a48aae93 --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.GivingToCustomer/nuget.config @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/IRabbitMqConsumer.cs b/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/IRabbitMqConsumer.cs new file mode 100644 index 00000000..09d96ea6 --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/IRabbitMqConsumer.cs @@ -0,0 +1,8 @@ +using RabbitMQ.Client; + +namespace Pcf.Infrastructure.RabbitMq; + +public interface IRabbitMqConsumer +{ + public Task Register(IChannel channel, string exchangeName, string queueName, string routingKey); +} \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/IRabbitMqProducer.cs b/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/IRabbitMqProducer.cs new file mode 100644 index 00000000..bad9c723 --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/IRabbitMqProducer.cs @@ -0,0 +1,6 @@ +namespace Pcf.Infrastructure.RabbitMq; + +public interface IRabbitMqProducer +{ + public Task Publish(TMessage message); +} \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/Pcf.Infrastructure.RabbitMq.csproj b/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/Pcf.Infrastructure.RabbitMq.csproj new file mode 100644 index 00000000..96ac1811 --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/Pcf.Infrastructure.RabbitMq.csproj @@ -0,0 +1,14 @@ + + + + net7.0 + enable + enable + + + + + + + + diff --git a/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/RabbitMqConfiguration.cs b/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/RabbitMqConfiguration.cs new file mode 100644 index 00000000..160db3f0 --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/RabbitMqConfiguration.cs @@ -0,0 +1,19 @@ +using RabbitMQ.Client; + +namespace Pcf.Infrastructure.RabbitMq; + +public static class RabbitMqConfiguration +{ + public static async Task GetRabbitConnection(RmqSettings rmqSettings) + { + ConnectionFactory factory = new ConnectionFactory + { + HostName = rmqSettings.Host, + VirtualHost = rmqSettings.VHost, + UserName = rmqSettings.Login, + Password = rmqSettings.Password + }; + + return await factory.CreateConnectionAsync(); + } +} \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/RabbitMqConsumer.cs b/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/RabbitMqConsumer.cs new file mode 100644 index 00000000..bb2b11fc --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/RabbitMqConsumer.cs @@ -0,0 +1,26 @@ +using RabbitMQ.Client; +using RabbitMQ.Client.Events; + +namespace Pcf.Infrastructure.RabbitMq; + +public abstract class RabbitMqConsumer : IRabbitMqConsumer +{ + public async Task Register(IChannel channel, string exchangeName, string queueName, string routingKey) + { + await channel.BasicQosAsync(0, 10, false); + await channel.QueueDeclareAsync(queueName, false, false, false, null); + await channel.QueueBindAsync(queueName, exchangeName, routingKey, null); + + var consumer = new AsyncEventingBasicConsumer(channel); + + consumer.ReceivedAsync += async (sender, e) => + { + await OnConsumerOnReceivedAsync(sender, e); + await channel.BasicAckAsync(e.DeliveryTag, false); + }; + + await channel.BasicConsumeAsync(queueName, false, consumer); + } + + protected abstract Task OnConsumerOnReceivedAsync(object sender, BasicDeliverEventArgs e); +} \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/RabbitMqProducer.cs b/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/RabbitMqProducer.cs new file mode 100644 index 00000000..f41091e0 --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/RabbitMqProducer.cs @@ -0,0 +1,37 @@ +using System.Text; +using System.Text.Json; +using RabbitMQ.Client; + +namespace Pcf.Infrastructure.RabbitMq; + +public class RabbitMqProducer : IRabbitMqProducer +{ + private readonly string _exchangeName; + private readonly string _routingKey; + private readonly IChannel _channel; + + public RabbitMqProducer( + string exchangeType, + string exchangeName, + string routingKey, + IChannel channel) + { + _exchangeName = exchangeName; + _routingKey = routingKey; + _channel = channel; + _channel.ExchangeDeclareAsync(_exchangeName, exchangeType); + } + + public async Task Publish(TMessage message) + { + var messageSerialized = JsonSerializer.Serialize(message); + var body = Encoding.UTF8.GetBytes(messageSerialized); + + await _channel.BasicPublishAsync( + exchange: _exchangeName, + routingKey: _routingKey, + body: body); + + Console.WriteLine($"Message {messageSerialized} is sent into exchange: {_exchangeName}"); + } +} \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/RmqSettings.cs b/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/RmqSettings.cs new file mode 100644 index 00000000..aef0cdc8 --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.Infrastructure.RabbitMq/RmqSettings.cs @@ -0,0 +1,10 @@ +namespace Pcf.Infrastructure.RabbitMq +{ + public class RmqSettings + { + public string Host { get; set; } + public string VHost { get; set; } + public string Login { get; set; } + public string Password { get; set; } + } +} \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Dockerfile b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Dockerfile index 2645897f..0796554d 100644 --- a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Dockerfile +++ b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Dockerfile @@ -4,6 +4,7 @@ WORKDIR /app # Copy the solution file and project files, then restore dependencies COPY *.sln . +COPY nuget.config . COPY */*.csproj ./ RUN for file in $(ls *.csproj); do mkdir -p ${file%.*} && mv $file ${file%.*}; done RUN dotnet restore diff --git a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Core/Abstractions/Gateways/IAdministrationGateway.cs b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Core/Abstractions/Gateways/IAdministrationGateway.cs index fa91b9d8..0148ef4e 100644 --- a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Core/Abstractions/Gateways/IAdministrationGateway.cs +++ b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Core/Abstractions/Gateways/IAdministrationGateway.cs @@ -1,9 +1,11 @@ using System; using System.Threading.Tasks; +using Infrastructure.RabbitMq; +using Pcf.ReceivingFromPartner.Core.Dto; namespace Pcf.ReceivingFromPartner.Core.Abstractions.Gateways { - public interface IAdministrationGateway + public interface IAdministrationGateway : IRabbitMqProducer { Task NotifyAdminAboutPartnerManagerPromoCode(Guid partnerManagerId); } diff --git a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Core/Abstractions/Gateways/IGivingPromoCodeToCustomerGateway.cs b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Core/Abstractions/Gateways/IGivingPromoCodeToCustomerGateway.cs index ad38ac13..4551ffa0 100644 --- a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Core/Abstractions/Gateways/IGivingPromoCodeToCustomerGateway.cs +++ b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Core/Abstractions/Gateways/IGivingPromoCodeToCustomerGateway.cs @@ -1,9 +1,11 @@ using System.Threading.Tasks; +using Infrastructure.RabbitMq; using Pcf.ReceivingFromPartner.Core.Domain; +using Pcf.ReceivingFromPartner.Core.Dto; namespace Pcf.ReceivingFromPartner.Core.Abstractions.Gateways { - public interface IGivingPromoCodeToCustomerGateway + public interface IGivingPromoCodeToCustomerGateway : IRabbitMqProducer { Task GivePromoCodeToCustomer(PromoCode promoCode); } diff --git a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Core/Dto/AdministrationDto.cs b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Core/Dto/AdministrationDto.cs new file mode 100644 index 00000000..3f70f976 --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Core/Dto/AdministrationDto.cs @@ -0,0 +1,8 @@ +using System; + +namespace Pcf.ReceivingFromPartner.Core.Dto; + +public class AdministrationDto +{ + public Guid PartnerId { get; set; } +} \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Integration/Dto/GivePromoCodeToCustomerDto.cs b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Core/Dto/GivePromoCodeToCustomerDto.cs similarity index 89% rename from Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Integration/Dto/GivePromoCodeToCustomerDto.cs rename to Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Core/Dto/GivePromoCodeToCustomerDto.cs index 920c555e..fbba0388 100644 --- a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Integration/Dto/GivePromoCodeToCustomerDto.cs +++ b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Core/Dto/GivePromoCodeToCustomerDto.cs @@ -1,6 +1,6 @@ using System; -namespace Pcf.ReceivingFromPartner.Integration.Dto +namespace Pcf.ReceivingFromPartner.Core.Dto { public class GivePromoCodeToCustomerDto { diff --git a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Core/Pcf.ReceivingFromPartner.Core.csproj b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Core/Pcf.ReceivingFromPartner.Core.csproj index 4c096661..4c94d65e 100644 --- a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Core/Pcf.ReceivingFromPartner.Core.csproj +++ b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Core/Pcf.ReceivingFromPartner.Core.csproj @@ -4,4 +4,8 @@ net8.0 + + + + diff --git a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Integration/AdministrationGateway.cs b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Integration/AdministrationGateway.cs index 446568b4..689e34f3 100644 --- a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Integration/AdministrationGateway.cs +++ b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Integration/AdministrationGateway.cs @@ -1,26 +1,25 @@ using System; -using System.Net.Http; using System.Threading.Tasks; +using Infrastructure.RabbitMq; using Pcf.ReceivingFromPartner.Core.Abstractions.Gateways; +using Pcf.ReceivingFromPartner.Core.Dto; +using RabbitMQ.Client; namespace Pcf.ReceivingFromPartner.Integration { - public class AdministrationGateway - : IAdministrationGateway + public class AdministrationGateway : RabbitMqProducer, IAdministrationGateway { - private readonly HttpClient _httpClient; - - public AdministrationGateway(HttpClient httpClient) - { - _httpClient = httpClient; - } + public AdministrationGateway(string exchangeType, string exchangeName, string routingKey, IChannel channel) : + base(exchangeType, exchangeName,routingKey, channel) { } public async Task NotifyAdminAboutPartnerManagerPromoCode(Guid partnerManagerId) { - var response = await _httpClient.PostAsync($"api/v1/employees/{partnerManagerId}/appliedPromocodes", - new StringContent(string.Empty)); + var message = new AdministrationDto() + { + PartnerId = partnerManagerId + }; - response.EnsureSuccessStatusCode(); + await Publish(message); } } } \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Integration/GivingPromoCodeToCustomerGateway.cs b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Integration/GivingPromoCodeToCustomerGateway.cs index abaa7d33..48add7f9 100644 --- a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Integration/GivingPromoCodeToCustomerGateway.cs +++ b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Integration/GivingPromoCodeToCustomerGateway.cs @@ -1,24 +1,26 @@ -using System.Net.Http; -using System.Threading.Tasks; -using Pcf.ReceivingFromPartner.Integration.Dto; +using System.Threading.Tasks; +using Infrastructure.RabbitMq; using Pcf.ReceivingFromPartner.Core.Abstractions.Gateways; using Pcf.ReceivingFromPartner.Core.Domain; +using Pcf.ReceivingFromPartner.Core.Dto; +using RabbitMQ.Client; namespace Pcf.ReceivingFromPartner.Integration { - public class GivingPromoCodeToCustomerGateway - : IGivingPromoCodeToCustomerGateway + public class GivingPromoCodeToCustomerGateway : + RabbitMqProducer, + IGivingPromoCodeToCustomerGateway { - private readonly HttpClient _httpClient; - - public GivingPromoCodeToCustomerGateway(HttpClient httpClient) - { - _httpClient = httpClient; - } + public GivingPromoCodeToCustomerGateway( + string exchangeType, + string exchangeName, + string routingKey, + IChannel channel): + base(exchangeType, exchangeName,routingKey, channel) { } public async Task GivePromoCodeToCustomer(PromoCode promoCode) { - var dto = new GivePromoCodeToCustomerDto() + var message = new GivePromoCodeToCustomerDto() { PartnerId = promoCode.Partner.Id, BeginDate = promoCode.BeginDate.ToShortDateString(), @@ -29,9 +31,7 @@ public async Task GivePromoCodeToCustomer(PromoCode promoCode) PartnerManagerId = promoCode.PartnerManagerId }; - var response = await _httpClient.PostAsJsonAsync("api/v1/promocodes", dto); - - response.EnsureSuccessStatusCode(); + await Publish(message); } } } \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Integration/Pcf.ReceivingFromPartner.Integration.csproj b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Integration/Pcf.ReceivingFromPartner.Integration.csproj index 6f5336fe..3addb932 100644 --- a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Integration/Pcf.ReceivingFromPartner.Integration.csproj +++ b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.Integration/Pcf.ReceivingFromPartner.Integration.csproj @@ -9,7 +9,9 @@ + + diff --git a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.WebHost/Pcf.ReceivingFromPartner.WebHost.csproj b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.WebHost/Pcf.ReceivingFromPartner.WebHost.csproj index c646b37f..3e090479 100644 --- a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.WebHost/Pcf.ReceivingFromPartner.WebHost.csproj +++ b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.WebHost/Pcf.ReceivingFromPartner.WebHost.csproj @@ -14,6 +14,7 @@ + diff --git a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.WebHost/Settings/ApplicationSettings.cs b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.WebHost/Settings/ApplicationSettings.cs new file mode 100644 index 00000000..d2a27451 --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.WebHost/Settings/ApplicationSettings.cs @@ -0,0 +1,9 @@ +using Infrastructure.RabbitMq; + +namespace Pcf.ReceivingFromPartner.WebHost.Settings +{ + public class ApplicationSettings + { + public RmqSettings RmqSettings { get; set; } + } +} \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.WebHost/Startup.cs b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.WebHost/Startup.cs index 532bb902..b1289fe8 100644 --- a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.WebHost/Startup.cs +++ b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.WebHost/Startup.cs @@ -1,4 +1,6 @@ using System; +using System.Threading.Tasks; +using Infrastructure.RabbitMq; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; @@ -12,6 +14,8 @@ using Pcf.ReceivingFromPartner.DataAccess.Repositories; using Pcf.ReceivingFromPartner.DataAccess.Data; using Pcf.ReceivingFromPartner.Integration; +using Pcf.ReceivingFromPartner.WebHost.Settings; +using RabbitMQ.Client; namespace Pcf.ReceivingFromPartner.WebHost { @@ -34,15 +38,7 @@ public void ConfigureServices(IServiceCollection services) services.AddScoped(); services.AddScoped(); - services.AddHttpClient(c => - { - c.BaseAddress = new Uri(Configuration["IntegrationSettings:GivingToCustomerApiUrl"]); - }); - - services.AddHttpClient(c => - { - c.BaseAddress = new Uri(Configuration["IntegrationSettings:AdministrationApiUrl"]); - }); + CreateGateways(services).Wait(); services.AddDbContext(x => { @@ -61,6 +57,36 @@ public void ConfigureServices(IServiceCollection services) }); } + private async Task CreateGateways(IServiceCollection services) + { + var rmqSettings = Configuration.Get().RmqSettings; + var connection = await RabbitMqConfiguration.GetRabbitConnection(rmqSettings); + var channel = await connection.CreateChannelAsync(); + + services.AddSingleton(provider => + { + var configuration = provider.GetRequiredService(); + + return new AdministrationGateway( + ExchangeType.Direct, + configuration["AdministrationExchangeName"], + configuration["AdministrationRoutingKey"], + channel + ); + }); + + services.AddSingleton(provider => + { + var configuration = provider.GetRequiredService(); + return new GivingPromoCodeToCustomerGateway( + ExchangeType.Direct, + configuration["GivingPromoCodeToCustomerExchangeName"], + configuration["GivingPromoCodeToCustomerRoutingKey"], + channel + ); + }); + } + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IDbInitializer dbInitializer) { @@ -88,6 +114,9 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IDbIniti endpoints.MapControllers(); }); + app.ApplicationServices.GetRequiredService(); + app.ApplicationServices.GetRequiredService(); + dbInitializer.InitializeDb(); } } diff --git a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.WebHost/appsettings.json b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.WebHost/appsettings.json index b5bbc80d..0182af6b 100644 --- a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.WebHost/appsettings.json +++ b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/Pcf.ReceivingFromPartner.WebHost/appsettings.json @@ -13,5 +13,16 @@ "GivingToCustomerApiUrl": "http://localhost:8093/", "AdministrationApiUrl": "http://localhost:8091/" }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "RmqSettings": { + "Host": "localhost", + "Port": 5672, + "VHost": "/", + "Login": "guest", + "Password": "guest" + }, + "AdministrationExchangeName": "exchange.administration", + "AdministrationRoutingKey": "routingKey.administration", + "GivingPromoCodeToCustomerExchangeName": "exchange.giving-promocode", + "GivingPromoCodeToCustomerRoutingKey": "routingKey.giving-promocode" } diff --git a/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/nuget.config b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/nuget.config new file mode 100644 index 00000000..a48aae93 --- /dev/null +++ b/Homeworks/RabbitMQ/src/Pcf.ReceivingFromPartner/nuget.config @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Homeworks/RabbitMQ/src/nuget.config b/Homeworks/RabbitMQ/src/nuget.config new file mode 100644 index 00000000..a48aae93 --- /dev/null +++ b/Homeworks/RabbitMQ/src/nuget.config @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file