Implementing the shipping info, and most of the rfid use case
This commit is contained in:
parent
07e2d6ef7e
commit
63cc274360
@ -7,7 +7,7 @@
|
|||||||
<DockerServiceName>webmvc</DockerServiceName>
|
<DockerServiceName>webmvc</DockerServiceName>
|
||||||
<DockerTargetOS>Linux</DockerTargetOS>
|
<DockerTargetOS>Linux</DockerTargetOS>
|
||||||
<ProjectVersion>2.1</ProjectVersion>
|
<ProjectVersion>2.1</ProjectVersion>
|
||||||
<DockerLaunchAction>LaunchBrowser</DockerLaunchAction>
|
<DockerLaunchAction>None</DockerLaunchAction>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include=".dockerignore" />
|
<None Include=".dockerignore" />
|
||||||
|
@ -34,5 +34,8 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events
|
|||||||
|
|
||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
public Boolean CheckForCustomisation { get; set; }
|
public Boolean CheckForCustomisation { get; set; }
|
||||||
|
|
||||||
|
/*[JsonProperty]
|
||||||
|
public String TenantId { get; set; }*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,14 @@ using RabbitMQ.Client;
|
|||||||
using RabbitMQ.Client.Events;
|
using RabbitMQ.Client.Events;
|
||||||
using RabbitMQ.Client.Exceptions;
|
using RabbitMQ.Client.Exceptions;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
||||||
{
|
{
|
||||||
@ -28,15 +32,20 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
|||||||
private readonly IEventBusSubscriptionsManager _subsManager;
|
private readonly IEventBusSubscriptionsManager _subsManager;
|
||||||
private readonly ILifetimeScope _autofac;
|
private readonly ILifetimeScope _autofac;
|
||||||
private readonly string AUTOFAC_SCOPE_NAME = "eshop_event_bus";
|
private readonly string AUTOFAC_SCOPE_NAME = "eshop_event_bus";
|
||||||
|
private static readonly String tenantACustomisationUrl = @"http://tenantacustomisation/";
|
||||||
|
private static readonly String tenantManagerUrl = @"http://tenantmanager/";
|
||||||
private readonly int _retryCount;
|
private readonly int _retryCount;
|
||||||
|
|
||||||
|
|
||||||
private IModel _consumerChannel;
|
private IModel _consumerChannel;
|
||||||
private string _queueName;
|
private string _queueName;
|
||||||
|
|
||||||
public EventBusRabbitMQ(IRabbitMQPersistentConnection persistentConnection, ILogger<EventBusRabbitMQ> logger,
|
public EventBusRabbitMQ(IRabbitMQPersistentConnection persistentConnection, ILogger<EventBusRabbitMQ> logger,
|
||||||
ILifetimeScope autofac, IEventBusSubscriptionsManager subsManager, string queueName = null, int retryCount = 5)
|
ILifetimeScope autofac, IEventBusSubscriptionsManager subsManager, string queueName = null,
|
||||||
|
int retryCount = 5)
|
||||||
{
|
{
|
||||||
_persistentConnection = persistentConnection ?? throw new ArgumentNullException(nameof(persistentConnection));
|
_persistentConnection =
|
||||||
|
persistentConnection ?? throw new ArgumentNullException(nameof(persistentConnection));
|
||||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||||
_subsManager = subsManager ?? new InMemoryEventBusSubscriptionsManager();
|
_subsManager = subsManager ?? new InMemoryEventBusSubscriptionsManager();
|
||||||
_queueName = queueName;
|
_queueName = queueName;
|
||||||
@ -76,18 +85,21 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
|||||||
|
|
||||||
var policy = RetryPolicy.Handle<BrokerUnreachableException>()
|
var policy = RetryPolicy.Handle<BrokerUnreachableException>()
|
||||||
.Or<SocketException>()
|
.Or<SocketException>()
|
||||||
.WaitAndRetry(_retryCount, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) =>
|
.WaitAndRetry(_retryCount, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
|
||||||
{
|
(ex, time) =>
|
||||||
_logger.LogWarning(ex, "Could not publish event: {EventId} after {Timeout}s ({ExceptionMessage})", @event.Id, $"{time.TotalSeconds:n1}", ex.Message);
|
{
|
||||||
});
|
_logger.LogWarning(ex,
|
||||||
|
"Could not publish event: {EventId} after {Timeout}s ({ExceptionMessage})", @event.Id,
|
||||||
|
$"{time.TotalSeconds:n1}", ex.Message);
|
||||||
|
});
|
||||||
|
|
||||||
var eventName = @event.GetType().Name;
|
var eventName = @event.GetType().Name;
|
||||||
|
|
||||||
_logger.LogWarning("Creating RabbitMQ channel to publish event: {EventId} ({EventName})", @event.Id, eventName);
|
_logger.LogWarning("Creating RabbitMQ channel to publish event: {EventId} ({EventName})", @event.Id,
|
||||||
|
eventName);
|
||||||
|
|
||||||
using (var channel = _persistentConnection.CreateModel())
|
using (var channel = _persistentConnection.CreateModel())
|
||||||
{
|
{
|
||||||
|
|
||||||
_logger.LogWarning("Declaring RabbitMQ exchange to publish event: {EventId}", @event.Id);
|
_logger.LogWarning("Declaring RabbitMQ exchange to publish event: {EventId}", @event.Id);
|
||||||
|
|
||||||
channel.ExchangeDeclare(exchange: BROKER_NAME, type: "direct");
|
channel.ExchangeDeclare(exchange: BROKER_NAME, type: "direct");
|
||||||
@ -115,7 +127,8 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
|||||||
public void SubscribeDynamic<TH>(string eventName)
|
public void SubscribeDynamic<TH>(string eventName)
|
||||||
where TH : IDynamicIntegrationEventHandler
|
where TH : IDynamicIntegrationEventHandler
|
||||||
{
|
{
|
||||||
_logger.LogInformation("Subscribing to dynamic event {EventName} with {EventHandler}", eventName, typeof(TH).GetGenericTypeName());
|
_logger.LogInformation("Subscribing to dynamic event {EventName} with {EventHandler}", eventName,
|
||||||
|
typeof(TH).GetGenericTypeName());
|
||||||
|
|
||||||
DoInternalSubscription(eventName);
|
DoInternalSubscription(eventName);
|
||||||
_subsManager.AddDynamicSubscription<TH>(eventName);
|
_subsManager.AddDynamicSubscription<TH>(eventName);
|
||||||
@ -129,7 +142,8 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
|||||||
var eventName = _subsManager.GetEventKey<T>();
|
var eventName = _subsManager.GetEventKey<T>();
|
||||||
DoInternalSubscription(eventName);
|
DoInternalSubscription(eventName);
|
||||||
|
|
||||||
_logger.LogInformation("Subscribing to event {EventName} with {EventHandler}", eventName, typeof(TH).GetGenericTypeName());
|
_logger.LogInformation("Subscribing to event {EventName} with {EventHandler}", eventName,
|
||||||
|
typeof(TH).GetGenericTypeName());
|
||||||
|
|
||||||
_subsManager.AddSubscription<T, TH>();
|
_subsManager.AddSubscription<T, TH>();
|
||||||
StartBasicConsume();
|
StartBasicConsume();
|
||||||
@ -148,8 +162,8 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
|||||||
using (var channel = _persistentConnection.CreateModel())
|
using (var channel = _persistentConnection.CreateModel())
|
||||||
{
|
{
|
||||||
channel.QueueBind(queue: _queueName,
|
channel.QueueBind(queue: _queueName,
|
||||||
exchange: BROKER_NAME,
|
exchange: BROKER_NAME,
|
||||||
routingKey: eventName);
|
routingKey: eventName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -239,13 +253,13 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
|||||||
var channel = _persistentConnection.CreateModel();
|
var channel = _persistentConnection.CreateModel();
|
||||||
|
|
||||||
channel.ExchangeDeclare(exchange: BROKER_NAME,
|
channel.ExchangeDeclare(exchange: BROKER_NAME,
|
||||||
type: "direct");
|
type: "direct");
|
||||||
|
|
||||||
channel.QueueDeclare(queue: _queueName,
|
channel.QueueDeclare(queue: _queueName,
|
||||||
durable: true,
|
durable: true,
|
||||||
exclusive: false,
|
exclusive: false,
|
||||||
autoDelete: false,
|
autoDelete: false,
|
||||||
arguments: null);
|
arguments: null);
|
||||||
|
|
||||||
channel.CallbackException += (sender, ea) =>
|
channel.CallbackException += (sender, ea) =>
|
||||||
{
|
{
|
||||||
@ -258,6 +272,60 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
|||||||
|
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void SendEventToTenant(Object @event)
|
||||||
|
{
|
||||||
|
string myJson = JsonConvert.SerializeObject(@event);
|
||||||
|
using (var client = new HttpClient())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//TODO replace URL with response from tenantmanager
|
||||||
|
var response = await client.PostAsync(
|
||||||
|
tenantACustomisationUrl + "api/OrderStatusChangedToSubmittedIntegrationEvents",
|
||||||
|
new StringContent(myJson, Encoding.UTF8, "application/json"));
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
_logger.LogInformation("----- Event sent to tenant{@event} -----", @event);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("----- Exception{@e} -- Event{@event} -----", e, @event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Boolean> IsEventCustomised(String eventName, String tenantId)
|
||||||
|
{
|
||||||
|
Boolean isCustomised = false;
|
||||||
|
|
||||||
|
var builder = new UriBuilder(tenantManagerUrl + "api/Customisations");
|
||||||
|
builder.Port = -1;
|
||||||
|
var query = HttpUtility.ParseQueryString(builder.Query);
|
||||||
|
query["eventName"] = eventName;
|
||||||
|
query["tenantId"] = tenantId;
|
||||||
|
builder.Query = query.ToString();
|
||||||
|
string url = builder.ToString();
|
||||||
|
|
||||||
|
using (var client = new HttpClient())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var response = await client.GetAsync(
|
||||||
|
url);
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
isCustomised =
|
||||||
|
JsonConvert.DeserializeObject<Boolean>(response.Content.ReadAsStringAsync().Result);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("----- Exception{@e}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return isCustomised;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task ProcessEvent(string eventName, string message)
|
private async Task ProcessEvent(string eventName, string message)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Processing RabbitMQ event: {EventName}", eventName);
|
_logger.LogWarning("Processing RabbitMQ event: {EventName}", eventName);
|
||||||
@ -271,7 +339,9 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
|||||||
{
|
{
|
||||||
if (subscription.IsDynamic)
|
if (subscription.IsDynamic)
|
||||||
{
|
{
|
||||||
var handler = scope.ResolveOptional(subscription.HandlerType) as IDynamicIntegrationEventHandler;
|
//TODO check if it is required here aswell
|
||||||
|
var handler =
|
||||||
|
scope.ResolveOptional(subscription.HandlerType) as IDynamicIntegrationEventHandler;
|
||||||
if (handler == null) continue;
|
if (handler == null) continue;
|
||||||
dynamic eventData = JObject.Parse(message);
|
dynamic eventData = JObject.Parse(message);
|
||||||
|
|
||||||
@ -281,17 +351,32 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var handler = scope.ResolveOptional(subscription.HandlerType);
|
var handler = scope.ResolveOptional(subscription.HandlerType);
|
||||||
if (eventName.Equals("OrderStatusChangedToSubmittedIntegrationEvent") || eventName.Equals("UserCheckoutAcceptedIntegrationEvent"))
|
|
||||||
{
|
|
||||||
Debug.WriteLine("Here");
|
|
||||||
}
|
|
||||||
if (handler == null) continue;
|
if (handler == null) continue;
|
||||||
var eventType = _subsManager.GetEventTypeByName(eventName);
|
var eventType = _subsManager.GetEventTypeByName(eventName);
|
||||||
var integrationEvent = JsonConvert.DeserializeObject(message, eventType);
|
var integrationEvent = JsonConvert.DeserializeObject(message, eventType);
|
||||||
|
//IsEventCustomised(eventName, integrationEvent.TenantId);
|
||||||
|
if (eventName.Equals("OrderStatusChangedToSubmittedIntegrationEvent") &&
|
||||||
|
integrationEvent is IntegrationEvent) //TODO replace with tenantmanager
|
||||||
|
{
|
||||||
|
//Casting
|
||||||
|
IntegrationEvent evt = (IntegrationEvent) integrationEvent;
|
||||||
|
//Checking if event should be sent to tenant, or handled normally
|
||||||
|
//Can instead create an endpoint in the tenant manager that also handles all the events that a tenant wants to postpone
|
||||||
|
//Additionally, an endpoint in the tenant manager is required, where the tenant
|
||||||
|
//Issue with the tenant knowing the id of the event
|
||||||
|
if (evt.CheckForCustomisation)
|
||||||
|
{
|
||||||
|
SendEventToTenant(integrationEvent);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var concreteType = typeof(IIntegrationEventHandler<>).MakeGenericType(eventType);
|
var concreteType = typeof(IIntegrationEventHandler<>).MakeGenericType(eventType);
|
||||||
|
|
||||||
await Task.Yield();
|
await Task.Yield();
|
||||||
await (Task)concreteType.GetMethod("Handle").Invoke(handler, new object[] { integrationEvent });
|
await (Task) concreteType.GetMethod("Handle")
|
||||||
|
.Invoke(handler, new object[] {integrationEvent});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -302,4 +387,4 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,133 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using TenantACustomisations.Database;
|
||||||
|
using TenantACustomisations.IntegrationEvents.Events;
|
||||||
|
|
||||||
|
namespace TenantACustomisations.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class OrderStatusChangedToSubmittedIntegrationEventsController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly TenantAContext _context;
|
||||||
|
private readonly IEventBus _eventBus;
|
||||||
|
private readonly ILogger<OrderStatusChangedToSubmittedIntegrationEventsController> _logger;
|
||||||
|
|
||||||
|
|
||||||
|
public OrderStatusChangedToSubmittedIntegrationEventsController(TenantAContext context, IEventBus eventBus, ILogger<OrderStatusChangedToSubmittedIntegrationEventsController> logger)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
_eventBus = eventBus;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/OrderStatusChangedToSubmittedIntegrationEvents
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<ActionResult<IEnumerable<OrderStatusChangedToSubmittedIntegrationEvent>>> GetOrderStatusChangedToSubmittedIntegrationEvent(String orderId)
|
||||||
|
{
|
||||||
|
if (String.IsNullOrEmpty(orderId))
|
||||||
|
{
|
||||||
|
return await _context.OrderStatusChangedToSubmittedIntegrationEvent.ToListAsync();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var orderStatusChangedToSubmittedIntegrationEvent = _context.OrderStatusChangedToSubmittedIntegrationEvent.Where(x => x.OrderId == Int32.Parse(orderId)).ToListAsync();
|
||||||
|
|
||||||
|
return await orderStatusChangedToSubmittedIntegrationEvent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/OrderStatusChangedToSubmittedIntegrationEvents/5
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
public async Task<ActionResult<OrderStatusChangedToSubmittedIntegrationEvent>> GetOrderStatusChangedToSubmittedIntegrationEvent(Guid id)
|
||||||
|
{
|
||||||
|
var orderStatusChangedToSubmittedIntegrationEvent = await _context.OrderStatusChangedToSubmittedIntegrationEvent.FindAsync(id);
|
||||||
|
|
||||||
|
if (orderStatusChangedToSubmittedIntegrationEvent == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
return orderStatusChangedToSubmittedIntegrationEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT: api/OrderStatusChangedToSubmittedIntegrationEvents/5
|
||||||
|
[HttpPut("{id}")]
|
||||||
|
public async Task<IActionResult> PutOrderStatusChangedToSubmittedIntegrationEvent(Guid id, OrderStatusChangedToSubmittedIntegrationEvent orderStatusChangedToSubmittedIntegrationEvent)
|
||||||
|
{
|
||||||
|
if (id != orderStatusChangedToSubmittedIntegrationEvent.Id)
|
||||||
|
{
|
||||||
|
return BadRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
_context.Entry(orderStatusChangedToSubmittedIntegrationEvent).State = EntityState.Modified;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
catch (DbUpdateConcurrencyException)
|
||||||
|
{
|
||||||
|
if (!OrderStatusChangedToSubmittedIntegrationEventExists(id))
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/OrderStatusChangedToSubmittedIntegrationEvents
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<ActionResult<OrderStatusChangedToSubmittedIntegrationEvent>> PostOrderStatusChangedToSubmittedIntegrationEvent(OrderStatusChangedToSubmittedIntegrationEvent orderStatusChangedToSubmittedIntegrationEvent)
|
||||||
|
{
|
||||||
|
_context.OrderStatusChangedToSubmittedIntegrationEvent.Add(orderStatusChangedToSubmittedIntegrationEvent);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
|
return CreatedAtAction("GetOrderStatusChangedToSubmittedIntegrationEvent", new { id = orderStatusChangedToSubmittedIntegrationEvent.Id }, orderStatusChangedToSubmittedIntegrationEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE: api/OrderStatusChangedToSubmittedIntegrationEvents/5
|
||||||
|
[HttpDelete("{id}")]
|
||||||
|
public async Task<ActionResult<OrderStatusChangedToSubmittedIntegrationEvent>> DeleteOrderStatusChangedToSubmittedIntegrationEvent(Guid id)
|
||||||
|
{
|
||||||
|
var orderStatusChangedToSubmittedIntegrationEvent = await _context.OrderStatusChangedToSubmittedIntegrationEvent.FindAsync(id);
|
||||||
|
if (orderStatusChangedToSubmittedIntegrationEvent == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_logger.LogInformation("----- Publishing integration event: {IntegrationEventId} from OrderStatusChangedToSubmittedIntegrationEventsController - ({@IntegrationEvent})", orderStatusChangedToSubmittedIntegrationEvent.Id, orderStatusChangedToSubmittedIntegrationEvent);
|
||||||
|
orderStatusChangedToSubmittedIntegrationEvent.CheckForCustomisation = false;
|
||||||
|
_eventBus.Publish(orderStatusChangedToSubmittedIntegrationEvent);
|
||||||
|
_context.OrderStatusChangedToSubmittedIntegrationEvent.Remove(orderStatusChangedToSubmittedIntegrationEvent);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
return orderStatusChangedToSubmittedIntegrationEvent;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "ERROR Publishing integration event: {IntegrationEventId} from OrderStatusChangedToSubmittedIntegrationEventsController", orderStatusChangedToSubmittedIntegrationEvent.Id);
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool OrderStatusChangedToSubmittedIntegrationEventExists(Guid id)
|
||||||
|
{
|
||||||
|
return _context.OrderStatusChangedToSubmittedIntegrationEvent.Any(e => e.Id == id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ using System.Threading.Tasks;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Design;
|
using Microsoft.EntityFrameworkCore.Design;
|
||||||
using TenantACustomisations.ExternalServices;
|
using TenantACustomisations.ExternalServices;
|
||||||
|
using TenantACustomisations.IntegrationEvents.Events;
|
||||||
|
|
||||||
namespace TenantACustomisations.Database
|
namespace TenantACustomisations.Database
|
||||||
{
|
{
|
||||||
@ -17,6 +18,12 @@ namespace TenantACustomisations.Database
|
|||||||
|
|
||||||
public DbSet<ShippingInformation> ShippingInformation { get; set; }
|
public DbSet<ShippingInformation> ShippingInformation { get; set; }
|
||||||
|
|
||||||
|
public DbSet<OrderStatusChangedToSubmittedIntegrationEvent> OrderStatusChangedToSubmittedIntegrationEvent
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
public class TenantAContextDesignFactory : IDesignTimeDbContextFactory<TenantAContext>
|
public class TenantAContextDesignFactory : IDesignTimeDbContextFactory<TenantAContext>
|
||||||
{
|
{
|
||||||
|
@ -8,9 +8,9 @@ namespace TenantACustomisations.IntegrationEvents.Events
|
|||||||
{
|
{
|
||||||
public class OrderStatusChangedToSubmittedIntegrationEvent : IntegrationEvent
|
public class OrderStatusChangedToSubmittedIntegrationEvent : IntegrationEvent
|
||||||
{
|
{
|
||||||
public int OrderId { get; }
|
public int OrderId { get; set; }
|
||||||
public string OrderStatus { get; }
|
public string OrderStatus { get; set; }
|
||||||
public string BuyerName { get; }
|
public string BuyerName { get; set; }
|
||||||
|
|
||||||
public OrderStatusChangedToSubmittedIntegrationEvent(int orderId, string orderStatus, string buyerName)
|
public OrderStatusChangedToSubmittedIntegrationEvent(int orderId, string orderStatus, string buyerName)
|
||||||
{
|
{
|
||||||
|
@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Microsoft.eShopOnContainers.WebMVC.Services;
|
using Microsoft.eShopOnContainers.WebMVC.Services;
|
||||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels.Customisation;
|
using Microsoft.eShopOnContainers.WebMVC.ViewModels.Customisation;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Polly.CircuitBreaker;
|
using Polly.CircuitBreaker;
|
||||||
using System;
|
using System;
|
||||||
@ -11,6 +12,7 @@ using System.Linq;
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
||||||
{
|
{
|
||||||
@ -20,18 +22,21 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
|||||||
private IOrderingService _orderSvc;
|
private IOrderingService _orderSvc;
|
||||||
private IBasketService _basketSvc;
|
private IBasketService _basketSvc;
|
||||||
private readonly IIdentityParser<ApplicationUser> _appUserParser;
|
private readonly IIdentityParser<ApplicationUser> _appUserParser;
|
||||||
private static String url = @"http://tenantacustomisation/";
|
private static String tenantACustomisationsUrl = @"http://tenantacustomisation/";
|
||||||
|
private readonly ILogger<OrderController> _logger;
|
||||||
|
|
||||||
public OrderController(IOrderingService orderSvc, IBasketService basketSvc, IIdentityParser<ApplicationUser> appUserParser)
|
|
||||||
|
public OrderController(IOrderingService orderSvc, IBasketService basketSvc,
|
||||||
|
IIdentityParser<ApplicationUser> appUserParser, ILogger<OrderController> logger)
|
||||||
{
|
{
|
||||||
_appUserParser = appUserParser;
|
_appUserParser = appUserParser;
|
||||||
_orderSvc = orderSvc;
|
_orderSvc = orderSvc;
|
||||||
_basketSvc = basketSvc;
|
_basketSvc = basketSvc;
|
||||||
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IActionResult> Create()
|
public async Task<IActionResult> Create()
|
||||||
{
|
{
|
||||||
|
|
||||||
var user = _appUserParser.Parse(HttpContext.User);
|
var user = _appUserParser.Parse(HttpContext.User);
|
||||||
var order = await _basketSvc.GetOrderDraft(user.Id);
|
var order = await _basketSvc.GetOrderDraft(user.Id);
|
||||||
var vm = _orderSvc.MapUserInfoIntoOrder(user, order);
|
var vm = _orderSvc.MapUserInfoIntoOrder(user, order);
|
||||||
@ -58,7 +63,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
|||||||
}
|
}
|
||||||
catch (BrokenCircuitException)
|
catch (BrokenCircuitException)
|
||||||
{
|
{
|
||||||
ModelState.AddModelError("Error", "It was not possible to create a new order, please try later on. (Business Msg Due to Circuit-Breaker)");
|
ModelState.AddModelError("Error",
|
||||||
|
"It was not possible to create a new order, please try later on. (Business Msg Due to Circuit-Breaker)");
|
||||||
}
|
}
|
||||||
|
|
||||||
return View("Create", model);
|
return View("Create", model);
|
||||||
@ -75,6 +81,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
|||||||
public async Task<IActionResult> Detail(string orderId)
|
public async Task<IActionResult> Detail(string orderId)
|
||||||
{
|
{
|
||||||
var user = _appUserParser.Parse(HttpContext.User);
|
var user = _appUserParser.Parse(HttpContext.User);
|
||||||
|
Boolean RFIDScanned = await AllGoodsRFIDScanned(orderId);
|
||||||
|
ViewData["RFIDScanned"] = RFIDScanned;
|
||||||
|
|
||||||
var order = await _orderSvc.GetOrder(user, orderId);
|
var order = await _orderSvc.GetOrder(user, orderId);
|
||||||
return View(order);
|
return View(order);
|
||||||
@ -85,34 +93,63 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
|||||||
var user = _appUserParser.Parse(HttpContext.User);
|
var user = _appUserParser.Parse(HttpContext.User);
|
||||||
var vm = await _orderSvc.GetMyOrders(user);
|
var vm = await _orderSvc.GetMyOrders(user);
|
||||||
List<ShippingInformation> shippingInformation = GetShippingInfo(vm);
|
List<ShippingInformation> shippingInformation = GetShippingInfo(vm);
|
||||||
|
_logger.LogInformation("----- Shipping info{@ShippingInformation}", shippingInformation);
|
||||||
|
|
||||||
ViewData["ShippingInfo"] = shippingInformation;
|
ViewData["ShippingInfo"] = shippingInformation;
|
||||||
return View(vm);
|
return View(vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async Task<Boolean> AllGoodsRFIDScanned(String orderId)
|
||||||
|
{
|
||||||
|
var builder = new UriBuilder(tenantACustomisationsUrl + "api/OrderStatusChangedToSubmittedIntegrationEvents");
|
||||||
|
builder.Port = -1;
|
||||||
|
var query = HttpUtility.ParseQueryString(builder.Query);
|
||||||
|
query["orderId"] = orderId;
|
||||||
|
builder.Query = query.ToString();
|
||||||
|
string url = builder.ToString();
|
||||||
|
|
||||||
|
using (var client = new HttpClient())
|
||||||
|
{
|
||||||
|
var response = await client.GetAsync(
|
||||||
|
url);
|
||||||
|
if (response.StatusCode.Equals(HttpStatusCode.NotFound))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private List<ShippingInformation> GetShippingInfo(List<Order> orders)
|
private List<ShippingInformation> GetShippingInfo(List<Order> orders)
|
||||||
{
|
{
|
||||||
List<ShippingInformation> shippingInformation = new List<ShippingInformation>();
|
List<ShippingInformation> shippingInformation = new List<ShippingInformation>();
|
||||||
using (var client = new HttpClient(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }))
|
using (var client = new HttpClient(new HttpClientHandler
|
||||||
|
{AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate}))
|
||||||
{
|
{
|
||||||
client.BaseAddress = new Uri(url);
|
client.BaseAddress = new Uri(tenantACustomisationsUrl);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HttpResponseMessage response = client.GetAsync("api/shippinginformation").Result;
|
HttpResponseMessage response = client.GetAsync("api/shippinginformations").Result;
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
string result = response.Content.ReadAsStringAsync().Result;
|
string result = response.Content.ReadAsStringAsync().Result;
|
||||||
List<ShippingInformation> results = JsonConvert.DeserializeObject<List<ShippingInformation>>(result);
|
_logger.LogInformation("----- Result{@result} -----", result);
|
||||||
results.ForEach( s =>
|
|
||||||
|
List<ShippingInformation>
|
||||||
|
results = JsonConvert.DeserializeObject<List<ShippingInformation>>(result);
|
||||||
|
results.ForEach(s =>
|
||||||
{
|
{
|
||||||
if(orders.Any(item => item.OrderNumber.Equals(s.OrderNumber)))
|
if (orders.Any(item => item.OrderNumber.Equals(s.OrderNumber)))
|
||||||
{
|
{
|
||||||
shippingInformation.Add(s);
|
shippingInformation.Add(s);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Console.WriteLine(e);
|
Console.WriteLine(e);
|
||||||
|
_logger.LogInformation("----- Exception{@e} -----", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,9 +3,12 @@
|
|||||||
@model Microsoft.eShopOnContainers.WebMVC.ViewModels.Order
|
@model Microsoft.eShopOnContainers.WebMVC.ViewModels.Order
|
||||||
|
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = "Order Detail";
|
ViewData["Title"] = "Order Detail";
|
||||||
var headerList= new List<Header>() {
|
var headerList = new List<Header>()
|
||||||
new Header() { Controller = "Catalog", Text = "Back to catalog" } };
|
{
|
||||||
|
new Header() {Controller = "Catalog", Text = "Back to catalog"}
|
||||||
|
};
|
||||||
|
var rfidScanned = ViewData["RFIDScanned"];
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="esh-orders_detail">
|
<div class="esh-orders_detail">
|
||||||
@ -14,20 +17,22 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<section class="esh-orders_detail-section">
|
<section class="esh-orders_detail-section">
|
||||||
<article class="esh-orders_detail-titles row">
|
<article class="esh-orders_detail-titles row">
|
||||||
<section class="esh-orders_detail-title col-3">Order number</section>
|
<section class="esh-orders_detail-title col-2">Order number</section>
|
||||||
<section class="esh-orders_detail-title col-3">Date</section>
|
<section class="esh-orders_detail-title col-2">Date</section>
|
||||||
<section class="esh-orders_detail-title col-3">Total</section>
|
<section class="esh-orders_detail-title col-2">Total</section>
|
||||||
<section class="esh-orders_detail-title col-3">Status</section>
|
<section class="esh-orders_detail-title col-2">Status</section>
|
||||||
|
<section class="esh-orders_detail-title col-2">RFID Scanned</section>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<article class="esh-orders_detail-items row">
|
<article class="esh-orders_detail-items row">
|
||||||
<section class="esh-orders_detail-item col-3">@Model.OrderNumber</section>
|
<section class="esh-orders_detail-item col-2">$@Model.Total</section>
|
||||||
<section class="esh-orders_detail-item col-3">@Model.Date</section>
|
<section class="esh-orders_detail-item col-2">@Model.OrderNumber</section>
|
||||||
<section class="esh-orders_detail-item col-3">$@Model.Total</section>
|
<section class="esh-orders_detail-item col-2">@Model.Date</section>
|
||||||
<section class="esh-orders_detail-title col-3">@Model.Status</section>
|
<section class="esh-orders_detail-title col-2">@Model.Status</section>
|
||||||
|
<section class="esh-orders_detail-title col-2">@rfidScanned</section>
|
||||||
</article>
|
</article>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="esh-orders_detail-section">
|
<section class="esh-orders_detail-section">
|
||||||
<article class="esh-orders_detail-titles row">
|
<article class="esh-orders_detail-titles row">
|
||||||
<section class="esh-orders_detail-title col-12">Description</section>
|
<section class="esh-orders_detail-title col-12">Description</section>
|
||||||
@ -88,4 +93,4 @@
|
|||||||
</article>
|
</article>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<article class="esh-orders-titles row">
|
<article class="esh-orders-titles row">
|
||||||
<section class="esh-orders-title col-2">Order number</section>
|
<section class="esh-orders-title col-1">Order number</section>
|
||||||
<section class="esh-orders-title col-2">Date</section>
|
<section class="esh-orders-title col-2">Date</section>
|
||||||
<section class="esh-orders-title col-1">Total</section>
|
<section class="esh-orders-title col-1">Total</section>
|
||||||
<section class="esh-orders-title col-1">Status</section>
|
<section class="esh-orders-title col-1">Status</section>
|
||||||
@ -32,26 +32,29 @@
|
|||||||
foreach (var item in Model)
|
foreach (var item in Model)
|
||||||
{
|
{
|
||||||
<article class="esh-orders-items row">
|
<article class="esh-orders-items row">
|
||||||
<section class="esh-orders-item col-2">@Html.DisplayFor(modelItem => item.OrderNumber)</section>
|
<section class="esh-orders-item col-1">@Html.DisplayFor(modelItem => item.OrderNumber)</section>
|
||||||
<section class="esh-orders-item col-2">@Html.DisplayFor(modelItem => item.Date)</section>
|
<section class="esh-orders-item col-2">@item.Date.ToShortDateString()</section>
|
||||||
<section class="esh-orders-item col-1">$ @Html.DisplayFor(modelItem => item.Total)</section>
|
<section class="esh-orders-item col-1">$ @Html.DisplayFor(modelItem => item.Total)</section>
|
||||||
<section class="esh-orders-item col-1">@Html.DisplayFor(modelItem => item.Status)</section>
|
<section class="esh-orders-item col-1">@Html.DisplayFor(modelItem => item.Status)</section>
|
||||||
<section class="esh-orders-item col-2">
|
<section class="esh-orders-item col-2">
|
||||||
@for (var i = 0; i < shippingInfo.Count(); i++)
|
@for (var i = 0; i < shippingInfo.Count(); i++)
|
||||||
{
|
{
|
||||||
var si = shippingInfo[i];
|
var si = shippingInfo[i];
|
||||||
if (si.OrderNumber.Equals(item.OrderNumber)){
|
if (si.OrderNumber.Equals(item.OrderNumber))
|
||||||
@si.ShippingTime
|
{
|
||||||
|
@si.ShippingTime.ToShortDateString();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</section>
|
</section>
|
||||||
<section class="esh-orders-item col-2">
|
<section class="esh-orders-item col-2">
|
||||||
@for (var i = 0; i < shippingInfo.Count(); i++)
|
@for (var i = 0; i < shippingInfo.Count(); i++)
|
||||||
{
|
{
|
||||||
var si = shippingInfo[i];
|
var si = shippingInfo[i];
|
||||||
if (si.OrderNumber.Equals(item.OrderNumber))
|
if (si.OrderNumber.Equals(item.OrderNumber))
|
||||||
{
|
{
|
||||||
@si.ArrivalTime
|
@si.ArrivalTime.ToShortDateString();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</section>
|
</section>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user