# Conflicts: # eShopOnContainers-ServicesAndWebApps.slnpull/627/head
@ -0,0 +1,11 @@ | |||
{ | |||
"requires": true, | |||
"lockfileVersion": 1, | |||
"dependencies": { | |||
"@aspnet/signalr": { | |||
"version": "1.0.0-preview1-update1", | |||
"resolved": "https://registry.npmjs.org/@aspnet/signalr/-/signalr-1.0.0-preview1-update1.tgz", | |||
"integrity": "sha512-TGFCoLa2svN37Ew5ue0kGFxbkmQzq2I9N5TMLFBWRrpTYF4txlE3yPX0EaPt/NToKBaK1A+VK8Q+1MGSYtnqUw==" | |||
} | |||
} | |||
} |
@ -0,0 +1,46 @@ | |||
using MediatR; | |||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; | |||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; | |||
using Microsoft.Extensions.Logging; | |||
using Ordering.API.Application.IntegrationEvents; | |||
using Ordering.API.Application.IntegrationEvents.Events; | |||
using Ordering.Domain.Events; | |||
using System; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
namespace Ordering.API.Application.DomainEventHandlers.OrderCancelled | |||
{ | |||
public class OrderCancelledDomainEventHandler | |||
: INotificationHandler<OrderCancelledDomainEvent> | |||
{ | |||
private readonly IOrderRepository _orderRepository; | |||
private readonly IBuyerRepository _buyerRepository; | |||
private readonly ILoggerFactory _logger; | |||
private readonly IOrderingIntegrationEventService _orderingIntegrationEventService; | |||
public OrderCancelledDomainEventHandler( | |||
IOrderRepository orderRepository, | |||
ILoggerFactory logger, | |||
IBuyerRepository buyerRepository, | |||
IOrderingIntegrationEventService orderingIntegrationEventService) | |||
{ | |||
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository)); | |||
_logger = logger ?? throw new ArgumentNullException(nameof(logger)); | |||
_buyerRepository = buyerRepository ?? throw new ArgumentNullException(nameof(buyerRepository)); | |||
} | |||
public async Task Handle(OrderCancelledDomainEvent orderCancelledDomainEvent, CancellationToken cancellationToken) | |||
{ | |||
_logger.CreateLogger(nameof(OrderCancelledDomainEvent)) | |||
.LogTrace($"Order with Id: {orderCancelledDomainEvent.Order.Id} has been successfully updated with " + | |||
$"a status order id: {OrderStatus.Shipped.Id}"); | |||
var order = await _orderRepository.GetAsync(orderCancelledDomainEvent.Order.Id); | |||
var buyer = await _buyerRepository.FindByIdAsync(order.GetBuyerId.Value.ToString()); | |||
var orderStatusChangedToCancelledIntegrationEvent = new OrderStatusChangedToCancelledIntegrationEvent(order.Id, order.OrderStatus.Name, buyer.Name); | |||
await _orderingIntegrationEventService.PublishThroughEventBusAsync(orderStatusChangedToCancelledIntegrationEvent); | |||
} | |||
} | |||
} |
@ -0,0 +1,47 @@ | |||
using MediatR; | |||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; | |||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; | |||
using Microsoft.Extensions.Logging; | |||
using Ordering.API.Application.IntegrationEvents; | |||
using Ordering.API.Application.IntegrationEvents.Events; | |||
using Ordering.Domain.Events; | |||
using System; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
namespace Ordering.API.Application.DomainEventHandlers.OrderShipped | |||
{ | |||
public class OrderShippedDomainEventHandler | |||
: INotificationHandler<OrderShippedDomainEvent> | |||
{ | |||
private readonly IOrderRepository _orderRepository; | |||
private readonly IBuyerRepository _buyerRepository; | |||
private readonly IOrderingIntegrationEventService _orderingIntegrationEventService; | |||
private readonly ILoggerFactory _logger; | |||
public OrderShippedDomainEventHandler( | |||
IOrderRepository orderRepository, | |||
ILoggerFactory logger, | |||
IBuyerRepository buyerRepository, | |||
IOrderingIntegrationEventService orderingIntegrationEventService) | |||
{ | |||
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository)); | |||
_logger = logger ?? throw new ArgumentNullException(nameof(logger)); | |||
_buyerRepository = buyerRepository ?? throw new ArgumentNullException(nameof(buyerRepository)); | |||
_orderingIntegrationEventService = orderingIntegrationEventService; | |||
} | |||
public async Task Handle(OrderShippedDomainEvent orderShippedDomainEvent, CancellationToken cancellationToken) | |||
{ | |||
_logger.CreateLogger(nameof(OrderShippedDomainEvent)) | |||
.LogTrace($"Order with Id: {orderShippedDomainEvent.Order.Id} has been successfully updated with " + | |||
$"a status order id: {OrderStatus.Shipped.Id}"); | |||
var order = await _orderRepository.GetAsync(orderShippedDomainEvent.Order.Id); | |||
var buyer = await _buyerRepository.FindByIdAsync(order.GetBuyerId.Value.ToString()); | |||
var orderStatusChangedToShippedIntegrationEvent = new OrderStatusChangedToShippedIntegrationEvent(order.Id, order.OrderStatus.Name, buyer.Name); | |||
await _orderingIntegrationEventService.PublishThroughEventBusAsync(orderStatusChangedToShippedIntegrationEvent); | |||
} | |||
} | |||
} |
@ -0,0 +1,22 @@ | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
namespace Ordering.API.Application.IntegrationEvents.Events | |||
{ | |||
public class OrderStatusChangedToCancelledIntegrationEvent : IntegrationEvent | |||
{ | |||
public int OrderId { get; } | |||
public string OrderStatus { get; } | |||
public string BuyerName { get; } | |||
public OrderStatusChangedToCancelledIntegrationEvent(int orderId, string orderStatus, string buyerName) | |||
{ | |||
OrderId = orderId; | |||
OrderStatus = orderStatus; | |||
BuyerName = buyerName; | |||
} | |||
} | |||
} |
@ -0,0 +1,22 @@ | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
namespace Ordering.API.Application.IntegrationEvents.Events | |||
{ | |||
public class OrderStatusChangedToShippedIntegrationEvent : IntegrationEvent | |||
{ | |||
public int OrderId { get; } | |||
public string OrderStatus { get; } | |||
public string BuyerName { get; } | |||
public OrderStatusChangedToShippedIntegrationEvent(int orderId, string orderStatus, string buyerName) | |||
{ | |||
OrderId = orderId; | |||
OrderStatus = orderStatus; | |||
BuyerName = buyerName; | |||
} | |||
} | |||
} |
@ -0,0 +1,22 @@ | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
namespace Ordering.API.Application.IntegrationEvents.Events | |||
{ | |||
public class OrderStatusChangedToSubmittedIntegrationEvent : IntegrationEvent | |||
{ | |||
public int OrderId { get; } | |||
public string OrderStatus { get; } | |||
public string BuyerName { get; } | |||
public OrderStatusChangedToSubmittedIntegrationEvent(int orderId, string orderStatus, string buyerName) | |||
{ | |||
OrderId = orderId; | |||
OrderStatus = orderStatus; | |||
BuyerName = buyerName; | |||
} | |||
} | |||
} |
@ -0,0 +1,238 @@ | |||
// <auto-generated /> | |||
using Microsoft.EntityFrameworkCore; | |||
using Microsoft.EntityFrameworkCore.Infrastructure; | |||
using Microsoft.EntityFrameworkCore.Metadata; | |||
using Microsoft.EntityFrameworkCore.Migrations; | |||
using Microsoft.EntityFrameworkCore.Storage; | |||
using Microsoft.EntityFrameworkCore.Storage.Internal; | |||
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; | |||
using System; | |||
namespace Ordering.API.Infrastructure.Migrations | |||
{ | |||
[DbContext(typeof(OrderingContext))] | |||
[Migration("20180412143935_NamePropertyInBuyer")] | |||
partial class NamePropertyInBuyer | |||
{ | |||
protected override void BuildTargetModel(ModelBuilder modelBuilder) | |||
{ | |||
#pragma warning disable 612, 618 | |||
modelBuilder | |||
.HasAnnotation("ProductVersion", "2.0.1-rtm-125") | |||
.HasAnnotation("Relational:Sequence:.orderitemseq", "'orderitemseq', '', '1', '10', '', '', 'Int64', 'False'") | |||
.HasAnnotation("Relational:Sequence:ordering.buyerseq", "'buyerseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") | |||
.HasAnnotation("Relational:Sequence:ordering.orderseq", "'orderseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") | |||
.HasAnnotation("Relational:Sequence:ordering.paymentseq", "'paymentseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") | |||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); | |||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer", b => | |||
{ | |||
b.Property<int>("Id") | |||
.ValueGeneratedOnAdd() | |||
.HasAnnotation("SqlServer:HiLoSequenceName", "buyerseq") | |||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering") | |||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); | |||
b.Property<string>("IdentityGuid") | |||
.IsRequired() | |||
.HasMaxLength(200); | |||
b.Property<string>("Name"); | |||
b.HasKey("Id"); | |||
b.HasIndex("IdentityGuid") | |||
.IsUnique(); | |||
b.ToTable("buyers","ordering"); | |||
}); | |||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.CardType", b => | |||
{ | |||
b.Property<int>("Id") | |||
.HasDefaultValue(1); | |||
b.Property<string>("Name") | |||
.IsRequired() | |||
.HasMaxLength(200); | |||
b.HasKey("Id"); | |||
b.ToTable("cardtypes","ordering"); | |||
}); | |||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod", b => | |||
{ | |||
b.Property<int>("Id") | |||
.ValueGeneratedOnAdd() | |||
.HasAnnotation("SqlServer:HiLoSequenceName", "paymentseq") | |||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering") | |||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); | |||
b.Property<string>("Alias") | |||
.IsRequired() | |||
.HasMaxLength(200); | |||
b.Property<int>("BuyerId"); | |||
b.Property<string>("CardHolderName") | |||
.IsRequired() | |||
.HasMaxLength(200); | |||
b.Property<string>("CardNumber") | |||
.IsRequired() | |||
.HasMaxLength(25); | |||
b.Property<int>("CardTypeId"); | |||
b.Property<DateTime>("Expiration"); | |||
b.HasKey("Id"); | |||
b.HasIndex("BuyerId"); | |||
b.HasIndex("CardTypeId"); | |||
b.ToTable("paymentmethods","ordering"); | |||
}); | |||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b => | |||
{ | |||
b.Property<int>("Id") | |||
.ValueGeneratedOnAdd() | |||
.HasAnnotation("SqlServer:HiLoSequenceName", "orderseq") | |||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering") | |||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); | |||
b.Property<int?>("BuyerId"); | |||
b.Property<string>("Description"); | |||
b.Property<DateTime>("OrderDate"); | |||
b.Property<int>("OrderStatusId"); | |||
b.Property<int?>("PaymentMethodId"); | |||
b.HasKey("Id"); | |||
b.HasIndex("BuyerId"); | |||
b.HasIndex("OrderStatusId"); | |||
b.HasIndex("PaymentMethodId"); | |||
b.ToTable("orders","ordering"); | |||
}); | |||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b => | |||
{ | |||
b.Property<int>("Id") | |||
.ValueGeneratedOnAdd() | |||
.HasAnnotation("SqlServer:HiLoSequenceName", "orderitemseq") | |||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); | |||
b.Property<decimal>("Discount"); | |||
b.Property<int>("OrderId"); | |||
b.Property<string>("PictureUrl"); | |||
b.Property<int>("ProductId"); | |||
b.Property<string>("ProductName") | |||
.IsRequired(); | |||
b.Property<decimal>("UnitPrice"); | |||
b.Property<int>("Units"); | |||
b.HasKey("Id"); | |||
b.HasIndex("OrderId"); | |||
b.ToTable("orderItems","ordering"); | |||
}); | |||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", b => | |||
{ | |||
b.Property<int>("Id") | |||
.HasDefaultValue(1); | |||
b.Property<string>("Name") | |||
.IsRequired() | |||
.HasMaxLength(200); | |||
b.HasKey("Id"); | |||
b.ToTable("orderstatus","ordering"); | |||
}); | |||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency.ClientRequest", b => | |||
{ | |||
b.Property<Guid>("Id") | |||
.ValueGeneratedOnAdd(); | |||
b.Property<string>("Name") | |||
.IsRequired(); | |||
b.Property<DateTime>("Time"); | |||
b.HasKey("Id"); | |||
b.ToTable("requests","ordering"); | |||
}); | |||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod", b => | |||
{ | |||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer") | |||
.WithMany("PaymentMethods") | |||
.HasForeignKey("BuyerId") | |||
.OnDelete(DeleteBehavior.Cascade); | |||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.CardType", "CardType") | |||
.WithMany() | |||
.HasForeignKey("CardTypeId") | |||
.OnDelete(DeleteBehavior.Cascade); | |||
}); | |||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b => | |||
{ | |||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer") | |||
.WithMany() | |||
.HasForeignKey("BuyerId"); | |||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", "OrderStatus") | |||
.WithMany() | |||
.HasForeignKey("OrderStatusId") | |||
.OnDelete(DeleteBehavior.Cascade); | |||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod") | |||
.WithMany() | |||
.HasForeignKey("PaymentMethodId") | |||
.OnDelete(DeleteBehavior.Restrict); | |||
b.OwnsOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", "Address", b1 => | |||
{ | |||
b1.Property<int>("OrderId"); | |||
b1.ToTable("orders","ordering"); | |||
b1.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order") | |||
.WithOne("Address") | |||
.HasForeignKey("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", "OrderId") | |||
.OnDelete(DeleteBehavior.Cascade); | |||
}); | |||
}); | |||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b => | |||
{ | |||
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order") | |||
.WithMany("OrderItems") | |||
.HasForeignKey("OrderId") | |||
.OnDelete(DeleteBehavior.Cascade); | |||
}); | |||
#pragma warning restore 612, 618 | |||
} | |||
} | |||
} |
@ -0,0 +1,86 @@ | |||
using Microsoft.EntityFrameworkCore.Migrations; | |||
using System; | |||
using System.Collections.Generic; | |||
namespace Ordering.API.Infrastructure.Migrations | |||
{ | |||
public partial class NamePropertyInBuyer : Migration | |||
{ | |||
protected override void Up(MigrationBuilder migrationBuilder) | |||
{ | |||
migrationBuilder.DropForeignKey( | |||
name: "FK_orderItems_orders_OrderId", | |||
schema: "ordering", | |||
table: "orderItems"); | |||
migrationBuilder.AddColumn<string>( | |||
name: "Name", | |||
schema: "ordering", | |||
table: "buyers", | |||
nullable: true); | |||
migrationBuilder.AddForeignKey( | |||
name: "FK_orderItems_orders_OrderId", | |||
schema: "ordering", | |||
table: "orderItems", | |||
column: "OrderId", | |||
principalSchema: "ordering", | |||
principalTable: "orders", | |||
principalColumn: "Id", | |||
onDelete: ReferentialAction.Cascade); | |||
} | |||
protected override void Down(MigrationBuilder migrationBuilder) | |||
{ | |||
migrationBuilder.DropForeignKey( | |||
name: "FK_orderItems_orders_OrderId", | |||
schema: "ordering", | |||
table: "orderItems"); | |||
migrationBuilder.DropColumn( | |||
name: "Name", | |||
schema: "ordering", | |||
table: "buyers"); | |||
migrationBuilder.AddColumn<string>( | |||
name: "City", | |||
schema: "ordering", | |||
table: "orders", | |||
nullable: true); | |||
migrationBuilder.AddColumn<string>( | |||
name: "Country", | |||
schema: "ordering", | |||
table: "orders", | |||
nullable: true); | |||
migrationBuilder.AddColumn<string>( | |||
name: "State", | |||
schema: "ordering", | |||
table: "orders", | |||
nullable: true); | |||
migrationBuilder.AddColumn<string>( | |||
name: "Street", | |||
schema: "ordering", | |||
table: "orders", | |||
nullable: true); | |||
migrationBuilder.AddColumn<string>( | |||
name: "ZipCode", | |||
schema: "ordering", | |||
table: "orders", | |||
nullable: true); | |||
migrationBuilder.AddForeignKey( | |||
name: "FK_orderItems_orders_OrderId", | |||
schema: "ordering", | |||
table: "orderItems", | |||
column: "OrderId", | |||
principalSchema: "ordering", | |||
principalTable: "orders", | |||
principalColumn: "Id", | |||
onDelete: ReferentialAction.Cascade); | |||
} | |||
} | |||
} |
@ -0,0 +1,18 @@ | |||
using MediatR; | |||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace Ordering.Domain.Events | |||
{ | |||
public class OrderCancelledDomainEvent : INotification | |||
{ | |||
public Order Order { get; } | |||
public OrderCancelledDomainEvent(Order order) | |||
{ | |||
Order = order; | |||
} | |||
} | |||
} |
@ -0,0 +1,15 @@ | |||
using MediatR; | |||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; | |||
namespace Ordering.Domain.Events | |||
{ | |||
public class OrderShippedDomainEvent : INotification | |||
{ | |||
public Order Order { get; } | |||
public OrderShippedDomainEvent(Order order) | |||
{ | |||
Order = order; | |||
} | |||
} | |||
} |
@ -0,0 +1,30 @@ | |||
using Autofac; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | |||
using Ordering.SignalrHub.IntegrationEvents; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Reflection; | |||
using System.Threading.Tasks; | |||
namespace Ordering.SignalrHub.AutofacModules | |||
{ | |||
public class ApplicationModule | |||
: Autofac.Module | |||
{ | |||
public string QueriesConnectionString { get; } | |||
public ApplicationModule() | |||
{ | |||
} | |||
protected override void Load(ContainerBuilder builder) | |||
{ | |||
builder.RegisterAssemblyTypes(typeof(OrderStatusChangedToAwaitingValidationIntegrationEvent).GetTypeInfo().Assembly) | |||
.AsClosedTypesOf(typeof(IIntegrationEventHandler<>)); | |||
} | |||
} | |||
} |
@ -0,0 +1,20 @@ | |||
FROM microsoft/aspnetcore:2.0 AS base | |||
WORKDIR /app | |||
EXPOSE 80 | |||
FROM microsoft/aspnetcore-build:2.0 AS build | |||
WORKDIR /src | |||
COPY eShopOnContainers-ServicesAndWebApps.sln ./ | |||
COPY src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj src/Services/Ordering/Ordering.SignalrHub/ | |||
RUN dotnet restore -nowarn:msb3202,nu1503 | |||
COPY . . | |||
WORKDIR /src/src/Services/Ordering/Ordering.SignalrHub | |||
RUN dotnet build Ordering.SignalrHub.csproj -c Release -o /app | |||
FROM build AS publish | |||
RUN dotnet publish Ordering.SignalrHub.csproj -c Release -o /app | |||
FROM base AS final | |||
WORKDIR /app | |||
COPY --from=publish /app . | |||
ENTRYPOINT ["dotnet", "Ordering.SignalrHub.dll"] |
@ -0,0 +1,28 @@ | |||
using Microsoft.AspNetCore.SignalR; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | |||
using Ordering.SignalrHub.IntegrationEvents.Events; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
namespace Ordering.SignalrHub.IntegrationEvents.EventHandling | |||
{ | |||
public class OrderStatusChangedToCancelledIntegrationEventHandler : IIntegrationEventHandler<OrderStatusChangedToCancelledIntegrationEvent> | |||
{ | |||
private readonly IHubContext<NotificationsHub> _hubContext; | |||
public OrderStatusChangedToCancelledIntegrationEventHandler(IHubContext<NotificationsHub> hubContext) | |||
{ | |||
_hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext)); | |||
} | |||
public async Task Handle(OrderStatusChangedToCancelledIntegrationEvent @event) | |||
{ | |||
await _hubContext.Clients | |||
.Group(@event.BuyerName) | |||
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus }); | |||
} | |||
} | |||
} |
@ -0,0 +1,26 @@ | |||
using Microsoft.AspNetCore.SignalR; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | |||
using Ordering.SignalrHub.IntegrationEvents.Events; | |||
using System; | |||
using System.Threading.Tasks; | |||
namespace Ordering.SignalrHub.IntegrationEvents.EventHandling | |||
{ | |||
public class OrderStatusChangedToPaidIntegrationEventHandler : IIntegrationEventHandler<OrderStatusChangedToPaidIntegrationEvent> | |||
{ | |||
private readonly IHubContext<NotificationsHub> _hubContext; | |||
public OrderStatusChangedToPaidIntegrationEventHandler(IHubContext<NotificationsHub> hubContext) | |||
{ | |||
_hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext)); | |||
} | |||
public async Task Handle(OrderStatusChangedToPaidIntegrationEvent @event) | |||
{ | |||
await _hubContext.Clients | |||
.Group(@event.BuyerName) | |||
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus }); | |||
} | |||
} | |||
} |
@ -0,0 +1,28 @@ | |||
using Microsoft.AspNetCore.SignalR; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | |||
using Ordering.SignalrHub.IntegrationEvents.Events; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
namespace Ordering.SignalrHub.IntegrationEvents.EventHandling | |||
{ | |||
public class OrderStatusChangedToShippedIntegrationEventHandler : IIntegrationEventHandler<OrderStatusChangedToShippedIntegrationEvent> | |||
{ | |||
private readonly IHubContext<NotificationsHub> _hubContext; | |||
public OrderStatusChangedToShippedIntegrationEventHandler(IHubContext<NotificationsHub> hubContext) | |||
{ | |||
_hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext)); | |||
} | |||
public async Task Handle(OrderStatusChangedToShippedIntegrationEvent @event) | |||
{ | |||
await _hubContext.Clients | |||
.Group(@event.BuyerName) | |||
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus }); | |||
} | |||
} | |||
} |
@ -0,0 +1,29 @@ | |||
using Microsoft.AspNetCore.SignalR; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | |||
using Ordering.SignalrHub.IntegrationEvents.Events; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
namespace Ordering.SignalrHub.IntegrationEvents.EventHandling | |||
{ | |||
public class OrderStatusChangedToStockConfirmedIntegrationEventHandler : | |||
IIntegrationEventHandler<OrderStatusChangedToStockConfirmedIntegrationEvent> | |||
{ | |||
private readonly IHubContext<NotificationsHub> _hubContext; | |||
public OrderStatusChangedToStockConfirmedIntegrationEventHandler(IHubContext<NotificationsHub> hubContext) | |||
{ | |||
_hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext)); | |||
} | |||
public async Task Handle(OrderStatusChangedToStockConfirmedIntegrationEvent @event) | |||
{ | |||
await _hubContext.Clients | |||
.Group(@event.BuyerName) | |||
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus }); | |||
} | |||
} | |||
} |
@ -0,0 +1,29 @@ | |||
using Microsoft.AspNetCore.SignalR; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | |||
using Ordering.SignalrHub.IntegrationEvents.Events; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
namespace Ordering.SignalrHub.IntegrationEvents.EventHandling | |||
{ | |||
public class OrderStatusChangedToSubmittedIntegrationEventHandler : | |||
IIntegrationEventHandler<OrderStatusChangedToSubmittedIntegrationEvent> | |||
{ | |||
private readonly IHubContext<NotificationsHub> _hubContext; | |||
public OrderStatusChangedToSubmittedIntegrationEventHandler(IHubContext<NotificationsHub> hubContext) | |||
{ | |||
_hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext)); | |||
} | |||
public async Task Handle(OrderStatusChangedToSubmittedIntegrationEvent @event) | |||
{ | |||
await _hubContext.Clients | |||
.Group(@event.BuyerName) | |||
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus }); | |||
} | |||
} | |||
} |
@ -0,0 +1,27 @@ | |||
using Microsoft.AspNetCore.SignalR; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
namespace Ordering.SignalrHub.IntegrationEvents | |||
{ | |||
public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler : IIntegrationEventHandler<OrderStatusChangedToAwaitingValidationIntegrationEvent> | |||
{ | |||
private readonly IHubContext<NotificationsHub> _hubContext; | |||
public OrderStatusChangedToAwaitingValidationIntegrationEventHandler(IHubContext<NotificationsHub> hubContext) | |||
{ | |||
_hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext)); | |||
} | |||
public async Task Handle(OrderStatusChangedToAwaitingValidationIntegrationEvent @event) | |||
{ | |||
await _hubContext.Clients | |||
.Group(@event.BuyerName) | |||
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus }); | |||
} | |||
} | |||
} |
@ -0,0 +1,19 @@ | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; | |||
using System.Collections.Generic; | |||
namespace Ordering.SignalrHub.IntegrationEvents | |||
{ | |||
public class OrderStatusChangedToAwaitingValidationIntegrationEvent : IntegrationEvent | |||
{ | |||
public int OrderId { get; } | |||
public string OrderStatus { get; } | |||
public string BuyerName { get; } | |||
public OrderStatusChangedToAwaitingValidationIntegrationEvent(int orderId, string orderStatus, string buyerName) | |||
{ | |||
OrderId = orderId; | |||
OrderStatus = orderStatus; | |||
BuyerName = buyerName; | |||
} | |||
} | |||
} |
@ -0,0 +1,22 @@ | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
namespace Ordering.SignalrHub.IntegrationEvents.Events | |||
{ | |||
public class OrderStatusChangedToCancelledIntegrationEvent : IntegrationEvent | |||
{ | |||
public int OrderId { get; } | |||
public string OrderStatus { get; } | |||
public string BuyerName { get; } | |||
public OrderStatusChangedToCancelledIntegrationEvent(int orderId, string orderStatus, string buyerName) | |||
{ | |||
OrderId = orderId; | |||
OrderStatus = orderStatus; | |||
BuyerName = buyerName; | |||
} | |||
} | |||
} |
@ -0,0 +1,23 @@ | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
namespace Ordering.SignalrHub.IntegrationEvents.Events | |||
{ | |||
public class OrderStatusChangedToPaidIntegrationEvent : IntegrationEvent | |||
{ | |||
public int OrderId { get; } | |||
public string OrderStatus { get; } | |||
public string BuyerName { get; } | |||
public OrderStatusChangedToPaidIntegrationEvent(int orderId, | |||
string orderStatus, string buyerName) | |||
{ | |||
OrderId = orderId; | |||
OrderStatus = orderStatus; | |||
BuyerName = buyerName; | |||
} | |||
} | |||
} |
@ -0,0 +1,22 @@ | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
namespace Ordering.SignalrHub.IntegrationEvents.Events | |||
{ | |||
public class OrderStatusChangedToShippedIntegrationEvent : IntegrationEvent | |||
{ | |||
public int OrderId { get; } | |||
public string OrderStatus { get; } | |||
public string BuyerName { get; } | |||
public OrderStatusChangedToShippedIntegrationEvent(int orderId, string orderStatus, string buyerName) | |||
{ | |||
OrderId = orderId; | |||
OrderStatus = orderStatus; | |||
BuyerName = buyerName; | |||
} | |||
} | |||
} |
@ -0,0 +1,18 @@ | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; | |||
namespace Ordering.SignalrHub.IntegrationEvents.Events | |||
{ | |||
public class OrderStatusChangedToStockConfirmedIntegrationEvent : IntegrationEvent | |||
{ | |||
public int OrderId { get; } | |||
public string OrderStatus { get; } | |||
public string BuyerName { get; } | |||
public OrderStatusChangedToStockConfirmedIntegrationEvent(int orderId, string orderStatus, string buyerName) | |||
{ | |||
OrderId = orderId; | |||
OrderStatus = orderStatus; | |||
BuyerName = buyerName; | |||
} | |||
} | |||
} |
@ -0,0 +1,22 @@ | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
namespace Ordering.SignalrHub.IntegrationEvents.Events | |||
{ | |||
public class OrderStatusChangedToSubmittedIntegrationEvent : IntegrationEvent | |||
{ | |||
public int OrderId { get; } | |||
public string OrderStatus { get; } | |||
public string BuyerName { get; } | |||
public OrderStatusChangedToSubmittedIntegrationEvent(int orderId, string orderStatus, string buyerName) | |||
{ | |||
OrderId = orderId; | |||
OrderStatus = orderStatus; | |||
BuyerName = buyerName; | |||
} | |||
} | |||
} |
@ -0,0 +1,26 @@ | |||
using Microsoft.AspNetCore.Authorization; | |||
using Microsoft.AspNetCore.SignalR; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
namespace Ordering.SignalrHub | |||
{ | |||
[Authorize] | |||
public class NotificationsHub : Hub | |||
{ | |||
public override async Task OnConnectedAsync() | |||
{ | |||
await Groups.AddAsync(Context.ConnectionId, Context.User.Identity.Name); | |||
await base.OnConnectedAsync(); | |||
} | |||
public override async Task OnDisconnectedAsync(Exception ex) | |||
{ | |||
await Groups.RemoveAsync(Context.ConnectionId, Context.User.Identity.Name); | |||
await base.OnDisconnectedAsync(ex); | |||
} | |||
} | |||
} |
@ -0,0 +1,26 @@ | |||
<Project Sdk="Microsoft.NET.Sdk.Web"> | |||
<PropertyGroup> | |||
<TargetFramework>netcoreapp2.0</TargetFramework> | |||
<DockerComposeProjectPath>..\..\..\..\docker-compose.dcproj</DockerComposeProjectPath> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<Folder Include="wwwroot\" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" /> | |||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.6" /> | |||
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.0.0-preview2-final" /> | |||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Core" Version="1.0.0-preview2-final" /> | |||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Redis" Version="1.0.0-preview2-final" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" /> | |||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj" /> | |||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBus\EventBus.csproj" /> | |||
</ItemGroup> | |||
</Project> |
@ -0,0 +1,25 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.IO; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
using Microsoft.AspNetCore; | |||
using Microsoft.AspNetCore.Hosting; | |||
using Microsoft.Extensions.Configuration; | |||
using Microsoft.Extensions.Logging; | |||
namespace Ordering.SignalrHub | |||
{ | |||
public class Program | |||
{ | |||
public static void Main(string[] args) | |||
{ | |||
BuildWebHost(args).Run(); | |||
} | |||
public static IWebHost BuildWebHost(string[] args) => | |||
WebHost.CreateDefaultBuilder(args) | |||
.UseStartup<Startup>() | |||
.Build(); | |||
} | |||
} |
@ -0,0 +1,27 @@ | |||
{ | |||
"iisSettings": { | |||
"windowsAuthentication": false, | |||
"anonymousAuthentication": true, | |||
"iisExpress": { | |||
"applicationUrl": "http://localhost:51311/", | |||
"sslPort": 0 | |||
} | |||
}, | |||
"profiles": { | |||
"IIS Express": { | |||
"commandName": "IISExpress", | |||
"launchBrowser": true, | |||
"environmentVariables": { | |||
"ASPNETCORE_ENVIRONMENT": "Development" | |||
} | |||
}, | |||
"Ordering.SignalrHub": { | |||
"commandName": "Project", | |||
"launchBrowser": true, | |||
"environmentVariables": { | |||
"ASPNETCORE_ENVIRONMENT": "Development" | |||
}, | |||
"applicationUrl": "http://localhost:51312/" | |||
} | |||
} | |||
} |
@ -0,0 +1,221 @@ | |||
using Autofac; | |||
using Autofac.Extensions.DependencyInjection; | |||
using Microsoft.AspNetCore.Authentication.JwtBearer; | |||
using Microsoft.AspNetCore.Builder; | |||
using Microsoft.Azure.ServiceBus; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus; | |||
using Microsoft.Extensions.Configuration; | |||
using Microsoft.Extensions.DependencyInjection; | |||
using Microsoft.Extensions.Logging; | |||
using Ordering.SignalrHub.AutofacModules; | |||
using Ordering.SignalrHub.IntegrationEvents; | |||
using Ordering.SignalrHub.IntegrationEvents.EventHandling; | |||
using Ordering.SignalrHub.IntegrationEvents.Events; | |||
using RabbitMQ.Client; | |||
using StackExchange.Redis; | |||
using System; | |||
using System.IdentityModel.Tokens.Jwt; | |||
namespace Ordering.SignalrHub | |||
{ | |||
public class Startup | |||
{ | |||
public Startup(IConfiguration configuration) | |||
{ | |||
Configuration = configuration; | |||
} | |||
// This method gets called by the runtime. Use this method to add services to the container. | |||
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 | |||
public IServiceProvider ConfigureServices(IServiceCollection services) | |||
{ | |||
services.AddCors(options => | |||
{ | |||
options.AddPolicy("CorsPolicy", | |||
builder => builder.AllowAnyOrigin() | |||
.AllowAnyMethod() | |||
.AllowAnyHeader() | |||
.AllowCredentials()); | |||
}); | |||
if (Configuration.GetValue<string>("IsClusterEnv") == bool.TrueString) | |||
{ | |||
services | |||
.AddSignalR() | |||
.AddRedis(Configuration["SignalrStoreConnectionString"]); | |||
//services | |||
// .AddSignalR() | |||
// .AddRedis(options => options.Factory = writer => | |||
// { | |||
// return ConnectionMultiplexer.Connect(Configuration["SignalrStoreConnectionString"], writer); | |||
// }); | |||
} | |||
else | |||
{ | |||
services.AddSignalR(); | |||
} | |||
if (Configuration.GetValue<bool>("AzureServiceBusEnabled")) | |||
{ | |||
services.AddSingleton<IServiceBusPersisterConnection>(sp => | |||
{ | |||
var logger = sp.GetRequiredService<ILogger<DefaultServiceBusPersisterConnection>>(); | |||
var serviceBusConnectionString = Configuration["EventBusConnection"]; | |||
var serviceBusConnection = new ServiceBusConnectionStringBuilder(serviceBusConnectionString); | |||
return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger); | |||
}); | |||
} | |||
else | |||
{ | |||
services.AddSingleton<IRabbitMQPersistentConnection>(sp => | |||
{ | |||
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>(); | |||
var factory = new ConnectionFactory() | |||
{ | |||
HostName = Configuration["EventBusConnection"] | |||
}; | |||
if (!string.IsNullOrEmpty(Configuration["EventBusUserName"])) | |||
{ | |||
factory.UserName = Configuration["EventBusUserName"]; | |||
} | |||
if (!string.IsNullOrEmpty(Configuration["EventBusPassword"])) | |||
{ | |||
factory.Password = Configuration["EventBusPassword"]; | |||
} | |||
var retryCount = 5; | |||
if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) | |||
{ | |||
retryCount = int.Parse(Configuration["EventBusRetryCount"]); | |||
} | |||
return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); | |||
}); | |||
} | |||
ConfigureAuthService(services); | |||
RegisterEventBus(services); | |||
services.AddOptions(); | |||
//configure autofac | |||
var container = new ContainerBuilder(); | |||
container.RegisterModule(new ApplicationModule()); | |||
container.Populate(services); | |||
return new AutofacServiceProvider(container.Build()); | |||
} | |||
public IConfiguration Configuration { get; } | |||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | |||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) | |||
{ | |||
loggerFactory.AddConsole(Configuration.GetSection("Logging")); | |||
loggerFactory.AddDebug(); | |||
loggerFactory.AddAzureWebAppDiagnostics(); | |||
loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace); | |||
var pathBase = Configuration["PATH_BASE"]; | |||
if (!string.IsNullOrEmpty(pathBase)) | |||
{ | |||
loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'"); | |||
app.UsePathBase(pathBase); | |||
} | |||
app.UseCors("CorsPolicy"); | |||
app.UseAuthentication(); | |||
app.UseSignalR(routes => | |||
{ | |||
routes.MapHub<NotificationsHub>("/notificationhub", options => | |||
options.Transports = Microsoft.AspNetCore.Http.Connections.TransportType.All); | |||
}); | |||
ConfigureEventBus(app); | |||
} | |||
private void ConfigureEventBus(IApplicationBuilder app) | |||
{ | |||
var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>(); | |||
eventBus.Subscribe<OrderStatusChangedToAwaitingValidationIntegrationEvent, OrderStatusChangedToAwaitingValidationIntegrationEventHandler>(); | |||
eventBus.Subscribe<OrderStatusChangedToPaidIntegrationEvent, OrderStatusChangedToPaidIntegrationEventHandler>(); | |||
eventBus.Subscribe<OrderStatusChangedToStockConfirmedIntegrationEvent, OrderStatusChangedToStockConfirmedIntegrationEventHandler>(); | |||
eventBus.Subscribe<OrderStatusChangedToShippedIntegrationEvent, OrderStatusChangedToShippedIntegrationEventHandler>(); | |||
eventBus.Subscribe<OrderStatusChangedToCancelledIntegrationEvent, OrderStatusChangedToCancelledIntegrationEventHandler>(); | |||
eventBus.Subscribe<OrderStatusChangedToSubmittedIntegrationEvent, OrderStatusChangedToSubmittedIntegrationEventHandler>(); | |||
} | |||
private void ConfigureAuthService(IServiceCollection services) | |||
{ | |||
// prevent from mapping "sub" claim to nameidentifier. | |||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); | |||
var identityUrl = Configuration.GetValue<string>("IdentityUrl"); | |||
services.AddAuthentication(options => | |||
{ | |||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; | |||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; | |||
}).AddJwtBearer(options => | |||
{ | |||
options.Authority = identityUrl; | |||
options.RequireHttpsMetadata = false; | |||
options.Audience = "orders.signalrhub"; | |||
}); | |||
} | |||
private void RegisterEventBus(IServiceCollection services) | |||
{ | |||
var subscriptionClientName = Configuration["SubscriptionClientName"]; | |||
if (Configuration.GetValue<bool>("AzureServiceBusEnabled")) | |||
{ | |||
services.AddSingleton<IEventBus, EventBusServiceBus>(sp => | |||
{ | |||
var serviceBusPersisterConnection = sp.GetRequiredService<IServiceBusPersisterConnection>(); | |||
var iLifetimeScope = sp.GetRequiredService<ILifetimeScope>(); | |||
var logger = sp.GetRequiredService<ILogger<EventBusServiceBus>>(); | |||
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>(); | |||
return new EventBusServiceBus(serviceBusPersisterConnection, logger, | |||
eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); | |||
}); | |||
} | |||
else | |||
{ | |||
services.AddSingleton<IEventBus, EventBusRabbitMQ>(sp => | |||
{ | |||
var rabbitMQPersistentConnection = sp.GetRequiredService<IRabbitMQPersistentConnection>(); | |||
var iLifetimeScope = sp.GetRequiredService<ILifetimeScope>(); | |||
var logger = sp.GetRequiredService<ILogger<EventBusRabbitMQ>>(); | |||
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>(); | |||
var retryCount = 5; | |||
if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) | |||
{ | |||
retryCount = int.Parse(Configuration["EventBusRetryCount"]); | |||
} | |||
return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount); | |||
}); | |||
} | |||
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>(); | |||
} | |||
} | |||
} |
@ -0,0 +1,15 @@ | |||
{ | |||
"IdentityUrl": "http://localhost:5105", | |||
"Logging": { | |||
"IncludeScopes": false, | |||
"LogLevel": { | |||
"Default": "Trace", | |||
"System": "Information", | |||
"Microsoft": "Information" | |||
} | |||
}, | |||
"AzureServiceBusEnabled": false, | |||
"SubscriptionClientName": "Ordering.signalrhub", | |||
"EventBusRetryCount": 5, | |||
"EventBusConnection": "localhost" | |||
} |
@ -0,0 +1,26 @@ | |||
{ | |||
"name": "asp.net", | |||
"version": "1.0.0", | |||
"lockfileVersion": 1, | |||
"requires": true, | |||
"dependencies": { | |||
"@aspnet/signalr": { | |||
"version": "1.0.0-preview2-final", | |||
"resolved": "https://registry.npmjs.org/@aspnet/signalr/-/signalr-1.0.0-preview2-final.tgz", | |||
"integrity": "sha512-XbqGbAG9Ow4L5Sc4n81A2S8lHSlxBNTjFm3WZQA94cIolPnW0bPK2u14UMooXRXxzjBtJViJMN/aoxWRwTWxig==" | |||
}, | |||
"jquery": { | |||
"version": "3.3.1", | |||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz", | |||
"integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg==" | |||
}, | |||
"toastr": { | |||
"version": "2.1.4", | |||
"resolved": "https://registry.npmjs.org/toastr/-/toastr-2.1.4.tgz", | |||
"integrity": "sha1-i0O+ZPudDEFIcURvLbjoyk6V8YE=", | |||
"requires": { | |||
"jquery": "3.3.1" | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,10 @@ | |||
{ | |||
"version": "1.0.0", | |||
"name": "asp.net", | |||
"private": true, | |||
"devDependencies": {}, | |||
"dependencies": { | |||
"@aspnet/signalr": "^1.0.0-preview2-final", | |||
"toastr": "^2.1.4" | |||
} | |||
} |
@ -0,0 +1,228 @@ | |||
.toast-title { | |||
font-weight: bold; | |||
} | |||
.toast-message { | |||
-ms-word-wrap: break-word; | |||
word-wrap: break-word; | |||
} | |||
.toast-message a, | |||
.toast-message label { | |||
color: #FFFFFF; | |||
} | |||
.toast-message a:hover { | |||
color: #CCCCCC; | |||
text-decoration: none; | |||
} | |||
.toast-close-button { | |||
position: relative; | |||
right: -0.3em; | |||
top: -0.3em; | |||
float: right; | |||
font-size: 20px; | |||
font-weight: bold; | |||
color: #FFFFFF; | |||
-webkit-text-shadow: 0 1px 0 #ffffff; | |||
text-shadow: 0 1px 0 #ffffff; | |||
opacity: 0.8; | |||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80); | |||
filter: alpha(opacity=80); | |||
line-height: 1; | |||
} | |||
.toast-close-button:hover, | |||
.toast-close-button:focus { | |||
color: #000000; | |||
text-decoration: none; | |||
cursor: pointer; | |||
opacity: 0.4; | |||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40); | |||
filter: alpha(opacity=40); | |||
} | |||
.rtl .toast-close-button { | |||
left: -0.3em; | |||
float: left; | |||
right: 0.3em; | |||
} | |||
/*Additional properties for button version | |||
iOS requires the button element instead of an anchor tag. | |||
If you want the anchor version, it requires `href="#"`.*/ | |||
button.toast-close-button { | |||
padding: 0; | |||
cursor: pointer; | |||
background: transparent; | |||
border: 0; | |||
-webkit-appearance: none; | |||
} | |||
.toast-top-center { | |||
top: 0; | |||
right: 0; | |||
width: 100%; | |||
} | |||
.toast-bottom-center { | |||
bottom: 0; | |||
right: 0; | |||
width: 100%; | |||
} | |||
.toast-top-full-width { | |||
top: 0; | |||
right: 0; | |||
width: 100%; | |||
} | |||
.toast-bottom-full-width { | |||
bottom: 0; | |||
right: 0; | |||
width: 100%; | |||
} | |||
.toast-top-left { | |||
top: 12px; | |||
left: 12px; | |||
} | |||
.toast-top-right { | |||
top: 12px; | |||
right: 12px; | |||
} | |||
.toast-bottom-right { | |||
right: 12px; | |||
bottom: 12px; | |||
} | |||
.toast-bottom-left { | |||
bottom: 12px; | |||
left: 12px; | |||
} | |||
#toast-container { | |||
position: fixed; | |||
z-index: 999999; | |||
pointer-events: none; | |||
/*overrides*/ | |||
} | |||
#toast-container * { | |||
-moz-box-sizing: border-box; | |||
-webkit-box-sizing: border-box; | |||
box-sizing: border-box; | |||
} | |||
#toast-container > div { | |||
position: relative; | |||
pointer-events: auto; | |||
overflow: hidden; | |||
margin: 0 0 6px; | |||
padding: 15px 15px 15px 50px; | |||
width: 300px; | |||
-moz-border-radius: 3px 3px 3px 3px; | |||
-webkit-border-radius: 3px 3px 3px 3px; | |||
border-radius: 3px 3px 3px 3px; | |||
background-position: 15px center; | |||
background-repeat: no-repeat; | |||
-moz-box-shadow: 0 0 12px #999999; | |||
-webkit-box-shadow: 0 0 12px #999999; | |||
box-shadow: 0 0 12px #999999; | |||
color: #FFFFFF; | |||
opacity: 0.8; | |||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80); | |||
filter: alpha(opacity=80); | |||
} | |||
#toast-container > div.rtl { | |||
direction: rtl; | |||
padding: 15px 50px 15px 15px; | |||
background-position: right 15px center; | |||
} | |||
#toast-container > div:hover { | |||
-moz-box-shadow: 0 0 12px #000000; | |||
-webkit-box-shadow: 0 0 12px #000000; | |||
box-shadow: 0 0 12px #000000; | |||
opacity: 1; | |||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100); | |||
filter: alpha(opacity=100); | |||
cursor: pointer; | |||
} | |||
#toast-container > .toast-info { | |||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=") !important; | |||
} | |||
#toast-container > .toast-error { | |||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important; | |||
} | |||
#toast-container > .toast-success { | |||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==") !important; | |||
} | |||
#toast-container > .toast-warning { | |||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=") !important; | |||
} | |||
#toast-container.toast-top-center > div, | |||
#toast-container.toast-bottom-center > div { | |||
width: 300px; | |||
margin-left: auto; | |||
margin-right: auto; | |||
} | |||
#toast-container.toast-top-full-width > div, | |||
#toast-container.toast-bottom-full-width > div { | |||
width: 96%; | |||
margin-left: auto; | |||
margin-right: auto; | |||
} | |||
.toast { | |||
background-color: #030303; | |||
} | |||
.toast-success { | |||
background-color: #51A351; | |||
} | |||
.toast-error { | |||
background-color: #BD362F; | |||
} | |||
.toast-info { | |||
background-color: #2F96B4; | |||
} | |||
.toast-warning { | |||
background-color: #F89406; | |||
} | |||
.toast-progress { | |||
position: absolute; | |||
left: 0; | |||
bottom: 0; | |||
height: 4px; | |||
background-color: #000000; | |||
opacity: 0.4; | |||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40); | |||
filter: alpha(opacity=40); | |||
} | |||
/*Responsive Design*/ | |||
@media all and (max-width: 240px) { | |||
#toast-container > div { | |||
padding: 8px 8px 8px 50px; | |||
width: 11em; | |||
} | |||
#toast-container > div.rtl { | |||
padding: 8px 50px 8px 8px; | |||
} | |||
#toast-container .toast-close-button { | |||
right: -0.2em; | |||
top: -0.2em; | |||
} | |||
#toast-container .rtl .toast-close-button { | |||
left: -0.2em; | |||
right: 0.2em; | |||
} | |||
} | |||
@media all and (min-width: 241px) and (max-width: 480px) { | |||
#toast-container > div { | |||
padding: 8px 8px 8px 50px; | |||
width: 18em; | |||
} | |||
#toast-container > div.rtl { | |||
padding: 8px 50px 8px 8px; | |||
} | |||
#toast-container .toast-close-button { | |||
right: -0.2em; | |||
top: -0.2em; | |||
} | |||
#toast-container .rtl .toast-close-button { | |||
left: -0.2em; | |||
right: 0.2em; | |||
} | |||
} | |||
@media all and (min-width: 481px) and (max-width: 768px) { | |||
#toast-container > div { | |||
padding: 15px 15px 15px 50px; | |||
width: 25em; | |||
} | |||
#toast-container > div.rtl { | |||
padding: 15px 50px 15px 15px; | |||
} | |||
} |
@ -0,0 +1,476 @@ | |||
/* | |||
* Toastr | |||
* Copyright 2012-2015 | |||
* Authors: John Papa, Hans Fjällemark, and Tim Ferrell. | |||
* All Rights Reserved. | |||
* Use, reproduction, distribution, and modification of this code is subject to the terms and | |||
* conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php | |||
* | |||
* ARIA Support: Greta Krafsig | |||
* | |||
* Project: https://github.com/CodeSeven/toastr | |||
*/ | |||
/* global define */ | |||
(function (define) { | |||
define(['jquery'], function ($) { | |||
return (function () { | |||
var $container; | |||
var listener; | |||
var toastId = 0; | |||
var toastType = { | |||
error: 'error', | |||
info: 'info', | |||
success: 'success', | |||
warning: 'warning' | |||
}; | |||
var toastr = { | |||
clear: clear, | |||
remove: remove, | |||
error: error, | |||
getContainer: getContainer, | |||
info: info, | |||
options: {}, | |||
subscribe: subscribe, | |||
success: success, | |||
version: '2.1.4', | |||
warning: warning | |||
}; | |||
var previousToast; | |||
return toastr; | |||
//////////////// | |||
function error(message, title, optionsOverride) { | |||
return notify({ | |||
type: toastType.error, | |||
iconClass: getOptions().iconClasses.error, | |||
message: message, | |||
optionsOverride: optionsOverride, | |||
title: title | |||
}); | |||
} | |||
function getContainer(options, create) { | |||
if (!options) { options = getOptions(); } | |||
$container = $('#' + options.containerId); | |||
if ($container.length) { | |||
return $container; | |||
} | |||
if (create) { | |||
$container = createContainer(options); | |||
} | |||
return $container; | |||
} | |||
function info(message, title, optionsOverride) { | |||
return notify({ | |||
type: toastType.info, | |||
iconClass: getOptions().iconClasses.info, | |||
message: message, | |||
optionsOverride: optionsOverride, | |||
title: title | |||
}); | |||
} | |||
function subscribe(callback) { | |||
listener = callback; | |||
} | |||
function success(message, title, optionsOverride) { | |||
return notify({ | |||
type: toastType.success, | |||
iconClass: getOptions().iconClasses.success, | |||
message: message, | |||
optionsOverride: optionsOverride, | |||
title: title | |||
}); | |||
} | |||
function warning(message, title, optionsOverride) { | |||
return notify({ | |||
type: toastType.warning, | |||
iconClass: getOptions().iconClasses.warning, | |||
message: message, | |||
optionsOverride: optionsOverride, | |||
title: title | |||
}); | |||
} | |||
function clear($toastElement, clearOptions) { | |||
var options = getOptions(); | |||
if (!$container) { getContainer(options); } | |||
if (!clearToast($toastElement, options, clearOptions)) { | |||
clearContainer(options); | |||
} | |||
} | |||
function remove($toastElement) { | |||
var options = getOptions(); | |||
if (!$container) { getContainer(options); } | |||
if ($toastElement && $(':focus', $toastElement).length === 0) { | |||
removeToast($toastElement); | |||
return; | |||
} | |||
if ($container.children().length) { | |||
$container.remove(); | |||
} | |||
} | |||
// internal functions | |||
function clearContainer (options) { | |||
var toastsToClear = $container.children(); | |||
for (var i = toastsToClear.length - 1; i >= 0; i--) { | |||
clearToast($(toastsToClear[i]), options); | |||
} | |||
} | |||
function clearToast ($toastElement, options, clearOptions) { | |||
var force = clearOptions && clearOptions.force ? clearOptions.force : false; | |||
if ($toastElement && (force || $(':focus', $toastElement).length === 0)) { | |||
$toastElement[options.hideMethod]({ | |||
duration: options.hideDuration, | |||
easing: options.hideEasing, | |||
complete: function () { removeToast($toastElement); } | |||
}); | |||
return true; | |||
} | |||
return false; | |||
} | |||
function createContainer(options) { | |||
$container = $('<div/>') | |||
.attr('id', options.containerId) | |||
.addClass(options.positionClass); | |||
$container.appendTo($(options.target)); | |||
return $container; | |||
} | |||
function getDefaults() { | |||
return { | |||
tapToDismiss: true, | |||
toastClass: 'toast', | |||
containerId: 'toast-container', | |||
debug: false, | |||
showMethod: 'fadeIn', //fadeIn, slideDown, and show are built into jQuery | |||
showDuration: 300, | |||
showEasing: 'swing', //swing and linear are built into jQuery | |||
onShown: undefined, | |||
hideMethod: 'fadeOut', | |||
hideDuration: 1000, | |||
hideEasing: 'swing', | |||
onHidden: undefined, | |||
closeMethod: false, | |||
closeDuration: false, | |||
closeEasing: false, | |||
closeOnHover: true, | |||
extendedTimeOut: 1000, | |||
iconClasses: { | |||
error: 'toast-error', | |||
info: 'toast-info', | |||
success: 'toast-success', | |||
warning: 'toast-warning' | |||
}, | |||
iconClass: 'toast-info', | |||
positionClass: 'toast-top-right', | |||
timeOut: 5000, // Set timeOut and extendedTimeOut to 0 to make it sticky | |||
titleClass: 'toast-title', | |||
messageClass: 'toast-message', | |||
escapeHtml: false, | |||
target: 'body', | |||
closeHtml: '<button type="button">×</button>', | |||
closeClass: 'toast-close-button', | |||
newestOnTop: true, | |||
preventDuplicates: false, | |||
progressBar: false, | |||
progressClass: 'toast-progress', | |||
rtl: false | |||
}; | |||
} | |||
function publish(args) { | |||
if (!listener) { return; } | |||
listener(args); | |||
} | |||
function notify(map) { | |||
var options = getOptions(); | |||
var iconClass = map.iconClass || options.iconClass; | |||
if (typeof (map.optionsOverride) !== 'undefined') { | |||
options = $.extend(options, map.optionsOverride); | |||
iconClass = map.optionsOverride.iconClass || iconClass; | |||
} | |||
if (shouldExit(options, map)) { return; } | |||
toastId++; | |||
$container = getContainer(options, true); | |||
var intervalId = null; | |||
var $toastElement = $('<div/>'); | |||
var $titleElement = $('<div/>'); | |||
var $messageElement = $('<div/>'); | |||
var $progressElement = $('<div/>'); | |||
var $closeElement = $(options.closeHtml); | |||
var progressBar = { | |||
intervalId: null, | |||
hideEta: null, | |||
maxHideTime: null | |||
}; | |||
var response = { | |||
toastId: toastId, | |||
state: 'visible', | |||
startTime: new Date(), | |||
options: options, | |||
map: map | |||
}; | |||
personalizeToast(); | |||
displayToast(); | |||
handleEvents(); | |||
publish(response); | |||
if (options.debug && console) { | |||
console.log(response); | |||
} | |||
return $toastElement; | |||
function escapeHtml(source) { | |||
if (source == null) { | |||
source = ''; | |||
} | |||
return source | |||
.replace(/&/g, '&') | |||
.replace(/"/g, '"') | |||
.replace(/'/g, ''') | |||
.replace(/</g, '<') | |||
.replace(/>/g, '>'); | |||
} | |||
function personalizeToast() { | |||
setIcon(); | |||
setTitle(); | |||
setMessage(); | |||
setCloseButton(); | |||
setProgressBar(); | |||
setRTL(); | |||
setSequence(); | |||
setAria(); | |||
} | |||
function setAria() { | |||
var ariaValue = ''; | |||
switch (map.iconClass) { | |||
case 'toast-success': | |||
case 'toast-info': | |||
ariaValue = 'polite'; | |||
break; | |||
default: | |||
ariaValue = 'assertive'; | |||
} | |||
$toastElement.attr('aria-live', ariaValue); | |||
} | |||
function handleEvents() { | |||
if (options.closeOnHover) { | |||
$toastElement.hover(stickAround, delayedHideToast); | |||
} | |||
if (!options.onclick && options.tapToDismiss) { | |||
$toastElement.click(hideToast); | |||
} | |||
if (options.closeButton && $closeElement) { | |||
$closeElement.click(function (event) { | |||
if (event.stopPropagation) { | |||
event.stopPropagation(); | |||
} else if (event.cancelBubble !== undefined && event.cancelBubble !== true) { | |||
event.cancelBubble = true; | |||
} | |||
if (options.onCloseClick) { | |||
options.onCloseClick(event); | |||
} | |||
hideToast(true); | |||
}); | |||
} | |||
if (options.onclick) { | |||
$toastElement.click(function (event) { | |||
options.onclick(event); | |||
hideToast(); | |||
}); | |||
} | |||
} | |||
function displayToast() { | |||
$toastElement.hide(); | |||
$toastElement[options.showMethod]( | |||
{duration: options.showDuration, easing: options.showEasing, complete: options.onShown} | |||
); | |||
if (options.timeOut > 0) { | |||
intervalId = setTimeout(hideToast, options.timeOut); | |||
progressBar.maxHideTime = parseFloat(options.timeOut); | |||
progressBar.hideEta = new Date().getTime() + progressBar.maxHideTime; | |||
if (options.progressBar) { | |||
progressBar.intervalId = setInterval(updateProgress, 10); | |||
} | |||
} | |||
} | |||
function setIcon() { | |||
if (map.iconClass) { | |||
$toastElement.addClass(options.toastClass).addClass(iconClass); | |||
} | |||
} | |||
function setSequence() { | |||
if (options.newestOnTop) { | |||
$container.prepend($toastElement); | |||
} else { | |||
$container.append($toastElement); | |||
} | |||
} | |||
function setTitle() { | |||
if (map.title) { | |||
var suffix = map.title; | |||
if (options.escapeHtml) { | |||
suffix = escapeHtml(map.title); | |||
} | |||
$titleElement.append(suffix).addClass(options.titleClass); | |||
$toastElement.append($titleElement); | |||
} | |||
} | |||
function setMessage() { | |||
if (map.message) { | |||
var suffix = map.message; | |||
if (options.escapeHtml) { | |||
suffix = escapeHtml(map.message); | |||
} | |||
$messageElement.append(suffix).addClass(options.messageClass); | |||
$toastElement.append($messageElement); | |||
} | |||
} | |||
function setCloseButton() { | |||
if (options.closeButton) { | |||
$closeElement.addClass(options.closeClass).attr('role', 'button'); | |||
$toastElement.prepend($closeElement); | |||
} | |||
} | |||
function setProgressBar() { | |||
if (options.progressBar) { | |||
$progressElement.addClass(options.progressClass); | |||
$toastElement.prepend($progressElement); | |||
} | |||
} | |||
function setRTL() { | |||
if (options.rtl) { | |||
$toastElement.addClass('rtl'); | |||
} | |||
} | |||
function shouldExit(options, map) { | |||
if (options.preventDuplicates) { | |||
if (map.message === previousToast) { | |||
return true; | |||
} else { | |||
previousToast = map.message; | |||
} | |||
} | |||
return false; | |||
} | |||
function hideToast(override) { | |||
var method = override && options.closeMethod !== false ? options.closeMethod : options.hideMethod; | |||
var duration = override && options.closeDuration !== false ? | |||
options.closeDuration : options.hideDuration; | |||
var easing = override && options.closeEasing !== false ? options.closeEasing : options.hideEasing; | |||
if ($(':focus', $toastElement).length && !override) { | |||
return; | |||
} | |||
clearTimeout(progressBar.intervalId); | |||
return $toastElement[method]({ | |||
duration: duration, | |||
easing: easing, | |||
complete: function () { | |||
removeToast($toastElement); | |||
clearTimeout(intervalId); | |||
if (options.onHidden && response.state !== 'hidden') { | |||
options.onHidden(); | |||
} | |||
response.state = 'hidden'; | |||
response.endTime = new Date(); | |||
publish(response); | |||
} | |||
}); | |||
} | |||
function delayedHideToast() { | |||
if (options.timeOut > 0 || options.extendedTimeOut > 0) { | |||
intervalId = setTimeout(hideToast, options.extendedTimeOut); | |||
progressBar.maxHideTime = parseFloat(options.extendedTimeOut); | |||
progressBar.hideEta = new Date().getTime() + progressBar.maxHideTime; | |||
} | |||
} | |||
function stickAround() { | |||
clearTimeout(intervalId); | |||
progressBar.hideEta = 0; | |||
$toastElement.stop(true, true)[options.showMethod]( | |||
{duration: options.showDuration, easing: options.showEasing} | |||
); | |||
} | |||
function updateProgress() { | |||
var percentage = ((progressBar.hideEta - (new Date().getTime())) / progressBar.maxHideTime) * 100; | |||
$progressElement.width(percentage + '%'); | |||
} | |||
} | |||
function getOptions() { | |||
return $.extend({}, getDefaults(), toastr.options); | |||
} | |||
function removeToast($toastElement) { | |||
if (!$container) { $container = getContainer(); } | |||
if ($toastElement.is(':visible')) { | |||
return; | |||
} | |||
$toastElement.remove(); | |||
$toastElement = null; | |||
if ($container.children().length === 0) { | |||
$container.remove(); | |||
previousToast = undefined; | |||
} | |||
} | |||
})(); | |||
}); | |||
}(typeof define === 'function' && define.amd ? define : function (deps, factory) { | |||
if (typeof module !== 'undefined' && module.exports) { //Node | |||
module.exports = factory(require('jquery')); | |||
} else { | |||
window.toastr = factory(window.jQuery); | |||
} | |||
})); |