Browse Source

Merge pull request #75 from abpframework/gterdem/grpc_implementation

eShopOnAbp: Add gRPC endpoint to the catalog service
ipaddr
Halil İbrahim Kalkan 5 years ago
committed by GitHub
parent
commit
df3c078a02
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 27
      services/basket/src/EShopOnAbp.BasketService.Application/BasketProductService.cs
  2. 2
      services/basket/src/EShopOnAbp.BasketService.Application/BasketServiceApplicationAutoMapperProfile.cs
  3. 18
      services/basket/src/EShopOnAbp.BasketService.Application/BasketServiceApplicationModule.cs
  4. 10
      services/basket/src/EShopOnAbp.BasketService.Application/EShopOnAbp.BasketService.Application.csproj
  5. 3
      services/basket/src/EShopOnAbp.BasketService.HttpApi.Host/appsettings.json
  6. 12
      services/catalog/src/EShopOnAbp.CatalogService.Application.Contracts/EShopOnAbp.CatalogService.Application.Contracts.csproj
  7. 32
      services/catalog/src/EShopOnAbp.CatalogService.Application.Contracts/Protos/product.proto
  8. 2
      services/catalog/src/EShopOnAbp.CatalogService.Application/CatalogServiceApplicationAutoMapperProfile.cs
  9. 26
      services/catalog/src/EShopOnAbp.CatalogService.Application/Grpc/PublicProductGrpService.cs
  10. 12
      services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/CatalogServiceHttpApiHostModule.cs
  11. 4
      services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/EShopOnAbp.CatalogService.HttpApi.Host.csproj
  12. 4
      services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/Program.cs
  13. 12
      services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/appsettings.json
  14. 2
      shared/EShopOnAbp.Shared.Hosting.AspNetCore/ApplicationBuilderHelper.cs

27
services/basket/src/EShopOnAbp.BasketService.Application/BasketProductService.cs

@ -1,7 +1,10 @@
using System;
using System.Threading.Tasks;
using EShopOnAbp.CatalogService.Grpc;
using EShopOnAbp.CatalogService.Products;
using Microsoft.Extensions.Logging;
using Volo.Abp;
using Volo.Abp.ObjectMapping;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
@ -9,17 +12,23 @@ namespace EShopOnAbp.BasketService;
public class BasketProductService : IBasketProductService, ITransientDependency
{
private readonly IPublicProductAppService _productAppService;
private readonly IDistributedCache<ProductDto, Guid> _cache;
private readonly ILogger<BasketProductService> _logger;
private readonly IObjectMapper _mapper;
private readonly ProductPublic.ProductPublicClient _productPublicGrpcClient;
public BasketProductService(
IPublicProductAppService productAppService,
IDistributedCache<ProductDto, Guid> cache)
IDistributedCache<ProductDto, Guid> cache,
ILogger<BasketProductService> logger,
IObjectMapper mapper,
ProductPublic.ProductPublicClient productPublicGrpcClient)
{
_productAppService = productAppService;
_cache = cache;
_logger = logger;
_mapper = mapper;
_productPublicGrpcClient = productPublicGrpcClient;
}
public async Task<ProductDto> GetAsync(Guid productId)
{
return await _cache.GetOrAddAsync(
@ -28,9 +37,13 @@ public class BasketProductService : IBasketProductService, ITransientDependency
);
}
private Task<ProductDto> GetProductAsync(Guid productId)
private async Task<ProductDto> GetProductAsync(Guid productId)
{
return _productAppService.GetAsync(productId) ??
var request = new ProductRequest { Id = productId.ToString() };
_logger.LogInformation("=== GRPC request {@request}", request);
var response = await _productPublicGrpcClient.GetByIdAsync(request);
_logger.LogInformation("=== GRPC response {@response}", response);
return _mapper.Map<ProductResponse, ProductDto>(response) ??
throw new UserFriendlyException(BasketServiceDomainErrorCodes.ProductNotFound);
}
}

