Skip to content

Commit 485bb9e

Browse files
committed
WIP
1 parent 586c6de commit 485bb9e

26 files changed

Lines changed: 535 additions & 17 deletions

docker-compose.override.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,5 +403,6 @@ services:
403403
- IdentityUrl=http://10.0.75.1:5105
404404
- CallBackUrl=http://localhost:5114
405405
- WebhooksUrl=http://webhooks.api
406+
- SelfUrl=http://webhooks.client/
406407
ports:
407408
- "5114:80"
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
7+
namespace Webhooks.API.IntegrationEvents
8+
{
9+
public class OrderStatusChangedToShippedIntegrationEvent : IntegrationEvent
10+
{
11+
public int OrderId { get; private set; }
12+
public string OrderStatus { get; private set; }
13+
public string BuyerName { get; private set; }
14+
15+
public OrderStatusChangedToShippedIntegrationEvent(int orderId, string orderStatus, string buyerName)
16+
{
17+
OrderId = orderId;
18+
OrderStatus = orderStatus;
19+
BuyerName = buyerName;
20+
}
21+
}
22+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
using Webhooks.API.Model;
7+
using Webhooks.API.Services;
8+
9+
namespace Webhooks.API.IntegrationEvents
10+
{
11+
public class OrderStatusChangedToShippedIntegrationEventHandler : IIntegrationEventHandler<OrderStatusChangedToShippedIntegrationEvent>
12+
{
13+
private readonly IWebhooksRetriever _retriever;
14+
private readonly IWebhooksSender _sender;
15+
public OrderStatusChangedToShippedIntegrationEventHandler(IWebhooksRetriever retriever, IWebhooksSender sender )
16+
{
17+
_retriever = retriever;
18+
_sender = sender;
19+
}
20+
21+
public async Task Handle(OrderStatusChangedToShippedIntegrationEvent @event)
22+
{
23+
var subscriptions = await _retriever.GetSubscriptionsOfType(WebhookType.OrderShipped);
24+
25+
var whook = new WebhookData(WebhookType.OrderShipped, @event);
26+
await _sender.SendAll(subscriptions, whook);
27+
}
28+
}
29+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using Newtonsoft.Json;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
7+
namespace Webhooks.API.Model
8+
{
9+
public class WebhookData
10+
{
11+
public DateTime When { get; }
12+
13+
public string Payload { get; }
14+
15+
public string Type { get; }
16+
17+
public WebhookData(WebhookType hookType, object data)
18+
{
19+
When = DateTime.UtcNow;
20+
Type = hookType.ToString();
21+
Payload = JsonConvert.SerializeObject(data);
22+
}
23+
24+
25+
}
26+
}

src/Services/Webhooks/Webhooks.API/Model/WebhookType.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace Webhooks.API.Model
77
{
88
public enum WebhookType
99
{
10-
CatalogItemPriceChange = 1
10+
CatalogItemPriceChange = 1,
11+
OrderShipped = 2
1112
}
1213
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using Webhooks.API.Model;
6+
7+
namespace Webhooks.API.Services
8+
{
9+
public interface IWebhooksRetriever
10+
{
11+
12+
Task<IEnumerable<WebhookSubscription>> GetSubscriptionsOfType(WebhookType type);
13+
}
14+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System.Collections.Generic;
2+
using System.Threading.Tasks;
3+
using Webhooks.API.Model;
4+
5+
namespace Webhooks.API.Services
6+
{
7+
public interface IWebhooksSender
8+
{
9+
Task SendAll(IEnumerable<WebhookSubscription> receivers, WebhookData data);
10+
}
11+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
using Webhooks.API.Infrastructure;
7+
using Webhooks.API.Model;
8+
9+
namespace Webhooks.API.Services
10+
{
11+
public class WebhooksRetriever : IWebhooksRetriever
12+
{
13+
private readonly WebhooksContext _db;
14+
public WebhooksRetriever(WebhooksContext db)
15+
{
16+
_db = db;
17+
}
18+
public async Task<IEnumerable<WebhookSubscription>> GetSubscriptionsOfType(WebhookType type)
19+
{
20+
var data = await _db.Subscriptions.Where(s => s.Type == type).ToListAsync();
21+
return data;
22+
}
23+
}
24+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using Microsoft.Extensions.Logging;
2+
using Newtonsoft.Json;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Net.Http;
7+
using System.Text;
8+
using System.Threading.Tasks;
9+
using Webhooks.API.Model;
10+
11+
namespace Webhooks.API.Services
12+
{
13+
public class WebhooksSender : IWebhooksSender
14+
{
15+
private readonly IHttpClientFactory _httpClientFactory;
16+
private readonly ILogger _logger;
17+
public WebhooksSender(IHttpClientFactory httpClientFactory, ILogger<WebhooksSender> logger)
18+
{
19+
_httpClientFactory = httpClientFactory;
20+
_logger = logger;
21+
}
22+
23+
public async Task SendAll(IEnumerable<WebhookSubscription> receivers, WebhookData data)
24+
{
25+
var client = _httpClientFactory.CreateClient();
26+
var json = JsonConvert.SerializeObject(data);
27+
var tasks = receivers.Select(r => OnSendData(r, json, client));
28+
await Task.WhenAll(tasks.ToArray());
29+
}
30+
31+
private Task OnSendData(WebhookSubscription subs, string jsonData, HttpClient client)
32+
{
33+
var request = new HttpRequestMessage()
34+
{
35+
RequestUri = new Uri(subs.DestUrl, UriKind.Absolute),
36+
Method = HttpMethod.Post,
37+
Content = new StringContent(jsonData, Encoding.UTF8, "application/json")
38+
};
39+
40+
if (!string.IsNullOrWhiteSpace(subs.Token))
41+
{
42+
request.Headers.Add("X-eshop-whtoken", subs.Token);
43+
}
44+
_logger.LogDebug($"Sending hook to {subs.DestUrl} of type {subs.Type.ToString()}");
45+
return client.SendAsync(request);
46+
}
47+
48+
}
49+
}

src/Services/Webhooks/Webhooks.API/Startup.cs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ public IServiceProvider ConfigureServices(IServiceCollection services)
6161
.AddCustomAuthentication(Configuration)
6262
.AddSingleton<IHttpContextAccessor, HttpContextAccessor>()
6363
.AddTransient<IIdentityService, IdentityService>()
64-
.AddTransient<IGrantUrlTesterService, GrantUrlTesterService>();
64+
.AddTransient<IGrantUrlTesterService, GrantUrlTesterService>()
65+
.AddTransient<IWebhooksRetriever, WebhooksRetriever>()
66+
.AddTransient<IWebhooksSender, WebhooksSender>();
6567

6668
var container = new ContainerBuilder();
6769
container.Populate(services);
@@ -125,6 +127,7 @@ protected virtual void ConfigureEventBus(IApplicationBuilder app)
125127
{
126128
var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
127129
eventBus.Subscribe<ProductPriceChangedIntegrationEvent, ProductPriceChangedIntegrationEventHandler>();
130+
eventBus.Subscribe<OrderStatusChangedToShippedIntegrationEvent, OrderStatusChangedToShippedIntegrationEventHandler>();
128131
}
129132
}
130133

@@ -287,19 +290,11 @@ public static IServiceCollection AddCustomHealthCheck(this IServiceCollection se
287290
public static IServiceCollection AddHttpClientServices(this IServiceCollection services, IConfiguration configuration)
288291
{
289292
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
290-
291-
292-
//register delegating handlers
293-
//services.AddTransient<HttpClientAuthorizationDelegatingHandler>();
294-
295-
//InfinteTimeSpan -> See: https://github.com/aspnet/HttpClientFactory/issues/194
296293
services.AddHttpClient("extendedhandlerlifetime").SetHandlerLifetime(Timeout.InfiniteTimeSpan);
297-
298294
//add http client services
299295
services.AddHttpClient("GrantClient")
300296
.SetHandlerLifetime(TimeSpan.FromMinutes(5));
301297
//.AddHttpMessageHandler<HttpClientAuthorizationDelegatingHandler>();
302-
303298
return services;
304299
}
305300

0 commit comments

Comments
 (0)