webhooks flow finished. Only missing bug in api that don't show the hooks

This commit is contained in:
eiximenis 2019-02-06 19:59:26 +01:00
parent 50a5f8b0b4
commit 5b237b0a8b
20 changed files with 144 additions and 59 deletions

View File

@ -14,7 +14,7 @@ services:
image: mongo
identity-api-test:
image: eshop/identity-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/identity-api-test:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Identity/Identity.API/Dockerfile
@ -22,7 +22,7 @@ services:
- sql-data-test
basket-api-test:
image: eshop/basket-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/basket-api-test:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Basket/Basket.API/Dockerfile
@ -35,7 +35,7 @@ services:
- ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests
basket-api-unit-test:
image: eshop/basket-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/basket-api-test:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Basket/Basket.API/Dockerfile
@ -48,7 +48,7 @@ services:
- ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests
catalog-api-test:
image: eshop/catalog-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/catalog-api-test:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Catalog/Catalog.API/Dockerfile
@ -60,7 +60,7 @@ services:
- ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests
catalog-api-unit-test:
image: eshop/catalog-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/catalog-api-test:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Catalog/Catalog.API/Dockerfile
@ -72,7 +72,7 @@ services:
- ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests
ordering-api-test:
image: eshop/ordering-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/ordering-api-test:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Ordering/Ordering.API/Dockerfile
@ -84,7 +84,7 @@ services:
- ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests
ordering-api-unit-test:
image: eshop/ordering-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/ordering-api-test:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Ordering/Ordering.API/Dockerfile
@ -96,7 +96,7 @@ services:
- ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests
marketing-api-test:
image: eshop/marketing-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/marketing-api-test:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Marketing/Marketing.API/Dockerfile
@ -110,7 +110,7 @@ services:
- ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests-results/}:/tests
payment-api-test:
image: eshop/payment-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/payment-api-test:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Payment/Payment.API/Dockerfile
@ -118,7 +118,7 @@ services:
- rabbitmq-test
locations-api-test:
image: eshop/locations-api-test:${TAG:-latest}
image: ${REGISTRY:-eshop}/locations-api-test:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Location/Locations.API/Dockerfile

View File

