Browse Source

Add proto to catalog

features/migration-dotnet3
ericuss 5 years ago
parent
commit
67af71d2ce
8 changed files with 178 additions and 14 deletions
  1. +1
    -0
      docker-compose.override.yml
  2. +2
    -0
      src/ApiGateways/Web.Bff.Shopping/aggregator/Config/UrlsConfig.cs
  3. +31
    -5
      src/ApiGateways/Web.Bff.Shopping/aggregator/Services/CatalogService.cs
  4. +3
    -3
      src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderingService.cs
  5. +1
    -0
      src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.localhost.json
  6. +117
    -2
      src/Services/Catalog/Catalog.API/Grpc/CatalogService.cs
  7. +1
    -1
      src/Services/Catalog/Catalog.API/Program.cs
  8. +22
    -3
      src/Services/Catalog/Catalog.API/Proto/catalog.proto

+ 1
- 0
docker-compose.override.yml View File

@ -306,6 +306,7 @@ services:
- urls__orders=http://ordering.api
- urls__identity=http://identity.api
- urls__grpcBasket=http://10.0.75.1:5580
- urls__grpcCatalog=http://10.0.75.1:9101
- urls__grpcOrdering=http://10.0.75.1:5581
- CatalogUrlHC=http://catalog.api/hc
- OrderingUrlHC=http://ordering.api/hc


+ 2
- 0
src/ApiGateways/Web.Bff.Shopping/aggregator/Config/UrlsConfig.cs View File

@ -11,6 +11,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config
{
// grpc call under REST must go trough port 80
public static string GetItemById(int id) => $"/api/v1/catalog/items/{id}";
public static string GetItemById(string ids) => $"/api/v1/catalog/items/ids/{string.Join(',', ids)}";
// REST call standard must go through port 5000
public static string GetItemsById(IEnumerable<int> ids) => $":5000/api/v1/catalog/items?ids={string.Join(',', ids)}";
}
@ -30,6 +31,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config
public string Catalog { get; set; }
public string Orders { get; set; }
public string GrpcBasket { get; set; }
public string GrpcCatalog { get; set; }
public string GrpcOrdering { get; set; }
}
}

+ 31
- 5
src/ApiGateways/Web.Bff.Shopping/aggregator/Services/CatalogService.cs View File

@ -6,6 +6,11 @@ using Newtonsoft.Json;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using CatalogApi;
using Grpc.Net.Client;
using System;
using static CatalogApi.Catalog;
using System.Linq;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
{
@ -24,17 +29,38 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
public async Task<CatalogItem> GetCatalogItemAsync(int id)
{
var uri=_urls.Catalog + UrlsConfig.CatalogOperations.GetItemById(id);
var stringContent = await _httpClient.GetStringAsync(uri);
_httpClient.BaseAddress = new Uri(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemById(id));
return JsonConvert.DeserializeObject<CatalogItem>(stringContent);
var client = GrpcClient.Create<CatalogClient>(_httpClient);
var request = new CatalogItemRequest { Id = id };
var response = await client.GetItemByIdAsync(request);
return MapToCatalogItemResponse(response);
}
public async Task<IEnumerable<CatalogItem>> GetCatalogItemsAsync(IEnumerable<int> ids)
{
var stringContent = await _httpClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemsById(ids));
_httpClient.BaseAddress = new Uri(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemsById(ids));
var client = GrpcClient.Create<CatalogClient>(_httpClient);
var request = new CatalogItemsRequest { Ids = string.Join(",", ids), PageIndex = 1, PageSize = 10 };
var response = await client.GetItemsByIdsAsync(request);
return response.Data.Select(this.MapToCatalogItemResponse);
//var stringContent = await _httpClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemsById(ids));
//var catalogItems = JsonConvert.DeserializeObject<CatalogItem[]>(stringContent);
return JsonConvert.DeserializeObject<CatalogItem[]>(stringContent);
//return catalogItems;
}
private CatalogItem MapToCatalogItemResponse(CatalogItemResponse catalogItemResponse)
{
return new CatalogItem
{
Id = catalogItemResponse.Id,
Name = catalogItemResponse.Name,
PictureUri = catalogItemResponse.PictureUri,
Price = (decimal)catalogItemResponse.Price
};
}
}
}

+ 3
- 3
src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderingService.cs View File

@ -45,13 +45,12 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
try
{
var command = MapToOrderDraftCommand(basketData);
var response = await client.CreateOrderDraftFromBasketDataAsync(command);
_logger.LogDebug(" grpc response: {@response}", response);
return MapToResponse(response);
return MapToResponse(response, basketData);
}
catch (RpcException e)
{
@ -63,7 +62,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
return null;
}
private OrderData MapToResponse(GrpcOrdering.OrderDraftDTO orderDraft)
private OrderData MapToResponse(GrpcOrdering.OrderDraftDTO orderDraft, BasketData basketData)
{
if (orderDraft == null)
{
@ -72,6 +71,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
var data = new OrderData
{
Buyer = basketData.BuyerId,
Total = (decimal)orderDraft.Total,
};


+ 1
- 0
src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.localhost.json View File

@ -5,6 +5,7 @@
"orders": "http://localhost:55102",
"identity": "http://localhost:55105",
"grpcBasket": "http://localhost:5580",
"grpcCatalog": "http://localhost:81",
"grpcOrdering": "http://localhost:5581"
}
}

+ 117
- 2
src/Services/Catalog/Catalog.API/Grpc/CatalogService.cs View File

