2016-11-03 17:52:15 +01:00
|
|
|
|
namespace Microsoft.eShopOnContainers.Services.Catalog.API
|
2016-09-06 17:09:19 -07:00
|
|
|
|
{
|
2017-03-27 14:05:28 +02:00
|
|
|
|
using global::Catalog.API.Infrastructure.Filters;
|
2017-04-17 12:28:12 +02:00
|
|
|
|
using global::Catalog.API.IntegrationEvents;
|
2016-11-03 17:52:15 +01:00
|
|
|
|
using Microsoft.AspNetCore.Builder;
|
|
|
|
|
using Microsoft.AspNetCore.Hosting;
|
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
2017-03-16 13:30:01 +01:00
|
|
|
|
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
|
|
|
|
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ;
|
2017-03-22 16:10:46 +01:00
|
|
|
|
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
|
2017-03-24 12:37:44 +01:00
|
|
|
|
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services;
|
2016-11-03 17:52:15 +01:00
|
|
|
|
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
|
|
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
2017-03-23 19:10:55 +01:00
|
|
|
|
using Microsoft.Extensions.HealthChecks;
|
2016-11-03 17:52:15 +01:00
|
|
|
|
using Microsoft.Extensions.Logging;
|
2017-03-13 11:03:35 +01:00
|
|
|
|
using Microsoft.Extensions.Options;
|
2016-12-07 13:57:31 +01:00
|
|
|
|
using System;
|
2017-03-24 12:37:44 +01:00
|
|
|
|
using System.Data.Common;
|
2017-04-17 12:28:12 +02:00
|
|
|
|
using System.Data.SqlClient;
|
2017-03-03 12:03:31 +01:00
|
|
|
|
using System.Reflection;
|
2016-11-03 17:52:15 +01:00
|
|
|
|
|
2016-09-06 17:09:19 -07:00
|
|
|
|
public class Startup
|
|
|
|
|
{
|
2016-10-31 16:54:55 +01:00
|
|
|
|
public IConfigurationRoot Configuration { get; }
|
|
|
|
|
|
2016-09-06 17:09:19 -07:00
|
|
|
|
public Startup(IHostingEnvironment env)
|
|
|
|
|
{
|
|
|
|
|
var builder = new ConfigurationBuilder()
|
|
|
|
|
.SetBasePath(env.ContentRootPath)
|
2016-11-14 15:48:30 +01:00
|
|
|
|
.AddJsonFile($"settings.json", optional: false, reloadOnChange: true)
|
2016-11-21 12:41:36 +01:00
|
|
|
|
.AddJsonFile($"settings.{env.EnvironmentName}.json", optional: true);
|
|
|
|
|
|
|
|
|
|
if (env.IsDevelopment())
|
|
|
|
|
{
|
2017-03-03 12:03:31 +01:00
|
|
|
|
builder.AddUserSecrets(typeof(Startup).GetTypeInfo().Assembly);
|
2016-11-21 12:41:36 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
builder.AddEnvironmentVariables();
|
2016-10-31 16:54:55 +01:00
|
|
|
|
|
2016-09-06 17:09:19 -07:00
|
|
|
|
Configuration = builder.Build();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ConfigureServices(IServiceCollection services)
|
|
|
|
|
{
|
2017-03-27 14:05:28 +02:00
|
|
|
|
// Add framework services.
|
2017-04-17 12:28:12 +02:00
|
|
|
|
|
2017-03-23 19:10:55 +01:00
|
|
|
|
services.AddHealthChecks(checks =>
|
|
|
|
|
{
|
2017-03-31 12:47:56 +02:00
|
|
|
|
checks.AddSqlCheck("CatalogDb", Configuration["ConnectionString"]);
|
2017-03-23 19:10:55 +01:00
|
|
|
|
});
|
|
|
|
|
|
2017-03-28 16:37:48 +02:00
|
|
|
|
services.AddMvc(options =>
|
2016-10-31 16:54:55 +01:00
|
|
|
|
{
|
2017-03-27 14:05:28 +02:00
|
|
|
|
options.Filters.Add(typeof(HttpGlobalExceptionFilter));
|
|
|
|
|
}).AddControllersAsServices();
|
|
|
|
|
|
2017-03-27 15:24:29 +02:00
|
|
|
|
services.AddDbContext<CatalogContext>(options =>
|
2016-10-31 16:54:55 +01:00
|
|
|
|
{
|
2017-03-27 10:18:41 +02:00
|
|
|
|
options.UseSqlServer(Configuration["ConnectionString"],
|
2017-03-26 18:00:04 -07:00
|
|
|
|
sqlServerOptionsAction: sqlOptions =>
|
2017-04-17 12:28:12 +02:00
|
|
|
|
{
|
2017-03-26 18:00:04 -07:00
|
|
|
|
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: 5, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
|
|
|
|
|
});
|
2017-04-17 12:28:12 +02:00
|
|
|
|
|
2017-03-04 17:29:36 -08:00
|
|
|
|
// Changing default behavior when client evaluation occurs to throw.
|
|
|
|
|
// Default in EF Core would be to log a warning when client evaluation is performed.
|
2017-03-26 18:00:04 -07:00
|
|
|
|
options.ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning));
|
2017-03-04 17:29:36 -08:00
|
|
|
|
//Check Client vs. Server evaluation: https://docs.microsoft.com/en-us/ef/core/querying/client-eval
|
2016-09-14 08:35:34 -07:00
|
|
|
|
});
|
|
|
|
|
|
2017-04-17 12:28:12 +02:00
|
|
|
|
services.Configure<CatalogSettings>(Configuration);
|
2017-01-09 10:33:43 +01:00
|
|
|
|
|
2016-09-06 17:09:19 -07:00
|
|
|
|
// Add framework services.
|
2016-11-03 17:52:15 +01:00
|
|
|
|
services.AddSwaggerGen();
|
|
|
|
|
services.ConfigureSwaggerGen(options =>
|
|
|
|
|
{
|
|
|
|
|
options.DescribeAllEnumsAsStrings();
|
|
|
|
|
options.SingleApiVersion(new Swashbuckle.Swagger.Model.Info()
|
|
|
|
|
{
|
2016-11-30 15:01:14 -08:00
|
|
|
|
Title = "eShopOnContainers - Catalog HTTP API",
|
2016-11-03 17:52:15 +01:00
|
|
|
|
Version = "v1",
|
2016-11-30 15:01:14 -08:00
|
|
|
|
Description = "The Catalog Microservice HTTP API. This is a Data-Driven/CRUD microservice sample",
|
2016-11-14 15:48:30 +01:00
|
|
|
|
TermsOfService = "Terms Of Service"
|
2016-11-03 17:52:15 +01:00
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2016-11-23 09:11:09 +01:00
|
|
|
|
services.AddCors(options =>
|
|
|
|
|
{
|
|
|
|
|
options.AddPolicy("CorsPolicy",
|
|
|
|
|
builder => builder.AllowAnyOrigin()
|
|
|
|
|
.AllowAnyMethod()
|
|
|
|
|
.AllowAnyHeader()
|
|
|
|
|
.AllowCredentials());
|
|
|
|
|
});
|
2016-10-31 16:54:55 +01:00
|
|
|
|
|
2017-03-24 12:37:44 +01:00
|
|
|
|
services.AddTransient<Func<DbConnection, IIntegrationEventLogService>>(
|
2017-04-17 12:28:12 +02:00
|
|
|
|
sp => (DbConnection c) => new IntegrationEventLogService(c));
|
|
|
|
|
|
2017-04-03 13:13:40 +02:00
|
|
|
|
services.AddTransient<ICatalogIntegrationEventService, CatalogIntegrationEventService>();
|
2017-04-17 12:28:12 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var serviceProvider = services.BuildServiceProvider();
|
|
|
|
|
|
|
|
|
|
services.AddSingleton<IEventBus>(sp =>
|
|
|
|
|
{
|
|
|
|
|
var settings = serviceProvider.GetRequiredService<IOptionsSnapshot<CatalogSettings>>().Value;
|
|
|
|
|
return new EventBusRabbitMQ(settings.EventBusConnection);
|
|
|
|
|
});
|
2016-09-06 17:09:19 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
|
|
|
|
|
{
|
2016-10-31 16:54:55 +01:00
|
|
|
|
//Configure logs
|
|
|
|
|
|
2016-09-06 17:09:19 -07:00
|
|
|
|
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
|
|
|
|
|
loggerFactory.AddDebug();
|
|
|
|
|
|
2016-11-23 09:11:09 +01:00
|
|
|
|
app.UseCors("CorsPolicy");
|
2016-10-31 16:54:55 +01:00
|
|
|
|
|
2016-12-07 13:57:31 +01:00
|
|
|
|
app.UseMvcWithDefaultRoute();
|
2016-11-03 17:52:15 +01:00
|
|
|
|
|
|
|
|
|
app.UseSwagger()
|
|
|
|
|
.UseSwaggerUi();
|
2016-12-07 13:57:31 +01:00
|
|
|
|
|
2017-03-20 15:37:31 +01:00
|
|
|
|
var context = (CatalogContext)app
|
|
|
|
|
.ApplicationServices.GetService(typeof(CatalogContext));
|
|
|
|
|
|
|
|
|
|
WaitForSqlAvailability(context, loggerFactory);
|
2017-04-17 12:28:12 +02:00
|
|
|
|
|
2016-12-07 13:57:31 +01:00
|
|
|
|
//Seed Data
|
|
|
|
|
CatalogContextSeed.SeedAsync(app, loggerFactory)
|
2017-04-17 12:28:12 +02:00
|
|
|
|
.Wait();
|
2017-03-24 12:37:44 +01:00
|
|
|
|
|
|
|
|
|
var integrationEventLogContext = new IntegrationEventLogContext(
|
|
|
|
|
new DbContextOptionsBuilder<IntegrationEventLogContext>()
|
2017-03-29 11:43:30 +02:00
|
|
|
|
.UseSqlServer(Configuration["ConnectionString"], b => b.MigrationsAssembly("Catalog.API"))
|
2017-03-24 12:37:44 +01:00
|
|
|
|
.Options);
|
2017-04-17 12:28:12 +02:00
|
|
|
|
|
2017-03-23 13:24:17 +01:00
|
|
|
|
integrationEventLogContext.Database.Migrate();
|
2017-03-20 15:37:31 +01:00
|
|
|
|
}
|
2016-12-07 13:57:31 +01:00
|
|
|
|
|
2017-03-20 15:37:31 +01:00
|
|
|
|
private void WaitForSqlAvailability(CatalogContext ctx, ILoggerFactory loggerFactory, int? retry = 0)
|
|
|
|
|
{
|
2017-04-17 12:28:12 +02:00
|
|
|
|
int retryForAvailability = retry.Value;
|
|
|
|
|
|
2017-03-20 15:37:31 +01:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
ctx.Database.OpenConnection();
|
|
|
|
|
}
|
2017-04-17 12:28:12 +02:00
|
|
|
|
catch (SqlException ex)
|
2017-03-20 15:37:31 +01:00
|
|
|
|
{
|
|
|
|
|
if (retryForAvailability < 10)
|
|
|
|
|
{
|
|
|
|
|
retryForAvailability++;
|
|
|
|
|
var log = loggerFactory.CreateLogger(nameof(Startup));
|
|
|
|
|
log.LogError(ex.Message);
|
|
|
|
|
WaitForSqlAvailability(ctx, loggerFactory, retryForAvailability);
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-04-17 12:28:12 +02:00
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
ctx.Database.CloseConnection();
|
2017-03-20 15:37:31 +01:00
|
|
|
|
}
|
2016-09-06 17:09:19 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|