@ -14,7 +14,7 @@ services:
image: rabbitmq:3-management-alpine
identity.api:
image: eshop/identity.api:${TAG:-latest}
image: ${REGISTRY:-eshop}/identity.api:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Identity/Identity.API/Dockerfile
@ -22,7 +22,7 @@ services:
- sql.data
basket.api:
image: eshop/basket.api:${TAG:-latest}
image: ${REGISTRY:-eshop}/basket.api:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Basket/Basket.API/Dockerfile
@ -32,7 +32,7 @@ services:
- rabbitmq
catalog.api:
image: eshop/catalog.api:${TAG:-latest}
image: ${REGISTRY:-eshop}/catalog.api:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Catalog/Catalog.API/Dockerfile
@ -41,7 +41,7 @@ services:
- rabbitmq
ordering.api:
image: eshop/ordering.api:${TAG:-latest}
image: ${REGISTRY:-eshop}/ordering.api:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Ordering/Ordering.API/Dockerfile
@ -50,7 +50,7 @@ services:
- rabbitmq
ordering.backgroundtasks:
image: eshop/ordering.backgroundtasks:${TAG:-latest}
image: ${REGISTRY:-eshop}/ordering.backgroundtasks:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile
@ -59,7 +59,7 @@ services:
- rabbitmq
marketing.api:
image: eshop/marketing.api:${TAG:-latest}
image: ${REGISTRY:-eshop}/marketing.api:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Marketing/Marketing.API/Dockerfile
@ -70,7 +70,7 @@ services:
- rabbitmq
payment.api:
image: eshop/payment.api:${TAG:-latest}
image: ${REGISTRY:-eshop}/payment.api:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Payment/Payment.API/Dockerfile
@ -78,7 +78,7 @@ services:
- rabbitmq
locations.api:
image: eshop/locations.api:${TAG:-latest}
image: ${REGISTRY:-eshop}/locations.api:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Location/Locations.API/Dockerfile
@ -87,7 +87,7 @@ services:
- rabbitmq
webhooks.api:
image: eshop/webhooks.api:${TAG:-latest}
image: ${REGISTRY:-eshop}/webhooks.api:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Webhooks/Webhooks.API/Dockerfile
@ -95,7 +95,7 @@ services:
- sql.data
mobileshoppingapigw:
image: eshop/ocelotapigw:${TAG:-latest}
image: ${REGISTRY:-eshop}/ocelotapigw:${TAG:-latest}
build:
context: .
dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile
@ -110,7 +110,7 @@ services:
- basket.api
mobilemarketingapigw:
image: eshop/ocelotapigw:${TAG:-latest}
image: ${REGISTRY:-eshop}/ocelotapigw:${TAG:-latest}
build:
context: .
dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile
@ -125,7 +125,7 @@ services:
- basket.api
webshoppingapigw:
image: eshop/ocelotapigw:${TAG:-latest}
image: ${REGISTRY:-eshop}/ocelotapigw:${TAG:-latest}
build:
context: .
dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile
@ -140,7 +140,7 @@ services:
- basket.api
webmarketingapigw:
image: eshop/ocelotapigw:${TAG:-latest}
image: ${REGISTRY:-eshop}/ocelotapigw:${TAG:-latest}
build:
context: .
dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile
@ -155,7 +155,7 @@ services:
- basket.api
mobileshoppingagg:
image: eshop/mobileshoppingagg:${TAG:-latest}
image: ${REGISTRY:-eshop}/mobileshoppingagg:${TAG:-latest}
build:
context: .
dockerfile: src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile
@ -170,7 +170,7 @@ services:
- basket.api
webshoppingagg:
image: eshop/webshoppingagg:${TAG:-latest}
image: ${REGISTRY:-eshop}/webshoppingagg:${TAG:-latest}
build:
context: .
dockerfile: src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile
@ -185,7 +185,7 @@ services:
- basket.api
ordering.signalrhub:
image: eshop/ordering.signalrhub:${TAG:-latest}
image: ${REGISTRY:-eshop}/ordering.signalrhub:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Ordering/Ordering.SignalrHub/Dockerfile
@ -200,13 +200,13 @@ services:
- basket.api
webstatus:
image: eshop/webstatus:${TAG:-latest}
image: ${REGISTRY:-eshop}/webstatus:${TAG:-latest}
build:
context: .
dockerfile: src/Web/WebStatus/Dockerfile
webspa:
image: eshop/webspa:${TAG:-latest}
image: ${REGISTRY:-eshop}/webspa:${TAG:-latest}
build:
context: .
dockerfile: src/Web/WebSPA/Dockerfile
@ -216,7 +216,7 @@ services:
# - webmarketingapigw
webmvc:
image: eshop/webmvc:${TAG:-latest}
image: ${REGISTRY:-eshop}/webmvc:${TAG:-latest}
build:
context: .
dockerfile: src/Web/WebMVC/Dockerfile
@ -226,7 +226,7 @@ services:
- webmarketingapigw
webhooks.client:
image: eshop/webhooks.client:${TAG:-latest}
image: ${REGISTRY:-eshop}/webhooks.client:${TAG:-latest}
build:
context: .
dockerfile: src/Web/WebhookClient/Dockerfile

View File

@ -1,7 +1,7 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.app.svc.ordering }}
name: {{ .Values.app.svc.webhooks }}
labels:
app: {{ template "webhooks-api.name" . }}
chart: {{ template "webhooks-api.chart" . }}

View File

@ -3,7 +3,7 @@ clusterName: eshop-aks
pathBase: /webhooks-api
image:
repository: eshop/ordering.api
repository: eshop/webhooks.api
tag: latest
pullPolicy: IfNotPresent
@ -12,7 +12,7 @@ service:
port: 80
ingress:
enabled: false
enabled: true
annotations: {}
hosts:
- chart-example.local

View File

@ -1,6 +1,7 @@
{{- $name := include "webhooks-web.fullname" . -}}
{{- $identity := include "url-of" (list .Values.app.ingress.entries.identity .) -}}
{{- $webhooksweb := include "url-of" (list .Values.app.ingress.entries.webhooksweb .) -}}
{{- $webhooks := include "url-of" (list .Values.app.ingress.entries.webhooks .) -}}
apiVersion: v1
kind: ConfigMap
@ -12,7 +13,7 @@ metadata:
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
data:
urls__webhooks: Server={{ $sqlsrv }};Initial Catalog={{ .Values.inf.sql.webhooks.db }};User Id={{ .Values.inf.sql.common.user }};Password={{ .Values.inf.sql.common.pwd }};
urls__webhooks: http://{{ $webhooks }}
identity_e: http://{{ $identity }}
webhooksweb_e: http://{{ $webhooksweb }}
urls_webhooksweb: http://{{ .Values.app.svc.webhooksweb }}

View File

