Newer
Older
InMemoryBus / src / ApplicationCore / CreateShippingLabel.cs
@Derek Comartin Derek Comartin on 17 Jan 2023 1 KB Init
using System;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
using Microsoft.eShopWeb.ApplicationCore.Services;
using Microsoft.eShopWeb.Events;
using Polly;

namespace Microsoft.eShopWeb;

public class CreateShippingLabel : INotificationHandler<OrderPlaced>
{
    private readonly IRepository<Order> _repository;
    private readonly FedexClient _fedexClient;

    public CreateShippingLabel(IRepository<Order> repository, FedexClient fedexClient)
    {
        _repository = repository;
        _fedexClient = fedexClient;
    }
    
    public async Task Handle(OrderPlaced notification, CancellationToken cancellationToken)
    {
        var order = await _repository.GetByIdAsync(notification.OrderId);
        if (order == null)
        {
            throw new InvalidOperationException("Order does not exist.");
        }
        
        var retryPolicy = Policy
            .Handle<InvalidOperationException>()
            .WaitAndRetry(new[]
            {
                TimeSpan.FromMilliseconds(100),
                TimeSpan.FromMilliseconds(200),
                TimeSpan.FromMilliseconds(500)
            });

        var shipment = retryPolicy.ExecuteAndCapture(() => _fedexClient.CreateShipment());
        if (shipment.Outcome == OutcomeType.Failure)
        {
            throw new InvalidOperationException("Could not create Fedex shipment");
        }
        
        order.Shipped(shipment.Result.TrackingNumber);
        
        await _repository.SaveChangesAsync();
    }
}