2
services/basket/src/EShopOnAbp.BasketService.Application/BasketServiceApplicationAutoMapperProfile.cs

@ -1,4 +1,5 @@
using AutoMapper;
using EShopOnAbp.CatalogService.Grpc;
using EShopOnAbp.CatalogService.Products;
namespace EShopOnAbp.BasketService
@ -8,6 +9,7 @@ namespace EShopOnAbp.BasketService
public BasketServiceApplicationAutoMapperProfile()
{
CreateMap<ProductEto, ProductDto>();
CreateMap<ProductResponse, ProductDto>();
}
}
}

18
services/basket/src/EShopOnAbp.BasketService.Application/BasketServiceApplicationModule.cs

@ -1,6 +1,12 @@
using EShopOnAbp.CatalogService;
using System;
using System.Collections.Generic;
using EShopOnAbp.CatalogService;
using EShopOnAbp.CatalogService.Grpc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Application;
using Volo.Abp.AutoMapper;
using Volo.Abp.Http.Client;
using Volo.Abp.Modularity;
namespace EShopOnAbp.BasketService
@ -16,10 +22,20 @@ namespace EShopOnAbp.BasketService
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<BasketServiceApplicationModule>();
});
context.Services.AddGrpcClient<ProductPublic.ProductPublicClient>((services, options) =>
{
var remoteServiceOptions = services.GetRequiredService<IOptionsMonitor<AbpRemoteServiceOptions>>().CurrentValue;
var catalogServiceConfiguration = remoteServiceOptions.RemoteServices.GetConfigurationOrDefault("Catalog");
var catalogGrpcUrl = catalogServiceConfiguration.GetOrDefault("GrpcUrl");
options.Address = new Uri(catalogGrpcUrl);
});
}
}
}

10
services/basket/src/EShopOnAbp.BasketService.Application/EShopOnAbp.BasketService.Application.csproj

@ -18,4 +18,14 @@
<PackageReference Include="Volo.Abp.Ddd.Application" Version="5.1.2" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.19.3" />
<PackageReference Include="Grpc.Net.ClientFactory" Version="2.42.0" />
<PackageReference Include="Grpc.Tools" Version="2.42.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="..\..\..\catalog\src\EShopOnAbp.CatalogService.Application.Contracts\Protos\product.proto" GrpcServices="Client" />
</ItemGroup>
</Project>

3
services/basket/src/EShopOnAbp.BasketService.HttpApi.Host/appsettings.json

@ -11,7 +11,8 @@
},
"RemoteServices": {
"Catalog": {
"BaseUrl": "https://localhost:44354/"
"BaseUrl": "https://localhost:44354/",
"GrpcUrl": "http://localhost:81"
}
},
"Logging": {

12
services/catalog/src/EShopOnAbp.CatalogService.Application.Contracts/EShopOnAbp.CatalogService.Application.Contracts.csproj

@ -16,4 +16,16 @@
<PackageReference Include="Volo.Abp.Authorization" Version="5.1.2" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.19.3" />
<PackageReference Include="Grpc.Core" Version="2.42.0" />
<PackageReference Include="Grpc.Tools" Version="2.42.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="Protos\product.proto" GrpcServices="Server" Generator="MSBuild:Compile" />
<Content Include="@(Protobuf)" />
<None Remove="@(Protobuf)" />
</ItemGroup>
</Project>

32
services/catalog/src/EShopOnAbp.CatalogService.Application.Contracts/Protos/product.proto

@ -0,0 +1,32 @@
syntax = "proto3";
/* >>
import "google/api/annotations.proto";
<< */
option csharp_namespace = "EShopOnAbp.CatalogService.Grpc";
package CatalogApi;
service ProductPublic {
rpc GetById(ProductRequest) returns (ProductResponse) {
/* >>
option (google.api.http) = {
get: "/api/catalog/product/{id}"
};
<< */
}
}
message ProductRequest {
string id = 1;
}
message ProductResponse {
string id = 1;
string code = 2;
string name = 3;
string imageName = 4;
float price = 5;
int32 stockCount = 6;
}

2
services/catalog/src/EShopOnAbp.CatalogService.Application/CatalogServiceApplicationAutoMapperProfile.cs

@ -1,4 +1,5 @@
using AutoMapper;
using EShopOnAbp.CatalogService.Grpc;
using EShopOnAbp.CatalogService.Products;
namespace EShopOnAbp.CatalogService
@ -8,6 +9,7 @@ namespace EShopOnAbp.CatalogService
public CatalogServiceApplicationAutoMapperProfile()
{
CreateMap<Product, ProductDto>();
CreateMap<Product, ProductResponse>();
}
}
}