@ -1,7 +1,7 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.app.svc.ordering }}
name: {{ .Values.app.svc.webhooksweb }}
labels:
app: {{ template "webhooks-web.name" . }}
chart: {{ template "webhooks-web.chart" . }}

View File

@ -3,7 +3,7 @@ clusterName: eshop-aks
pathBase: /webhooks-web
image:
repository: eshop/webhooksweb
repository: eshop/webhooks.client
tag: latest
pullPolicy: IfNotPresent
@ -12,7 +12,7 @@ service:
port: 80
ingress:
enabled: false
enabled: true
annotations: {}
hosts:
- chart-example.local

View File

@ -6,7 +6,7 @@
<ItemGroup>
<PackageReference Include="Polly" Version="6.0.1" />
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0-preview3-35497" />
<PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>

View File

@ -274,7 +274,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API
services.AddTransient<Func<DbConnection, IIntegrationEventLogService>>(
sp => (DbConnection c) => new IntegrationEventLogService(c));
// services.AddTransient<ICatalogIntegrationEventService, CatalogIntegrationEventService>();
services.AddTransient<ICatalogIntegrationEventService, CatalogIntegrationEventService>();
if (configuration.GetValue<bool>("AzureServiceBusEnabled"))
{

View File

@ -0,0 +1,33 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Webhooks.API.IntegrationEvents
{
public class OrderStatusChangedToPaidIntegrationEvent : IntegrationEvent
{
public int OrderId { get; }
public IEnumerable<OrderStockItem> OrderStockItems { get; }
public OrderStatusChangedToPaidIntegrationEvent(int orderId,
IEnumerable<OrderStockItem> orderStockItems)
{
OrderId = orderId;
OrderStockItems = orderStockItems;
}
}
public class OrderStockItem
{
public int ProductId { get; }
public int Units { get; }
public OrderStockItem(int productId, int units)
{
ProductId = productId;
Units = units;
}
}
}

View File

@ -0,0 +1,32 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Webhooks.API.Model;
using Webhooks.API.Services;
using Microsoft.Extensions.Logging;
namespace Webhooks.API.IntegrationEvents
{
public class OrderStatusChangedToPaidIntegrationEventHandler : IIntegrationEventHandler<OrderStatusChangedToPaidIntegrationEvent>
{
private readonly IWebhooksRetriever _retriever;
private readonly IWebhooksSender _sender;
private readonly ILogger _logger;
public OrderStatusChangedToPaidIntegrationEventHandler(IWebhooksRetriever retriever, IWebhooksSender sender, ILogger<OrderStatusChangedToShippedIntegrationEventHandler> logger )
{
_retriever = retriever;
_sender = sender;
_logger = logger;
}
public async Task Handle(OrderStatusChangedToPaidIntegrationEvent @event)
{
var subscriptions = await _retriever.GetSubscriptionsOfType(WebhookType.OrderPaid);
_logger.LogInformation($"Received OrderStatusChangedToShippedIntegrationEvent and got {subscriptions.Count()} subscriptions to process");
var whook = new WebhookData(WebhookType.OrderPaid, @event);
await _sender.SendAll(subscriptions, whook);
}
}
}

View File

@ -5,6 +5,7 @@ using System.Linq;
using System.Threading.Tasks;
using Webhooks.API.Model;
using Webhooks.API.Services;
using Microsoft.Extensions.Logging;
namespace Webhooks.API.IntegrationEvents
{
@ -12,16 +13,18 @@ namespace Webhooks.API.IntegrationEvents
{
private readonly IWebhooksRetriever _retriever;
private readonly IWebhooksSender _sender;
public OrderStatusChangedToShippedIntegrationEventHandler(IWebhooksRetriever retriever, IWebhooksSender sender )
private readonly ILogger _logger;
public OrderStatusChangedToShippedIntegrationEventHandler(IWebhooksRetriever retriever, IWebhooksSender sender, ILogger<OrderStatusChangedToShippedIntegrationEventHandler> logger )
{
_retriever = retriever;
_sender = sender;
_logger = logger;
}
public async Task Handle(OrderStatusChangedToShippedIntegrationEvent @event)
{
var subscriptions = await _retriever.GetSubscriptionsOfType(WebhookType.OrderShipped);
_logger.LogInformation($"Received OrderStatusChangedToShippedIntegrationEvent and got {subscriptions.Count()} subscriptions to process");
var whook = new WebhookData(WebhookType.OrderShipped, @event);
await _sender.SendAll(subscriptions, whook);
}

View File

@ -8,6 +8,7 @@ namespace Webhooks.API.Model
public enum WebhookType
{
CatalogItemPriceChange = 1,
OrderShipped = 2
OrderShipped = 2,
OrderPaid = 3
}
}

View File

@ -128,6 +128,7 @@ namespace Webhooks.API
var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
eventBus.Subscribe<ProductPriceChangedIntegrationEvent, ProductPriceChangedIntegrationEventHandler>();
eventBus.Subscribe<OrderStatusChangedToShippedIntegrationEvent, OrderStatusChangedToShippedIntegrationEventHandler>();
eventBus.Subscribe<OrderStatusChangedToPaidIntegrationEvent, OrderStatusChangedToPaidIntegrationEventHandler>();
}
}
@ -264,9 +265,9 @@ namespace Webhooks.API
}
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
//services.AddTransient<OrderStatusChangedToAwaitingValidationIntegrationEventHandler>();
services.AddTransient<ProductPriceChangedIntegrationEventHandler>();
services.AddTransient<OrderStatusChangedToShippedIntegrationEventHandler>();
services.AddTransient<OrderStatusChangedToPaidIntegrationEventHandler>();
return services;
}
@ -303,8 +304,6 @@ namespace Webhooks.API
services.AddTransient<Func<DbConnection, IIntegrationEventLogService>>(
sp => (DbConnection c) => new IntegrationEventLogService(c));
// services.AddTransient<ICatalogIntegrationEventService, CatalogIntegrationEventService>();
if (configuration.GetValue<bool>("AzureServiceBusEnabled"))
{
services.AddSingleton<IServiceBusPersisterConnection>(sp =>

View File

@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
@ -15,28 +16,38 @@ namespace WebhookClient.Controllers
{
private readonly Settings _settings;
private readonly ILogger _logger;
public WebhooksReceivedController(IOptions<Settings> settings)
public WebhooksReceivedController(IOptions<Settings> settings, ILogger<WebhooksReceivedController> logger)
{
_settings = settings.Value;
_logger = logger;
}
[HttpPost]
public IActionResult NewWebhook(WebhookData hook)
{
var header = Request.Headers[HeaderNames.WebHookCheckHeader];
var token = header.FirstOrDefault();
_logger.LogInformation($"Received hook with token {token}. My token is {_settings.Token}. Token validation is set to {_settings.ValidateToken}");
if (!_settings.ValidateToken || _settings.Token == token)
{
_logger.LogInformation($"Received hook is processed");
var received = HttpContext.Session.Get<IEnumerable<WebHookReceived>>(SessionKeys.HooksKey)?.ToList() ?? new List<WebHookReceived>();
received.Add(new WebHookReceived()
var newHook = new WebHookReceived()
{
Data = hook.Payload,
When = hook.When,
Token = token
});
return Ok();
};
received.Add(newHook);
HttpContext.Session.Set<IEnumerable<WebHookReceived>>(SessionKeys.HooksKey, received);
return Ok(newHook);
}
_logger.LogInformation($"Received hook is NOT processed - Bad Request returned.");
return BadRequest();
}
}

View File

@ -7,10 +7,10 @@ namespace WebhookClient.Models
{
public class WebhookData
{
public DateTime When { get; }
public DateTime When { get; set; }
public string Payload { get; }
public string Payload { get; set; }
public string Type { get; }
public string Type { get; set; }
}
}

View File

@ -6,7 +6,7 @@
<h3>Register webhook</h3>
<p>This page registers the "OrderShipped" Webhook by sending a POST to webhooks.</p>
<p>This page registers the "OrderPaid" Webhook by sending a POST to webhooks.</p>
<form method="post">
<p>Token: <input type="text" asp-for="Token" /></p>

View File

@ -54,7 +54,7 @@ namespace WebhookClient.Pages
var payload = new WebhookSubscriptionRequest()
{
Event = "OrderShipped",
Event = "OrderPaid",
GrantUrl = granturl,
Url = url,
Token = Token

View File

@ -41,6 +41,13 @@ namespace WebhookClient
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var pathBase = Configuration["PATH_BASE"];
if (!string.IsNullOrEmpty(pathBase))
{
app.UsePathBase(pathBase);
}
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
@ -49,10 +56,8 @@ namespace WebhookClient
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseAuthentication();
app.UseHttpsRedirection();
app.Map("/check", capp =>
{
capp.Run(async (context) =>

View File

@ -1,7 +1,7 @@
{
"Logging": {
"LogLevel": {
"Default": "Warning"
"Default": "Information"
}
},
"AllowedHosts": "*"