@ -0,0 +1,106 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
using Microsoft.AspNetCore.Http; | |||
using Microsoft.AspNetCore.Mvc; | |||
using Microsoft.EntityFrameworkCore; | |||
using TenantAShippingInformation.Database; | |||
using TenantAShippingInformation.Models; | |||
namespace TenantAShippingInformation.Controllers | |||
{ | |||
[Route("api/[controller]")] | |||
[ApiController] | |||
public class ShippingInformationsController : ControllerBase | |||
{ | |||
private readonly TenantAContext _context; | |||
public ShippingInformationsController(TenantAContext context) | |||
{ | |||
_context = context; | |||
} | |||
// GET: api/ShippingInformations | |||
[HttpGet] | |||
public async Task<ActionResult<IEnumerable<ShippingInformation>>> GetShippingInformation() | |||
{ | |||
return await _context.ShippingInformation.ToListAsync(); | |||
} | |||
// GET: api/ShippingInformations/5 | |||
[HttpGet("{id}")] | |||
public async Task<ActionResult<ShippingInformation>> GetShippingInformation(int id) | |||
{ | |||
var shippingInformation = await _context.ShippingInformation.FindAsync(id); | |||
if (shippingInformation == null) | |||
{ | |||
return NotFound(); | |||
} | |||
return shippingInformation; | |||
} | |||
// PUT: api/ShippingInformations/5 | |||
[HttpPut("{id}")] | |||
public async Task<IActionResult> PutShippingInformation(int id, ShippingInformation shippingInformation) | |||
{ | |||
if (id != shippingInformation.ShippingInformationId) | |||
{ | |||
return BadRequest(); | |||
} | |||
_context.Entry(shippingInformation).State = EntityState.Modified; | |||
try | |||
{ | |||
await _context.SaveChangesAsync(); | |||
} | |||
catch (DbUpdateConcurrencyException) | |||
{ | |||
if (!ShippingInformationExists(id)) | |||
{ | |||
return NotFound(); | |||
} | |||
else | |||
{ | |||
throw; | |||
} | |||
} | |||
return NoContent(); | |||
} | |||
// POST: api/ShippingInformations | |||
[HttpPost] | |||
public async Task<ActionResult<ShippingInformation>> PostShippingInformation(ShippingInformation shippingInformation) | |||
{ | |||
_context.ShippingInformation.Add(shippingInformation); | |||
await _context.SaveChangesAsync(); | |||
return CreatedAtAction("GetShippingInformation", new { id = shippingInformation.ShippingInformationId }, shippingInformation); | |||
} | |||
// DELETE: api/ShippingInformations/5 | |||
[HttpDelete("{id}")] | |||
public async Task<ActionResult<ShippingInformation>> DeleteShippingInformation(int id) | |||
{ | |||
var shippingInformation = await _context.ShippingInformation.FindAsync(id); | |||
if (shippingInformation == null) | |||
{ | |||
return NotFound(); | |||
} | |||
_context.ShippingInformation.Remove(shippingInformation); | |||
await _context.SaveChangesAsync(); | |||
return shippingInformation; | |||
} | |||
private bool ShippingInformationExists(int id) | |||
{ | |||
return _context.ShippingInformation.Any(e => e.ShippingInformationId == id); | |||
} | |||
} | |||
} |
@ -0,0 +1,106 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
using Microsoft.AspNetCore.Http; | |||
using Microsoft.AspNetCore.Mvc; | |||
using Microsoft.EntityFrameworkCore; | |||
using TenantBShippingInformation.Database; | |||
using TenantBShippingInformation.Models; | |||
namespace TenantBShippingInformation.Controllers | |||
{ | |||
[Route("api/[controller]")] | |||
[ApiController] | |||
public class ShippingInformationsController : ControllerBase | |||
{ | |||
private readonly TenantBContext _context; | |||
public ShippingInformationsController(TenantBContext context) | |||
{ | |||
_context = context; | |||
} | |||
// GET: api/ShippingInformations | |||
[HttpGet] | |||
public async Task<ActionResult<IEnumerable<ShippingInformation>>> GetShippingInformation() | |||
{ | |||
return await _context.ShippingInformation.ToListAsync(); | |||
} | |||
// GET: api/ShippingInformations/5 | |||
[HttpGet("{id}")] | |||
public async Task<ActionResult<ShippingInformation>> GetShippingInformation(int id) | |||
{ | |||
var shippingInformation = await _context.ShippingInformation.FindAsync(id); | |||
if (shippingInformation == null) | |||
{ | |||
return NotFound(); | |||
} | |||
return shippingInformation; | |||
} | |||
// PUT: api/ShippingInformations/5 | |||
[HttpPut("{id}")] | |||
public async Task<IActionResult> PutShippingInformation(int id, ShippingInformation shippingInformation) | |||
{ | |||
if (id != shippingInformation.ShippingInformationId) | |||
{ | |||
return BadRequest(); | |||
} | |||
_context.Entry(shippingInformation).State = EntityState.Modified; | |||
try | |||
{ | |||
await _context.SaveChangesAsync(); | |||
} | |||
catch (DbUpdateConcurrencyException) | |||
{ | |||
if (!ShippingInformationExists(id)) | |||
{ | |||
return NotFound(); | |||
} | |||
else | |||
{ | |||
throw; | |||
} | |||
} | |||
return NoContent(); | |||
} | |||
// POST: api/ShippingInformations | |||
[HttpPost] | |||
public async Task<ActionResult<ShippingInformation>> PostShippingInformation(ShippingInformation shippingInformation) | |||
{ | |||
_context.ShippingInformation.Add(shippingInformation); | |||
await _context.SaveChangesAsync(); | |||
return CreatedAtAction("GetShippingInformation", new { id = shippingInformation.ShippingInformationId }, shippingInformation); | |||
} | |||
// DELETE: api/ShippingInformations/5 | |||
[HttpDelete("{id}")] | |||
public async Task<ActionResult<ShippingInformation>> DeleteShippingInformation(int id) | |||
{ | |||
var shippingInformation = await _context.ShippingInformation.FindAsync(id); | |||
if (shippingInformation == null) | |||
{ | |||
return NotFound(); | |||
} | |||
_context.ShippingInformation.Remove(shippingInformation); | |||
await _context.SaveChangesAsync(); | |||
return shippingInformation; | |||
} | |||
private bool ShippingInformationExists(int id) | |||
{ | |||
return _context.ShippingInformation.Any(e => e.ShippingInformationId == id); | |||
} | |||
} | |||
} |
@ -1,28 +0,0 @@ | |||
using Microsoft.EntityFrameworkCore; | |||
using Microsoft.EntityFrameworkCore.Design; | |||
using TenantAShippingInformation.Models; | |||
namespace TenantAShippingInformation.Database | |||
{ | |||
public class TenantAContext : DbContext | |||
{ | |||
public TenantAContext(DbContextOptions<TenantAContext> options) | |||
: base(options) | |||
{ | |||
} | |||
public DbSet<ShippingInformation> ShippingInformation { get; set; } | |||
} | |||
public class TenantAContextDesignFactory : IDesignTimeDbContextFactory<TenantAContext> | |||
{ | |||
public TenantAContext CreateDbContext(string[] args) | |||
{ | |||
var optionsBuilder = new DbContextOptionsBuilder<TenantAContext>() | |||
.UseSqlServer("Server=.;Initial Catalog=Microsoft.eShopOnContainers.Services.TenantAShippingInformationDb;Integrated Security=true"); | |||
return new TenantAContext(optionsBuilder.Options); | |||
} | |||
} | |||
} |
@ -0,0 +1,28 @@ | |||
using Microsoft.EntityFrameworkCore; | |||
using Microsoft.EntityFrameworkCore.Design; | |||
using TenantBShippingInformation.Models; | |||
namespace TenantBShippingInformation.Database | |||
{ | |||
public class TenantBContext : DbContext | |||
{ | |||
public TenantBContext(DbContextOptions<TenantBContext> options) | |||
: base(options) | |||
{ | |||
} | |||
public DbSet<ShippingInformation> ShippingInformation { get; set; } | |||
} | |||
public class TenantBContextDesignFactory : IDesignTimeDbContextFactory<TenantBContext> | |||
{ | |||
public TenantBContext CreateDbContext(string[] args) | |||
{ | |||
var optionsBuilder = new DbContextOptionsBuilder<TenantBContext>() | |||
.UseSqlServer("Server=.;Initial Catalog=Microsoft.eShopOnContainers.Services.TenantBShippingInformationDb;Integrated Security=true"); | |||
return new TenantBContext(optionsBuilder.Options); | |||
} | |||
} | |||
} |
@ -0,0 +1,87 @@ | |||
using Microsoft.AspNetCore; | |||
using Microsoft.AspNetCore.Hosting; | |||
using Microsoft.Extensions.Configuration; | |||
using Serilog; | |||
using System; | |||
using System.IO; | |||
namespace TenantBShippingInformation | |||
{ | |||
public class Program | |||
{ | |||
public static readonly string Namespace = typeof(Program).Namespace; | |||
public static readonly string AppName = Namespace; | |||
public static int Main(string[] args) | |||
{ | |||
var configuration = GetConfiguration(); | |||
Log.Logger = CreateSerilogLogger(configuration); | |||
try | |||
{ | |||
Log.Information("Configuring web host ({ApplicationContext})...", AppName); | |||
var host = BuildWebHost(configuration, args); | |||
Log.Information("Starting web host ({ApplicationContext})...", AppName); | |||
host.Run(); | |||
return 0; | |||
} | |||
catch (Exception ex) | |||
{ | |||
Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", AppName); | |||
return 1; | |||
} | |||
finally | |||
{ | |||
Log.CloseAndFlush(); | |||
} | |||
} | |||
private static IWebHost BuildWebHost(IConfiguration configuration, string[] args) => | |||
WebHost.CreateDefaultBuilder(args) | |||
.CaptureStartupErrors(false) | |||
.UseStartup<Startup>() | |||
.UseApplicationInsights() | |||
.UseContentRoot(Directory.GetCurrentDirectory()) | |||
.UseConfiguration(configuration) | |||
.UseSerilog() | |||
.Build(); | |||
private static Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) | |||
{ | |||
var seqServerUrl = configuration["Serilog:SeqServerUrl"]; | |||
var logstashUrl = configuration["Serilog:LogstashgUrl"]; | |||
return new LoggerConfiguration() | |||
.MinimumLevel.Verbose() | |||
.Enrich.WithProperty("ApplicationContext", AppName) | |||
.Enrich.FromLogContext() | |||
.WriteTo.Console() | |||
.WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl) | |||
.WriteTo.Http(string.IsNullOrWhiteSpace(logstashUrl) ? "http://logstash:8080" : logstashUrl) | |||
.ReadFrom.Configuration(configuration) | |||
.CreateLogger(); | |||
} | |||
private static IConfiguration GetConfiguration() | |||
{ | |||
var builder = new ConfigurationBuilder() | |||
.SetBasePath(Directory.GetCurrentDirectory()) | |||
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) | |||
.AddEnvironmentVariables(); | |||
var config = builder.Build(); | |||
if (config.GetValue<bool>("UseVault", false)) | |||
{ | |||
builder.AddAzureKeyVault( | |||
$"https://{config["Vault:Name"]}.vault.azure.net/", | |||
config["Vault:ClientId"], | |||
config["Vault:ClientSecret"]); | |||
} | |||
return builder.Build(); | |||
} | |||
} | |||
} |
@ -0,0 +1,27 @@ | |||
{ | |||
"iisSettings": { | |||
"windowsAuthentication": false, | |||
"anonymousAuthentication": true, | |||
"iisExpress": { | |||
"applicationUrl": "http://localhost:50373", | |||
"sslPort": 44351 | |||
} | |||
}, | |||
"profiles": { | |||
"IIS Express": { | |||
"commandName": "IISExpress", | |||
"launchBrowser": true, | |||
"environmentVariables": { | |||
"ASPNETCORE_ENVIRONMENT": "Development" | |||
} | |||
}, | |||
"TenantBShippingInformation": { | |||
"commandName": "Project", | |||
"launchBrowser": true, | |||
"applicationUrl": "https://localhost:5001;http://localhost:5000", | |||
"environmentVariables": { | |||
"ASPNETCORE_ENVIRONMENT": "Development" | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,414 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Data.Common; | |||
using System.IdentityModel.Tokens.Jwt; | |||
using System.Reflection; | |||
using Autofac; | |||
using Autofac.Extensions.DependencyInjection; | |||
using HealthChecks.UI.Client; | |||
using Microsoft.ApplicationInsights.Extensibility; | |||
using Microsoft.ApplicationInsights.ServiceFabric; | |||
using Microsoft.AspNetCore.Authentication.JwtBearer; | |||
using Microsoft.AspNetCore.Builder; | |||
using Microsoft.AspNetCore.Diagnostics.HealthChecks; | |||
using Microsoft.AspNetCore.Http; | |||
using Microsoft.AspNetCore.Mvc; | |||
using Microsoft.Azure.ServiceBus; | |||
using Microsoft.EntityFrameworkCore; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services; | |||
using Microsoft.Extensions.Configuration; | |||
using Microsoft.Extensions.DependencyInjection; | |||
using Microsoft.Extensions.Diagnostics.HealthChecks; | |||
using Microsoft.Extensions.Logging; | |||
using RabbitMQ.Client; | |||
using Swashbuckle.AspNetCore.Swagger; | |||
using TenantBShippingInformation.Infrastructure.AutofacModules; | |||
using TenantBShippingInformation.Infrastructure.Filters; | |||
using TenantBShippingInformation.Database; | |||
using TenantBShippingInformation.IntegrationEvents.Events; | |||
using TenantBShippingInformation.IntegrationEvents.EventHandling; | |||
namespace TenantBShippingInformation | |||
{ | |||
public class Startup | |||
{ | |||
public Startup(IConfiguration configuration) | |||
{ | |||
Configuration = configuration; | |||
} | |||
public IConfiguration Configuration { get; } | |||
public IServiceProvider ConfigureServices(IServiceCollection services) | |||
{ | |||
services.AddApplicationInsights(Configuration) | |||
.AddCustomMvc() | |||
.AddHealthChecks(Configuration) | |||
.AddCustomDbContext(Configuration) | |||
.AddCustomSwagger(Configuration) | |||
.AddCustomIntegrations(Configuration) | |||
.AddCustomConfiguration(Configuration) | |||
.AddEventBus(Configuration) | |||
.AddCustomAuthentication(Configuration); | |||
//configure autofac | |||
var container = new ContainerBuilder(); | |||
container.Populate(services); | |||
container.RegisterModule(new MediatorModule()); | |||
container.RegisterModule(new ApplicationModule(Configuration["ConnectionString"])); | |||
return new AutofacServiceProvider(container.Build()); | |||
} | |||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) | |||
{ | |||
//loggerFactory.AddAzureWebAppDiagnostics(); | |||
//loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace); | |||
var pathBase = Configuration["PATH_BASE"]; | |||
if (!string.IsNullOrEmpty(pathBase)) | |||
{ | |||
loggerFactory.CreateLogger<Startup>().LogDebug("Using PATH BASE '{pathBase}'", pathBase); | |||
app.UsePathBase(pathBase); | |||
} | |||
app.UseCors("CorsPolicy"); | |||
app.UseHealthChecks("/liveness", new HealthCheckOptions | |||
{ | |||
Predicate = r => r.Name.Contains("self") | |||
}); | |||
app.UseHealthChecks("/hc", new HealthCheckOptions() | |||
{ | |||
Predicate = _ => true, | |||
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse | |||
}); | |||
ConfigureAuth(app); | |||
app.UseMvcWithDefaultRoute(); | |||
app.UseSwagger() | |||
.UseSwaggerUI(c => | |||
{ | |||
c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Ordering.API V1"); | |||
c.OAuthClientId("orderingswaggerui"); | |||
c.OAuthAppName("Ordering Swagger UI"); | |||
}); | |||
ConfigureEventBus(app); | |||
using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope()) | |||
{ | |||
var context = serviceScope.ServiceProvider.GetRequiredService<TenantBContext>(); | |||
context.Database.EnsureCreated(); | |||
} | |||
} | |||
private void ConfigureEventBus(IApplicationBuilder app) | |||
{ | |||
var eventBus = app.ApplicationServices.GetRequiredService<Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions.IEventBus>(); | |||
//eventBus.Subscribe<UserCheckoutAcceptedIntegrationEvent, IIntegrationEventHandler<UserCheckoutAcceptedIntegrationEvent>>(); | |||
eventBus.Subscribe<OrderStatusChangedToSubmittedIntegrationEvent, OrderStatusChangedToSubmittedIntegrationEventHandler>(); | |||
} | |||
protected virtual void ConfigureAuth(IApplicationBuilder app) | |||
{ | |||
if (Configuration.GetValue<bool>("UseLoadTest")) | |||
{ | |||
//app.UseMiddleware<ByPassAuthMiddleware>(); | |||
//TODO | |||
} | |||
app.UseAuthentication(); | |||
} | |||
} | |||
static class CustomExtensionsMethods | |||
{ | |||
public static IServiceCollection AddApplicationInsights(this IServiceCollection services, IConfiguration configuration) | |||
{ | |||
services.AddApplicationInsightsTelemetry(configuration); | |||
var orchestratorType = configuration.GetValue<string>("OrchestratorType"); | |||
if (orchestratorType?.ToUpper() == "K8S") | |||
{ | |||
// Enable K8s telemetry initializer | |||
services.AddApplicationInsightsKubernetesEnricher(); | |||
} | |||
if (orchestratorType?.ToUpper() == "SF") | |||
{ | |||
// Enable SF telemetry initializer | |||
services.AddSingleton<ITelemetryInitializer>((serviceProvider) => | |||
new FabricTelemetryInitializer()); | |||
} | |||
return services; | |||
} | |||
public static IServiceCollection AddCustomMvc(this IServiceCollection services) | |||
{ | |||
// Add framework services. | |||
services.AddMvc(options => | |||
{ | |||
options.Filters.Add(typeof(HttpGlobalExceptionFilter)); | |||
}) | |||
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2) | |||
.AddControllersAsServices(); //Injecting Controllers themselves thru DI | |||
//For further info see: http://docs.autofac.org/en/latest/integration/aspnetcore.html#controllers-as-services | |||
services.AddCors(options => | |||
{ | |||
options.AddPolicy("CorsPolicy", | |||
builder => builder | |||
.SetIsOriginAllowed((host) => true) | |||
.AllowAnyMethod() | |||
.AllowAnyHeader() | |||
.AllowCredentials()); | |||
}); | |||
return services; | |||
} | |||
public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) | |||
{ | |||
var hcBuilder = services.AddHealthChecks(); | |||
hcBuilder.AddCheck("self", () => HealthCheckResult.Healthy()); | |||
hcBuilder | |||
.AddSqlServer( | |||
configuration["ConnectionString"], | |||
name: "OrderingDB-check", | |||
tags: new string[] { "orderingdb" }); | |||
if (configuration.GetValue<bool>("AzureServiceBusEnabled")) | |||
{ | |||
hcBuilder | |||
.AddAzureServiceBusTopic( | |||
configuration["EventBusConnection"], | |||
topicName: "eshop_event_bus", | |||
name: "ordering-servicebus-check", | |||
tags: new string[] { "servicebus" }); | |||
} | |||
else | |||
{ | |||
hcBuilder | |||
.AddRabbitMQ( | |||
$"amqp://{configuration["EventBusConnection"]}", | |||
name: "ordering-rabbitmqbus-check", | |||
tags: new string[] { "rabbitmqbus" }); | |||
} | |||
return services; | |||
} | |||
public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration) | |||
{ | |||
services.AddDbContext<TenantBContext>(options => | |||
options.UseSqlServer(configuration["ConnectionString"])); | |||
services.AddDbContext<IntegrationEventLogContext>(options => | |||
{ | |||
options.UseSqlServer(configuration["ConnectionString"], | |||
sqlServerOptionsAction: sqlOptions => | |||
{ | |||
sqlOptions.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name); | |||
//Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency | |||
sqlOptions.EnableRetryOnFailure(maxRetryCount: 10, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); | |||
}); | |||
}); | |||
return services; | |||
} | |||
public static IServiceCollection AddCustomSwagger(this IServiceCollection services, IConfiguration configuration) | |||
{ | |||
services.AddSwaggerGen(options => | |||
{ | |||
options.DescribeAllEnumsAsStrings(); | |||
options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info | |||
{ | |||
Title = "Ordering HTTP API", | |||
Version = "v1", | |||
Description = "The Ordering Service HTTP API", | |||
TermsOfService = "Terms Of Service" | |||
}); | |||
options.AddSecurityDefinition("oauth2", new OAuth2Scheme | |||
{ | |||
Type = "oauth2", | |||
Flow = "implicit", | |||
AuthorizationUrl = $"{configuration.GetValue<string>("IdentityUrlExternal")}/connect/authorize", | |||
TokenUrl = $"{configuration.GetValue<string>("IdentityUrlExternal")}/connect/token", | |||
Scopes = new Dictionary<string, string>() | |||
{ | |||
{ "orders", "Ordering API" } | |||
} | |||
}); | |||
options.OperationFilter<AuthorizeCheckOperationFilter>(); | |||
}); | |||
return services; | |||
} | |||
public static IServiceCollection AddCustomIntegrations(this IServiceCollection services, IConfiguration configuration) | |||
{ | |||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); | |||
//services.AddTransient<IIdentityService, IdentityService>(); | |||
services.AddTransient<Func<DbConnection, IIntegrationEventLogService>>( | |||
sp => (DbConnection c) => new IntegrationEventLogService(c)); | |||
//services.AddTransient<IOrderingIntegrationEventService, OrderingIntegrationEventService>(); | |||
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); | |||
}); | |||
} | |||
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"]; | |||
} | |||
factory.VirtualHost = "TenantB"; | |||
var retryCount = 5; | |||
if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) | |||
{ | |||
retryCount = int.Parse(configuration["EventBusRetryCount"]); | |||
} | |||
return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); | |||
}); | |||
} | |||
return services; | |||
} | |||
public static IServiceCollection AddCustomConfiguration(this IServiceCollection services, IConfiguration configuration) | |||
{ | |||
services.AddOptions(); | |||
//services.Configure<OrderingSettings>(configuration); | |||
services.Configure<ApiBehaviorOptions>(options => | |||
{ | |||
options.InvalidModelStateResponseFactory = context => | |||
{ | |||
var problemDetails = new ValidationProblemDetails(context.ModelState) | |||
{ | |||
Instance = context.HttpContext.Request.Path, | |||
Status = StatusCodes.Status400BadRequest, | |||
Detail = "Please refer to the errors property for additional details." | |||
}; | |||
return new BadRequestObjectResult(problemDetails) | |||
{ | |||
ContentTypes = { "application/problem+json", "application/problem+xml" } | |||
}; | |||
}; | |||
}); | |||
return services; | |||
} | |||
public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) | |||
{ | |||
var subscriptionClientName = configuration["SubscriptionClientName"]; | |||
/* if (configuration.GetValue<bool>("AzureServiceBusEnabled")) | |||
{ | |||
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<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, "TenantB", subscriptionClientName, retryCount); | |||
}); | |||
} | |||
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>(); | |||
//services.AddTransient<TenantAUserCheckoutAcceptedIntegrationEventHandler>(); | |||
return services; | |||
} | |||
public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) | |||
{ | |||
// prevent from mapping "sub" claim to nameidentifier. | |||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); | |||
var identityUrl = configuration.GetValue<string>("IdentityUrl"); | |||
services.AddAuthentication(options => | |||
{ | |||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; | |||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; | |||
}).AddJwtBearer(options => | |||
{ | |||
options.Authority = identityUrl; | |||
options.RequireHttpsMetadata = false; | |||
options.Audience = "orders"; | |||
}); | |||
return services; | |||
} | |||
} | |||
} |
@ -0,0 +1,56 @@ | |||
<Project Sdk="Microsoft.NET.Sdk.Web"> | |||
<PropertyGroup> | |||
<TargetFramework>netcoreapp2.2</TargetFramework> | |||
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="AspNetCore.HealthChecks.AzureServiceBus" Version="2.2.0" /> | |||
<PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="2.2.0" /> | |||
<PackageReference Include="AspNetCore.HealthChecks.SqlServer" Version="2.2.0" /> | |||
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.4" /> | |||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" /> | |||
<PackageReference Include="Dapper" Version="1.50.7" /> | |||
<PackageReference Include="FluentValidation.AspNetCore" Version="7.5.0" /> | |||
<PackageReference Include="MediatR" Version="5.1.0" /> | |||
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="5.1.0" /> | |||
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.11.0" /> | |||
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.2.1" /> | |||
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.6.1" /> | |||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.2" /> | |||
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.2.2" /> | |||
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0" /> | |||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" /> | |||
<PackageReference Include="Microsoft.AspNetCore.HealthChecks" Version="1.0.0" /> | |||
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" /> | |||
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.2.0" /> | |||
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.2.0" /> | |||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.4" /> | |||
<PackageReference Include="Polly" Version="6.0.1" /> | |||
<PackageReference Include="Serilog" Version="2.9.0" /> | |||
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" /> | |||
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.1.3" /> | |||
<PackageReference Include="Serilog.Settings.Configuration" Version="3.0.1" /> | |||
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> | |||
<PackageReference Include="Serilog.Sinks.Http" Version="4.2.1" /> | |||
<PackageReference Include="Serilog.Sinks.Seq" Version="4.0.0" /> | |||
<PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" /> | |||
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="4.0.1" /> | |||
<PackageReference Include="System.Reflection" Version="4.3.0" /> | |||
<PackageReference Include="System.ValueTuple" Version="4.5.0" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\..\..\BuildingBlocks\Devspaces.Support\Devspaces.Support.csproj" /> | |||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" /> | |||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj" /> | |||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBus\EventBus.csproj" /> | |||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\IntegrationEventLogEF\IntegrationEventLogEF.csproj" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<PackageReference Update="Microsoft.NETCore.App" Version="2.2.0" /> | |||
</ItemGroup> | |||
</Project> |
@ -0,0 +1,9 @@ | |||
{ | |||
"Logging": { | |||
"LogLevel": { | |||
"Default": "Debug", | |||
"System": "Information", | |||
"Microsoft": "Information" | |||
} | |||
} | |||
} |
@ -0,0 +1,29 @@ | |||
{ | |||
"Serilog": { | |||
"SeqServerUrl": null, | |||
"LogstashgUrl": null, | |||
"MinimumLevel": { | |||
"Default": "Information", | |||
"Override": { | |||
"Microsoft": "Warning", | |||
"Microsoft.eShopOnContainers": "Information", | |||
"System": "Warning" | |||
} | |||
} | |||
}, | |||
"IdentityUrl": "http://localhost:5105", | |||
//"ConnectionString": "127.0.0.1", | |||
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.TenantBShippingInformationDb;User Id=sa;Password=Pass@word;", | |||
"AzureServiceBusEnabled": false, | |||
"SubscriptionClientName": "TenantBShippingInformation", | |||
"ApplicationInsights": { | |||
"InstrumentationKey": "" | |||
}, | |||
"EventBusRetryCount": 5, | |||
"UseVault": false, | |||
"Vault": { | |||
"Name": "eshop", | |||
"ClientId": "your-clien-id", | |||
"ClientSecret": "your-client-secret" | |||
} | |||
} |