Skip to content

Commit

Permalink
Missing aggregator project
Browse files Browse the repository at this point in the history
  • Loading branch information
eiximenis committed Feb 27, 2018
1 parent 8cfb74f commit a18cec2
Show file tree
Hide file tree
Showing 34 changed files with 970 additions and 7 deletions.
13 changes: 12 additions & 1 deletion docker-compose.override.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ services:
- BasketApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5103
- OrderingApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5102
- MobileShoppingAggClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5120
- WebShoppingAggClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5121
- UseCustomizationData=True
- ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
- OrchestratorType=${ORCHESTRATOR_TYPE}
Expand Down Expand Up @@ -262,4 +263,14 @@ services:
- urls__orders=http://ordering.api
- urls__identity=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110.
ports:
- "5120:80"
- "5120:80"

webshoppingagg:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- urls__basket=http://basket.api
- urls__catalog=http://catalog.api
- urls__orders=http://ordering.api
- urls__identity=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110.
ports:
- "5121:80"
1 change: 1 addition & 0 deletions docker-compose.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ services:
- BasketApiClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5103
- OrderingApiClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5102
- MobileShoppingAggClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5120
- WebShoppingAggClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5120
- UseCustomizationData=True
- ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
- OrchestratorType=${ORCHESTRATOR_TYPE}
Expand Down
6 changes: 6 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,9 @@ services:
context: .
dockerfile: src/Aggregators/Mobile.Shopping.HttpAggregator/Dockerfile

webshoppingagg:
image: eshop/webshoppingagg
build:
context: .
dockerfile: src/Aggregators/Mobile.Shopping.HttpAggregator/Dockerfile

