2016-11-24 14:58:37 +01:00
|
|
|
|
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure
|
2016-11-22 18:40:47 +01:00
|
|
|
|
{
|
|
|
|
|
using AspNetCore.Builder;
|
2017-09-13 14:53:06 +02:00
|
|
|
|
using global::Ordering.API.Extensions;
|
|
|
|
|
using Microsoft.AspNetCore.Hosting;
|
2016-11-22 18:40:47 +01:00
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
2017-01-17 18:32:40 -08:00
|
|
|
|
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
|
|
|
|
|
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
|
2017-06-20 12:54:32 -07:00
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
2017-09-13 14:53:06 +02:00
|
|
|
|
using Microsoft.Extensions.Options;
|
|
|
|
|
using Ordering.Infrastructure;
|
|
|
|
|
using Polly;
|
2017-06-20 12:54:32 -07:00
|
|
|
|
using System;
|
2017-09-13 14:53:06 +02:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Data.SqlClient;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading.Tasks;
|
2016-11-22 18:40:47 +01:00
|
|
|
|
|
|
|
|
|
public class OrderingContextSeed
|
|
|
|
|
{
|
2017-09-13 14:53:06 +02:00
|
|
|
|
public async Task SeedAsync(OrderingContext context, IHostingEnvironment env,IOptions<OrderingSettings> settings, ILogger<OrderingContextSeed> logger)
|
2016-11-22 18:40:47 +01:00
|
|
|
|
{
|
2017-09-13 14:53:06 +02:00
|
|
|
|
var policy = CreatePolicy(logger, nameof(OrderingContextSeed));
|
2017-06-20 12:54:32 -07:00
|
|
|
|
|
2017-09-13 14:53:06 +02:00
|
|
|
|
await policy.ExecuteAsync(async () =>
|
|
|
|
|
{
|
2017-06-20 12:54:32 -07:00
|
|
|
|
|
2017-09-13 14:53:06 +02:00
|
|
|
|
var useCustomizationData = settings.Value
|
|
|
|
|
.UseCustomizationData;
|
2017-06-20 12:54:32 -07:00
|
|
|
|
|
2017-09-13 14:53:06 +02:00
|
|
|
|
var contentRootPath = env.ContentRootPath;
|
2017-06-20 12:54:32 -07:00
|
|
|
|
|
2016-11-22 18:40:47 +01:00
|
|
|
|
|
2017-09-13 14:53:06 +02:00
|
|
|
|
using (context)
|
2016-11-24 14:58:37 +01:00
|
|
|
|
{
|
2017-09-13 14:53:06 +02:00
|
|
|
|
context.Database.Migrate();
|
2016-11-24 14:58:37 +01:00
|
|
|
|
|
2017-09-13 14:53:06 +02:00
|
|
|
|
if (!context.CardTypes.Any())
|
|
|
|
|
{
|
2018-02-20 23:35:41 +00:00
|
|
|
|
context.CardTypes.AddRange(useCustomizationData
|
2017-09-13 14:53:06 +02:00
|
|
|
|
? GetCardTypesFromFile(contentRootPath, logger)
|
|
|
|
|
: GetPredefinedCardTypes());
|
2016-11-24 14:58:37 +01:00
|
|
|
|
|
2017-09-13 14:53:06 +02:00
|
|
|
|
await context.SaveChangesAsync();
|
|
|
|
|
}
|
2016-11-24 14:58:37 +01:00
|
|
|
|
|
2017-09-13 14:53:06 +02:00
|
|
|
|
if (!context.OrderStatus.Any())
|
|
|
|
|
{
|
2018-02-20 23:35:41 +00:00
|
|
|
|
context.OrderStatus.AddRange(useCustomizationData
|
2017-09-13 14:53:06 +02:00
|
|
|
|
? GetOrderStatusFromFile(contentRootPath, logger)
|
|
|
|
|
: GetPredefinedOrderStatus());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await context.SaveChangesAsync();
|
|
|
|
|
}
|
|
|
|
|
});
|
2016-11-22 18:40:47 +01:00
|
|
|
|
}
|
|
|
|
|
|
2017-09-13 14:53:06 +02:00
|
|
|
|
private IEnumerable<CardType> GetCardTypesFromFile(string contentRootPath, ILogger<OrderingContextSeed> log)
|
2017-06-20 12:54:32 -07:00
|
|
|
|
{
|
|
|
|
|
string csvFileCardTypes = Path.Combine(contentRootPath, "Setup", "CardTypes.csv");
|
|
|
|
|
|
|
|
|
|
if (!File.Exists(csvFileCardTypes))
|
|
|
|
|
{
|
|
|
|
|
return GetPredefinedCardTypes();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string[] csvheaders;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
string[] requiredHeaders = { "CardType" };
|
|
|
|
|
csvheaders = GetHeaders(requiredHeaders, csvFileCardTypes);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
log.LogError(ex.Message);
|
|
|
|
|
return GetPredefinedCardTypes();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int id = 1;
|
|
|
|
|
return File.ReadAllLines(csvFileCardTypes)
|
|
|
|
|
.Skip(1) // skip header column
|
|
|
|
|
.SelectTry(x => CreateCardType(x, ref id))
|
|
|
|
|
.OnCaughtException(ex => { log.LogError(ex.Message); return null; })
|
|
|
|
|
.Where(x => x != null);
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-13 14:53:06 +02:00
|
|
|
|
private CardType CreateCardType(string value, ref int id)
|
2017-06-20 12:54:32 -07:00
|
|
|
|
{
|
|
|
|
|
if (String.IsNullOrEmpty(value))
|
|
|
|
|
{
|
|
|
|
|
throw new Exception("Orderstatus is null or empty");
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-23 11:49:25 -07:00
|
|
|
|
return new CardType(id++, value.Trim('"').Trim());
|
2017-06-20 12:54:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
2017-09-13 14:53:06 +02:00
|
|
|
|
private IEnumerable<CardType> GetPredefinedCardTypes()
|
2017-06-20 12:54:32 -07:00
|
|
|
|
{
|
|
|
|
|
return new List<CardType>()
|
|
|
|
|
{
|
|
|
|
|
CardType.Amex,
|
|
|
|
|
CardType.Visa,
|
|
|
|
|
CardType.MasterCard
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-13 14:53:06 +02:00
|
|
|
|
private IEnumerable<OrderStatus> GetOrderStatusFromFile(string contentRootPath, ILogger<OrderingContextSeed> log)
|
2017-06-20 12:54:32 -07:00
|
|
|
|
{
|
|
|
|
|
string csvFileOrderStatus = Path.Combine(contentRootPath, "Setup", "OrderStatus.csv");
|
|
|
|
|
|
|
|
|
|
if (!File.Exists(csvFileOrderStatus))
|
|
|
|
|
{
|
|
|
|
|
return GetPredefinedOrderStatus();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string[] csvheaders;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
string[] requiredHeaders = { "OrderStatus" };
|
|
|
|
|
csvheaders = GetHeaders(requiredHeaders, csvFileOrderStatus);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
log.LogError(ex.Message);
|
|
|
|
|
return GetPredefinedOrderStatus();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int id = 1;
|
|
|
|
|
return File.ReadAllLines(csvFileOrderStatus)
|
|
|
|
|
.Skip(1) // skip header row
|
|
|
|
|
.SelectTry(x => CreateOrderStatus(x, ref id))
|
|
|
|
|
.OnCaughtException(ex => { log.LogError(ex.Message); return null; })
|
|
|
|
|
.Where(x => x != null);
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-13 14:53:06 +02:00
|
|
|
|
private OrderStatus CreateOrderStatus(string value, ref int id)
|
2017-06-20 12:54:32 -07:00
|
|
|
|
{
|
|
|
|
|
if (String.IsNullOrEmpty(value))
|
|
|
|
|
{
|
|
|
|
|
throw new Exception("Orderstatus is null or empty");
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-23 11:49:25 -07:00
|
|
|
|
return new OrderStatus(id++, value.Trim('"').Trim().ToLowerInvariant());
|
2017-06-20 12:54:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
2017-09-13 14:53:06 +02:00
|
|
|
|
private IEnumerable<OrderStatus> GetPredefinedOrderStatus()
|
2017-06-20 12:54:32 -07:00
|
|
|
|
{
|
|
|
|
|
return new List<OrderStatus>()
|
|
|
|
|
{
|
|
|
|
|
OrderStatus.Submitted,
|
|
|
|
|
OrderStatus.AwaitingValidation,
|
|
|
|
|
OrderStatus.StockConfirmed,
|
|
|
|
|
OrderStatus.Paid,
|
|
|
|
|
OrderStatus.Shipped,
|
|
|
|
|
OrderStatus.Cancelled
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-13 14:53:06 +02:00
|
|
|
|
private string[] GetHeaders(string[] requiredHeaders, string csvfile)
|
2017-06-20 12:54:32 -07:00
|
|
|
|
{
|
|
|
|
|
string[] csvheaders = File.ReadLines(csvfile).First().ToLowerInvariant().Split(',');
|
|
|
|
|
|
|
|
|
|
if (csvheaders.Count() != requiredHeaders.Count())
|
|
|
|
|
{
|
|
|
|
|
throw new Exception($"requiredHeader count '{ requiredHeaders.Count()}' is different then read header '{csvheaders.Count()}'");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var requiredHeader in requiredHeaders)
|
|
|
|
|
{
|
|
|
|
|
if (!csvheaders.Contains(requiredHeader))
|
|
|
|
|
{
|
|
|
|
|
throw new Exception($"does not contain required header '{requiredHeader}'");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return csvheaders;
|
|
|
|
|
}
|
2017-09-13 14:53:06 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Policy CreatePolicy( ILogger<OrderingContextSeed> logger, string prefix, int retries =3)
|
|
|
|
|
{
|
|
|
|
|
return Policy.Handle<SqlException>().
|
|
|
|
|
WaitAndRetryAsync(
|
|
|
|
|
retryCount: retries,
|
|
|
|
|
sleepDurationProvider: retry => TimeSpan.FromSeconds(5),
|
|
|
|
|
onRetry: (exception, timeSpan, retry, ctx) =>
|
|
|
|
|
{
|
|
|
|
|
logger.LogTrace($"[{prefix}] Exception {exception.GetType().Name} with message ${exception.Message} detected on attempt {retry} of {retries}");
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
2016-11-22 18:40:47 +01:00
|
|
|
|
}
|
|
|
|
|
}
|