Merge branch 'dev' of https://github.com/dotnet-architecture/eShopOnContainers into dev
This commit is contained in:
commit
b7c5613238
@ -2,7 +2,7 @@ version: '2'
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
ci-build:
|
ci-build:
|
||||||
image: microsoft/aspnetcore-build:1.0-1.1
|
image: microsoft/aspnetcore-build:1.1.2
|
||||||
volumes:
|
volumes:
|
||||||
- .:/src
|
- .:/src
|
||||||
working_dir: /src
|
working_dir: /src
|
||||||
|
56
docker-compose.nobuild.yml
Normal file
56
docker-compose.nobuild.yml
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
version: '2'
|
||||||
|
|
||||||
|
services:
|
||||||
|
basket.api:
|
||||||
|
image: eshop/basket.api
|
||||||
|
depends_on:
|
||||||
|
- basket.data
|
||||||
|
- identity.api
|
||||||
|
- rabbitmq
|
||||||
|
|
||||||
|
catalog.api:
|
||||||
|
image: eshop/catalog.api
|
||||||
|
depends_on:
|
||||||
|
- sql.data
|
||||||
|
- rabbitmq
|
||||||
|
|
||||||
|
identity.api:
|
||||||
|
image: eshop/identity.api
|
||||||
|
depends_on:
|
||||||
|
- sql.data
|
||||||
|
|
||||||
|
ordering.api:
|
||||||
|
image: eshop/ordering.api
|
||||||
|
depends_on:
|
||||||
|
- sql.data
|
||||||
|
|
||||||
|
webspa:
|
||||||
|
image: eshop/webspa
|
||||||
|
depends_on:
|
||||||
|
- identity.api
|
||||||
|
- basket.api
|
||||||
|
|
||||||
|
webmvc:
|
||||||
|
image: eshop/webmvc
|
||||||
|
depends_on:
|
||||||
|
- catalog.api
|
||||||
|
- ordering.api
|
||||||
|
- identity.api
|
||||||
|
- basket.api
|
||||||
|
|
||||||
|
sql.data:
|
||||||
|
image: microsoft/mssql-server-linux
|
||||||
|
|
||||||
|
basket.data:
|
||||||
|
image: redis
|
||||||
|
ports:
|
||||||
|
- "6379:6379"
|
||||||
|
|
||||||
|
rabbitmq:
|
||||||
|
image: rabbitmq
|
||||||
|
ports:
|
||||||
|
- "5672:5672"
|
||||||
|
|
||||||
|
webstatus:
|
||||||
|
image: eshop/webstatus
|
||||||
|
|
@ -5,7 +5,7 @@ services:
|
|||||||
image: eshop/basket.api
|
image: eshop/basket.api
|
||||||
build:
|
build:
|
||||||
context: ./src/Services/Basket/Basket.API
|
context: ./src/Services/Basket/Basket.API
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
depends_on:
|
depends_on:
|
||||||
- basket.data
|
- basket.data
|
||||||
- identity.api
|
- identity.api
|
||||||
@ -15,7 +15,7 @@ services:
|
|||||||
image: eshop/catalog.api
|
image: eshop/catalog.api
|
||||||
build:
|
build:
|
||||||
context: ./src/Services/Catalog/Catalog.API
|
context: ./src/Services/Catalog/Catalog.API
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
depends_on:
|
depends_on:
|
||||||
- sql.data
|
- sql.data
|
||||||
- rabbitmq
|
- rabbitmq
|
||||||
@ -24,7 +24,7 @@ services:
|
|||||||
image: eshop/identity.api
|
image: eshop/identity.api
|
||||||
build:
|
build:
|
||||||
context: ./src/Services/Identity/Identity.API
|
context: ./src/Services/Identity/Identity.API
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
depends_on:
|
depends_on:
|
||||||
- sql.data
|
- sql.data
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ services:
|
|||||||
image: eshop/ordering.api
|
image: eshop/ordering.api
|
||||||
build:
|
build:
|
||||||
context: ./src/Services/Ordering/Ordering.API
|
context: ./src/Services/Ordering/Ordering.API
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
depends_on:
|
depends_on:
|
||||||
- sql.data
|
- sql.data
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ services:
|
|||||||
image: eshop/webspa
|
image: eshop/webspa
|
||||||
build:
|
build:
|
||||||
context: ./src/Web/WebSPA
|
context: ./src/Web/WebSPA
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
depends_on:
|
depends_on:
|
||||||
- identity.api
|
- identity.api
|
||||||
- basket.api
|
- basket.api
|
||||||
@ -49,7 +49,7 @@ services:
|
|||||||
image: eshop/webmvc
|
image: eshop/webmvc
|
||||||
build:
|
build:
|
||||||
context: ./src/Web/WebMVC
|
context: ./src/Web/WebMVC
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
depends_on:
|
depends_on:
|
||||||
- catalog.api
|
- catalog.api
|
||||||
- ordering.api
|
- ordering.api
|
||||||
@ -73,4 +73,5 @@ services:
|
|||||||
image: eshop/webstatus
|
image: eshop/webstatus
|
||||||
build:
|
build:
|
||||||
context: ./src/Web/WebStatus
|
context: ./src/Web/WebStatus
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.26403.3
|
VisualStudioVersion = 15.0.26430.12
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F6-4D07-B109-DA28AD288A63}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F6-4D07-B109-DA28AD288A63}"
|
||||||
EndProject
|
EndProject
|
||||||
|
@ -96,7 +96,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
|||||||
// as it is disposed after each call
|
// as it is disposed after each call
|
||||||
var origin = GetOriginFromUri(uri);
|
var origin = GetOriginFromUri(uri);
|
||||||
|
|
||||||
return HttpInvoker(origin, () =>
|
return HttpInvoker(origin, async () =>
|
||||||
{
|
{
|
||||||
var requestMessage = new HttpRequestMessage(method, uri);
|
var requestMessage = new HttpRequestMessage(method, uri);
|
||||||
|
|
||||||
@ -112,7 +112,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
|||||||
requestMessage.Headers.Add("x-requestid", requestId);
|
requestMessage.Headers.Add("x-requestid", requestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
var response = _client.SendAsync(requestMessage).Result;
|
var response = await _client.SendAsync(requestMessage);
|
||||||
|
|
||||||
// raise exception if HttpResponseCode 500
|
// raise exception if HttpResponseCode 500
|
||||||
// needed for circuit breaker to track fails
|
// needed for circuit breaker to track fails
|
||||||
@ -122,7 +122,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
|||||||
throw new HttpRequestException();
|
throw new HttpRequestException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(response);
|
return response;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,13 +132,13 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
|||||||
|
|
||||||
if (!_policyWrappers.TryGetValue(normalizedOrigin, out PolicyWrap policyWrap))
|
if (!_policyWrappers.TryGetValue(normalizedOrigin, out PolicyWrap policyWrap))
|
||||||
{
|
{
|
||||||
policyWrap = Policy.Wrap(_policyCreator(normalizedOrigin).ToArray());
|
policyWrap = Policy.WrapAsync(_policyCreator(normalizedOrigin).ToArray());
|
||||||
_policyWrappers.TryAdd(normalizedOrigin, policyWrap);
|
_policyWrappers.TryAdd(normalizedOrigin, policyWrap);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Executes the action applying all
|
// Executes the action applying all
|
||||||
// the policies defined in the wrapper
|
// the policies defined in the wrapper
|
||||||
return await policyWrap.Execute(action, new Context(normalizedOrigin));
|
return await policyWrap.ExecuteAsync(action, new Context(normalizedOrigin));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,8 +14,9 @@ namespace eShopOnContainers.Core.Services.Identity
|
|||||||
// Dictionary with values for the authorize request
|
// Dictionary with values for the authorize request
|
||||||
var dic = new Dictionary<string, string>();
|
var dic = new Dictionary<string, string>();
|
||||||
dic.Add("client_id", "xamarin");
|
dic.Add("client_id", "xamarin");
|
||||||
dic.Add("response_type", "id_token token");
|
dic.Add("client_secret", "secret");
|
||||||
dic.Add("scope", "openid profile basket orders");
|
dic.Add("response_type", "code id_token token");
|
||||||
|
dic.Add("scope", "openid profile basket orders offline_access");
|
||||||
|
|
||||||
dic.Add("redirect_uri", GlobalSetting.Instance.IdentityCallback);
|
dic.Add("redirect_uri", GlobalSetting.Instance.IdentityCallback);
|
||||||
dic.Add("nonce", Guid.NewGuid().ToString("N"));
|
dic.Add("nonce", Guid.NewGuid().ToString("N"));
|
||||||
@ -24,7 +25,7 @@ namespace eShopOnContainers.Core.Services.Identity
|
|||||||
var currentCSRFToken = Guid.NewGuid().ToString("N");
|
var currentCSRFToken = Guid.NewGuid().ToString("N");
|
||||||
dic.Add("state", currentCSRFToken);
|
dic.Add("state", currentCSRFToken);
|
||||||
|
|
||||||
var authorizeUri = authorizeRequest.Create(dic);
|
var authorizeUri = authorizeRequest.Create(dic);
|
||||||
return authorizeUri;
|
return authorizeUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
<TargetFramework>netcoreapp1.1</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>1.1.2</RuntimeFrameworkVersion>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<PackageTargetFallback>$(PackageTargetFallback);netstandard1.6.1;dnxcore50;portable-net451+win8</PackageTargetFallback>
|
<PackageTargetFallback>$(PackageTargetFallback);netstandard1.6.1;dnxcore50;portable-net451+win8</PackageTargetFallback>
|
||||||
<DockerComposeProjectPath>..\..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
|
<DockerComposeProjectPath>..\..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM microsoft/aspnetcore:1.1
|
FROM microsoft/aspnetcore:1.1.2
|
||||||
ARG source
|
ARG source
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
<TargetFramework>netcoreapp1.1</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>1.1.2</RuntimeFrameworkVersion>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<UserSecretsId>aspnet-Catalog.API-20161122013618</UserSecretsId>
|
<UserSecretsId>aspnet-Catalog.API-20161122013618</UserSecretsId>
|
||||||
<PackageTargetFallback>$(PackageTargetFallback);dotnet5.6;portable-net45+win8</PackageTargetFallback>
|
<PackageTargetFallback>$(PackageTargetFallback);dotnet5.6;portable-net45+win8</PackageTargetFallback>
|
||||||
@ -44,6 +45,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.2" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.2" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="1.0.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="1.0.0" />
|
||||||
|
<PackageReference Include="Polly" Version="5.1.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM microsoft/aspnetcore:1.1
|
FROM microsoft/aspnetcore:1.1.2
|
||||||
ARG source
|
ARG source
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
@ -17,11 +17,13 @@
|
|||||||
using Microsoft.Extensions.HealthChecks;
|
using Microsoft.Extensions.HealthChecks;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
using Polly;
|
||||||
using RabbitMQ.Client;
|
using RabbitMQ.Client;
|
||||||
using System;
|
using System;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
using System.Data.SqlClient;
|
using System.Data.SqlClient;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
public class Startup
|
public class Startup
|
||||||
{
|
{
|
||||||
@ -85,7 +87,7 @@
|
|||||||
services.AddSwaggerGen(options =>
|
services.AddSwaggerGen(options =>
|
||||||
{
|
{
|
||||||
options.DescribeAllEnumsAsStrings();
|
options.DescribeAllEnumsAsStrings();
|
||||||
options.SwaggerDoc("v1",new Swashbuckle.AspNetCore.Swagger.Info
|
options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info
|
||||||
{
|
{
|
||||||
Title = "eShopOnContainers - Catalog HTTP API",
|
Title = "eShopOnContainers - Catalog HTTP API",
|
||||||
Version = "v1",
|
Version = "v1",
|
||||||
@ -144,11 +146,7 @@
|
|||||||
var context = (CatalogContext)app
|
var context = (CatalogContext)app
|
||||||
.ApplicationServices.GetService(typeof(CatalogContext));
|
.ApplicationServices.GetService(typeof(CatalogContext));
|
||||||
|
|
||||||
WaitForSqlAvailability(context, loggerFactory);
|
WaitForSqlAvailabilityAsync(context, loggerFactory, app).Wait();
|
||||||
|
|
||||||
//Seed Data
|
|
||||||
CatalogContextSeed.SeedAsync(app, loggerFactory)
|
|
||||||
.Wait();
|
|
||||||
|
|
||||||
var integrationEventLogContext = new IntegrationEventLogContext(
|
var integrationEventLogContext = new IntegrationEventLogContext(
|
||||||
new DbContextOptionsBuilder<IntegrationEventLogContext>()
|
new DbContextOptionsBuilder<IntegrationEventLogContext>()
|
||||||
@ -158,28 +156,28 @@
|
|||||||
integrationEventLogContext.Database.Migrate();
|
integrationEventLogContext.Database.Migrate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WaitForSqlAvailability(CatalogContext ctx, ILoggerFactory loggerFactory, int? retry = 0)
|
private async Task WaitForSqlAvailabilityAsync(CatalogContext ctx, ILoggerFactory loggerFactory, IApplicationBuilder app, int retries = 0)
|
||||||
{
|
{
|
||||||
int retryForAvailability = retry.Value;
|
var logger = loggerFactory.CreateLogger(nameof(Startup));
|
||||||
|
var policy = CreatePolicy(retries, logger, nameof (WaitForSqlAvailabilityAsync));
|
||||||
|
await policy.ExecuteAsync(async () =>
|
||||||
|
{
|
||||||
|
await CatalogContextSeed.SeedAsync(app, loggerFactory);
|
||||||
|
});
|
||||||
|
|
||||||
try
|
}
|
||||||
{
|
|
||||||
ctx.Database.OpenConnection();
|
private Policy CreatePolicy(int retries, ILogger logger, string prefix)
|
||||||
}
|
{
|
||||||
catch (SqlException ex)
|
return Policy.Handle<SqlException>().
|
||||||
{
|
WaitAndRetryAsync(
|
||||||
if (retryForAvailability < 10)
|
retryCount: retries,
|
||||||
{
|
sleepDurationProvider: retry => TimeSpan.FromSeconds(5),
|
||||||
retryForAvailability++;
|
onRetry: (exception, timeSpan, retry, ctx) =>
|
||||||
var log = loggerFactory.CreateLogger(nameof(Startup));
|
{
|
||||||
log.LogError(ex.Message);
|
logger.LogTrace($"[{prefix}] Exception {exception.GetType().Name} with message ${exception.Message} detected on attempt {retry} of {retries}");
|
||||||
WaitForSqlAvailability(ctx, loggerFactory, retryForAvailability);
|
}
|
||||||
}
|
);
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
ctx.Database.CloseConnection();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using IdentityServer4.Models;
|
using IdentityServer4;
|
||||||
using Microsoft.Extensions.Options;
|
using IdentityServer4.Models;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using IdentityServer4;
|
|
||||||
|
|
||||||
namespace Identity.API.Configuration
|
namespace Identity.API.Configuration
|
||||||
{
|
{
|
||||||
@ -56,19 +55,26 @@ namespace Identity.API.Configuration
|
|||||||
{
|
{
|
||||||
ClientId = "xamarin",
|
ClientId = "xamarin",
|
||||||
ClientName = "eShop Xamarin OpenId Client",
|
ClientName = "eShop Xamarin OpenId Client",
|
||||||
AllowedGrantTypes = GrantTypes.Implicit,
|
AllowedGrantTypes = GrantTypes.Hybrid,
|
||||||
AllowAccessTokensViaBrowser = true,
|
//Used to retrieve the access token on the back channel.
|
||||||
RedirectUris = { clientsUrl["Xamarin"] },
|
ClientSecrets =
|
||||||
|
{
|
||||||
|
new Secret("secret".Sha256())
|
||||||
|
},
|
||||||
|
RedirectUris = { clientsUrl["Xamarin"] },
|
||||||
RequireConsent = false,
|
RequireConsent = false,
|
||||||
PostLogoutRedirectUris = { $"{clientsUrl["Xamarin"]}/Account/Redirecting" },
|
PostLogoutRedirectUris = { $"{clientsUrl["Xamarin"]}/Account/Redirecting" },
|
||||||
AllowedCorsOrigins = { "http://eshopxamarin" },
|
AllowedCorsOrigins = { "http://eshopxamarin" },
|
||||||
AllowedScopes =
|
AllowedScopes = new List<string>
|
||||||
{
|
{
|
||||||
IdentityServerConstants.StandardScopes.OpenId,
|
IdentityServerConstants.StandardScopes.OpenId,
|
||||||
IdentityServerConstants.StandardScopes.Profile,
|
IdentityServerConstants.StandardScopes.Profile,
|
||||||
|
IdentityServerConstants.StandardScopes.OfflineAccess,
|
||||||
"orders",
|
"orders",
|
||||||
"basket"
|
"basket"
|
||||||
}
|
},
|
||||||
|
//Allow requesting refresh tokens for long lived API access
|
||||||
|
AllowOfflineAccess = true
|
||||||
},
|
},
|
||||||
new Client
|
new Client
|
||||||
{
|
{
|
||||||
@ -97,7 +103,7 @@ namespace Identity.API.Configuration
|
|||||||
IdentityServerConstants.StandardScopes.Profile,
|
IdentityServerConstants.StandardScopes.Profile,
|
||||||
IdentityServerConstants.StandardScopes.OfflineAccess,
|
IdentityServerConstants.StandardScopes.OfflineAccess,
|
||||||
"orders",
|
"orders",
|
||||||
"basket",
|
"basket"
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM microsoft/aspnetcore:1.1
|
FROM microsoft/aspnetcore:1.1.2
|
||||||
ARG source
|
ARG source
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
<TargetFramework>netcoreapp1.1</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>1.1.2</RuntimeFrameworkVersion>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<UserSecretsId>aspnet-eShopOnContainers.Identity-90487118-103c-4ff0-b9da-e5e26f7ab0c5</UserSecretsId>
|
<UserSecretsId>aspnet-eShopOnContainers.Identity-90487118-103c-4ff0-b9da-e5e26f7ab0c5</UserSecretsId>
|
||||||
<PackageTargetFallback>$(PackageTargetFallback);dotnet5.6;portable-net45+win8</PackageTargetFallback>
|
<PackageTargetFallback>$(PackageTargetFallback);dotnet5.6;portable-net45+win8</PackageTargetFallback>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM microsoft/aspnetcore:1.1
|
FROM microsoft/aspnetcore:1.1.2
|
||||||
ARG source
|
ARG source
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
<TargetFramework>netcoreapp1.1</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>1.1.2</RuntimeFrameworkVersion>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<UserSecretsId>aspnet-Ordering.API-20161122013547</UserSecretsId>
|
<UserSecretsId>aspnet-Ordering.API-20161122013547</UserSecretsId>
|
||||||
<PackageTargetFallback>$(PackageTargetFallback);netstandard1.6.1;dnxcore50;portable-net451+win8</PackageTargetFallback>
|
<PackageTargetFallback>$(PackageTargetFallback);netstandard1.6.1;dnxcore50;portable-net451+win8</PackageTargetFallback>
|
||||||
@ -57,6 +58,7 @@
|
|||||||
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="1.2.0" />
|
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="1.2.0" />
|
||||||
<PackageReference Include="Dapper" Version="1.50.2" />
|
<PackageReference Include="Dapper" Version="1.50.2" />
|
||||||
<PackageReference Include="System.ValueTuple" Version="4.3.1" />
|
<PackageReference Include="System.ValueTuple" Version="4.3.1" />
|
||||||
|
<PackageReference Include="Polly" Version="5.1.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -23,10 +23,13 @@
|
|||||||
using Microsoft.Extensions.HealthChecks;
|
using Microsoft.Extensions.HealthChecks;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Ordering.Infrastructure;
|
using Ordering.Infrastructure;
|
||||||
|
using Polly;
|
||||||
using RabbitMQ.Client;
|
using RabbitMQ.Client;
|
||||||
using System;
|
using System;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
|
using System.Data.SqlClient;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
public class Startup
|
public class Startup
|
||||||
{
|
{
|
||||||
@ -156,7 +159,7 @@
|
|||||||
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
|
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
|
||||||
});
|
});
|
||||||
|
|
||||||
OrderingContextSeed.SeedAsync(app).Wait();
|
WaitForSqlAvailabilityAsync(loggerFactory, app).Wait();
|
||||||
|
|
||||||
var integrationEventLogContext = new IntegrationEventLogContext(
|
var integrationEventLogContext = new IntegrationEventLogContext(
|
||||||
new DbContextOptionsBuilder<IntegrationEventLogContext>()
|
new DbContextOptionsBuilder<IntegrationEventLogContext>()
|
||||||
@ -175,5 +178,30 @@
|
|||||||
RequireHttpsMetadata = false
|
RequireHttpsMetadata = false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async Task WaitForSqlAvailabilityAsync(ILoggerFactory loggerFactory, IApplicationBuilder app, int retries = 0)
|
||||||
|
{
|
||||||
|
var logger = loggerFactory.CreateLogger(nameof(Startup));
|
||||||
|
var policy = CreatePolicy(retries, logger, nameof(WaitForSqlAvailabilityAsync));
|
||||||
|
await policy.ExecuteAsync(async () =>
|
||||||
|
{
|
||||||
|
await OrderingContextSeed.SeedAsync(app);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Policy CreatePolicy(int retries, ILogger logger, string prefix)
|
||||||
|
{
|
||||||
|
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}");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM microsoft/aspnetcore:1.1
|
FROM microsoft/aspnetcore:1.1.2
|
||||||
ARG source
|
ARG source
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
@ -20,7 +20,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Infrastructure
|
|||||||
=> new Policy[]
|
=> new Policy[]
|
||||||
{
|
{
|
||||||
Policy.Handle<HttpRequestException>()
|
Policy.Handle<HttpRequestException>()
|
||||||
.WaitAndRetry(
|
.WaitAndRetryAsync(
|
||||||
// number of retries
|
// number of retries
|
||||||
6,
|
6,
|
||||||
// exponential backofff
|
// exponential backofff
|
||||||
@ -36,7 +36,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Infrastructure
|
|||||||
_logger.LogDebug(msg);
|
_logger.LogDebug(msg);
|
||||||
}),
|
}),
|
||||||
Policy.Handle<HttpRequestException>()
|
Policy.Handle<HttpRequestException>()
|
||||||
.CircuitBreaker(
|
.CircuitBreakerAsync(
|
||||||
// number of exceptions before breaking circuit
|
// number of exceptions before breaking circuit
|
||||||
5,
|
5,
|
||||||
// time circuit opened before retry
|
// time circuit opened before retry
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
<TargetFramework>netcoreapp1.1</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>1.1.2</RuntimeFrameworkVersion>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<UserSecretsId>aspnet-Microsoft.eShopOnContainers-946ae052-8305-4a99-965b-ec8636ddbae3</UserSecretsId>
|
<UserSecretsId>aspnet-Microsoft.eShopOnContainers-946ae052-8305-4a99-965b-ec8636ddbae3</UserSecretsId>
|
||||||
<PackageTargetFallback>$(PackageTargetFallback);dotnet5.6;portable-net45+win8</PackageTargetFallback>
|
<PackageTargetFallback>$(PackageTargetFallback);dotnet5.6;portable-net45+win8</PackageTargetFallback>
|
||||||
|
2
src/Web/WebMVC/wwwroot/css/site.min.css
vendored
2
src/Web/WebMVC/wwwroot/css/site.min.css
vendored
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
|||||||
FROM microsoft/aspnetcore:1.1
|
FROM microsoft/aspnetcore:1.1.2
|
||||||
ARG source
|
ARG source
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
<TargetFramework>netcoreapp1.1</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>1.1.2</RuntimeFrameworkVersion>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<PackageId>eShopOnContainers.WebSPA</PackageId>
|
<PackageId>eShopOnContainers.WebSPA</PackageId>
|
||||||
<UserSecretsId>aspnetcorespa-c23d27a4-eb88-4b18-9b77-2a93f3b15119</UserSecretsId>
|
<UserSecretsId>aspnetcorespa-c23d27a4-eb88-4b18-9b77-2a93f3b15119</UserSecretsId>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM microsoft/aspnetcore:1.1
|
FROM microsoft/aspnetcore:1.1.2
|
||||||
ARG source
|
ARG source
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
<TargetFramework>netcoreapp1.1.2</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>1.1.2</RuntimeFrameworkVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user