Updated codes from net21rc1 branch
This commit is contained in:
parent
571b4e1a4c
commit
49200d77b2
@ -1,8 +1,8 @@
|
|||||||
FROM microsoft/aspnetcore:2.0 AS base
|
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
FROM microsoft/aspnetcore-build:2.0 AS build
|
FROM microsoft/dotnet:2.1-sdk AS build
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY src/ApiGateways/ApiGw-Base/OcelotApiGw.csproj src/ApiGateways/ApiGw-Base/
|
COPY src/ApiGateways/ApiGw-Base/OcelotApiGw.csproj src/ApiGateways/ApiGw-Base/
|
||||||
RUN dotnet restore src/ApiGateways/ApiGw-Base/
|
RUN dotnet restore src/ApiGateways/ApiGw-Base/
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
FROM microsoft/aspnetcore:2.0.5 AS base
|
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
FROM microsoft/aspnetcore-build:2.0 AS build
|
FROM microsoft/dotnet:2.1-sdk AS build
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN dotnet restore -nowarn:msb3202,nu1503
|
|
||||||
WORKDIR /src/src/ApiGateways/Mobile.Bff.Shopping/aggregator
|
WORKDIR /src/src/ApiGateways/Mobile.Bff.Shopping/aggregator
|
||||||
|
RUN dotnet restore -nowarn:msb3202,nu1503
|
||||||
RUN dotnet build --no-restore -c Release -o /app
|
RUN dotnet build --no-restore -c Release -o /app
|
||||||
|
|
||||||
FROM build AS publish
|
FROM build AS publish
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure
|
||||||
|
{
|
||||||
|
public class HttpClientAuthorizationDelegatingHandler
|
||||||
|
: DelegatingHandler
|
||||||
|
{
|
||||||
|
private readonly IHttpContextAccessor _httpContextAccesor;
|
||||||
|
|
||||||
|
public HttpClientAuthorizationDelegatingHandler(IHttpContextAccessor httpContextAccesor)
|
||||||
|
{
|
||||||
|
_httpContextAccesor = httpContextAccesor;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var authorizationHeader = _httpContextAccesor.HttpContext
|
||||||
|
.Request.Headers["Authorization"];
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(authorizationHeader))
|
||||||
|
{
|
||||||
|
request.Headers.Add("Authorization", new List<string>() { authorizationHeader });
|
||||||
|
}
|
||||||
|
|
||||||
|
var token = await GetToken();
|
||||||
|
|
||||||
|
if (token != null)
|
||||||
|
{
|
||||||
|
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await base.SendAsync(request, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task<string> GetToken()
|
||||||
|
{
|
||||||
|
const string ACCESS_TOKEN = "access_token";
|
||||||
|
|
||||||
|
return await _httpContextAccesor.HttpContext
|
||||||
|
.GetTokenAsync(ACCESS_TOKEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,53 +1,41 @@
|
|||||||
using System;
|
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
|
||||||
using System.Collections.Generic;
|
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Authentication;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
|
using System.Net.Http;
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
||||||
{
|
{
|
||||||
public class BasketService : IBasketService
|
public class BasketService : IBasketService
|
||||||
{
|
{
|
||||||
|
|
||||||
private readonly IHttpClient _apiClient;
|
private readonly HttpClient _httpClient;
|
||||||
private readonly ILogger<BasketService> _logger;
|
private readonly ILogger<BasketService> _logger;
|
||||||
private readonly UrlsConfig _urls;
|
private readonly UrlsConfig _urls;
|
||||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
|
||||||
|
|
||||||
public BasketService(IHttpClient httpClient, IHttpContextAccessor httpContextAccessor, ILogger<BasketService> logger, IOptionsSnapshot<UrlsConfig> config)
|
public BasketService(HttpClient httpClient, ILogger<BasketService> logger, IOptions<UrlsConfig> config)
|
||||||
{
|
{
|
||||||
_apiClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_urls = config.Value;
|
_urls = config.Value;
|
||||||
_httpContextAccessor = httpContextAccessor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<BasketData> GetById(string id)
|
public async Task<BasketData> GetById(string id)
|
||||||
{
|
{
|
||||||
var token = await GetUserTokenAsync();
|
var data = await _httpClient.GetStringAsync(_urls.Basket + UrlsConfig.BasketOperations.GetItemById(id));
|
||||||
var data = await _apiClient.GetStringAsync(_urls.Basket + UrlsConfig.BasketOperations.GetItemById(id), token);
|
|
||||||
var basket = !string.IsNullOrEmpty(data) ? JsonConvert.DeserializeObject<BasketData>(data) : null;
|
var basket = !string.IsNullOrEmpty(data) ? JsonConvert.DeserializeObject<BasketData>(data) : null;
|
||||||
|
|
||||||
return basket;
|
return basket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Update(BasketData currentBasket)
|
public async Task Update(BasketData currentBasket)
|
||||||
{
|
{
|
||||||
var token = await GetUserTokenAsync();
|
var basketContent = new StringContent(JsonConvert.SerializeObject(currentBasket), System.Text.Encoding.UTF8, "application/json");
|
||||||
var data = await _apiClient.PostAsync<BasketData>(_urls.Basket + UrlsConfig.BasketOperations.UpdateBasket(), currentBasket, token);
|
|
||||||
int i = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
async Task<string> GetUserTokenAsync()
|
var data = await _httpClient.PostAsync(_urls.Basket + UrlsConfig.BasketOperations.UpdateBasket(), basketContent);
|
||||||
{
|
|
||||||
var context = _httpContextAccessor.HttpContext;
|
|
||||||
return await context.GetTokenAsync("access_token");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,43 +1,41 @@
|
|||||||
using System;
|
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
|
||||||
using System.Collections.Generic;
|
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
|
using System.Collections.Generic;
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
||||||
{
|
{
|
||||||
public class CatalogService : ICatalogService
|
public class CatalogService : ICatalogService
|
||||||
{
|
{
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
private readonly IHttpClient _apiClient;
|
|
||||||
private readonly ILogger<CatalogService> _logger;
|
private readonly ILogger<CatalogService> _logger;
|
||||||
private readonly UrlsConfig _urls;
|
private readonly UrlsConfig _urls;
|
||||||
|
|
||||||
public CatalogService(IHttpClient httpClient, ILogger<CatalogService> logger, IOptionsSnapshot<UrlsConfig> config)
|
public CatalogService(HttpClient httpClient, ILogger<CatalogService> logger, IOptions<UrlsConfig> config)
|
||||||
{
|
{
|
||||||
_apiClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_urls = config.Value;
|
_urls = config.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<CatalogItem> GetCatalogItem(int id)
|
public async Task<CatalogItem> GetCatalogItem(int id)
|
||||||
{
|
{
|
||||||
var data = await _apiClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemById(id));
|
var stringContent = await _httpClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemById(id));
|
||||||
var item = JsonConvert.DeserializeObject<CatalogItem>(data);
|
var catalogItem = JsonConvert.DeserializeObject<CatalogItem>(stringContent);
|
||||||
return item;
|
|
||||||
|
return catalogItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<CatalogItem>> GetCatalogItems(IEnumerable<int> ids)
|
public async Task<IEnumerable<CatalogItem>> GetCatalogItems(IEnumerable<int> ids)
|
||||||
{
|
{
|
||||||
var data = await _apiClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemsById(ids));
|
var stringContent = await _httpClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemsById(ids));
|
||||||
var item = JsonConvert.DeserializeObject<CatalogItem[]>(data);
|
var catalogItems = JsonConvert.DeserializeObject<CatalogItem[]>(stringContent);
|
||||||
return item;
|
|
||||||
|
|
||||||
|
return catalogItems;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,20 @@
|
|||||||
using System;
|
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
|
||||||
using System.Collections.Generic;
|
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
|
using System.Net.Http;
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
||||||
{
|
{
|
||||||
public class OrderApiClient : IOrderApiClient
|
public class OrderApiClient : IOrderApiClient
|
||||||
{
|
{
|
||||||
|
private readonly HttpClient _apiClient;
|
||||||
private readonly IHttpClient _apiClient;
|
|
||||||
private readonly ILogger<OrderApiClient> _logger;
|
private readonly ILogger<OrderApiClient> _logger;
|
||||||
private readonly UrlsConfig _urls;
|
private readonly UrlsConfig _urls;
|
||||||
|
|
||||||
public OrderApiClient(IHttpClient httpClient, ILogger<OrderApiClient> logger, IOptionsSnapshot<UrlsConfig> config)
|
public OrderApiClient(HttpClient httpClient, ILogger<OrderApiClient> logger, IOptions<UrlsConfig> config)
|
||||||
{
|
{
|
||||||
_apiClient = httpClient;
|
_apiClient = httpClient;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
@ -27,11 +23,15 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
|||||||
|
|
||||||
public async Task<OrderData> GetOrderDraftFromBasket(BasketData basket)
|
public async Task<OrderData> GetOrderDraftFromBasket(BasketData basket)
|
||||||
{
|
{
|
||||||
var url = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft();
|
var uri = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft();
|
||||||
var response = await _apiClient.PostAsync<BasketData>(url, basket);
|
var content = new StringContent(JsonConvert.SerializeObject(basket), System.Text.Encoding.UTF8, "application/json");
|
||||||
|
var response = await _apiClient.PostAsync(uri, content);
|
||||||
|
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
var jsonResponse = await response.Content.ReadAsStringAsync();
|
|
||||||
return JsonConvert.DeserializeObject<OrderData>(jsonResponse);
|
var ordersDraftResponse = await response.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
|
return JsonConvert.DeserializeObject<OrderData>(ordersDraftResponse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,18 +96,6 @@
|
|||||||
"UpstreamPathTemplate": "/catalog-api/{everything}",
|
"UpstreamPathTemplate": "/catalog-api/{everything}",
|
||||||
"UpstreamHttpMethod": []
|
"UpstreamHttpMethod": []
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"DownstreamPathTemplate": "/{everything}",
|
|
||||||
"DownstreamScheme": "http",
|
|
||||||
"DownstreamHostAndPorts": [
|
|
||||||
{
|
|
||||||
"Host": "marketing.api",
|
|
||||||
"Port": 80
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"UpstreamPathTemplate": "/marketing-api/{everything}",
|
|
||||||
"UpstreamHttpMethod": []
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"DownstreamPathTemplate": "/{everything}",
|
"DownstreamPathTemplate": "/{everything}",
|
||||||
"DownstreamScheme": "http",
|
"DownstreamScheme": "http",
|
||||||
@ -119,18 +107,6 @@
|
|||||||
],
|
],
|
||||||
"UpstreamPathTemplate": "/payment-api/{everything}",
|
"UpstreamPathTemplate": "/payment-api/{everything}",
|
||||||
"UpstreamHttpMethod": []
|
"UpstreamHttpMethod": []
|
||||||
},
|
|
||||||
{
|
|
||||||
"DownstreamPathTemplate": "/{everything}",
|
|
||||||
"DownstreamScheme": "http",
|
|
||||||
"DownstreamHostAndPorts": [
|
|
||||||
{
|
|
||||||
"Host": "locations.api",
|
|
||||||
"Port": 80
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"UpstreamPathTemplate": "/location-api/{everything}",
|
|
||||||
"UpstreamHttpMethod": []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
],
|
],
|
||||||
|
@ -36,7 +36,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
|
|||||||
var basket = await _repository.GetBasketAsync(id);
|
var basket = await _repository.GetBasketAsync(id);
|
||||||
if (basket == null)
|
if (basket == null)
|
||||||
{
|
{
|
||||||
return NotFound();
|
return Ok(new CustomerBasket(id) { });
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(basket);
|
return Ok(basket);
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
FROM microsoft/aspnetcore:2.0.5 AS base
|
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
FROM microsoft/aspnetcore-build:2.0.5-2.1.4 AS build
|
FROM microsoft/dotnet:2.1-sdk AS build
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN dotnet restore -nowarn:msb3202,nu1503
|
|
||||||
WORKDIR /src/src/Services/Basket/Basket.API
|
WORKDIR /src/src/Services/Basket/Basket.API
|
||||||
|
RUN dotnet restore -nowarn:msb3202,nu1503
|
||||||
RUN dotnet build --no-restore -c Release -o /app
|
RUN dotnet build --no-restore -c Release -o /app
|
||||||
|
|
||||||
FROM build AS publish
|
FROM build AS publish
|
||||||
|
@ -15,6 +15,7 @@ using System.Threading.Tasks;
|
|||||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
|
namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
|
||||||
{
|
{
|
||||||
[Route("api/v1/[controller]")]
|
[Route("api/v1/[controller]")]
|
||||||
|
[ApiController]
|
||||||
public class CatalogController : ControllerBase
|
public class CatalogController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly CatalogContext _catalogContext;
|
private readonly CatalogContext _catalogContext;
|
||||||
@ -25,8 +26,8 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
|
|||||||
{
|
{
|
||||||
_catalogContext = context ?? throw new ArgumentNullException(nameof(context));
|
_catalogContext = context ?? throw new ArgumentNullException(nameof(context));
|
||||||
_catalogIntegrationEventService = catalogIntegrationEventService ?? throw new ArgumentNullException(nameof(catalogIntegrationEventService));
|
_catalogIntegrationEventService = catalogIntegrationEventService ?? throw new ArgumentNullException(nameof(catalogIntegrationEventService));
|
||||||
|
|
||||||
_settings = settings.Value;
|
_settings = settings.Value;
|
||||||
|
|
||||||
((DbContext)context).ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
|
((DbContext)context).ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
FROM microsoft/aspnetcore:2.0.5 AS base
|
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
FROM microsoft/aspnetcore-build:2.0.5-2.1.4 AS build
|
FROM microsoft/dotnet:2.1-sdk AS build
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN dotnet restore -nowarn:msb3202,nu1503
|
|
||||||
WORKDIR /src/src/Services/Catalog/Catalog.API
|
WORKDIR /src/src/Services/Catalog/Catalog.API
|
||||||
|
RUN dotnet restore -nowarn:msb3202,nu1503
|
||||||
RUN dotnet build --no-restore -c Release -o /app
|
RUN dotnet build --no-restore -c Release -o /app
|
||||||
|
|
||||||
FROM build AS publish
|
FROM build AS publish
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using Catalog.API.Infrastructure.ActionResults;
|
using Catalog.API.Infrastructure.ActionResults;
|
||||||
using Catalog.API.Infrastructure.Exceptions;
|
using Catalog.API.Infrastructure.Exceptions;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
@ -27,12 +28,16 @@ namespace Catalog.API.Infrastructure.Filters
|
|||||||
|
|
||||||
if (context.Exception.GetType() == typeof(CatalogDomainException))
|
if (context.Exception.GetType() == typeof(CatalogDomainException))
|
||||||
{
|
{
|
||||||
var json = new JsonErrorResponse
|
var problemDetails = new ValidationProblemDetails()
|
||||||
{
|
{
|
||||||
Messages = new[] { context.Exception.Message }
|
Instance = context.HttpContext.Request.Path,
|
||||||
|
Status = StatusCodes.Status400BadRequest,
|
||||||
|
Detail = "Please refer to the errors property for additional details."
|
||||||
};
|
};
|
||||||
|
|
||||||
context.Result = new BadRequestObjectResult(json);
|
problemDetails.Errors.Add("DomainValidations", new string[] { context.Exception.Message.ToString() });
|
||||||
|
|
||||||
|
context.Result = new BadRequestObjectResult(problemDetails);
|
||||||
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
|
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -17,7 +17,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
|
|||||||
new ApiResource("locations", "Locations Service"),
|
new ApiResource("locations", "Locations Service"),
|
||||||
new ApiResource("mobileshoppingagg", "Mobile Shopping Aggregator"),
|
new ApiResource("mobileshoppingagg", "Mobile Shopping Aggregator"),
|
||||||
new ApiResource("webshoppingagg", "Web Shopping Aggregator"),
|
new ApiResource("webshoppingagg", "Web Shopping Aggregator"),
|
||||||
new ApiResource("orders.signalrhub", "Ordering Signalr Hub")
|
new ApiResource("orders.signalrhub", "Ordering SignalR Hub")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
|
|||||||
}
|
}
|
||||||
|
|
||||||
// client want to access resources (aka scopes)
|
// client want to access resources (aka scopes)
|
||||||
public static IEnumerable<Client> GetClients(Dictionary<string,string> clientsUrl)
|
public static IEnumerable<Client> GetClients(Dictionary<string, string> clientsUrl)
|
||||||
{
|
{
|
||||||
return new List<Client>
|
return new List<Client>
|
||||||
{
|
{
|
||||||
@ -112,6 +112,10 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
|
|||||||
{
|
{
|
||||||
$"{clientsUrl["Mvc"]}/signout-callback-oidc"
|
$"{clientsUrl["Mvc"]}/signout-callback-oidc"
|
||||||
},
|
},
|
||||||
|
AllowedCorsOrigins = new List<string>
|
||||||
|
{
|
||||||
|
$"{clientsUrl["Mvc"]}"
|
||||||
|
},
|
||||||
AllowedScopes = new List<string>
|
AllowedScopes = new List<string>
|
||||||
{
|
{
|
||||||
IdentityServerConstants.StandardScopes.OpenId,
|
IdentityServerConstants.StandardScopes.OpenId,
|
||||||
@ -165,7 +169,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
|
|||||||
AllowedGrantTypes = GrantTypes.Implicit,
|
AllowedGrantTypes = GrantTypes.Implicit,
|
||||||
AllowAccessTokensViaBrowser = true,
|
AllowAccessTokensViaBrowser = true,
|
||||||
|
|
||||||
RedirectUris = { $"{clientsUrl["LocationsApi"]}/swagger/o2c.html" },
|
RedirectUris = { $"{clientsUrl["LocationsApi"]}/swagger/oauth2-redirect.html" },
|
||||||
PostLogoutRedirectUris = { $"{clientsUrl["LocationsApi"]}/swagger/" },
|
PostLogoutRedirectUris = { $"{clientsUrl["LocationsApi"]}/swagger/" },
|
||||||
|
|
||||||
AllowedScopes =
|
AllowedScopes =
|
||||||
@ -180,7 +184,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
|
|||||||
AllowedGrantTypes = GrantTypes.Implicit,
|
AllowedGrantTypes = GrantTypes.Implicit,
|
||||||
AllowAccessTokensViaBrowser = true,
|
AllowAccessTokensViaBrowser = true,
|
||||||
|
|
||||||
RedirectUris = { $"{clientsUrl["MarketingApi"]}/swagger/o2c.html" },
|
RedirectUris = { $"{clientsUrl["MarketingApi"]}/swagger/oauth2-redirect.html" },
|
||||||
PostLogoutRedirectUris = { $"{clientsUrl["MarketingApi"]}/swagger/" },
|
PostLogoutRedirectUris = { $"{clientsUrl["MarketingApi"]}/swagger/" },
|
||||||
|
|
||||||
AllowedScopes =
|
AllowedScopes =
|
||||||
@ -195,7 +199,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
|
|||||||
AllowedGrantTypes = GrantTypes.Implicit,
|
AllowedGrantTypes = GrantTypes.Implicit,
|
||||||
AllowAccessTokensViaBrowser = true,
|
AllowAccessTokensViaBrowser = true,
|
||||||
|
|
||||||
RedirectUris = { $"{clientsUrl["BasketApi"]}/swagger/o2c.html" },
|
RedirectUris = { $"{clientsUrl["BasketApi"]}/swagger/oauth2-redirect.html" },
|
||||||
PostLogoutRedirectUris = { $"{clientsUrl["BasketApi"]}/swagger/" },
|
PostLogoutRedirectUris = { $"{clientsUrl["BasketApi"]}/swagger/" },
|
||||||
|
|
||||||
AllowedScopes =
|
AllowedScopes =
|
||||||
@ -210,7 +214,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
|
|||||||
AllowedGrantTypes = GrantTypes.Implicit,
|
AllowedGrantTypes = GrantTypes.Implicit,
|
||||||
AllowAccessTokensViaBrowser = true,
|
AllowAccessTokensViaBrowser = true,
|
||||||
|
|
||||||
RedirectUris = { $"{clientsUrl["OrderingApi"]}/swagger/o2c.html" },
|
RedirectUris = { $"{clientsUrl["OrderingApi"]}/swagger/oauth2-redirect.html" },
|
||||||
PostLogoutRedirectUris = { $"{clientsUrl["OrderingApi"]}/swagger/" },
|
PostLogoutRedirectUris = { $"{clientsUrl["OrderingApi"]}/swagger/" },
|
||||||
|
|
||||||
AllowedScopes =
|
AllowedScopes =
|
||||||
@ -225,7 +229,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
|
|||||||
AllowedGrantTypes = GrantTypes.Implicit,
|
AllowedGrantTypes = GrantTypes.Implicit,
|
||||||
AllowAccessTokensViaBrowser = true,
|
AllowAccessTokensViaBrowser = true,
|
||||||
|
|
||||||
RedirectUris = { $"{clientsUrl["MobileShoppingAgg"]}/swagger/o2c.html" },
|
RedirectUris = { $"{clientsUrl["MobileShoppingAgg"]}/swagger/oauth2-redirect.html" },
|
||||||
PostLogoutRedirectUris = { $"{clientsUrl["MobileShoppingAgg"]}/swagger/" },
|
PostLogoutRedirectUris = { $"{clientsUrl["MobileShoppingAgg"]}/swagger/" },
|
||||||
|
|
||||||
AllowedScopes =
|
AllowedScopes =
|
||||||
@ -240,7 +244,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Configuration
|
|||||||
AllowedGrantTypes = GrantTypes.Implicit,
|
AllowedGrantTypes = GrantTypes.Implicit,
|
||||||
AllowAccessTokensViaBrowser = true,
|
AllowAccessTokensViaBrowser = true,
|
||||||
|
|
||||||
RedirectUris = { $"{clientsUrl["WebShoppingAgg"]}/swagger/o2c.html" },
|
RedirectUris = { $"{clientsUrl["WebShoppingAgg"]}/swagger/oauth2-redirect.html" },
|
||||||
PostLogoutRedirectUris = { $"{clientsUrl["WebShoppingAgg"]}/swagger/" },
|
PostLogoutRedirectUris = { $"{clientsUrl["WebShoppingAgg"]}/swagger/" },
|
||||||
|
|
||||||
AllowedScopes =
|
AllowedScopes =
|
||||||
|
@ -20,8 +20,8 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data
|
|||||||
{
|
{
|
||||||
private readonly IPasswordHasher<ApplicationUser> _passwordHasher = new PasswordHasher<ApplicationUser>();
|
private readonly IPasswordHasher<ApplicationUser> _passwordHasher = new PasswordHasher<ApplicationUser>();
|
||||||
|
|
||||||
public async Task SeedAsync(ApplicationDbContext context,IHostingEnvironment env,
|
public async Task SeedAsync(ApplicationDbContext context, IHostingEnvironment env,
|
||||||
ILogger<ApplicationDbContextSeed> logger, IOptions<AppSettings> settings,int? retry = 0)
|
ILogger<ApplicationDbContextSeed> logger, IOptions<AppSettings> settings, int? retry = 0)
|
||||||
{
|
{
|
||||||
int retryForAvaiability = retry.Value;
|
int retryForAvaiability = retry.Value;
|
||||||
|
|
||||||
@ -51,9 +51,9 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data
|
|||||||
{
|
{
|
||||||
retryForAvaiability++;
|
retryForAvaiability++;
|
||||||
|
|
||||||
logger.LogError(ex.Message,$"There is an error migrating data for ApplicationDbContext");
|
logger.LogError(ex.Message, $"There is an error migrating data for ApplicationDbContext");
|
||||||
|
|
||||||
await SeedAsync(context,env,logger,settings, retryForAvaiability);
|
await SeedAsync(context, env, logger, settings, retryForAvaiability);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,7 +87,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data
|
|||||||
|
|
||||||
List<ApplicationUser> users = File.ReadAllLines(csvFileUsers)
|
List<ApplicationUser> users = File.ReadAllLines(csvFileUsers)
|
||||||
.Skip(1) // skip header column
|
.Skip(1) // skip header column
|
||||||
.Select(row => Regex.Split(row, ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)") )
|
.Select(row => Regex.Split(row, ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)"))
|
||||||
.SelectTry(column => CreateApplicationUser(column, csvheaders))
|
.SelectTry(column => CreateApplicationUser(column, csvheaders))
|
||||||
.OnCaughtException(ex => { logger.LogError(ex.Message); return null; })
|
.OnCaughtException(ex => { logger.LogError(ex.Message); return null; })
|
||||||
.Where(x => x != null)
|
.Where(x => x != null)
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
using IdentityServer4.EntityFramework.DbContexts;
|
using IdentityServer4.EntityFramework.DbContexts;
|
||||||
|
using IdentityServer4.EntityFramework.Entities;
|
||||||
using IdentityServer4.EntityFramework.Mappers;
|
using IdentityServer4.EntityFramework.Mappers;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.eShopOnContainers.Services.Identity.API.Configuration;
|
using Microsoft.eShopOnContainers.Services.Identity.API.Configuration;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -30,16 +33,37 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data
|
|||||||
{
|
{
|
||||||
foreach (var client in Config.GetClients(clientUrls))
|
foreach (var client in Config.GetClients(clientUrls))
|
||||||
{
|
{
|
||||||
await context.Clients.AddAsync(client.ToEntity());
|
context.Clients.Add(client.ToEntity());
|
||||||
}
|
}
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
// Checking always for old redirects to fix existing deployments
|
||||||
|
// to use new swagger-ui redirect uri as of v3.0.0
|
||||||
|
// There should be no problem for new ones
|
||||||
|
// ref: https://github.com/dotnet-architecture/eShopOnContainers/issues/586
|
||||||
|
else
|
||||||
|
{
|
||||||
|
List<ClientRedirectUri> oldRedirects = (await context.Clients.Include(c => c.RedirectUris).ToListAsync())
|
||||||
|
.SelectMany(c => c.RedirectUris)
|
||||||
|
.Where(ru => ru.RedirectUri.EndsWith("/o2c.html"))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (oldRedirects.Any())
|
||||||
|
{
|
||||||
|
foreach (var ru in oldRedirects)
|
||||||
|
{
|
||||||
|
ru.RedirectUri = ru.RedirectUri.Replace("/o2c.html", "/oauth2-redirect.html");
|
||||||
|
context.Update(ru.Client);
|
||||||
|
}
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!context.IdentityResources.Any())
|
if (!context.IdentityResources.Any())
|
||||||
{
|
{
|
||||||
foreach (var resource in Config.GetResources())
|
foreach (var resource in Config.GetResources())
|
||||||
{
|
{
|
||||||
await context.IdentityResources.AddAsync(resource.ToEntity());
|
context.IdentityResources.Add(resource.ToEntity());
|
||||||
}
|
}
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
@ -48,7 +72,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API.Data
|
|||||||
{
|
{
|
||||||
foreach (var api in Config.GetApis())
|
foreach (var api in Config.GetApis())
|
||||||
{
|
{
|
||||||
await context.ApiResources.AddAsync(api.ToEntity());
|
context.ApiResources.Add(api.ToEntity());
|
||||||
}
|
}
|
||||||
|
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
|
@ -1,12 +1,26 @@
|
|||||||
FROM microsoft/aspnetcore:2.0.5 AS base
|
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
FROM microsoft/aspnetcore-build:2.0.5-2.1.4 AS build
|
FROM microsoft/dotnet:2.1-sdk AS sdk-with-node
|
||||||
|
ENV NODE_VERSION 8.11.1
|
||||||
|
ENV NODE_DOWNLOAD_SHA 0e20787e2eda4cc31336d8327556ebc7417e8ee0a6ba0de96a09b0ec2b841f60
|
||||||
|
RUN curl -SL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz" --output nodejs.tar.gz \
|
||||||
|
&& echo "$NODE_DOWNLOAD_SHA nodejs.tar.gz" | sha256sum -c - \
|
||||||
|
&& tar -xzf "nodejs.tar.gz" -C /usr/local --strip-components=1 \
|
||||||
|
&& rm nodejs.tar.gz \
|
||||||
|
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs
|
||||||
|
|
||||||
|
FROM sdk-with-node AS updated-npm
|
||||||
|
RUN npm i -g npm
|
||||||
|
|
||||||
|
|
||||||
|
FROM updated-npm as build
|
||||||
|
RUN npm install -g bower@1.8.4
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN dotnet restore -nowarn:msb3202,nu1503
|
|
||||||
WORKDIR /src/src/Services/Identity/Identity.API
|
WORKDIR /src/src/Services/Identity/Identity.API
|
||||||
|
RUN dotnet restore -nowarn:msb3202,nu1503
|
||||||
RUN dotnet build --no-restore -c Release -o /app
|
RUN dotnet build --no-restore -c Release -o /app
|
||||||
|
|
||||||
FROM build AS publish
|
FROM build AS publish
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.IdentityDb;User Id=sa;Password=Pass@word;",
|
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.IdentityDb;User Id=sa;Password=Pass@word;",
|
||||||
"IsClusterEnv": "False",
|
"IsClusterEnv": "False",
|
||||||
|
"IdentityServer": "http://localhost:5105",
|
||||||
"MvcClient": "http://localhost:5100",
|
"MvcClient": "http://localhost:5100",
|
||||||
"SpaClient": "http://localhost:5104",
|
"SpaClient": "http://localhost:5104",
|
||||||
"XamarinCallback": "http://localhost:5105/xamarincallback",
|
"XamarinCallback": "http://localhost:5105/xamarincallback",
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
FROM microsoft/aspnetcore:2.0.5 AS base
|
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
FROM microsoft/aspnetcore-build:2.0.5-2.1.4 AS build
|
FROM microsoft/dotnet:2.1-sdk AS build
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN dotnet restore -nowarn:msb3202,nu1503
|
|
||||||
WORKDIR /src/src/Services/Location/Locations.API
|
WORKDIR /src/src/Services/Location/Locations.API
|
||||||
|
RUN dotnet restore -nowarn:msb3202,nu1503
|
||||||
RUN dotnet build --no-restore -c Release -o /app
|
RUN dotnet build --no-restore -c Release -o /app
|
||||||
|
|
||||||
FROM build AS publish
|
FROM build AS publish
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
FROM microsoft/aspnetcore:2.0.5 AS base
|
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
FROM microsoft/aspnetcore-build:2.0.5-2.1.4 AS build
|
FROM microsoft/dotnet:2.1-sdk AS build
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN dotnet restore -nowarn:msb3202,nu1503
|
|
||||||
WORKDIR /src/src/Services/Marketing/Marketing.API
|
WORKDIR /src/src/Services/Marketing/Marketing.API
|
||||||
|
RUN dotnet restore -nowarn:msb3202,nu1503
|
||||||
RUN dotnet build --no-restore -c Release -o /app
|
RUN dotnet build --no-restore -c Release -o /app
|
||||||
|
|
||||||
FROM build AS publish
|
FROM build AS publish
|
||||||
|
@ -28,6 +28,7 @@ namespace Ordering.API.Application.DomainEventHandlers.OrderCancelled
|
|||||||
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
|
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
|
||||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||||
_buyerRepository = buyerRepository ?? throw new ArgumentNullException(nameof(buyerRepository));
|
_buyerRepository = buyerRepository ?? throw new ArgumentNullException(nameof(buyerRepository));
|
||||||
|
_orderingIntegrationEventService = orderingIntegrationEventService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Handle(OrderCancelledDomainEvent orderCancelledDomainEvent, CancellationToken cancellationToken)
|
public async Task Handle(OrderCancelledDomainEvent orderCancelledDomainEvent, CancellationToken cancellationToken)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries
|
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries
|
||||||
{
|
{
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -7,7 +8,7 @@
|
|||||||
{
|
{
|
||||||
Task<Order> GetOrderAsync(int id);
|
Task<Order> GetOrderAsync(int id);
|
||||||
|
|
||||||
Task<IEnumerable<OrderSummary>> GetOrdersAsync();
|
Task<IEnumerable<OrderSummary>> GetOrdersFromUserAsync(Guid userId);
|
||||||
|
|
||||||
Task<IEnumerable<CardType>> GetCardTypesAsync();
|
Task<IEnumerable<CardType>> GetCardTypesAsync();
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
public class OrderQueries
|
public class OrderQueries
|
||||||
:IOrderQueries
|
: IOrderQueries
|
||||||
{
|
{
|
||||||
private string _connectionString = string.Empty;
|
private string _connectionString = string.Empty;
|
||||||
|
|
||||||
@ -42,18 +42,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<OrderSummary>> GetOrdersAsync()
|
public async Task<IEnumerable<OrderSummary>> GetOrdersFromUserAsync(Guid userId)
|
||||||
{
|
{
|
||||||
using (var connection = new SqlConnection(_connectionString))
|
using (var connection = new SqlConnection(_connectionString))
|
||||||
{
|
{
|
||||||
connection.Open();
|
connection.Open();
|
||||||
|
|
||||||
return await connection.QueryAsync<OrderSummary>(@"SELECT o.[Id] as ordernumber,o.[OrderDate] as [date],os.[Name] as [status],SUM(oi.units*oi.unitprice) as total
|
return await connection.QueryAsync<OrderSummary>(@"SELECT o.[Id] as ordernumber,o.[OrderDate] as [date],os.[Name] as [status], SUM(oi.units*oi.unitprice) as total
|
||||||
FROM [ordering].[Orders] o
|
FROM [ordering].[Orders] o
|
||||||
LEFT JOIN[ordering].[orderitems] oi ON o.Id = oi.orderid
|
LEFT JOIN[ordering].[orderitems] oi ON o.Id = oi.orderid
|
||||||
LEFT JOIN[ordering].[orderstatus] os on o.OrderStatusId = os.Id
|
LEFT JOIN[ordering].[orderstatus] os on o.OrderStatusId = os.Id
|
||||||
|
LEFT JOIN[ordering].[buyers] ob on o.BuyerId = ob.Id
|
||||||
|
WHERE ob.IdentityGuid = @userId
|
||||||
GROUP BY o.[Id], o.[OrderDate], os.[Name]
|
GROUP BY o.[Id], o.[OrderDate], os.[Name]
|
||||||
ORDER BY o.[Id]");
|
ORDER BY o.[Id]", new { userId });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
|
|||||||
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries;
|
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries;
|
||||||
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services;
|
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services;
|
||||||
using Ordering.API.Application.Commands;
|
using Ordering.API.Application.Commands;
|
||||||
using Ordering.API.Application.Models;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
@ -15,6 +14,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
|
|||||||
{
|
{
|
||||||
[Route("api/v1/[controller]")]
|
[Route("api/v1/[controller]")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
|
[ApiController]
|
||||||
public class OrdersController : Controller
|
public class OrdersController : Controller
|
||||||
{
|
{
|
||||||
private readonly IMediator _mediator;
|
private readonly IMediator _mediator;
|
||||||
@ -87,8 +87,8 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
|
|||||||
[ProducesResponseType(typeof(IEnumerable<OrderSummary>), (int)HttpStatusCode.OK)]
|
[ProducesResponseType(typeof(IEnumerable<OrderSummary>), (int)HttpStatusCode.OK)]
|
||||||
public async Task<IActionResult> GetOrders()
|
public async Task<IActionResult> GetOrders()
|
||||||
{
|
{
|
||||||
var orders = await _orderQueries.GetOrdersAsync();
|
var userid = _identityService.GetUserIdentity();
|
||||||
|
var orders = await _orderQueries.GetOrdersFromUserAsync(Guid.Parse(userid));
|
||||||
return Ok(orders);
|
return Ok(orders);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
FROM microsoft/aspnetcore:2.0.5 AS base
|
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
FROM microsoft/aspnetcore-build:2.0.5-2.1.4 AS build
|
FROM microsoft/dotnet:2.1-sdk AS build
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN dotnet restore -nowarn:msb3202,nu1503
|
|
||||||
WORKDIR /src/src/Services/Ordering/Ordering.API
|
WORKDIR /src/src/Services/Ordering/Ordering.API
|
||||||
|
RUN dotnet restore -nowarn:msb3202,nu1503
|
||||||
RUN dotnet build --no-restore -c Release -o /app
|
RUN dotnet build --no-restore -c Release -o /app
|
||||||
|
|
||||||
FROM build AS publish
|
FROM build AS publish
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
using AspNetCore.Mvc;
|
using AspNetCore.Mvc;
|
||||||
using global::Ordering.Domain.Exceptions;
|
using global::Ordering.Domain.Exceptions;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.ActionResults;
|
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.ActionResults;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
@ -27,14 +28,16 @@
|
|||||||
|
|
||||||
if (context.Exception.GetType() == typeof(OrderingDomainException))
|
if (context.Exception.GetType() == typeof(OrderingDomainException))
|
||||||
{
|
{
|
||||||
var json = new JsonErrorResponse
|
var problemDetails = new ValidationProblemDetails()
|
||||||
{
|
{
|
||||||
Messages = new[] { context.Exception.Message }
|
Instance = context.HttpContext.Request.Path,
|
||||||
|
Status = StatusCodes.Status400BadRequest,
|
||||||
|
Detail = "Please refer to the errors property for additional details."
|
||||||
};
|
};
|
||||||
|
|
||||||
// Result asigned to a result object but in destiny the response is empty. This is a known bug of .net core 1.1
|
problemDetails.Errors.Add("DomainValidations", new string[] { context.Exception.Message.ToString() });
|
||||||
//It will be fixed in .net core 1.1.2. See https://github.com/aspnet/Mvc/issues/5594 for more information
|
|
||||||
context.Result = new BadRequestObjectResult(json);
|
context.Result = new BadRequestObjectResult(problemDetails);
|
||||||
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
|
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
|
|
||||||
public string EventBusConnection { get; set; }
|
public string EventBusConnection { get; set; }
|
||||||
|
|
||||||
public int GracePeriodTime { get; set; }
|
|
||||||
|
|
||||||
public int CheckUpdateTime { get; set; }
|
public int CheckUpdateTime { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
},
|
},
|
||||||
"AzureServiceBusEnabled": false,
|
"AzureServiceBusEnabled": false,
|
||||||
"SubscriptionClientName": "Ordering",
|
"SubscriptionClientName": "Ordering",
|
||||||
"GracePeriodTime": "1",
|
|
||||||
"CheckUpdateTime": "30000",
|
"CheckUpdateTime": "30000",
|
||||||
"ApplicationInsights": {
|
"ApplicationInsights": {
|
||||||
"InstrumentationKey": ""
|
"InstrumentationKey": ""
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
FROM microsoft/aspnetcore:2.0.5 AS base
|
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
FROM microsoft/aspnetcore-build:2.0.5-2.1.4 AS build
|
FROM microsoft/dotnet:2.1-sdk AS build
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN dotnet restore -nowarn:msb3202,nu1503
|
|
||||||
WORKDIR /src/src/Services/Ordering/Ordering.BackgroundTasks
|
WORKDIR /src/src/Services/Ordering/Ordering.BackgroundTasks
|
||||||
|
RUN dotnet restore -nowarn:msb3202,nu1503
|
||||||
RUN dotnet build --no-restore -c Release -o /app
|
RUN dotnet build --no-restore -c Release -o /app
|
||||||
|
|
||||||
FROM build AS publish
|
FROM build AS publish
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
FROM microsoft/aspnetcore:2.0 AS base
|
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
FROM microsoft/aspnetcore-build:2.0 AS build
|
FROM microsoft/dotnet:2.1-sdk AS build
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY eShopOnContainers-ServicesAndWebApps.sln ./
|
|
||||||
COPY src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj src/Services/Ordering/Ordering.SignalrHub/
|
|
||||||
RUN dotnet restore -nowarn:msb3202,nu1503
|
|
||||||
COPY . .
|
COPY . .
|
||||||
WORKDIR /src/src/Services/Ordering/Ordering.SignalrHub
|
WORKDIR /src/src/Services/Ordering/Ordering.SignalrHub
|
||||||
RUN dotnet build Ordering.SignalrHub.csproj -c Release -o /app
|
RUN dotnet restore -nowarn:msb3202,nu1503
|
||||||
|
RUN dotnet build --no-restore Ordering.SignalrHub.csproj -c Release -o /app
|
||||||
|
|
||||||
FROM build AS publish
|
FROM build AS publish
|
||||||
RUN dotnet publish Ordering.SignalrHub.csproj -c Release -o /app
|
RUN dotnet publish --no-restore Ordering.SignalrHub.csproj -c Release -o /app
|
||||||
|
|
||||||
FROM base AS final
|
FROM base AS final
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
@ -13,13 +13,13 @@ namespace Ordering.SignalrHub
|
|||||||
|
|
||||||
public override async Task OnConnectedAsync()
|
public override async Task OnConnectedAsync()
|
||||||
{
|
{
|
||||||
await Groups.AddAsync(Context.ConnectionId, Context.User.Identity.Name);
|
await Groups.AddToGroupAsync(Context.ConnectionId, Context.User.Identity.Name);
|
||||||
await base.OnConnectedAsync();
|
await base.OnConnectedAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task OnDisconnectedAsync(Exception ex)
|
public override async Task OnDisconnectedAsync(Exception ex)
|
||||||
{
|
{
|
||||||
await Groups.RemoveAsync(Context.ConnectionId, Context.User.Identity.Name);
|
await Groups.AddToGroupAsync(Context.ConnectionId, Context.User.Identity.Name);
|
||||||
await base.OnDisconnectedAsync(ex);
|
await base.OnDisconnectedAsync(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
FROM microsoft/aspnetcore:2.0.5 AS base
|
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
FROM microsoft/aspnetcore-build:2.0.5-2.1.4 AS build
|
FROM microsoft/dotnet:2.1-sdk AS build
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN dotnet restore -nowarn:msb3202,nu1503
|
|
||||||
WORKDIR /src/src/Services/Payment/Payment.API
|
WORKDIR /src/src/Services/Payment/Payment.API
|
||||||
|
RUN dotnet restore -nowarn:msb3202,nu1503
|
||||||
RUN dotnet build --no-restore -c Release -o /app
|
RUN dotnet build --no-restore -c Release -o /app
|
||||||
|
|
||||||
FROM build AS publish
|
FROM build AS publish
|
||||||
|
@ -7,9 +7,8 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
|||||||
{
|
{
|
||||||
public class AppSettings
|
public class AppSettings
|
||||||
{
|
{
|
||||||
public Connectionstrings ConnectionStrings { get; set; }
|
//public Connectionstrings ConnectionStrings { get; set; }
|
||||||
public string MarketingUrl { get; set; }
|
public string MarketingUrl { get; set; }
|
||||||
|
|
||||||
public string PurchaseUrl { get; set; }
|
public string PurchaseUrl { get; set; }
|
||||||
public string SignalrHubUrl { get; set; }
|
public string SignalrHubUrl { get; set; }
|
||||||
public bool ActivateCampaignDetailFunction { get; set; }
|
public bool ActivateCampaignDetailFunction { get; set; }
|
||||||
|
@ -71,7 +71,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
|||||||
{
|
{
|
||||||
var user = _appUserParser.Parse(HttpContext.User);
|
var user = _appUserParser.Parse(HttpContext.User);
|
||||||
await _basketSvc.AddItemToBasket(user, productDetails.Id);
|
await _basketSvc.AddItemToBasket(user, productDetails.Id);
|
||||||
//await _basketSvc.AddItemToBasket(user, product);
|
|
||||||
}
|
}
|
||||||
return RedirectToAction("Index", "Catalog");
|
return RedirectToAction("Index", "Catalog");
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,9 @@
|
|||||||
using System;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.eShopOnContainers.WebMVC.Services;
|
using Microsoft.eShopOnContainers.WebMVC.Services;
|
||||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using System.Net.Http;
|
|
||||||
using Polly.CircuitBreaker;
|
using Polly.CircuitBreaker;
|
||||||
using WebMVC.Models;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
||||||
{
|
{
|
||||||
@ -52,10 +47,11 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
|||||||
return RedirectToAction("Index");
|
return RedirectToAction("Index");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(BrokenCircuitException)
|
catch (BrokenCircuitException)
|
||||||
{
|
{
|
||||||
ModelState.AddModelError("Error", "It was not possible to create a new order, please try later on. (Business Msg Due to Circuit-Breaker)");
|
ModelState.AddModelError("Error", "It was not possible to create a new order, please try later on. (Business Msg Due to Circuit-Breaker)");
|
||||||
}
|
}
|
||||||
|
|
||||||
return View("Create", model);
|
return View("Create", model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
|
|
||||||
using Microsoft.eShopOnContainers.WebMVC.Services;
|
using Microsoft.eShopOnContainers.WebMVC.Services;
|
||||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||||
using System;
|
using Newtonsoft.Json;
|
||||||
using System.Collections.Generic;
|
using System.Net.Http;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace WebMVC.Controllers
|
namespace WebMVC.Controllers
|
||||||
@ -14,6 +11,7 @@ namespace WebMVC.Controllers
|
|||||||
class TestPayload
|
class TestPayload
|
||||||
{
|
{
|
||||||
public int CatalogItemId { get; set; }
|
public int CatalogItemId { get; set; }
|
||||||
|
|
||||||
public string BasketId { get; set; }
|
public string BasketId { get; set; }
|
||||||
|
|
||||||
public int Quantity { get; set; }
|
public int Quantity { get; set; }
|
||||||
@ -22,9 +20,10 @@ namespace WebMVC.Controllers
|
|||||||
[Authorize]
|
[Authorize]
|
||||||
public class TestController : Controller
|
public class TestController : Controller
|
||||||
{
|
{
|
||||||
private readonly IHttpClient _client;
|
private readonly IHttpClientFactory _client;
|
||||||
private readonly IIdentityParser<ApplicationUser> _appUserParser;
|
private readonly IIdentityParser<ApplicationUser> _appUserParser;
|
||||||
public TestController(IHttpClient client, IIdentityParser<ApplicationUser> identityParser)
|
|
||||||
|
public TestController(IHttpClientFactory client, IIdentityParser<ApplicationUser> identityParser)
|
||||||
{
|
{
|
||||||
_client = client;
|
_client = client;
|
||||||
_appUserParser = identityParser;
|
_appUserParser = identityParser;
|
||||||
@ -33,18 +32,24 @@ namespace WebMVC.Controllers
|
|||||||
public async Task<IActionResult> Ocelot()
|
public async Task<IActionResult> Ocelot()
|
||||||
{
|
{
|
||||||
var url = "http://apigw/shopping/api/v1/basket/items";
|
var url = "http://apigw/shopping/api/v1/basket/items";
|
||||||
|
|
||||||
var payload = new TestPayload()
|
var payload = new TestPayload()
|
||||||
{
|
{
|
||||||
CatalogItemId = 1,
|
CatalogItemId = 1,
|
||||||
Quantity = 1,
|
Quantity = 1,
|
||||||
BasketId = _appUserParser.Parse(User).Id
|
BasketId = _appUserParser.Parse(User).Id
|
||||||
};
|
};
|
||||||
var token = await HttpContext.GetTokenAsync("access_token");
|
|
||||||
var response = await _client.PostAsync<TestPayload>(url, payload, token);
|
var content = new StringContent(JsonConvert.SerializeObject(payload), System.Text.Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
|
||||||
|
var response = await _client.CreateClient(nameof(IBasketService))
|
||||||
|
.PostAsync(url, content);
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
var str = await response.Content.ReadAsStringAsync();
|
var str = await response.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
return Ok(str);
|
return Ok(str);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1,12 +1,25 @@
|
|||||||
FROM microsoft/aspnetcore:2.0.5 AS base
|
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
FROM microsoft/aspnetcore-build:2.0.5-2.1.4 AS build
|
FROM microsoft/dotnet:2.1-sdk AS sdk-with-node
|
||||||
|
ENV NODE_VERSION 8.11.1
|
||||||
|
ENV NODE_DOWNLOAD_SHA 0e20787e2eda4cc31336d8327556ebc7417e8ee0a6ba0de96a09b0ec2b841f60
|
||||||
|
RUN curl -SL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz" --output nodejs.tar.gz \
|
||||||
|
&& echo "$NODE_DOWNLOAD_SHA nodejs.tar.gz" | sha256sum -c - \
|
||||||
|
&& tar -xzf "nodejs.tar.gz" -C /usr/local --strip-components=1 \
|
||||||
|
&& rm nodejs.tar.gz \
|
||||||
|
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs
|
||||||
|
|
||||||
|
FROM sdk-with-node AS updated-npm
|
||||||
|
RUN npm i -g npm
|
||||||
|
|
||||||
|
FROM updated-npm as build
|
||||||
|
RUN npm install -g bower@1.8.4
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN dotnet restore -nowarn:msb3202,nu1503
|
|
||||||
WORKDIR /src/src/Web/WebMVC
|
WORKDIR /src/src/Web/WebMVC
|
||||||
|
RUN dotnet restore -nowarn:msb3202,nu1503
|
||||||
RUN dotnet build --no-restore -c Release -o /app
|
RUN dotnet build --no-restore -c Release -o /app
|
||||||
|
|
||||||
FROM build AS publish
|
FROM build AS publish
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WebMVC.Infrastructure
|
||||||
|
{
|
||||||
|
public class HttpClientAuthorizationDelegatingHandler
|
||||||
|
: DelegatingHandler
|
||||||
|
{
|
||||||
|
private readonly IHttpContextAccessor _httpContextAccesor;
|
||||||
|
|
||||||
|
public HttpClientAuthorizationDelegatingHandler(IHttpContextAccessor httpContextAccesor)
|
||||||
|
{
|
||||||
|
_httpContextAccesor = httpContextAccesor;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var authorizationHeader = _httpContextAccesor.HttpContext
|
||||||
|
.Request.Headers["Authorization"];
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(authorizationHeader))
|
||||||
|
{
|
||||||
|
request.Headers.Add("Authorization", new List<string>() { authorizationHeader });
|
||||||
|
}
|
||||||
|
|
||||||
|
var token = await GetToken();
|
||||||
|
|
||||||
|
if (token != null)
|
||||||
|
{
|
||||||
|
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await base.SendAsync(request, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task<string> GetToken()
|
||||||
|
{
|
||||||
|
const string ACCESS_TOKEN = "access_token";
|
||||||
|
|
||||||
|
return await _httpContextAccesor.HttpContext
|
||||||
|
.GetTokenAsync(ACCESS_TOKEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WebMVC.Infrastructure
|
||||||
|
{
|
||||||
|
public class HttpClientRequestIdDelegatingHandler
|
||||||
|
: DelegatingHandler
|
||||||
|
{
|
||||||
|
|
||||||
|
public HttpClientRequestIdDelegatingHandler()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (request.Method == HttpMethod.Post || request.Method == HttpMethod.Put)
|
||||||
|
{
|
||||||
|
request.Headers.Add("x-requestid", Guid.NewGuid().ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return await base.SendAsync(request, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +0,0 @@
|
|||||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.WebMVC.Infrastructure
|
|
||||||
{
|
|
||||||
public interface IResilientHttpClientFactory
|
|
||||||
{
|
|
||||||
ResilientHttpClient CreateResilientHttpClient();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Polly;
|
|
||||||
using System;
|
|
||||||
using System.Net.Http;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.WebMVC.Infrastructure
|
|
||||||
{
|
|
||||||
public class ResilientHttpClientFactory : IResilientHttpClientFactory
|
|
||||||
{
|
|
||||||
private readonly ILogger<ResilientHttpClient> _logger;
|
|
||||||
private readonly int _retryCount;
|
|
||||||
private readonly int _exceptionsAllowedBeforeBreaking;
|
|
||||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
|
||||||
|
|
||||||
public ResilientHttpClientFactory(ILogger<ResilientHttpClient> logger, IHttpContextAccessor httpContextAccessor, int exceptionsAllowedBeforeBreaking = 5, int retryCount = 6)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_exceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking;
|
|
||||||
_retryCount = retryCount;
|
|
||||||
_httpContextAccessor = httpContextAccessor;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public ResilientHttpClient CreateResilientHttpClient()
|
|
||||||
=> new ResilientHttpClient((origin) => CreatePolicies(), _logger, _httpContextAccessor);
|
|
||||||
|
|
||||||
private Policy[] CreatePolicies()
|
|
||||||
=> new Policy[]
|
|
||||||
{
|
|
||||||
Policy.Handle<HttpRequestException>()
|
|
||||||
.WaitAndRetryAsync(
|
|
||||||
// number of retries
|
|
||||||
_retryCount,
|
|
||||||
// exponential backofff
|
|
||||||
retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
|
|
||||||
// on retry
|
|
||||||
(exception, timeSpan, retryCount, context) =>
|
|
||||||
{
|
|
||||||
var msg = $"Retry {retryCount} implemented with Polly's RetryPolicy " +
|
|
||||||
$"of {context.PolicyKey} " +
|
|
||||||
$"at {context.ExecutionKey}, " +
|
|
||||||
$"due to: {exception}.";
|
|
||||||
_logger.LogWarning(msg);
|
|
||||||
_logger.LogDebug(msg);
|
|
||||||
}),
|
|
||||||
Policy.Handle<HttpRequestException>()
|
|
||||||
.CircuitBreakerAsync(
|
|
||||||
// number of exceptions before breaking circuit
|
|
||||||
_exceptionsAllowedBeforeBreaking,
|
|
||||||
// time circuit opened before retry
|
|
||||||
TimeSpan.FromMinutes(1),
|
|
||||||
(exception, duration) =>
|
|
||||||
{
|
|
||||||
// on circuit opened
|
|
||||||
_logger.LogTrace("Circuit breaker opened");
|
|
||||||
},
|
|
||||||
() =>
|
|
||||||
{
|
|
||||||
// on circuit closed
|
|
||||||
_logger.LogTrace("Circuit breaker reset");
|
|
||||||
})
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,7 +17,7 @@ namespace WebMVC.Infrastructure
|
|||||||
{
|
{
|
||||||
var log = loggerFactory.CreateLogger("WebMVC seed");
|
var log = loggerFactory.CreateLogger("WebMVC seed");
|
||||||
|
|
||||||
var settings = (AppSettings)applicationBuilder
|
var settings = applicationBuilder
|
||||||
.ApplicationServices.GetRequiredService<IOptions<AppSettings>>().Value;
|
.ApplicationServices.GetRequiredService<IOptions<AppSettings>>().Value;
|
||||||
|
|
||||||
var useCustomizationData = settings.UseCustomizationData;
|
var useCustomizationData = settings.UseCustomizationData;
|
||||||
@ -66,9 +66,9 @@ namespace WebMVC.Infrastructure
|
|||||||
string imagePath = Path.Combine(webroot, "images");
|
string imagePath = Path.Combine(webroot, "images");
|
||||||
string[] imageFiles = Directory.GetFiles(imagePath).Select(file => Path.GetFileName(file)).ToArray();
|
string[] imageFiles = Directory.GetFiles(imagePath).Select(file => Path.GetFileName(file)).ToArray();
|
||||||
|
|
||||||
using (ZipArchive zip = ZipFile.Open(imagesZipFile, ZipArchiveMode.Read))
|
using (var zip = ZipFile.Open(imagesZipFile, ZipArchiveMode.Read))
|
||||||
{
|
{
|
||||||
foreach (ZipArchiveEntry entry in zip.Entries)
|
foreach (var entry in zip.Entries)
|
||||||
{
|
{
|
||||||
if (imageFiles.Contains(entry.Name))
|
if (imageFiles.Contains(entry.Name))
|
||||||
{
|
{
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
"commandName": "IISExpress",
|
"commandName": "IISExpress",
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
}
|
},
|
||||||
|
"use64Bit": true
|
||||||
},
|
},
|
||||||
"Microsoft.eShopOnContainers.WebMVC": {
|
"Microsoft.eShopOnContainers.WebMVC": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
|
|
||||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using WebMVC.Infrastructure;
|
using WebMVC.Infrastructure;
|
||||||
using WebMVC.Models;
|
using WebMVC.Models;
|
||||||
@ -14,42 +12,40 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
|||||||
{
|
{
|
||||||
public class BasketService : IBasketService
|
public class BasketService : IBasketService
|
||||||
{
|
{
|
||||||
private readonly IOptionsSnapshot<AppSettings> _settings;
|
private readonly IOptions<AppSettings> _settings;
|
||||||
private readonly IHttpClient _apiClient;
|
private readonly HttpClient _apiClient;
|
||||||
private readonly string _basketByPassUrl;
|
private readonly string _basketByPassUrl;
|
||||||
private readonly string _purchaseUrl;
|
private readonly string _purchaseUrl;
|
||||||
private readonly IHttpContextAccessor _httpContextAccesor;
|
|
||||||
|
|
||||||
private readonly string _bffUrl;
|
private readonly string _bffUrl;
|
||||||
|
|
||||||
public BasketService(IOptionsSnapshot<AppSettings> settings,
|
public BasketService(HttpClient httpClient, IOptions<AppSettings> settings)
|
||||||
IHttpContextAccessor httpContextAccesor, IHttpClient httpClient)
|
|
||||||
{
|
{
|
||||||
|
_apiClient = httpClient;
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
|
|
||||||
_basketByPassUrl = $"{_settings.Value.PurchaseUrl}/api/v1/b/basket";
|
_basketByPassUrl = $"{_settings.Value.PurchaseUrl}/api/v1/b/basket";
|
||||||
_purchaseUrl = $"{_settings.Value.PurchaseUrl}/api/v1";
|
_purchaseUrl = $"{_settings.Value.PurchaseUrl}/api/v1";
|
||||||
_httpContextAccesor = httpContextAccesor;
|
|
||||||
_apiClient = httpClient;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Basket> GetBasket(ApplicationUser user)
|
public async Task<Basket> GetBasket(ApplicationUser user)
|
||||||
{
|
{
|
||||||
var token = await GetUserTokenAsync();
|
var uri = API.Basket.GetBasket(_basketByPassUrl, user.Id);
|
||||||
var getBasketUri = API.Basket.GetBasket(_basketByPassUrl, user.Id);
|
|
||||||
|
|
||||||
var dataString = await _apiClient.GetStringAsync(getBasketUri, token);
|
var responseString = await _apiClient.GetStringAsync(uri);
|
||||||
|
|
||||||
return string.IsNullOrEmpty(dataString) ?
|
return string.IsNullOrEmpty(responseString) ?
|
||||||
new Basket() { BuyerId = user.Id} :
|
new Basket() { BuyerId = user.Id } :
|
||||||
JsonConvert.DeserializeObject<Basket>(dataString);
|
JsonConvert.DeserializeObject<Basket>(responseString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Basket> UpdateBasket(Basket basket)
|
public async Task<Basket> UpdateBasket(Basket basket)
|
||||||
{
|
{
|
||||||
var token = await GetUserTokenAsync();
|
var uri = API.Basket.UpdateBasket(_basketByPassUrl);
|
||||||
var updateBasketUri = API.Basket.UpdateBasket(_basketByPassUrl);
|
|
||||||
|
|
||||||
var response = await _apiClient.PostAsync(updateBasketUri, basket, token);
|
var basketContent = new StringContent(JsonConvert.SerializeObject(basket), System.Text.Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
var response = await _apiClient.PostAsync(uri, basketContent);
|
||||||
|
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
|
|
||||||
@ -58,65 +54,64 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
|||||||
|
|
||||||
public async Task Checkout(BasketDTO basket)
|
public async Task Checkout(BasketDTO basket)
|
||||||
{
|
{
|
||||||
var token = await GetUserTokenAsync();
|
var uri = API.Basket.CheckoutBasket(_basketByPassUrl);
|
||||||
var updateBasketUri = API.Basket.CheckoutBasket(_basketByPassUrl);
|
var basketContent = new StringContent(JsonConvert.SerializeObject(basket), System.Text.Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
var response = await _apiClient.PostAsync(updateBasketUri, basket, token);
|
var response = await _apiClient.PostAsync(uri, basketContent);
|
||||||
|
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Basket> SetQuantities(ApplicationUser user, Dictionary<string, int> quantities)
|
public async Task<Basket> SetQuantities(ApplicationUser user, Dictionary<string, int> quantities)
|
||||||
{
|
{
|
||||||
|
var uri = API.Purchase.UpdateBasketItem(_purchaseUrl);
|
||||||
|
|
||||||
var token = await GetUserTokenAsync();
|
var basketUpdate = new
|
||||||
var updateBasketUri = API.Purchase.UpdateBasketItem(_purchaseUrl);
|
|
||||||
var userId = user.Id;
|
|
||||||
|
|
||||||
var response = await _apiClient.PutAsync(updateBasketUri, new
|
|
||||||
{
|
{
|
||||||
BasketId = userId,
|
BasketId = user.Id,
|
||||||
Updates = quantities.Select(kvp => new
|
Updates = quantities.Select(kvp => new
|
||||||
{
|
{
|
||||||
BasketItemId = kvp.Key,
|
BasketItemId = kvp.Key,
|
||||||
NewQty = kvp.Value
|
NewQty = kvp.Value
|
||||||
}).ToArray()
|
}).ToArray()
|
||||||
}, token);
|
};
|
||||||
|
|
||||||
|
var basketContent = new StringContent(JsonConvert.SerializeObject(basketUpdate), System.Text.Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
var response = await _apiClient.PutAsync(uri, basketContent);
|
||||||
|
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
|
|
||||||
var jsonResponse = await response.Content.ReadAsStringAsync();
|
var jsonResponse = await response.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
return JsonConvert.DeserializeObject<Basket>(jsonResponse);
|
return JsonConvert.DeserializeObject<Basket>(jsonResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Order> GetOrderDraft(string basketId)
|
public async Task<Order> GetOrderDraft(string basketId)
|
||||||
{
|
{
|
||||||
var token = await GetUserTokenAsync();
|
var uri = API.Purchase.GetOrderDraft(_purchaseUrl, basketId);
|
||||||
var draftOrderUri = API.Purchase.GetOrderDraft(_purchaseUrl, basketId);
|
|
||||||
var json = await _apiClient.GetStringAsync(draftOrderUri, token);
|
var responseString = await _apiClient.GetStringAsync(uri);
|
||||||
return JsonConvert.DeserializeObject<Order>(json);
|
|
||||||
|
var response = JsonConvert.DeserializeObject<Order>(responseString);
|
||||||
|
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public async Task AddItemToBasket(ApplicationUser user, int productId)
|
public async Task AddItemToBasket(ApplicationUser user, int productId)
|
||||||
{
|
{
|
||||||
var token = await GetUserTokenAsync();
|
var uri = API.Purchase.AddItemToBasket(_purchaseUrl);
|
||||||
var updateBasketUri = API.Purchase.AddItemToBasket(_purchaseUrl);
|
|
||||||
var userId = user.Id;
|
|
||||||
|
|
||||||
var response = await _apiClient.PostAsync(updateBasketUri, new
|
var newItem = new
|
||||||
{
|
{
|
||||||
CatalogItemId = productId,
|
CatalogItemId = productId,
|
||||||
BasketId = userId,
|
BasketId = user.Id,
|
||||||
Quantity = 1
|
Quantity = 1
|
||||||
}, token);
|
};
|
||||||
|
|
||||||
}
|
var basketContent = new StringContent(JsonConvert.SerializeObject(newItem), System.Text.Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
async Task<string> GetUserTokenAsync()
|
var response = await _apiClient.PostAsync(uri, basketContent);
|
||||||
{
|
|
||||||
var context = _httpContextAccesor.HttpContext;
|
|
||||||
return await context.GetTokenAsync("access_token");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,69 +1,49 @@
|
|||||||
namespace Microsoft.eShopOnContainers.WebMVC.Services
|
namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||||
{
|
{
|
||||||
using global::WebMVC.Infrastructure;
|
using global::WebMVC.Infrastructure;
|
||||||
using AspNetCore.Authentication;
|
|
||||||
using AspNetCore.Http;
|
|
||||||
using BuildingBlocks.Resilience.Http;
|
|
||||||
using ViewModels;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using ViewModels;
|
||||||
|
|
||||||
public class CampaignService : ICampaignService
|
public class CampaignService : ICampaignService
|
||||||
{
|
{
|
||||||
private readonly IOptionsSnapshot<AppSettings> _settings;
|
private readonly IOptions<AppSettings> _settings;
|
||||||
private readonly IHttpClient _apiClient;
|
private readonly HttpClient _httpClient;
|
||||||
private readonly ILogger<CampaignService> _logger;
|
private readonly ILogger<CampaignService> _logger;
|
||||||
private readonly string _remoteServiceBaseUrl;
|
private readonly string _remoteServiceBaseUrl;
|
||||||
private readonly IHttpContextAccessor _httpContextAccesor;
|
|
||||||
|
|
||||||
public CampaignService(IOptionsSnapshot<AppSettings> settings, IHttpClient httpClient,
|
public CampaignService(IOptions<AppSettings> settings, HttpClient httpClient, ILogger<CampaignService> logger)
|
||||||
ILogger<CampaignService> logger, IHttpContextAccessor httpContextAccesor)
|
|
||||||
{
|
{
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
_apiClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
_remoteServiceBaseUrl = $"{_settings.Value.MarketingUrl}/api/v1/m/campaigns/";
|
_remoteServiceBaseUrl = $"{_settings.Value.MarketingUrl}/api/v1/m/campaigns/";
|
||||||
_httpContextAccesor = httpContextAccesor ?? throw new ArgumentNullException(nameof(httpContextAccesor));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Campaign> GetCampaigns(int pageSize, int pageIndex)
|
public async Task<Campaign> GetCampaigns(int pageSize, int pageIndex)
|
||||||
{
|
{
|
||||||
var allCampaignItemsUri = API.Marketing.GetAllCampaigns(_remoteServiceBaseUrl,
|
var uri = API.Marketing.GetAllCampaigns(_remoteServiceBaseUrl, pageSize, pageIndex);
|
||||||
pageSize, pageIndex);
|
|
||||||
|
|
||||||
var authorizationToken = await GetUserTokenAsync();
|
var responseString = await _httpClient.GetStringAsync(uri);
|
||||||
var dataString = await _apiClient.GetStringAsync(allCampaignItemsUri, authorizationToken);
|
|
||||||
|
|
||||||
var response = JsonConvert.DeserializeObject<Campaign>(dataString);
|
var response = JsonConvert.DeserializeObject<Campaign>(responseString);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<CampaignItem> GetCampaignById(int id)
|
public async Task<CampaignItem> GetCampaignById(int id)
|
||||||
{
|
{
|
||||||
var campaignByIdItemUri = API.Marketing.GetAllCampaignById(_remoteServiceBaseUrl, id);
|
var uri = API.Marketing.GetAllCampaignById(_remoteServiceBaseUrl, id);
|
||||||
|
|
||||||
var authorizationToken = await GetUserTokenAsync();
|
var responseString = await _httpClient.GetStringAsync(uri);
|
||||||
var dataString = await _apiClient.GetStringAsync(campaignByIdItemUri, authorizationToken);
|
|
||||||
|
|
||||||
var response = JsonConvert.DeserializeObject<CampaignItem>(dataString);
|
var response = JsonConvert.DeserializeObject<CampaignItem>(responseString);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetUserIdentity()
|
|
||||||
{
|
|
||||||
return _httpContextAccesor.HttpContext.User.FindFirst("sub").Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<string> GetUserTokenAsync()
|
|
||||||
{
|
|
||||||
var context = _httpContextAccesor.HttpContext;
|
|
||||||
return await context.GetTokenAsync("access_token");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,11 +1,11 @@
|
|||||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
|
|
||||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using WebMVC.Infrastructure;
|
using WebMVC.Infrastructure;
|
||||||
|
|
||||||
@ -13,16 +13,16 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
|||||||
{
|
{
|
||||||
public class CatalogService : ICatalogService
|
public class CatalogService : ICatalogService
|
||||||
{
|
{
|
||||||
private readonly IOptionsSnapshot<AppSettings> _settings;
|
private readonly IOptions<AppSettings> _settings;
|
||||||
private readonly IHttpClient _apiClient;
|
private readonly HttpClient _httpClient;
|
||||||
private readonly ILogger<CatalogService> _logger;
|
private readonly ILogger<CatalogService> _logger;
|
||||||
|
|
||||||
private readonly string _remoteServiceBaseUrl;
|
private readonly string _remoteServiceBaseUrl;
|
||||||
|
|
||||||
public CatalogService(IOptionsSnapshot<AppSettings> settings, IHttpClient httpClient, ILogger<CatalogService> logger)
|
public CatalogService(HttpClient httpClient, ILogger<CatalogService> logger, IOptions<AppSettings> settings)
|
||||||
{
|
{
|
||||||
|
_httpClient = httpClient;
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
_apiClient = httpClient;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
_remoteServiceBaseUrl = $"{_settings.Value.PurchaseUrl}/api/v1/c/catalog/";
|
_remoteServiceBaseUrl = $"{_settings.Value.PurchaseUrl}/api/v1/c/catalog/";
|
||||||
@ -30,25 +30,26 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
|||||||
|
|
||||||
public async Task<Catalog> GetCatalogItems(int page, int take, int? brand, int? type)
|
public async Task<Catalog> GetCatalogItems(int page, int take, int? brand, int? type)
|
||||||
{
|
{
|
||||||
var allcatalogItemsUri = API.Catalog.GetAllCatalogItems(_remoteServiceBaseUrl, page, take, brand, type);
|
var uri = API.Catalog.GetAllCatalogItems(_remoteServiceBaseUrl, page, take, brand, type);
|
||||||
|
|
||||||
var dataString = await _apiClient.GetStringAsync(allcatalogItemsUri);
|
var responseString = await _httpClient.GetStringAsync(uri);
|
||||||
|
|
||||||
var response = JsonConvert.DeserializeObject<Catalog>(dataString);
|
var catalog = JsonConvert.DeserializeObject<Catalog>(responseString);
|
||||||
|
|
||||||
return response;
|
return catalog;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<SelectListItem>> GetBrands()
|
public async Task<IEnumerable<SelectListItem>> GetBrands()
|
||||||
{
|
{
|
||||||
var getBrandsUri = API.Catalog.GetAllBrands(_remoteServiceBaseUrl);
|
var uri = API.Catalog.GetAllBrands(_remoteServiceBaseUrl);
|
||||||
|
|
||||||
var dataString = await _apiClient.GetStringAsync(getBrandsUri);
|
var responseString = await _httpClient.GetStringAsync(uri);
|
||||||
|
|
||||||
var items = new List<SelectListItem>();
|
var items = new List<SelectListItem>();
|
||||||
|
|
||||||
items.Add(new SelectListItem() { Value = null, Text = "All", Selected = true });
|
items.Add(new SelectListItem() { Value = null, Text = "All", Selected = true });
|
||||||
|
|
||||||
var brands = JArray.Parse(dataString);
|
var brands = JArray.Parse(responseString);
|
||||||
|
|
||||||
foreach (var brand in brands.Children<JObject>())
|
foreach (var brand in brands.Children<JObject>())
|
||||||
{
|
{
|
||||||
@ -64,14 +65,14 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
|||||||
|
|
||||||
public async Task<IEnumerable<SelectListItem>> GetTypes()
|
public async Task<IEnumerable<SelectListItem>> GetTypes()
|
||||||
{
|
{
|
||||||
var getTypesUri = API.Catalog.GetAllTypes(_remoteServiceBaseUrl);
|
var uri = API.Catalog.GetAllTypes(_remoteServiceBaseUrl);
|
||||||
|
|
||||||
var dataString = await _apiClient.GetStringAsync(getTypesUri);
|
var responseString = await _httpClient.GetStringAsync(uri);
|
||||||
|
|
||||||
var items = new List<SelectListItem>();
|
var items = new List<SelectListItem>();
|
||||||
items.Add(new SelectListItem() { Value = null, Text = "All", Selected = true });
|
items.Add(new SelectListItem() { Value = null, Text = "All", Selected = true });
|
||||||
|
|
||||||
var brands = JArray.Parse(dataString);
|
var brands = JArray.Parse(responseString);
|
||||||
foreach (var brand in brands.Children<JObject>())
|
foreach (var brand in brands.Children<JObject>())
|
||||||
{
|
{
|
||||||
items.Add(new SelectListItem()
|
items.Add(new SelectListItem()
|
||||||
@ -80,6 +81,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
|||||||
Text = brand.Value<string>("type")
|
Text = brand.Value<string>("type")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.WebMVC.Services
|
namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||||
{
|
{
|
||||||
public class IdentityParser:IIdentityParser<ApplicationUser>
|
public class IdentityParser : IIdentityParser<ApplicationUser>
|
||||||
{
|
{
|
||||||
public ApplicationUser Parse(IPrincipal principal)
|
public ApplicationUser Parse(IPrincipal principal)
|
||||||
{
|
{
|
||||||
@ -18,7 +18,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
|||||||
{
|
{
|
||||||
return new ApplicationUser
|
return new ApplicationUser
|
||||||
{
|
{
|
||||||
|
|
||||||
CardHolderName = claims.Claims.FirstOrDefault(x => x.Type == "card_holder")?.Value ?? "",
|
CardHolderName = claims.Claims.FirstOrDefault(x => x.Type == "card_holder")?.Value ?? "",
|
||||||
CardNumber = claims.Claims.FirstOrDefault(x => x.Type == "card_number")?.Value ?? "",
|
CardNumber = claims.Claims.FirstOrDefault(x => x.Type == "card_number")?.Value ?? "",
|
||||||
Expiration = claims.Claims.FirstOrDefault(x => x.Type == "card_expiration")?.Value ?? "",
|
Expiration = claims.Claims.FirstOrDefault(x => x.Type == "card_expiration")?.Value ?? "",
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.eShopOnContainers.WebMVC;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
|
|
||||||
using Microsoft.eShopOnContainers.WebMVC;
|
|
||||||
using Microsoft.eShopOnContainers.WebMVC.Services;
|
using Microsoft.eShopOnContainers.WebMVC.Services;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using System;
|
using Newtonsoft.Json;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using WebMVC.Infrastructure;
|
using WebMVC.Infrastructure;
|
||||||
using WebMVC.Models;
|
using WebMVC.Models;
|
||||||
@ -14,36 +12,27 @@ namespace WebMVC.Services
|
|||||||
{
|
{
|
||||||
public class LocationService : ILocationService
|
public class LocationService : ILocationService
|
||||||
{
|
{
|
||||||
private readonly IOptionsSnapshot<AppSettings> _settings;
|
private readonly IOptions<AppSettings> _settings;
|
||||||
private readonly IHttpClient _apiClient;
|
private readonly HttpClient _httpClient;
|
||||||
private readonly ILogger<CampaignService> _logger;
|
private readonly ILogger<CampaignService> _logger;
|
||||||
private readonly string _remoteServiceBaseUrl;
|
private readonly string _remoteServiceBaseUrl;
|
||||||
private readonly IHttpContextAccessor _httpContextAccesor;
|
|
||||||
|
|
||||||
public LocationService(IOptionsSnapshot<AppSettings> settings, IHttpClient httpClient,
|
public LocationService(HttpClient httpClient, IOptions<AppSettings> settings, ILogger<CampaignService> logger)
|
||||||
ILogger<CampaignService> logger, IHttpContextAccessor httpContextAccesor)
|
|
||||||
{
|
{
|
||||||
|
_httpClient = httpClient;
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
_apiClient = httpClient;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
_remoteServiceBaseUrl = $"{_settings.Value.MarketingUrl}/api/v1/l/locations/";
|
_remoteServiceBaseUrl = $"{_settings.Value.MarketingUrl}/api/v1/l/locations/";
|
||||||
_httpContextAccesor = httpContextAccesor ?? throw new ArgumentNullException(nameof(httpContextAccesor));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CreateOrUpdateUserLocation(LocationDTO location)
|
public async Task CreateOrUpdateUserLocation(LocationDTO location)
|
||||||
{
|
{
|
||||||
var createOrUpdateUserLocationUri = API.Locations.CreateOrUpdateUserLocation(_remoteServiceBaseUrl);
|
var uri = API.Locations.CreateOrUpdateUserLocation(_remoteServiceBaseUrl);
|
||||||
|
var locationContent = new StringContent(JsonConvert.SerializeObject(location), System.Text.Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
var authorizationToken = await GetUserTokenAsync();
|
var response = await _httpClient.PostAsync(uri, locationContent);
|
||||||
var response = await _apiClient.PostAsync(createOrUpdateUserLocationUri, location, authorizationToken);
|
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> GetUserTokenAsync()
|
|
||||||
{
|
|
||||||
var context = _httpContextAccesor.HttpContext;
|
|
||||||
return await context.GetTokenAsync("access_token");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
|
|
||||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using WebMVC.Infrastructure;
|
using WebMVC.Infrastructure;
|
||||||
using WebMVC.Models;
|
using WebMVC.Models;
|
||||||
@ -14,69 +12,54 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
|||||||
{
|
{
|
||||||
public class OrderingService : IOrderingService
|
public class OrderingService : IOrderingService
|
||||||
{
|
{
|
||||||
private IHttpClient _apiClient;
|
private HttpClient _httpClient;
|
||||||
private readonly string _remoteServiceBaseUrl;
|
private readonly string _remoteServiceBaseUrl;
|
||||||
private readonly IOptionsSnapshot<AppSettings> _settings;
|
private readonly IOptions<AppSettings> _settings;
|
||||||
private readonly IHttpContextAccessor _httpContextAccesor;
|
|
||||||
|
|
||||||
public OrderingService(IOptionsSnapshot<AppSettings> settings, IHttpContextAccessor httpContextAccesor, IHttpClient httpClient)
|
|
||||||
|
public OrderingService(HttpClient httpClient, IOptions<AppSettings> settings)
|
||||||
{
|
{
|
||||||
_remoteServiceBaseUrl = $"{settings.Value.PurchaseUrl}/api/v1/o/orders";
|
_httpClient = httpClient;
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
_httpContextAccesor = httpContextAccesor;
|
|
||||||
_apiClient = httpClient;
|
_remoteServiceBaseUrl = $"{settings.Value.PurchaseUrl}/api/v1/o/orders";
|
||||||
}
|
}
|
||||||
|
|
||||||
async public Task<Order> GetOrder(ApplicationUser user, string id)
|
async public Task<Order> GetOrder(ApplicationUser user, string id)
|
||||||
{
|
{
|
||||||
var token = await GetUserTokenAsync();
|
var uri = API.Order.GetOrder(_remoteServiceBaseUrl, id);
|
||||||
var getOrderUri = API.Order.GetOrder(_remoteServiceBaseUrl, id);
|
|
||||||
|
|
||||||
var dataString = await _apiClient.GetStringAsync(getOrderUri, token);
|
var responseString = await _httpClient.GetStringAsync(uri);
|
||||||
|
|
||||||
var response = JsonConvert.DeserializeObject<Order>(dataString);
|
var response = JsonConvert.DeserializeObject<Order>(responseString);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
async public Task<List<Order>> GetMyOrders(ApplicationUser user)
|
async public Task<List<Order>> GetMyOrders(ApplicationUser user)
|
||||||
{
|
{
|
||||||
var token = await GetUserTokenAsync();
|
var uri = API.Order.GetAllMyOrders(_remoteServiceBaseUrl);
|
||||||
var allMyOrdersUri = API.Order.GetAllMyOrders(_remoteServiceBaseUrl);
|
|
||||||
|
|
||||||
var dataString = await _apiClient.GetStringAsync(allMyOrdersUri, token);
|
var responseString = await _httpClient.GetStringAsync(uri);
|
||||||
var response = JsonConvert.DeserializeObject<List<Order>>(dataString);
|
|
||||||
|
var response = JsonConvert.DeserializeObject<List<Order>>(responseString);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Order MapUserInfoIntoOrder(ApplicationUser user, Order order)
|
|
||||||
{
|
|
||||||
order.City = user.City;
|
|
||||||
order.Street = user.Street;
|
|
||||||
order.State = user.State;
|
|
||||||
order.Country = user.Country;
|
|
||||||
order.ZipCode = user.ZipCode;
|
|
||||||
|
|
||||||
order.CardNumber = user.CardNumber;
|
|
||||||
order.CardHolderName = user.CardHolderName;
|
|
||||||
order.CardExpiration = new DateTime(int.Parse("20" + user.Expiration.Split('/')[1]), int.Parse(user.Expiration.Split('/')[0]), 1);
|
|
||||||
order.CardSecurityNumber = user.SecurityNumber;
|
|
||||||
|
|
||||||
return order;
|
|
||||||
}
|
|
||||||
|
|
||||||
async public Task CancelOrder(string orderId)
|
async public Task CancelOrder(string orderId)
|
||||||
{
|
{
|
||||||
var token = await GetUserTokenAsync();
|
|
||||||
var order = new OrderDTO()
|
var order = new OrderDTO()
|
||||||
{
|
{
|
||||||
OrderNumber = orderId
|
OrderNumber = orderId
|
||||||
};
|
};
|
||||||
|
|
||||||
var cancelOrderUri = API.Order.CancelOrder(_remoteServiceBaseUrl);
|
var uri = API.Order.CancelOrder(_remoteServiceBaseUrl);
|
||||||
|
var orderContent = new StringContent(JsonConvert.SerializeObject(order), System.Text.Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
var response = await _apiClient.PutAsync(cancelOrderUri, order, token, Guid.NewGuid().ToString());
|
var response = await _httpClient.PutAsync(uri, orderContent);
|
||||||
|
|
||||||
if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError)
|
if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError)
|
||||||
{
|
{
|
||||||
@ -88,15 +71,15 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
|||||||
|
|
||||||
async public Task ShipOrder(string orderId)
|
async public Task ShipOrder(string orderId)
|
||||||
{
|
{
|
||||||
var token = await GetUserTokenAsync();
|
|
||||||
var order = new OrderDTO()
|
var order = new OrderDTO()
|
||||||
{
|
{
|
||||||
OrderNumber = orderId
|
OrderNumber = orderId
|
||||||
};
|
};
|
||||||
|
|
||||||
var shipOrderUri = API.Order.ShipOrder(_remoteServiceBaseUrl);
|
var uri = API.Order.ShipOrder(_remoteServiceBaseUrl);
|
||||||
|
var orderContent = new StringContent(JsonConvert.SerializeObject(order), System.Text.Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
var response = await _apiClient.PutAsync(shipOrderUri, order, token, Guid.NewGuid().ToString());
|
var response = await _httpClient.PutAsync(uri, orderContent);
|
||||||
|
|
||||||
if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError)
|
if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError)
|
||||||
{
|
{
|
||||||
@ -120,6 +103,22 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
|||||||
destination.CardSecurityNumber = original.CardSecurityNumber;
|
destination.CardSecurityNumber = original.CardSecurityNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Order MapUserInfoIntoOrder(ApplicationUser user, Order order)
|
||||||
|
{
|
||||||
|
order.City = user.City;
|
||||||
|
order.Street = user.Street;
|
||||||
|
order.State = user.State;
|
||||||
|
order.Country = user.Country;
|
||||||
|
order.ZipCode = user.ZipCode;
|
||||||
|
|
||||||
|
order.CardNumber = user.CardNumber;
|
||||||
|
order.CardHolderName = user.CardHolderName;
|
||||||
|
order.CardExpiration = new DateTime(int.Parse("20" + user.Expiration.Split('/')[1]), int.Parse(user.Expiration.Split('/')[0]), 1);
|
||||||
|
order.CardSecurityNumber = user.SecurityNumber;
|
||||||
|
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
public BasketDTO MapOrderToBasket(Order order)
|
public BasketDTO MapOrderToBasket(Order order)
|
||||||
{
|
{
|
||||||
order.CardExpirationApiFormat();
|
order.CardExpirationApiFormat();
|
||||||
@ -140,18 +139,5 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
|||||||
RequestId = order.RequestId
|
RequestId = order.RequestId
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFakeIdToProducts(Order order)
|
|
||||||
{
|
|
||||||
var id = 1;
|
|
||||||
order.OrderItems.ForEach(x => { x.ProductId = id; id++; });
|
|
||||||
}
|
|
||||||
|
|
||||||
async Task<string> GetUserTokenAsync()
|
|
||||||
{
|
|
||||||
var context = _httpContextAccesor.HttpContext;
|
|
||||||
|
|
||||||
return await context.GetTokenAsync("access_token");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.Annotations
|
|||||||
DateTime d = new DateTime(year, month, 1);
|
DateTime d = new DateTime(year, month, 1);
|
||||||
|
|
||||||
return d > DateTime.UtcNow;
|
return d > DateTime.UtcNow;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,24 @@
|
|||||||
FROM microsoft/aspnetcore:2.0.5 AS base
|
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
FROM microsoft/aspnetcore-build:2.0.5-2.1.4 AS build
|
FROM microsoft/dotnet:2.1-sdk AS sdk-with-node
|
||||||
|
ENV NODE_VERSION 8.11.1
|
||||||
|
ENV NODE_DOWNLOAD_SHA 0e20787e2eda4cc31336d8327556ebc7417e8ee0a6ba0de96a09b0ec2b841f60
|
||||||
|
RUN curl -SL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz" --output nodejs.tar.gz \
|
||||||
|
&& echo "$NODE_DOWNLOAD_SHA nodejs.tar.gz" | sha256sum -c - \
|
||||||
|
&& tar -xzf "nodejs.tar.gz" -C /usr/local --strip-components=1 \
|
||||||
|
&& rm nodejs.tar.gz \
|
||||||
|
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs
|
||||||
|
|
||||||
|
FROM sdk-with-node AS updated-npm
|
||||||
|
RUN npm i -g npm
|
||||||
|
|
||||||
|
FROM updated-npm as build
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN dotnet restore -nowarn:msb3202,nu1503
|
|
||||||
WORKDIR /src/src/Web/WebSPA
|
WORKDIR /src/src/Web/WebSPA
|
||||||
|
RUN dotnet restore -nowarn:msb3202,nu1503
|
||||||
RUN dotnet build --no-restore -c Release -o /app
|
RUN dotnet build --no-restore -c Release -o /app
|
||||||
|
|
||||||
FROM build AS publish
|
FROM build AS publish
|
||||||
|
@ -2,8 +2,12 @@
|
|||||||
"iisSettings": {
|
"iisSettings": {
|
||||||
"windowsAuthentication": false,
|
"windowsAuthentication": false,
|
||||||
"anonymousAuthentication": true,
|
"anonymousAuthentication": true,
|
||||||
|
"iis": {
|
||||||
|
"applicationUrl": "http://localhost/WebSPA",
|
||||||
|
"sslPort": 0
|
||||||
|
},
|
||||||
"iisExpress": {
|
"iisExpress": {
|
||||||
"applicationUrl": "http://localhost:58018/",
|
"applicationUrl": "http://localhost:5104",
|
||||||
"sslPort": 0
|
"sslPort": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -11,8 +15,9 @@
|
|||||||
"IIS Express": {
|
"IIS Express": {
|
||||||
"commandName": "IISExpress",
|
"commandName": "IISExpress",
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Production"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
}
|
},
|
||||||
|
"use64Bit": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -90,7 +90,7 @@
|
|||||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta8" />
|
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta8" />
|
||||||
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.1.1" />
|
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.2" />
|
<PackageReference Include="Microsoft.AspNetCore.App" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection.Redis" Version="0.4.1" />
|
<PackageReference Include="Microsoft.AspNetCore.DataProtection.Redis" Version="0.4.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
FROM microsoft/aspnetcore:2.0.5 AS base
|
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
FROM microsoft/aspnetcore-build:2.0.5-2.1.4 AS build
|
FROM microsoft/dotnet:2.1-sdk AS build
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN dotnet restore -nowarn:msb3202,nu1503
|
|
||||||
WORKDIR /src/src/Web/WebStatus
|
WORKDIR /src/src/Web/WebStatus
|
||||||
|
RUN dotnet restore -nowarn:msb3202,nu1503
|
||||||
RUN dotnet build --no-restore -c Release -o /app
|
RUN dotnet build --no-restore -c Release -o /app
|
||||||
|
|
||||||
FROM build AS publish
|
FROM build AS publish
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"OrderingUrl": "http://localhost:5102/hc",
|
"OrderingUrl": "http://localhost:5102/hc",
|
||||||
|
"OrderingBackgroundTasksUrl": "http://localhost:5111/hc",
|
||||||
"BasketUrl": "http://localhost:5103/hc",
|
"BasketUrl": "http://localhost:5103/hc",
|
||||||
"CatalogUrl": "http://localhost:5101/hc",
|
"CatalogUrl": "http://localhost:5101/hc",
|
||||||
"IdentityUrl": "http://localhost:5105/hc",
|
"IdentityUrl": "http://localhost:5105/hc",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user