51 changes: 51 additions & 0 deletions eShopOnContainers-ServicesAndWebApps.sln
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Aggregators", "Aggregators"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mobile.Shopping.HttpAggregator", "src\Aggregators\Mobile.Shopping.HttpAggregator\Mobile.Shopping.HttpAggregator.csproj", "{6E99F232-1536-424F-A28C-91692C8FD325}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Web.Shopping.HttpAggregator", "src\Aggregators\Web.Shopping.HttpAggregator\Web.Shopping.HttpAggregator.csproj", "{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
Expand Down Expand Up @@ -1415,6 +1417,54 @@ Global
{6E99F232-1536-424F-A28C-91692C8FD325}.Release|x64.Build.0 = Release|Any CPU
{6E99F232-1536-424F-A28C-91692C8FD325}.Release|x86.ActiveCfg = Release|Any CPU
{6E99F232-1536-424F-A28C-91692C8FD325}.Release|x86.Build.0 = Release|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.AppStore|ARM.Build.0 = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.AppStore|iPhone.Build.0 = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.AppStore|x64.ActiveCfg = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.AppStore|x64.Build.0 = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.AppStore|x86.ActiveCfg = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.AppStore|x86.Build.0 = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Debug|ARM.ActiveCfg = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Debug|ARM.Build.0 = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Debug|iPhone.Build.0 = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Debug|x64.ActiveCfg = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Debug|x64.Build.0 = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Debug|x86.ActiveCfg = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Debug|x86.Build.0 = Debug|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Release|Any CPU.Build.0 = Release|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Release|ARM.ActiveCfg = Release|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Release|ARM.Build.0 = Release|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Release|iPhone.ActiveCfg = Release|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Release|iPhone.Build.0 = Release|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Release|x64.ActiveCfg = Release|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Release|x64.Build.0 = Release|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Release|x86.ActiveCfg = Release|Any CPU
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1465,6 +1515,7 @@ Global
{E0C5162E-DF26-4341-9E51-14AE800D7505} = {7A58AA20-67F3-48F3-88C8-24EBFE621792}
{EA378316-9D49-4A6B-858E-D4A25F948A74} = {932D8224-11F6-4D07-B109-DA28AD288A63}
{6E99F232-1536-424F-A28C-91692C8FD325} = {EA378316-9D49-4A6B-858E-D4A25F948A74}
{714CE0A1-E8BE-4CF1-8948-C1202E1526E2} = {EA378316-9D49-4A6B-858E-D4A25F948A74}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {25728519-5F0F-4973-8A64-0A81EB4EA8D9}
Expand Down
31 changes: 31 additions & 0 deletions src/Aggregators/Web.Shopping.HttpAggregator/Config/UrlsConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config
{
public class UrlsConfig
{
public class CatalogOperations
{
public static string GetItemById(int id) => $"/api/v1/catalog/items/{id}";
public static string GetItemsById(IEnumerable<int> ids) => $"/api/v1/catalog/items?ids={string.Join(',', ids)}";
}

public class BasketOperations
{
public static string GetItemById(string id) => $"/api/v1/basket/{id}";
public static string UpdateBasket() => "/api/v1/basket";
}

public class OrdersOperations
{
public static string GetOrderDraft() => "/api/v1/orders/draft";
}

public string Basket { get; set; }
public string Catalog { get; set; }
public string Orders { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
{
[Route("api/v1/[controller]")]
[Authorize]
public class BasketController : Controller
{
private readonly ICatalogService _catalog;
private readonly IBasketService _basket;
public BasketController(ICatalogService catalogService, IBasketService basketService)
{
_catalog = catalogService;
_basket = basketService;
}

[HttpPost]
[HttpPut]
public async Task<IActionResult> UpdateAllBasket([FromBody] UpdateBasketRequest data)
{

if (data.Items == null || !data.Items.Any())
{
return BadRequest("Need to pass at least one basket line");
}

// Retrieve the current basket
var currentBasket = await _basket.GetById(data.BuyerId);
if (currentBasket == null)
{
currentBasket = new BasketData(data.BuyerId);
}

var catalogItems = await _catalog.GetCatalogItems(data.Items.Select(x => x.ProductId));
var newBasket = new BasketData(data.BuyerId);

foreach (var bitem in data.Items)
{
var catalogItem = catalogItems.SingleOrDefault(ci => ci.Id == bitem.ProductId);
if (catalogItem == null)
{
return BadRequest($"Basket refers to a non-existing catalog item ({bitem.ProductId})");
}

newBasket.Items.Add(new BasketDataItem()
{
Id = bitem.Id,
ProductId = catalogItem.Id.ToString(),
ProductName = catalogItem.Name,
PictureUrl = catalogItem.PictureUri,
UnitPrice = catalogItem.Price,
Quantity = bitem.Quantity
});
}

await _basket.Update(newBasket);
return Ok(newBasket);
}

[HttpPut]
[Route("items")]
public async Task<IActionResult> UpdateQuantities([FromBody] UpdateBasketItemsRequest data)
{
if (!data.Updates.Any())
{
return BadRequest("No updates sent");
}

// Retrieve the current basket
var currentBasket = await _basket.GetById(data.BasketId);
if (currentBasket == null)
{
return BadRequest($"Basket with id {data.BasketId} not found.");
}

// Update with new quantities
foreach (var update in data.Updates)
{
var basketItem = currentBasket.Items.SingleOrDefault(bitem => bitem.Id == update.BasketItemId);
if (basketItem == null)
{
return BadRequest($"Basket item with id {update.BasketItemId} not found");
}
basketItem.Quantity = update.NewQty;
}

// Save the updated basket
await _basket.Update(currentBasket);
return Ok(currentBasket);
}

[HttpPost]
[Route("items")]
public async Task<IActionResult> AddBasketItem([FromBody] AddBasketItemRequest data)
{
if (data == null || data.Quantity == 0)
{
return BadRequest("Invalid payload");
}

// Step 1: Get the item from catalog
var item = await _catalog.GetCatalogItem(data.CatalogItemId);

//item.PictureUri =

// Step 2: Get current basket status
var currentBasket = (await _basket.GetById(data.BasketId)) ?? new BasketData(data.BasketId);
// Step 3: Merge current status with new product
currentBasket.Items.Add(new BasketDataItem()
{
UnitPrice = item.Price,
PictureUrl = item.PictureUri,
ProductId = item.Id.ToString(),
ProductName = item.Name,
Quantity = data.Quantity,
Id = Guid.NewGuid().ToString()
});

// Step 4: Update basket
await _basket.Update(currentBasket);


return Ok();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
{
[Route("")]
public class HomeController : Controller
{
[HttpGet()]
public IActionResult Index()
{
return new RedirectResult("~/swagger");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
{
[Route("api/v1/[controller]")]
[Authorize]
public class OrderController : Controller
{
private readonly IBasketService _basketService;
private readonly IOrderApiClient _orderClient;
public OrderController(IBasketService basketService, IOrderApiClient orderClient)
{
_basketService = basketService;
_orderClient = orderClient;
}

[Route("draft/{basketId}")]
[HttpGet]
public async Task<IActionResult> GetOrderDraft(string basketId)
{
if (string.IsNullOrEmpty(basketId))
{
return BadRequest("Need a valid basketid");
}
// Get the basket data and build a order draft based on it
var basket = await _basketService.GetById(basketId);
if (basket == null)
{
return BadRequest($"No basket found for id {basketId}");
}

var orderDraft = await _orderClient.GetOrderDraftFromBasket(basket);
return Ok(orderDraft);
}
}
}
18 changes: 18 additions & 0 deletions src/Aggregators/Web.Shopping.HttpAggregator/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM microsoft/aspnetcore:2.0.5 AS base
WORKDIR /app
EXPOSE 80

FROM microsoft/aspnetcore-build:2.0 AS build
WORKDIR /src
COPY . .
RUN dotnet restore -nowarn:msb3202,nu1503
WORKDIR /src/src/Aggregators/Web.Shopping.HttpAggregator
RUN dotnet build --no-restore -c Release -o /app

FROM build AS publish
RUN dotnet publish --no-restore -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Web.Shopping.HttpAggregator.dll"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Filters
{
using Microsoft.AspNetCore.Authorization;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Collections.Generic;
using System.Linq;

namespace Basket.API.Infrastructure.Filters
{
public class AuthorizeCheckOperationFilter : IOperationFilter
{
public void Apply(Operation operation, OperationFilterContext context)
{
// Check for authorize attribute
var hasAuthorize = context.ApiDescription.ControllerAttributes().OfType<AuthorizeAttribute>().Any() ||
context.ApiDescription.ActionAttributes().OfType<AuthorizeAttribute>().Any();

if (hasAuthorize)
{
operation.Responses.Add("401", new Response { Description = "Unauthorized" });
operation.Responses.Add("403", new Response { Description = "Forbidden" });

operation.Security = new List<IDictionary<string, IEnumerable<string>>>();
operation.Security.Add(new Dictionary<string, IEnumerable<string>>
{
{ "oauth2", new [] { "Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator" } }
});
}
}
}
}
}
Loading

0 comments on commit a18cec2

Please sign in to comment.