using System;
using System.Data.Common;
using System.Net.Http;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Billing.Contracts;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using NServiceBus;
using Sales.Contracts;
using Shipping.Contracts;
namespace Sales
{
public class PlaceOrderController : Controller
{
private readonly IMessageSession _messageSession;
public PlaceOrderController(IMessageSession messageSession)
{
_messageSession = messageSession;
}
[HttpPost("/sales/orders/{orderId:Guid}")]
public async Task<IActionResult> Action([FromRoute] Guid orderId)
{
await _messageSession.Send(new PlaceOrder
{
OrderId = orderId
});
return NoContent();
}
}
public class PlaceOrderHandler : IHandleMessages<PlaceOrder>
{
private readonly SalesDbContext _dbContext;
public PlaceOrderHandler(SalesDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task Handle(PlaceOrder message, IMessageHandlerContext context)
{
await _dbContext.Database.EnsureCreatedAsync();
await _dbContext.Orders.AddAsync(new Order
{
OrderId = message.OrderId,
Status = OrderStatus.Pending
});
await _dbContext.SaveChangesAsync();
var orderPlaced = new OrderPlaced
{
OrderId = message.OrderId
};
await context.Publish(orderPlaced);
}
}
public class PlaceOrderSagaData : ContainSagaData
{
public Guid OrderId { get; set; }
}
public class PlaceOrderSaga :
Saga<PlaceOrderSagaData>,
IAmStartedByMessages<OrderPlaced>,
IHandleMessages<OrderBilled>,
IHandleMessages<ShippingLabelCreated>
{
protected override void ConfigureHowToFindSaga(SagaPropertyMapper<PlaceOrderSagaData> mapper)
{
mapper.MapSaga(saga => saga.OrderId)
.ToMessage<OrderPlaced>(msg => msg.OrderId)
.ToMessage<OrderBilled>(msg => msg.OrderId)
.ToMessage<ShippingLabelCreated>(msg => msg.OrderId);
}
public async Task Handle(OrderPlaced message, IMessageHandlerContext context)
{
await context.Send(new BillOrder
{
OrderId = message.OrderId
});
}
public async Task Handle(OrderBilled message, IMessageHandlerContext context)
{
await context.Send(new CreateShippingLabel
{
OrderId = message.OrderId
});
}
public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context)
{
await context.Send(new ReadyToShipOrder
{
OrderId = Data.OrderId
});
MarkAsComplete();
}
}
}