@ -0,0 +1,15 @@ | |||
namespace Ordering.BackgroundTasks | |||
{ | |||
public class BackgroundTaskSettings | |||
{ | |||
public string ConnectionString { get; set; } | |||
public string EventBusConnection { get; set; } | |||
public int GracePeriodTime { get; set; } | |||
public int CheckUpdateTime { get; set; } | |||
public string SubscriptionClientName { get; set; } | |||
} | |||
} |
@ -0,0 +1,18 @@ | |||
FROM mcr.microsoft.com/dotnet/core/runtime:3.0-buster-slim AS base | |||
WORKDIR /app | |||
FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build | |||
WORKDIR /src | |||
COPY ["src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj", "src/Services/Ordering/Ordering.BackgroundTasks/"] | |||
RUN dotnet restore "src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj" | |||
COPY . . | |||
WORKDIR "/src/src/Services/Ordering/Ordering.BackgroundTasks" | |||
RUN dotnet build "Ordering.BackgroundTasks.csproj" -c Release -o /app | |||
FROM build AS publish | |||
RUN dotnet publish "Ordering.BackgroundTasks.csproj" -c Release -o /app | |||
FROM base AS final | |||
WORKDIR /app | |||
COPY --from=publish /app . | |||
ENTRYPOINT ["dotnet", "Ordering.BackgroundTasks.dll"] |
@ -0,0 +1,12 @@ | |||
namespace Ordering.BackgroundTasks.Events | |||
{ | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; | |||
public class GracePeriodConfirmedIntegrationEvent : IntegrationEvent | |||
{ | |||
public int OrderId { get; } | |||
public GracePeriodConfirmedIntegrationEvent(int orderId) => | |||
OrderId = orderId; | |||
} | |||
} |
@ -0,0 +1,141 @@ | |||
using Autofac; | |||
using Microsoft.Azure.ServiceBus; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus; | |||
using Microsoft.Extensions.Configuration; | |||
using Microsoft.Extensions.DependencyInjection; | |||
using Microsoft.Extensions.Diagnostics.HealthChecks; | |||
using Microsoft.Extensions.Logging; | |||
using RabbitMQ.Client; | |||
using Serilog; | |||
namespace Ordering.BackgroundTasks.Extensions | |||
{ | |||
public static class CustomExtensionMethods | |||
{ | |||
public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) | |||
{ | |||
var hcBuilder = services.AddHealthChecks(); | |||
hcBuilder.AddCheck("self", () => HealthCheckResult.Healthy()); | |||
hcBuilder.AddSqlServer( | |||
configuration["ConnectionString"], | |||
name: "OrderingTaskDB-check", | |||
tags: new string[] { "orderingtaskdb" }); | |||
if (configuration.GetValue<bool>("AzureServiceBusEnabled")) | |||
{ | |||
hcBuilder.AddAzureServiceBusTopic( | |||
configuration["EventBusConnection"], | |||
topicName: "eshop_event_bus", | |||
name: "orderingtask-servicebus-check", | |||
tags: new string[] { "servicebus" }); | |||
} | |||
else | |||
{ | |||
hcBuilder.AddRabbitMQ( | |||
$"amqp://{configuration["EventBusConnection"]}", | |||
name: "orderingtask-rabbitmqbus-check", | |||
tags: new string[] { "rabbitmqbus" }); | |||
} | |||
return services; | |||
} | |||
public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) | |||
{ | |||
var subscriptionClientName = configuration["SubscriptionClientName"]; | |||
if (configuration.GetValue<bool>("AzureServiceBusEnabled")) | |||
{ | |||
services.AddSingleton<IServiceBusPersisterConnection>(sp => | |||
{ | |||
var logger = sp.GetRequiredService<ILogger<DefaultServiceBusPersisterConnection>>(); | |||
var serviceBusConnectionString = configuration["EventBusConnection"]; | |||
var serviceBusConnection = new ServiceBusConnectionStringBuilder(serviceBusConnectionString); | |||
return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger); | |||
}); | |||
services.AddSingleton<IEventBus, EventBusServiceBus>(sp => | |||
{ | |||
var serviceBusPersisterConnection = sp.GetRequiredService<IServiceBusPersisterConnection>(); | |||
var iLifetimeScope = sp.GetRequiredService<ILifetimeScope>(); | |||
var logger = sp.GetRequiredService<ILogger<EventBusServiceBus>>(); | |||
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>(); | |||
return new EventBusServiceBus(serviceBusPersisterConnection, logger, eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); | |||
}); | |||
} | |||
else | |||
{ | |||
services.AddSingleton<IRabbitMQPersistentConnection>(sp => | |||
{ | |||
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>(); | |||
var factory = new ConnectionFactory() | |||
{ | |||
HostName = configuration["EventBusConnection"], | |||
DispatchConsumersAsync = true | |||
}; | |||
if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) | |||
{ | |||
factory.UserName = configuration["EventBusUserName"]; | |||
} | |||
if (!string.IsNullOrEmpty(configuration["EventBusPassword"])) | |||
{ | |||
factory.Password = configuration["EventBusPassword"]; | |||
} | |||
var retryCount = 5; | |||
if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) | |||
{ | |||
retryCount = int.Parse(configuration["EventBusRetryCount"]); | |||
} | |||
return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); | |||
}); | |||
services.AddSingleton<IEventBus, EventBusRabbitMQ>(sp => | |||
{ | |||
var rabbitMQPersistentConnection = sp.GetRequiredService<IRabbitMQPersistentConnection>(); | |||
var iLifetimeScope = sp.GetRequiredService<ILifetimeScope>(); | |||
var logger = sp.GetRequiredService<ILogger<EventBusRabbitMQ>>(); | |||
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>(); | |||
var retryCount = 5; | |||
if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) | |||
{ | |||
retryCount = int.Parse(configuration["EventBusRetryCount"]); | |||
} | |||
return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount); | |||
}); | |||
} | |||
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>(); | |||
return services; | |||
} | |||
public static ILoggingBuilder UseSerilog(this ILoggingBuilder builder, IConfiguration configuration) | |||
{ | |||
Log.Logger = new LoggerConfiguration() | |||
.MinimumLevel.Verbose() | |||
.Enrich.WithProperty("ApplicationContext", "BackgroundTasks") | |||
.Enrich.FromLogContext() | |||
.WriteTo.Console() | |||
.ReadFrom.Configuration(configuration) | |||
.CreateLogger(); | |||
return builder; | |||
} | |||
} | |||
} |
@ -0,0 +1,33 @@ | |||
<Project Sdk="Microsoft.NET.Sdk.Worker"> | |||
<PropertyGroup> | |||
<TargetFramework>$(NetCoreTargetVersion)</TargetFramework> | |||
<UserSecretsId>dotnet-Ordering.BackgroundTasks-9D3E1DD6-405B-447F-8AAB-1708B36D260E</UserSecretsId> | |||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS> | |||
<LangVersion>$(LangVersion)</LangVersion> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="$(Microsoft_Extensions_Hosting)" /> | |||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="$(Microsoft_VisualStudio_Azure_Containers_Tools_Targets)" /> | |||
<PackageReference Include="Dapper" Version="$(Dapper)" /> | |||
<PackageReference Include="Serilog.AspNetCore" Version="$(Serilog_AspNetCore)" /> | |||
<PackageReference Include="Serilog.Enrichers.Environment" Version="$(Serilog_Enrichers_Environment)" /> | |||
<PackageReference Include="Serilog.Settings.Configuration" Version="$(Serilog_Settings_Configuration)" /> | |||
<PackageReference Include="Serilog.Sinks.Console" Version="$(Serilog_Sinks_Console)" /> | |||
<PackageReference Include="Serilog.Sinks.Seq" Version="$(Serilog_Sinks_Seq)" /> | |||
<PackageReference Include="Serilog.Sinks.Http" Version="$(Serilog_Sinks_Http)" /> | |||
<PackageReference Include="Autofac" Version="$(Autofac)" /> | |||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="$(Autofac_Extensions_DependencyInjection)" /> | |||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="$(Microsoft_AspNetCore_Diagnostics_HealthChecks)" /> | |||
<PackageReference Include="AspNetCore.HealthChecks.AzureServiceBus" Version="$(AspNetCore_HealthChecks_AzureServiceBus)" /> | |||
<PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="$(AspNetCore_HealthChecks_Rabbitmq)" /> | |||
<PackageReference Include="AspNetCore.HealthChecks.SqlServer" Version="$(AspNetCore_HealthChecks_SqlServer)" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" /> | |||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj" /> | |||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBus\EventBus.csproj" /> | |||
</ItemGroup> | |||
</Project> |
@ -0,0 +1,40 @@ | |||
using Autofac.Extensions.DependencyInjection; | |||
using Microsoft.Extensions.Configuration; | |||
using Microsoft.Extensions.DependencyInjection; | |||
using Microsoft.Extensions.Hosting; | |||
using Ordering.BackgroundTasks.Extensions; | |||
using Ordering.BackgroundTasks.Tasks; | |||
using Serilog; | |||
using System.IO; | |||
namespace Ordering.BackgroundTasks | |||
{ | |||
public class Program | |||
{ | |||
public static void Main(string[] args) | |||
{ | |||
CreateHostBuilder(args).Build().Run(); | |||
} | |||
public static IHostBuilder CreateHostBuilder(string[] args) => | |||
Host.CreateDefaultBuilder(args) | |||
.ConfigureAppConfiguration((hostContext, builder) => | |||
{ | |||
builder.SetBasePath(Directory.GetCurrentDirectory()); | |||
builder.AddJsonFile("appsettings.json", optional: true); | |||
builder.AddJsonFile($"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json", optional: true); | |||
builder.AddEnvironmentVariables(); | |||
builder.AddCommandLine(args); | |||
}) | |||
.ConfigureLogging((host, builder) => builder.UseSerilog(host.Configuration).AddSerilog()) | |||
.ConfigureServices((host, services) => | |||
{ | |||
services.AddCustomHealthCheck(host.Configuration); | |||
services.Configure<BackgroundTaskSettings>(host.Configuration); | |||
services.AddOptions(); | |||
services.AddHostedService<GracePeriodManagerService>(); | |||
services.AddEventBus(host.Configuration); | |||
services.AddAutofac(container => container.Populate(services)); | |||
}); | |||
} | |||
} |
@ -0,0 +1,13 @@ | |||
{ | |||
"profiles": { | |||
"Ordering.BackgroundTasks": { | |||
"commandName": "Project", | |||
"environmentVariables": { | |||
"DOTNET_ENVIRONMENT": "Development" | |||
} | |||
}, | |||
"Docker": { | |||
"commandName": "Docker" | |||
} | |||
} | |||
} |
@ -0,0 +1,9 @@ | |||
{ | |||
"Logging": { | |||
"LogLevel": { | |||
"Default": "Debug", | |||
"System": "Information", | |||
"Microsoft": "Information" | |||
} | |||
} | |||
} |
@ -0,0 +1,26 @@ | |||
{ | |||
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;", | |||
"Serilog": { | |||
"SeqServerUrl": null, | |||
"LogstashgUrl": null, | |||
"MinimumLevel": { | |||
"Default": "Information", | |||
"Override": { | |||
"Microsoft": "Warning", | |||
"Microsoft.eShopOnContainers": "Information", | |||
"System": "Warning" | |||
} | |||
} | |||
}, | |||
"SubscriptionClientName": "BackgroundTasks", | |||
"GracePeriodTime": "1", | |||
"CheckUpdateTime": "1000", | |||
"ApplicationInsights": { | |||
"InstrumentationKey": "" | |||
}, | |||
"AzureServiceBusEnabled": false, | |||
"EventBusRetryCount": 5, | |||
"EventBusConnection": "", | |||
"EventBusUserName": "", | |||
"EventBusPassword": "" | |||
} |