26
services/catalog/src/EShopOnAbp.CatalogService.Application/Grpc/PublicProductGrpService.cs

@ -0,0 +1,26 @@
using System;
using System.Threading.Tasks;
using EShopOnAbp.CatalogService.Products;
using Grpc.Core;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.ObjectMapping;
namespace EShopOnAbp.CatalogService.Grpc;
public class PublicProductGrpService : ProductPublic.ProductPublicBase
{
private readonly IRepository<Product, Guid> _productRepository;
private readonly IObjectMapper _objectMapper;
public PublicProductGrpService(IRepository<Product, Guid> productRepository, IObjectMapper objectMapper)
{
_productRepository = productRepository;
_objectMapper = objectMapper;
}
public override async Task<ProductResponse> GetById(ProductRequest request, ServerCallContext context)
{
var product = await _productRepository.GetAsync(Guid.Parse(request.Id));
return _objectMapper.Map<Product, ProductResponse>(product);
}
}

12
services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/CatalogServiceHttpApiHostModule.cs

@ -7,9 +7,12 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using EShopOnAbp.CatalogService.Grpc;
using EShopOnAbp.CatalogService.MongoDB;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
@ -80,6 +83,10 @@ public class CatalogServiceHttpApiHostModule : AbpModule
});
Configure<AbpAntiForgeryOptions>(options => { options.AutoValidate = false; });
context.Services.AddGrpc(options =>
{
options.EnableDetailedErrors = true;
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
@ -111,7 +118,10 @@ public class CatalogServiceHttpApiHostModule : AbpModule
app.UseAbpSerilogEnrichers();
app.UseAuditing();
app.UseUnitOfWork();
app.UseConfiguredEndpoints();
app.UseConfiguredEndpoints(endpoints =>
{
endpoints.MapGrpcService<PublicProductGrpService>();
});
}
public override async Task OnPostApplicationInitializationAsync(ApplicationInitializationContext context)

4
services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/EShopOnAbp.CatalogService.HttpApi.Host.csproj

@ -18,6 +18,10 @@
<ItemGroup>
<ProjectReference Include="..\..\..\..\shared\EShopOnAbp.Shared.Hosting.Microservices\EShopOnAbp.Shared.Hosting.Microservices.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore.Server" Version="2.42.0" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Logs\**" />

4
services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/Program.cs

@ -17,8 +17,8 @@ public class Program
try
{
Log.Information($"Starting {assemblyName}.");
var app = await ApplicationBuilderHelper
.BuildApplicationAsync<CatalogServiceHttpApiHostModule>(args);
var app = await ApplicationBuilderHelper.BuildApplicationAsync<CatalogServiceHttpApiHostModule>(args);
await app.InitializeApplicationAsync();
await app.RunAsync();

12
services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/appsettings.json

@ -40,5 +40,17 @@
},
"ElasticSearch": {
"Url": "http://localhost:9200"
},
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "https://localhost:44354",
"Protocols": "Http1AndHttp2"
},
"gRPC": {
"Url": "http://localhost:81",
"Protocols": "Http2"
}
}
}
}

2
shared/EShopOnAbp.Shared.Hosting.AspNetCore/ApplicationBuilderHelper.cs

@ -1,5 +1,7 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;

Loading…
Cancel
Save