@ -8,6 +8,7 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.eShopOnContainers.Services.Catalog.API;
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
using Microsoft.eShopOnContainers.Services.Catalog.API.Model;
using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using static CatalogApi.Catalog;
@ -26,10 +27,10 @@ namespace Catalog.API.Grpc
_logger = logger;
}
public override async Task<CatalogItemResponse> GetItemById(CatalogItemRequest request, ServerCallContext context)
public override async Task<CatalogItemResponse> GetItemById(CatalogItemRequest request, ServerCallContext context)
{
_logger.LogInformation($"Begin grpc call CatalogService.GetItemById for product id {request.Id}");
if (request.Id <=0)
if (request.Id <= 0)
{
context.Status = new Status(StatusCode.FailedPrecondition, $"Id must be > 0 (received {request.Id})");
return null;
@ -60,5 +61,119 @@ namespace Catalog.API.Grpc
context.Status = new Status(StatusCode.NotFound, $"Product with id {request.Id} do not exist");
return null;
}
public override async Task<PaginatedItemsResponse> GetItemsByIds(CatalogItemsRequest request, ServerCallContext context)
{
if (!string.IsNullOrEmpty(request.Ids))
{
var items = await GetItemsByIdsAsync(request.Ids);
if (!items.Any())
{
context.Status = new Status(StatusCode.NotFound, $"ids value invalid. Must be comma-separated list of numbers");
}
context.Status = new Status(StatusCode.OK, string.Empty);
return this.MapToResponse(items);
}
var totalItems = await _catalogContext.CatalogItems
.LongCountAsync();
var itemsOnPage = await _catalogContext.CatalogItems
.OrderBy(c => c.Name)
.Skip(request.PageSize * request.PageIndex)
.Take(request.PageSize)
.ToListAsync();
/* The "awesome" fix for testing Devspaces */
/*
foreach (var pr in itemsOnPage) {
pr.Name = "Awesome " + pr.Name;
}
*/
itemsOnPage = ChangeUriPlaceholder(itemsOnPage);
var model = this.MapToResponse(itemsOnPage, totalItems, request.PageIndex, request.PageSize);
context.Status = new Status(StatusCode.OK, string.Empty);
return model;
}
private PaginatedItemsResponse MapToResponse(List<CatalogItem> items)
{
return this.MapToResponse(items, items.Count(), 1, items.Count());
}
private PaginatedItemsResponse MapToResponse(List<CatalogItem> items, long count, int pageIndex, int pageSize)
{
var result = new PaginatedItemsResponse()
{
Count = count,
PageIndex = pageIndex,
PageSize = pageSize,
};
items.ForEach(i => result.Data.Add(new CatalogItemResponse()
{
AvailableStock = i.AvailableStock,
Description = i.Description,
Id = i.Id,
MaxStockThreshold = i.MaxStockThreshold,
Name = i.Name,
OnReorder = i.OnReorder,
PictureFileName = i.PictureFileName,
PictureUri = i.PictureUri,
RestockThreshold = i.RestockThreshold,
CatalogBrand = new CatalogApi.CatalogBrand()
{
Id = i.CatalogBrand.Id,
Name = i.CatalogBrand.Brand,
},
CatalogType = new CatalogApi.CatalogType()
{
Id = i.CatalogType.Id,
Type = i.CatalogType.Type,
},
Price = (double)i.Price,
}));
return result;
}
private async Task<List<CatalogItem>> GetItemsByIdsAsync(string ids)
{
var numIds = ids.Split(',').Select(id => (Ok: int.TryParse(id, out int x), Value: x));
if (!numIds.All(nid => nid.Ok))
{
return new List<CatalogItem>();
}
var idsToSelect = numIds
.Select(id => id.Value);
var items = await _catalogContext.CatalogItems.Where(ci => idsToSelect.Contains(ci.Id)).ToListAsync();
items = ChangeUriPlaceholder(items);
return items;
}
private List<CatalogItem> ChangeUriPlaceholder(List<CatalogItem> items)
{
var baseUri = _settings.PicBaseUrl;
var azureStorageEnabled = _settings.AzureStorageEnabled;
foreach (var item in items)
{
item.FillProductUrl(baseUri, azureStorageEnabled: azureStorageEnabled);
}
return items;
}
}
}

+ 1
- 1
src/Services/Catalog/Catalog.API/Program.cs View File

@ -105,7 +105,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API
private static (int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config)
{
var grpcPort = config.GetValue("GRPC_PORT", 5001);
var grpcPort = config.GetValue("GRPC_PORT", 81);
var port = config.GetValue("PORT", 80);
return (port, grpcPort);
}


+ 22
- 3
src/Services/Catalog/Catalog.API/Proto/catalog.proto View File

@ -10,6 +10,11 @@ package CatalogApi;
message CatalogItemRequest {
int32 id = 1;
}
message CatalogItemsRequest {
string ids = 1;
int32 pageSize = 2;
int32 pageIndex = 3;
}
message CatalogItemResponse {
int32 id = 1;
@ -36,12 +41,26 @@ message CatalogType {
string type = 2;
}
message PaginatedItemsResponse {
int32 pageIndex = 1;
int32 pageSize = 2;
int64 count = 3;
repeated CatalogItemResponse data = 4;
}
service Catalog {
rpc GetItemById (CatalogItemRequest) returns (CatalogItemResponse) {
/* >>
/* >>
option (google.api.http) = {
get: "/api/v1/catalog/items/{id}"
};
<< */
}
<< */
}
rpc GetItemsByIds (CatalogItemsRequest) returns (PaginatedItemsResponse) {
/* >>
option (google.api.http) = {
get: "/api/v1/catalog/items/ids/{ids}"
};
<< */
}
}

Loading…
Cancel
Save