This commit is contained in:
parent
0f6aeabfcc
commit
5c7829bdbd
@ -4,6 +4,6 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<!-- All Fake packages -->
|
<!-- All Fake packages -->
|
||||||
<!-- 清本地nuget缓存:dotnet nuget locals -c http-cache -->
|
<!-- 清本地nuget缓存:dotnet nuget locals -c http-cache -->
|
||||||
<FakePackageVersion>8.0.6</FakePackageVersion>
|
<FakePackageVersion>8.0.6.2</FakePackageVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -20,8 +20,7 @@
|
|||||||
<ProjectReference Include="..\TrackCenter.Repository\TrackCenter.Repository.csproj" />
|
<ProjectReference Include="..\TrackCenter.Repository\TrackCenter.Repository.csproj" />
|
||||||
<PackageReference Include="Fake.Autofac" Version="$(FakePackageVersion)" />
|
<PackageReference Include="Fake.Autofac" Version="$(FakePackageVersion)" />
|
||||||
<PackageReference Include="Fake.Consul" Version="$(FakePackageVersion)" />
|
<PackageReference Include="Fake.Consul" Version="$(FakePackageVersion)" />
|
||||||
<PackageReference Include="Fake.EventBus.IntegrationEventLog" Version="$(FakePackageVersion)" />
|
<PackageReference Include="Fake.Messaging.Dashboard" Version="$(FakePackageVersion)" />
|
||||||
<PackageReference Include="Fake.EventBus.Dashboard" Version="$(FakePackageVersion)" />
|
|
||||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.3" />
|
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.3" />
|
||||||
|
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
|
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
|
||||||
|
|||||||
@ -5,8 +5,8 @@ using Fake.AspNetCore.ExceptionHandling;
|
|||||||
using Fake.AspNetCore.Newtonsoft;
|
using Fake.AspNetCore.Newtonsoft;
|
||||||
using Fake.AspNetCore.Swagger;
|
using Fake.AspNetCore.Swagger;
|
||||||
using Fake.Autofac;
|
using Fake.Autofac;
|
||||||
using Fake.EventBus.Dashboard;
|
using Fake.Messaging.Dashboard;
|
||||||
using Fake.EventBus.IntegrationEventLog;
|
using Fake.Messaging.EntityFrameworkCore;
|
||||||
using Fake.FeiShu;
|
using Fake.FeiShu;
|
||||||
using Fake.Json;
|
using Fake.Json;
|
||||||
using Fake.Modularity;
|
using Fake.Modularity;
|
||||||
@ -33,9 +33,8 @@ namespace TrackCenter.Api;
|
|||||||
[DependsOn(typeof(FakeAspNetCoreModule))]
|
[DependsOn(typeof(FakeAspNetCoreModule))]
|
||||||
[DependsOn(typeof(TrackCenterApplicationModule))]
|
[DependsOn(typeof(TrackCenterApplicationModule))]
|
||||||
[DependsOn(typeof(TrackCenterRepositoryModule))]
|
[DependsOn(typeof(TrackCenterRepositoryModule))]
|
||||||
// RabbitMQ 物理总线之后 Replace IDistributedEventBus → Outbox(与 admin 一致)
|
// Messaging 独立队列(Outbox/Inbox + Dashboard);物理传输由 FakeMessagingRabbitMqModule 提供
|
||||||
[DependsOn(typeof(FakeEventBusIntegrationEventLogModule))]
|
[DependsOn(typeof(FakeMessagingDashboardModule))]
|
||||||
[DependsOn(typeof(FakeEventBusDashboardModule))]
|
|
||||||
[DependsOn(typeof(FakeSerilogModule))]
|
[DependsOn(typeof(FakeSerilogModule))]
|
||||||
public class TrackCenterApiModule : FakeModule
|
public class TrackCenterApiModule : FakeModule
|
||||||
{
|
{
|
||||||
@ -59,10 +58,11 @@ public class TrackCenterApiModule : FakeModule
|
|||||||
// 配置签名验证选项
|
// 配置签名验证选项
|
||||||
services.Configure<SignatureValidationOptions>(configuration.GetSection("SignatureValidation"));
|
services.Configure<SignatureValidationOptions>(configuration.GetSection("SignatureValidation"));
|
||||||
|
|
||||||
// Outbox / Inbox 与业务同库(EF),通过 DbTransaction 征用 SqlSugar 事务
|
// Outbox / Inbox(fk_msg_*)与业务同库(EF),通过 DbTransaction 征用 SqlSugar 事务
|
||||||
services.AddDbContext<IntegrationEventLogContext>(options =>
|
services.AddDbContext<MessagingDbContext>(options =>
|
||||||
{
|
{
|
||||||
var connectionString = configuration.GetConnectionString("IntegrationEventLog")
|
var connectionString = configuration.GetConnectionString("Messaging")
|
||||||
|
?? configuration.GetConnectionString("IntegrationEventLog")
|
||||||
?? configuration.GetConnectionString("Default")
|
?? configuration.GetConnectionString("Default")
|
||||||
?? configuration["ConnectionStrings:Default"]
|
?? configuration["ConnectionStrings:Default"]
|
||||||
?? string.Empty;
|
?? string.Empty;
|
||||||
@ -73,6 +73,13 @@ public class TrackCenterApiModule : FakeModule
|
|||||||
#endif
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Dashboard 路径保持 /eventbus,兼容旧书签与网关
|
||||||
|
services.Configure<MessagingDashboardOptions>(o =>
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(o.PathMatch) || o.PathMatch == "/messaging")
|
||||||
|
o.PathMatch = "/eventbus";
|
||||||
|
});
|
||||||
|
|
||||||
// 全局授权配置:所有接口默认需要授权
|
// 全局授权配置:所有接口默认需要授权
|
||||||
services.AddMvc(options =>
|
services.AddMvc(options =>
|
||||||
{
|
{
|
||||||
@ -207,7 +214,7 @@ public class TrackCenterApiModule : FakeModule
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 必须在 UsePathBase 之后:完整对外路径为 {PathBase}/eventbus
|
// 必须在 UsePathBase 之后:完整对外路径为 {PathBase}/eventbus
|
||||||
app.UseFakeEventBusDashboard();
|
app.UseFakeMessagingDashboard();
|
||||||
|
|
||||||
app.Services.GetRequiredService<IFeiShuNotificationService>().Send("Application started");
|
app.Services.GetRequiredService<IFeiShuNotificationService>().Send("Application started");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,12 @@
|
|||||||
namespace TrackCenter.Application.Rabbit;
|
using Fake.Messaging;
|
||||||
|
|
||||||
public class InterfaceRelayForwardReplayEvent
|
namespace TrackCenter.Application.Events;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 接口通回调报文(外部生产,无 Fake MessageId / DLX)。
|
||||||
|
/// </summary>
|
||||||
|
[MessageRoute(Topic = GlobalConst.InterfaceRelayExchange, TopicType = "direct")]
|
||||||
|
public class InterfaceRelayForwardReplayEvent : Message
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 请求Id
|
/// 请求Id
|
||||||
@ -1,4 +1,4 @@
|
|||||||
using Fake.EventBus.Distributed;
|
using Fake.Messaging;
|
||||||
|
|
||||||
namespace TrackCenter.Application.Events;
|
namespace TrackCenter.Application.Events;
|
||||||
|
|
||||||
@ -6,7 +6,8 @@ namespace TrackCenter.Application.Events;
|
|||||||
/// 订单 POD 拉取(当前仓库无订阅方,仍走 Outbox 投递以兼容后续消费者)。
|
/// 订单 POD 拉取(当前仓库无订阅方,仍走 Outbox 投递以兼容后续消费者)。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class OrderPodPullEvent : IntegrationEvent
|
[MessageRoute(nameof(OrderPodPullEvent))]
|
||||||
|
public class OrderPodPullEvent : Message
|
||||||
{
|
{
|
||||||
// 确定应用
|
// 确定应用
|
||||||
public string AppKey { get; set; }
|
public string AppKey { get; set; }
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
using Fake.EventBus.Distributed;
|
using Fake.Messaging;
|
||||||
|
|
||||||
namespace TrackCenter.Application.Events;
|
namespace TrackCenter.Application.Events;
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class TrackChangeAfterUpdateOrderEvent : IntegrationEvent
|
[MessageRoute(nameof(TrackChangeAfterUpdateOrderEvent))]
|
||||||
|
public class TrackChangeAfterUpdateOrderEvent : Message
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 订单Id
|
/// 订单Id
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
using Fake.EventBus.Distributed;
|
using Fake.Messaging;
|
||||||
using TrackCenter.Application.Dtos.ProvideServices;
|
using TrackCenter.Application.Dtos.ProvideServices;
|
||||||
|
|
||||||
namespace TrackCenter.Application.Events;
|
namespace TrackCenter.Application.Events;
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class TrackDeleteEvent : IntegrationEvent
|
[MessageRoute(nameof(TrackDeleteEvent))]
|
||||||
|
public class TrackDeleteEvent : Message
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据esId定位轨迹,优先级最高
|
/// 根据esId定位轨迹,优先级最高
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
using Fake.EventBus.Distributed;
|
using Fake.Messaging;
|
||||||
|
|
||||||
namespace TrackCenter.Application.Events;
|
namespace TrackCenter.Application.Events;
|
||||||
|
|
||||||
@ -7,7 +7,8 @@ namespace TrackCenter.Application.Events;
|
|||||||
/// 每次可传递多个订单,但仅能传递同一个轨迹内容
|
/// 每次可传递多个订单,但仅能传递同一个轨迹内容
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class TrackPushEvent : IntegrationEvent
|
[MessageRoute(nameof(TrackPushEvent))]
|
||||||
|
public class TrackPushEvent : Message
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 操作类型
|
/// 操作类型
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
using Fake.EventBus.Distributed;
|
using Fake.Messaging;
|
||||||
using TrackCenter.Application.Dtos.ProvideServices;
|
using TrackCenter.Application.Dtos.ProvideServices;
|
||||||
|
|
||||||
namespace TrackCenter.Application.Events;
|
namespace TrackCenter.Application.Events;
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class TrackUpsertEvent : IntegrationEvent
|
[MessageRoute(nameof(TrackUpsertEvent))]
|
||||||
|
public class TrackUpsertEvent : Message
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 应用
|
/// 应用
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
|
using Fake.Messaging;
|
||||||
namespace TrackCenter.Application.Events;
|
namespace TrackCenter.Application.Events;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 轨迹刷新引发的新增/更新(独立队列,与 <see cref="TrackUpsertEvent"/> 隔离)。
|
/// 轨迹刷新引发的新增/更新(独立队列,与 <see cref="TrackUpsertEvent"/> 隔离)。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
|
[MessageRoute(nameof(TrackUpsertForRefreshEvent))]
|
||||||
public class TrackUpsertForRefreshEvent : TrackUpsertEvent
|
public class TrackUpsertForRefreshEvent : TrackUpsertEvent
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
using Fake.EventBus;
|
using Fake.Messaging;
|
||||||
using Fake.EventBus.Distributed;
|
|
||||||
using Fake.UnitOfWork;
|
|
||||||
using TrackCenter.Application.Events;
|
using TrackCenter.Application.Events;
|
||||||
using TrackCenter.Application.Services.Warning.Handlers;
|
using TrackCenter.Application.Services.Warning.Handlers;
|
||||||
using TrackCenter.Domain.Aggregates.OrderAggregate;
|
using TrackCenter.Domain.Aggregates.OrderAggregate;
|
||||||
@ -8,7 +6,7 @@ using TrackCenter.Domain.Aggregates.OrderAggregate;
|
|||||||
namespace TrackCenter.Application.Messaging;
|
namespace TrackCenter.Application.Messaging;
|
||||||
|
|
||||||
public class TrackChangeAfterUpdateOrderEventHandler(IOrderRepository orderRepository, IServiceProvider serviceProvider)
|
public class TrackChangeAfterUpdateOrderEventHandler(IOrderRepository orderRepository, IServiceProvider serviceProvider)
|
||||||
: IEventHandler<TrackChangeAfterUpdateOrderEvent>, ITransientDependency
|
: IMessageHandle<TrackChangeAfterUpdateOrderEvent>, ITransientDependency
|
||||||
{
|
{
|
||||||
public virtual async Task HandleAsync(
|
public virtual async Task HandleAsync(
|
||||||
TrackChangeAfterUpdateOrderEvent @event,
|
TrackChangeAfterUpdateOrderEvent @event,
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using Fake.EventBus;
|
using Fake.Messaging;
|
||||||
using Fake.EventBus.Distributed;
|
|
||||||
using Fake.UnitOfWork;
|
using Fake.UnitOfWork;
|
||||||
using InterfaceForward.Domain.Shared.Helpers;
|
using InterfaceForward.Domain.Shared.Helpers;
|
||||||
using TrackCenter.Application.Dtos.ProvideServices;
|
using TrackCenter.Application.Dtos.ProvideServices;
|
||||||
@ -17,23 +16,23 @@ namespace TrackCenter.Application.Messaging;
|
|||||||
public class TrackDeleteEventHandler(
|
public class TrackDeleteEventHandler(
|
||||||
ProvideQueries provideQueries,
|
ProvideQueries provideQueries,
|
||||||
IOrderRepository orderRepository,
|
IOrderRepository orderRepository,
|
||||||
IDistributedEventBus eventBus,
|
IMessagePublisher messagePublisher,
|
||||||
ITrackDetailsEsRepository trackDetailsEsRepository,
|
ITrackDetailsEsRepository trackDetailsEsRepository,
|
||||||
IOrderOperationRecordEsRepository orderOperationRecordEsRepository,
|
IOrderOperationRecordEsRepository orderOperationRecordEsRepository,
|
||||||
BroadcastingService broadcastingService,
|
BroadcastingService broadcastingService,
|
||||||
WarningSignalPublisher warningSignalPublisher)
|
WarningSignalPublisher warningSignalPublisher)
|
||||||
: IEventHandler<TrackDeleteEvent>, ITransientDependency
|
: IMessageHandle<TrackDeleteEvent>, ITransientDependency
|
||||||
{
|
{
|
||||||
[UnitOfWork(IsTransactional = true)]
|
[UnitOfWork(IsTransactional = true)]
|
||||||
public virtual async Task HandleAsync(TrackDeleteEvent @event, CancellationToken cancellationToken = default)
|
public virtual async Task HandleAsync(TrackDeleteEvent message, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (!CanDelete(@event)) return;
|
if (!CanDelete(message)) return;
|
||||||
|
|
||||||
// 处理删除轨迹
|
// 处理删除轨迹
|
||||||
await HandleDeleteTrackAsync(@event);
|
await HandleDeleteTrackAsync(message);
|
||||||
|
|
||||||
// 根据订单关联关系异步向下刷(异步)
|
// 根据订单关联关系异步向下刷(异步)
|
||||||
await DownByOrderLink(@event);
|
await DownByOrderLink(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DownByOrderLink(TrackDeleteEvent @event)
|
private async Task DownByOrderLink(TrackDeleteEvent @event)
|
||||||
@ -77,7 +76,7 @@ public class TrackDeleteEventHandler(
|
|||||||
var subEvent = nextEvent.DeepCopy();
|
var subEvent = nextEvent.DeepCopy();
|
||||||
subEvent.OrderIds = subOrderIds;
|
subEvent.OrderIds = subOrderIds;
|
||||||
// 关联单继续走删除链路(原 CAP 误发到 Upsert topic,此处修正)
|
// 关联单继续走删除链路(原 CAP 误发到 Upsert topic,此处修正)
|
||||||
await eventBus.PublishAsync(subEvent);
|
await messagePublisher.PublishAsync(subEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,63 +1,44 @@
|
|||||||
using System.Text;
|
using Fake.Messaging;
|
||||||
using Fake.UnitOfWork;
|
using Fake.UnitOfWork;
|
||||||
|
using InterfaceForward.Domain.Shared.Helpers;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using RabbitMQ.Client.Events;
|
|
||||||
using TrackCenter.Application.Dtos.TrackPush;
|
using TrackCenter.Application.Dtos.TrackPush;
|
||||||
|
using TrackCenter.Application.Events;
|
||||||
using TrackCenter.Application.Helpers;
|
using TrackCenter.Application.Helpers;
|
||||||
using TrackCenter.Application.Services.Broadcasting;
|
using TrackCenter.Application.Services.Broadcasting;
|
||||||
using TrackCenter.Application.Services.Warning.Handlers;
|
using TrackCenter.Application.Services.Warning.Handlers;
|
||||||
using TrackCenter.Domain.Aggregates.OrderAggregate;
|
using TrackCenter.Domain.Aggregates.OrderAggregate;
|
||||||
using TrackCenter.Domain.Aggregates.TrackPushAggregate;
|
using TrackCenter.Domain.Aggregates.TrackPushAggregate;
|
||||||
|
|
||||||
namespace TrackCenter.Application.Rabbit;
|
namespace TrackCenter.Application.Messaging;
|
||||||
|
|
||||||
[ExposeServices(typeof(IRabbitHandler))]
|
/// <summary>
|
||||||
public class TrackPushCompletedEventHandler : ITransientDependency, IRabbitHandler
|
/// 接口通轨迹推送完成回调 → 独立队列 <see cref="GlobalConst.TrackPushCompletedSubscribe"/>。
|
||||||
|
/// </summary>
|
||||||
|
[MessageSubscribe(GlobalConst.TrackPushCompletedSubscribe, ExternalQueue = true)]
|
||||||
|
public class TrackPushCompletedEventHandler(
|
||||||
|
IOrderRepository orderRepository,
|
||||||
|
ITrackPushRecordEsRepository trackPushRecordEsRepository,
|
||||||
|
BroadcastingService broadcastingService,
|
||||||
|
IReturnWarningHandler returnWarningHandler)
|
||||||
|
: IMessageHandle<InterfaceRelayForwardReplayEvent>, ITransientDependency
|
||||||
{
|
{
|
||||||
private readonly IOrderRepository _orderRepository;
|
public virtual async Task HandleAsync(
|
||||||
private readonly ITrackPushRecordEsRepository _trackPushRecordEsRepository;
|
InterfaceRelayForwardReplayEvent message,
|
||||||
private readonly BroadcastingService _broadcastingService;
|
CancellationToken cancellationToken = default)
|
||||||
private readonly IReturnWarningHandler _returnWarningHandler;
|
|
||||||
|
|
||||||
public TrackPushCompletedEventHandler(IOrderRepository orderRepository,
|
|
||||||
ITrackPushRecordEsRepository trackPushRecordEsRepository,
|
|
||||||
BroadcastingService broadcastingService, IReturnWarningHandler returnWarningHandler)
|
|
||||||
{
|
{
|
||||||
_orderRepository = orderRepository;
|
|
||||||
_trackPushRecordEsRepository = trackPushRecordEsRepository;
|
|
||||||
_broadcastingService = broadcastingService;
|
|
||||||
_returnWarningHandler = returnWarningHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Enable(ConsumeOptions options)
|
|
||||||
{
|
|
||||||
return options.Queue.StartsWith(GlobalConst.TrackPushCompletedSubscribe);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnitOfWork(IsTransactional = true)]
|
|
||||||
public virtual async Task Handle(BasicDeliverEventArgs args)
|
|
||||||
{
|
|
||||||
var msg = string.Empty;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
msg = Encoding.UTF8.GetString(args.Body.ToArray());
|
await ConsumerAsync(message);
|
||||||
var @event = System.Text.Json.JsonSerializer.Deserialize<InterfaceRelayForwardReplayEvent>(msg);
|
|
||||||
if (@event == null)
|
|
||||||
{
|
|
||||||
Log.Warning(
|
|
||||||
$"rabbit on queue received msg can't convert to {nameof(InterfaceRelayForwardReplayEvent)}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await ConsumerAsync(@event);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error($"TrackPushCompletedEventHandler出错,错误信息:{ex}\r\n-----\r\n消息:{msg}");
|
Log.Error($"TrackPushCompletedEventHandler出错,错误信息:{ex}\r\n-----\r\n消息:{message.ToJson()}");
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ConsumerAsync(InterfaceRelayForwardReplayEvent @event)
|
private async Task ConsumerAsync(InterfaceRelayForwardReplayEvent @event)
|
||||||
{
|
{
|
||||||
var optionType = Base64Helper.DeSerialize<string>(@event.Attach);
|
var optionType = Base64Helper.DeSerialize<string>(@event.Attach);
|
||||||
var pushInputs = new List<TrackPushInput>();
|
var pushInputs = new List<TrackPushInput>();
|
||||||
@ -91,16 +72,16 @@ public class TrackPushCompletedEventHandler : ITransientDependency, IRabbitHandl
|
|||||||
|
|
||||||
// 推送广播
|
// 推送广播
|
||||||
if (logs.First().IsToMq)
|
if (logs.First().IsToMq)
|
||||||
_broadcastingService.TrackPushCompletedPublicTopic(logs.Select(log => BuildDto(log, @event.Data)).ToList());
|
broadcastingService.TrackPushCompletedPublicTopic(logs.Select(log => BuildDto(log, @event.Data)).ToList());
|
||||||
|
|
||||||
// 写入推送日志
|
// 写入推送日志
|
||||||
await _trackPushRecordEsRepository.AddManyAsync(logs);
|
await trackPushRecordEsRepository.AddManyAsync(logs);
|
||||||
|
|
||||||
// 同步更新订单主表
|
// 同步更新订单主表
|
||||||
await TrackPushAfterUpdateOrderAsync(isAdd, @event.IsSuccess, logs);
|
await TrackPushAfterUpdateOrderAsync(isAdd, @event.IsSuccess, logs);
|
||||||
|
|
||||||
// 引发预警计算
|
// 引发预警计算
|
||||||
await _returnWarningHandler.ReceiveTrackPushRecordHandleAsync(@event.IsSuccess, @event.RequestParams, logs, pushInputs, updateInputs);
|
await returnWarningHandler.ReceiveTrackPushRecordHandleAsync(@event.IsSuccess, @event.RequestParams, logs, pushInputs, updateInputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task TrackPushAfterUpdateOrderAsync(bool isAdd, bool isSuccess, List<TrackPushRecordIndex> logs)
|
private async Task TrackPushAfterUpdateOrderAsync(bool isAdd, bool isSuccess, List<TrackPushRecordIndex> logs)
|
||||||
@ -118,7 +99,7 @@ public class TrackPushCompletedEventHandler : ITransientDependency, IRabbitHandl
|
|||||||
LatestPushError = x.Message
|
LatestPushError = x.Message
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
await _orderRepository.UpdateRangeAsync(orders, x => new
|
await orderRepository.UpdateRangeAsync(orders, x => new
|
||||||
{
|
{
|
||||||
x.QuestionType,
|
x.QuestionType,
|
||||||
x.LatestPushError
|
x.LatestPushError
|
||||||
@ -136,7 +117,7 @@ public class TrackPushCompletedEventHandler : ITransientDependency, IRabbitHandl
|
|||||||
LatestPushTime = x.CreateTime,
|
LatestPushTime = x.CreateTime,
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
await _orderRepository.UpdateRangeAsync(orders, x => new
|
await orderRepository.UpdateRangeAsync(orders, x => new
|
||||||
{
|
{
|
||||||
x.QuestionType,
|
x.QuestionType,
|
||||||
x.LatestPushError,
|
x.LatestPushError,
|
||||||
@ -1,7 +1,6 @@
|
|||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Fake.EventBus;
|
using Fake.Messaging;
|
||||||
using Fake.EventBus.Distributed;
|
|
||||||
using Fake.UnitOfWork;
|
using Fake.UnitOfWork;
|
||||||
using InterfaceForward.Domain.Shared.Helpers;
|
using InterfaceForward.Domain.Shared.Helpers;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
@ -29,7 +28,7 @@ public class TrackPushEventHandler(
|
|||||||
BroadcastingService broadcastingService,
|
BroadcastingService broadcastingService,
|
||||||
ITrackDetailsEsRepository trackDetailsEsRepository,
|
ITrackDetailsEsRepository trackDetailsEsRepository,
|
||||||
InterfaceForwardService interfaceForwardService)
|
InterfaceForwardService interfaceForwardService)
|
||||||
: IEventHandler<TrackPushEvent>, ITransientDependency
|
: IMessageHandle<TrackPushEvent>, ITransientDependency
|
||||||
{
|
{
|
||||||
private List<OrderEntity> _orders = null!;
|
private List<OrderEntity> _orders = null!;
|
||||||
private List<TrackPushContentConfigDto> _pushConfigs = null!;
|
private List<TrackPushContentConfigDto> _pushConfigs = null!;
|
||||||
|
|||||||
@ -1,13 +1,11 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Text;
|
using Fake.Messaging;
|
||||||
using Fake.EventBus.Distributed;
|
|
||||||
using Fake.UnitOfWork;
|
using Fake.UnitOfWork;
|
||||||
using InterfaceForward.Domain.Shared.Helpers;
|
using InterfaceForward.Domain.Shared.Helpers;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using RabbitMQ.Client.Events;
|
|
||||||
using TrackCenter.Application.Dtos.TrackPull;
|
using TrackCenter.Application.Dtos.TrackPull;
|
||||||
using TrackCenter.Application.Events;
|
using TrackCenter.Application.Events;
|
||||||
using TrackCenter.Application.Helpers;
|
using TrackCenter.Application.Helpers;
|
||||||
@ -16,47 +14,37 @@ using TrackCenter.Application.Services.TrackPull;
|
|||||||
using TrackCenter.Domain.Aggregates.OrderAggregate;
|
using TrackCenter.Domain.Aggregates.OrderAggregate;
|
||||||
using TrackCenter.Domain.Aggregates.TrackDetailsAggregate;
|
using TrackCenter.Domain.Aggregates.TrackDetailsAggregate;
|
||||||
|
|
||||||
namespace TrackCenter.Application.Rabbit;
|
namespace TrackCenter.Application.Messaging;
|
||||||
|
|
||||||
[ExposeServices(typeof(IRabbitHandler))]
|
/// <summary>
|
||||||
|
/// 接口通轨迹刷新回调 → 独立队列 <see cref="GlobalConst.TrackRefreshSubscribe"/>。
|
||||||
|
/// </summary>
|
||||||
|
[MessageSubscribe(GlobalConst.TrackRefreshSubscribe, ExternalQueue = true)]
|
||||||
public class TrackRefreshEventHandler(
|
public class TrackRefreshEventHandler(
|
||||||
IOrderRepository orderRepository,
|
IOrderRepository orderRepository,
|
||||||
IDistributedEventBus eventBus,
|
IMessagePublisher messagePublisher,
|
||||||
TrackPullCacheService trackPullCacheService,
|
TrackPullCacheService trackPullCacheService,
|
||||||
ITrackDetailsEsRepository trackDetailsEsRepository,
|
ITrackDetailsEsRepository trackDetailsEsRepository,
|
||||||
ILogger<TrackRefreshEventHandler> logger,
|
ILogger<TrackRefreshEventHandler> logger,
|
||||||
IOptionsMonitor<InterfaceRelayParamsConfigOptions> options)
|
IOptionsMonitor<InterfaceRelayParamsConfigOptions> options)
|
||||||
: ITransientDependency, IRabbitHandler
|
: IMessageHandle<InterfaceRelayForwardReplayEvent>, ITransientDependency
|
||||||
{
|
{
|
||||||
public bool Enable(ConsumeOptions coptions)
|
public virtual async Task HandleAsync(
|
||||||
|
InterfaceRelayForwardReplayEvent message,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return coptions.Queue.StartsWith(GlobalConst.TrackRefreshSubscribe);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnitOfWork(IsTransactional = true)]
|
|
||||||
public virtual async Task Handle(BasicDeliverEventArgs args)
|
|
||||||
{
|
|
||||||
var msg = string.Empty;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
msg = Encoding.UTF8.GetString(args.Body.ToArray());
|
await ConsumerAsync(message);
|
||||||
var @event = System.Text.Json.JsonSerializer.Deserialize<InterfaceRelayForwardReplayEvent>(msg);
|
|
||||||
if (@event == null)
|
|
||||||
{
|
|
||||||
logger.LogWarning(
|
|
||||||
$"rabbit on queue received msg can't convert to {nameof(InterfaceRelayForwardReplayEvent)}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await ConsumerAsync(@event);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error($"TrackRefreshEventHandler出错,错误信息:{ex}\r\n-----\r\n消息:{msg}");
|
Log.Error($"TrackRefreshEventHandler出错,错误信息:{ex}\r\n-----\r\n消息:{message.ToJson()}");
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ConsumerAsync(InterfaceRelayForwardReplayEvent @event)
|
private async Task ConsumerAsync(InterfaceRelayForwardReplayEvent @event)
|
||||||
{
|
{
|
||||||
if (!@event.IsSuccess)
|
if (!@event.IsSuccess)
|
||||||
{
|
{
|
||||||
@ -71,15 +59,6 @@ public class TrackRefreshEventHandler(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 最优先级,最匹配的 权重 sort
|
|
||||||
|
|
||||||
// 客户、渠道、产品
|
|
||||||
// */*/* 全部
|
|
||||||
// 客户A/渠道A/产品A
|
|
||||||
// 客户A
|
|
||||||
|
|
||||||
// 客户A 渠道B 产品A
|
|
||||||
|
|
||||||
var config = await trackPullCacheService.GetPullParamsWithContentAsync(attach.AppKey,
|
var config = await trackPullCacheService.GetPullParamsWithContentAsync(attach.AppKey,
|
||||||
attach.ServiceProviderCode, attach.OrderType);
|
attach.ServiceProviderCode, attach.OrderType);
|
||||||
if (config is null)
|
if (config is null)
|
||||||
@ -134,7 +113,6 @@ public class TrackRefreshEventHandler(
|
|||||||
ServiceProviderCode = attach.ServiceProviderCode
|
ServiceProviderCode = attach.ServiceProviderCode
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
if (trackToken is JArray trackTokens)
|
if (trackToken is JArray trackTokens)
|
||||||
{
|
{
|
||||||
foreach (var item in trackTokens)
|
foreach (var item in trackTokens)
|
||||||
@ -284,7 +262,7 @@ public class TrackRefreshEventHandler(
|
|||||||
Extra = trackExtra
|
Extra = trackExtra
|
||||||
};
|
};
|
||||||
|
|
||||||
await eventBus.PublishAsync(trackUpsertEvent);
|
await messagePublisher.PublishAsync(trackUpsertEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task InsertNotMappedTrackAsync(JToken trackToken, TrackRefreshContext context, string? trackPlace,
|
private async Task InsertNotMappedTrackAsync(JToken trackToken, TrackRefreshContext context, string? trackPlace,
|
||||||
@ -1,5 +1,4 @@
|
|||||||
using Fake.EventBus;
|
using Fake.Messaging;
|
||||||
using Fake.EventBus.Distributed;
|
|
||||||
using Fake.UnitOfWork;
|
using Fake.UnitOfWork;
|
||||||
using InterfaceForward.Domain.Shared.Helpers;
|
using InterfaceForward.Domain.Shared.Helpers;
|
||||||
using TrackCenter.Application.Events;
|
using TrackCenter.Application.Events;
|
||||||
@ -18,30 +17,22 @@ namespace TrackCenter.Application.Messaging;
|
|||||||
|
|
||||||
public class TrackUpsertEventHandler(
|
public class TrackUpsertEventHandler(
|
||||||
IOrderRepository orderRepository,
|
IOrderRepository orderRepository,
|
||||||
IDistributedEventBus eventBus,
|
IMessagePublisher messagePublisher,
|
||||||
ProvideQueries provideQueries,
|
ProvideQueries provideQueries,
|
||||||
ITrackDetailsEsRepository trackDetailsEsRepository,
|
ITrackDetailsEsRepository trackDetailsEsRepository,
|
||||||
IOrderOperationRecordEsRepository orderOperationRecordEsRepository,
|
IOrderOperationRecordEsRepository orderOperationRecordEsRepository,
|
||||||
BroadcastingService broadcastingService,
|
BroadcastingService broadcastingService,
|
||||||
WarningSignalPublisher warningSignalPublisher)
|
WarningSignalPublisher warningSignalPublisher)
|
||||||
:
|
:
|
||||||
IEventHandler<TrackUpsertEvent>,
|
IMessageHandle<TrackUpsertEvent>,
|
||||||
IEventHandler<TrackUpsertForRefreshEvent>,
|
IMessageHandle<TrackUpsertForRefreshEvent>,
|
||||||
ITransientDependency
|
ITransientDependency
|
||||||
{
|
{
|
||||||
Task IEventHandler.HandleAsync(Event eventData, CancellationToken cancellationToken)
|
public Task HandleAsync(TrackUpsertEvent message, CancellationToken cancellationToken = default)
|
||||||
=> eventData switch
|
=> ConsumerAsync(message);
|
||||||
{
|
|
||||||
TrackUpsertForRefreshEvent refresh => HandleAsync(refresh, cancellationToken),
|
|
||||||
TrackUpsertEvent upsert => HandleAsync(upsert, cancellationToken),
|
|
||||||
_ => Task.CompletedTask
|
|
||||||
};
|
|
||||||
|
|
||||||
public Task HandleAsync(TrackUpsertEvent @event, CancellationToken cancellationToken = default)
|
public Task HandleAsync(TrackUpsertForRefreshEvent message, CancellationToken cancellationToken = default)
|
||||||
=> ConsumerAsync(@event);
|
=> ConsumerAsync(message);
|
||||||
|
|
||||||
public Task HandleAsync(TrackUpsertForRefreshEvent @event, CancellationToken cancellationToken = default)
|
|
||||||
=> ConsumerAsync(@event);
|
|
||||||
|
|
||||||
private async Task ConsumerAsync(TrackUpsertEvent @event)
|
private async Task ConsumerAsync(TrackUpsertEvent @event)
|
||||||
{
|
{
|
||||||
@ -107,7 +98,7 @@ public class TrackUpsertEventHandler(
|
|||||||
{
|
{
|
||||||
var subEvent = nextEvent.DeepCopy();
|
var subEvent = nextEvent.DeepCopy();
|
||||||
subEvent.OrderIdentifiers = subOrderIds.ToArray();
|
subEvent.OrderIdentifiers = subOrderIds.ToArray();
|
||||||
await eventBus.PublishAsync(subEvent);
|
await messagePublisher.PublishAsync(subEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -200,7 +191,7 @@ public class TrackUpsertEventHandler(
|
|||||||
// 如果存在轨迹标记,则触发订单pod拉取
|
// 如果存在轨迹标记,则触发订单pod拉取
|
||||||
if (!string.IsNullOrWhiteSpace(trackContent.TrackFlagId))
|
if (!string.IsNullOrWhiteSpace(trackContent.TrackFlagId))
|
||||||
{
|
{
|
||||||
await eventBus.PublishAsync(new OrderPodPullEvent
|
await messagePublisher.PublishAsync(new OrderPodPullEvent
|
||||||
{
|
{
|
||||||
AppKey = @event.AppKey,
|
AppKey = @event.AppKey,
|
||||||
OrderIdEsIdDict = insertTracks.ToDictionary(x => x.OrderId, y => y.Id),
|
OrderIdEsIdDict = insertTracks.ToDictionary(x => x.OrderId, y => y.Id),
|
||||||
@ -213,7 +204,7 @@ public class TrackUpsertEventHandler(
|
|||||||
await TrackChangePublicTopicAsync(trackContent, trackChangeEtos, true);
|
await TrackChangePublicTopicAsync(trackContent, trackChangeEtos, true);
|
||||||
|
|
||||||
// 触发订单主表更新事件(异步)
|
// 触发订单主表更新事件(异步)
|
||||||
await eventBus.PublishAsync(new TrackChangeAfterUpdateOrderEvent
|
await messagePublisher.PublishAsync(new TrackChangeAfterUpdateOrderEvent
|
||||||
{
|
{
|
||||||
OrderIds = canNextOrderIds.ToArray(),
|
OrderIds = canNextOrderIds.ToArray(),
|
||||||
IsCompleted = trackContent.IsCompleted,
|
IsCompleted = trackContent.IsCompleted,
|
||||||
@ -248,7 +239,7 @@ public class TrackUpsertEventHandler(
|
|||||||
ForcedPush = @event.ForcedPush,
|
ForcedPush = @event.ForcedPush,
|
||||||
IsToMq = (trackContent.IsToMq || @event.IsToMq)
|
IsToMq = (trackContent.IsToMq || @event.IsToMq)
|
||||||
};
|
};
|
||||||
await eventBus.PublishAsync(trackPushEvent);
|
await messagePublisher.PublishAsync(trackPushEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<List<TrackDetailsIndex>> UpsertTrackAsync(
|
private async Task<List<TrackDetailsIndex>> UpsertTrackAsync(
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
using RabbitMQ.Client.Events;
|
|
||||||
|
|
||||||
namespace TrackCenter.Application.Rabbit;
|
|
||||||
|
|
||||||
public interface IRabbitHandler
|
|
||||||
{
|
|
||||||
bool Enable(ConsumeOptions options);
|
|
||||||
|
|
||||||
Task Handle(BasicDeliverEventArgs args);
|
|
||||||
}
|
|
||||||
@ -1,166 +0,0 @@
|
|||||||
using Fake.RabbitMQ;
|
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using RabbitMQ.Client;
|
|
||||||
using RabbitMQ.Client.Events;
|
|
||||||
|
|
||||||
namespace TrackCenter.Application.Rabbit;
|
|
||||||
|
|
||||||
public class RabbitClient(
|
|
||||||
IRabbitMqChannelPool channelPool,
|
|
||||||
IServiceScopeFactory serviceScopeFactory,
|
|
||||||
ILogger<RabbitClient> logger,
|
|
||||||
IOptions<RabbitOptions> options) : ISingletonDependency, IHostedService
|
|
||||||
{
|
|
||||||
public void Subscribe(ConsumeOptions consumeOptions)
|
|
||||||
{
|
|
||||||
using var channelAccessor = channelPool.Acquire(consumeOptions.Queue);
|
|
||||||
|
|
||||||
if (!channelAccessor.IsNew) return;
|
|
||||||
var channel = channelAccessor.Channel;
|
|
||||||
var decl = new DefaultDeclaration(channel);
|
|
||||||
|
|
||||||
consumeOptions.Declaration.Invoke(decl);
|
|
||||||
|
|
||||||
if (consumeOptions.FetchCount > 0)
|
|
||||||
{
|
|
||||||
channel.BasicQos(0, consumeOptions.FetchCount, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
var consumer = new AsyncEventingBasicConsumer(channel);
|
|
||||||
consumer.Received += (model, ea) =>
|
|
||||||
{
|
|
||||||
_ = Task.Run(async () =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await using var scope = serviceScopeFactory.CreateAsyncScope();
|
|
||||||
foreach (var handler in scope.ServiceProvider.GetServices<IRabbitHandler>())
|
|
||||||
{
|
|
||||||
if (handler.Enable(consumeOptions))
|
|
||||||
{
|
|
||||||
await handler.Handle(ea);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
channel.BasicAck(ea.DeliveryTag, false);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
logger.LogError($"rabbit on queue({consumeOptions.Queue}) received error: {ex}");
|
|
||||||
channel.BasicNack(ea.DeliveryTag, false, consumeOptions.FailedRequeue);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
};
|
|
||||||
|
|
||||||
channel.CallbackException += (sender, args) =>
|
|
||||||
{
|
|
||||||
logger.LogError(args.Exception, "RabbitMQ channel exception");
|
|
||||||
};
|
|
||||||
|
|
||||||
channel.BasicConsume(queue: consumeOptions.Queue,
|
|
||||||
autoAck: false,
|
|
||||||
consumer: consumer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Publish(string exchange, string routingKey, byte[] data, Action<IBasicProperties>? options = null)
|
|
||||||
{
|
|
||||||
using var channelAccessor = channelPool.Acquire(routingKey);
|
|
||||||
var props = channelAccessor.Channel.CreateBasicProperties();
|
|
||||||
options?.Invoke(props);
|
|
||||||
channelAccessor.Channel.BasicPublish(exchange, routingKey, props, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PublishByConfirmSelect(
|
|
||||||
string exchange,
|
|
||||||
string routingKey,
|
|
||||||
byte[] data,
|
|
||||||
Action<IBasicProperties>? options = null
|
|
||||||
)
|
|
||||||
{
|
|
||||||
using var activity = RabbitInstrumentation.ActivitySource.StartActivity("/" + exchange + "/" + routingKey);
|
|
||||||
activity?.SetTag("kind", "publish");
|
|
||||||
using var channelAccessor = channelPool.Acquire(routingKey);
|
|
||||||
var basicProperties = channelAccessor.Channel.CreateBasicProperties();
|
|
||||||
|
|
||||||
// 配置属性
|
|
||||||
if (options != null)
|
|
||||||
options(basicProperties);
|
|
||||||
var model = channelAccessor.Channel;
|
|
||||||
|
|
||||||
// 启用发布确认
|
|
||||||
model.ConfirmSelect();
|
|
||||||
var readOnlyMemory = (ReadOnlyMemory<byte>) data;
|
|
||||||
model.BasicPublish(exchange, routingKey, basicProperties, readOnlyMemory);
|
|
||||||
model.WaitForConfirmsOrDie();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PublishByConfirmSelect(
|
|
||||||
string exchange,
|
|
||||||
string routingKey,
|
|
||||||
IEnumerable<byte[]> datas,
|
|
||||||
Action<IBasicProperties>? options = null
|
|
||||||
)
|
|
||||||
{
|
|
||||||
using var activity = RabbitInstrumentation.ActivitySource.StartActivity("/" + exchange + "/" + routingKey);
|
|
||||||
activity?.SetTag("kind", "publish");
|
|
||||||
using var channelAccessor = channelPool.Acquire(routingKey);
|
|
||||||
var basicProperties = channelAccessor.Channel.CreateBasicProperties();
|
|
||||||
|
|
||||||
// 配置属性
|
|
||||||
if (options != null)
|
|
||||||
options(basicProperties);
|
|
||||||
var model = channelAccessor.Channel;
|
|
||||||
|
|
||||||
// 启用发布确认
|
|
||||||
model.ConfirmSelect();
|
|
||||||
foreach (var data in datas)
|
|
||||||
{
|
|
||||||
var readOnlyMemory = (ReadOnlyMemory<byte>) data;
|
|
||||||
model.BasicPublish(exchange, routingKey, basicProperties, readOnlyMemory);
|
|
||||||
}
|
|
||||||
|
|
||||||
model.WaitForConfirmsOrDie();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UnSubscribe(string queueName, string exchange, string routingKey, bool deleteQueue = false)
|
|
||||||
{
|
|
||||||
logger.LogInformation(
|
|
||||||
$"UnSubscribe queue: {queueName} exchange: {exchange} routingKey: {routingKey} deleteQueue: {deleteQueue}");
|
|
||||||
using var channelAccessor = channelPool.Acquire(queueName);
|
|
||||||
if (deleteQueue)
|
|
||||||
{
|
|
||||||
var passive = channelAccessor.Channel.QueueDeclarePassive(queueName);
|
|
||||||
logger.LogInformation($"Queue {queueName} exists, deleting... {passive.MessageCount} messages in queue");
|
|
||||||
channelAccessor.Channel.QueueDelete(queueName);
|
|
||||||
}
|
|
||||||
|
|
||||||
channelPool.Release(queueName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task StartAsync(CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
if (options.Value.Declarations.Count > 0)
|
|
||||||
{
|
|
||||||
using var channelAccessor = channelPool.Acquire();
|
|
||||||
var channel = channelAccessor.Channel;
|
|
||||||
var decl = new DefaultDeclaration(channel);
|
|
||||||
options.Value.Declarations.ForEach(q => q.Invoke(decl));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var opt in options.Value.Consumes)
|
|
||||||
{
|
|
||||||
Subscribe(opt);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task StopAsync(CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
channelPool.Dispose();
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
using System.Diagnostics;
|
|
||||||
using System.Diagnostics.Metrics;
|
|
||||||
|
|
||||||
namespace TrackCenter.Application.Rabbit;
|
|
||||||
|
|
||||||
public class RabbitInstrumentation
|
|
||||||
{
|
|
||||||
public const string MeterName = "Fake.Rabbit.Meter";
|
|
||||||
public const string ActivitySourceName = "Fake.Rabbit.ActivitySource";
|
|
||||||
|
|
||||||
static RabbitInstrumentation()
|
|
||||||
{
|
|
||||||
string version = typeof (RabbitInstrumentation).Assembly.GetName().Version?.ToString();
|
|
||||||
Meter = new Meter(MeterName, version);
|
|
||||||
ActivitySource = new ActivitySource(ActivitySourceName, version);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Meter Meter { get; }
|
|
||||||
|
|
||||||
public static ActivitySource ActivitySource { get; }
|
|
||||||
}
|
|
||||||
@ -1,84 +0,0 @@
|
|||||||
using RabbitMQ.Client;
|
|
||||||
|
|
||||||
namespace TrackCenter.Application.Rabbit;
|
|
||||||
|
|
||||||
public class RabbitOptions
|
|
||||||
{
|
|
||||||
public List<ConsumeOptions> Consumes { get; set; } = new();
|
|
||||||
|
|
||||||
public List<Action<IDeclaration>> Declarations { get; set; } = new();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ConsumeOptions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 队列名
|
|
||||||
/// </summary>
|
|
||||||
public string Queue { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 并行度
|
|
||||||
/// </summary>
|
|
||||||
public ushort FetchCount { get; set; } = 1;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// handle发生异常,是否重回队列
|
|
||||||
/// </summary>
|
|
||||||
public bool FailedRequeue { get; set; }
|
|
||||||
|
|
||||||
public Action<IDeclaration> Declaration { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IDeclaration
|
|
||||||
{
|
|
||||||
void QueueDeclare(string queue, bool durable, bool autoDelete = false, bool exclusive = false,
|
|
||||||
IDictionary<string, object> arguments = null);
|
|
||||||
|
|
||||||
void ExchangeDeclare(string exchange, string type, bool durable, bool autoDelete = false,
|
|
||||||
IDictionary<string, object> arguments = null);
|
|
||||||
|
|
||||||
void QueueBind(string queue, string exchange, string routingKey,
|
|
||||||
IDictionary<string, object> arguments = null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DefaultDeclaration : IDeclaration
|
|
||||||
{
|
|
||||||
private readonly IModel _chnl;
|
|
||||||
|
|
||||||
// ReSharper disable once ConvertToPrimaryConstructor
|
|
||||||
public DefaultDeclaration(IModel chnl)
|
|
||||||
{
|
|
||||||
_chnl = chnl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void QueueDeclare(string queue, bool durable, bool autoDelete = false, bool exclusive = false,
|
|
||||||
IDictionary<string, object> arguments = null)
|
|
||||||
{
|
|
||||||
_chnl.QueueDeclare(
|
|
||||||
queue: queue,
|
|
||||||
durable: durable,
|
|
||||||
autoDelete: autoDelete,
|
|
||||||
exclusive: exclusive,
|
|
||||||
arguments: arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ExchangeDeclare(string exchange, string type, bool durable, bool autoDelete = false,
|
|
||||||
IDictionary<string, object> arguments = null)
|
|
||||||
{
|
|
||||||
_chnl.ExchangeDeclare(
|
|
||||||
exchange: exchange,
|
|
||||||
type: type,
|
|
||||||
durable: durable,
|
|
||||||
autoDelete: autoDelete,
|
|
||||||
arguments: arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void QueueBind(string queue, string exchange, string routingKey, IDictionary<string, object> arguments)
|
|
||||||
{
|
|
||||||
_chnl.QueueBind(
|
|
||||||
queue: queue,
|
|
||||||
exchange: exchange,
|
|
||||||
routingKey: routingKey,
|
|
||||||
arguments: arguments);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,74 +1,102 @@
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Fake.RabbitMQ;
|
||||||
using InterfaceForward.Domain.Shared.Helpers;
|
using InterfaceForward.Domain.Shared.Helpers;
|
||||||
|
using RabbitMQ.Client;
|
||||||
using TrackCenter.Application.Dtos.TrackPush;
|
using TrackCenter.Application.Dtos.TrackPush;
|
||||||
using TrackCenter.Application.Events;
|
using TrackCenter.Application.Events;
|
||||||
using TrackCenter.Application.Rabbit;
|
|
||||||
|
|
||||||
namespace TrackCenter.Application.Services.Broadcasting;
|
namespace TrackCenter.Application.Services.Broadcasting;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 广播服务
|
/// 对外 Topic 广播(下游仍按 Newtonsoft PascalCase 契约消费,不经 Messaging 信封)。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BroadcastingService : ITransientDependency
|
public class BroadcastingService(IRabbitMqChannelPool channelPool) : ITransientDependency
|
||||||
{
|
{
|
||||||
private readonly RabbitClient _rabbitClient;
|
public void TrackChangePublicTopic(TrackChangeEto eto, string AppCode)
|
||||||
|
|
||||||
public BroadcastingService(RabbitClient rabbitClient)
|
|
||||||
{
|
{
|
||||||
_rabbitClient = rabbitClient;
|
PublishByConfirmSelect(
|
||||||
}
|
|
||||||
|
|
||||||
public void TrackChangePublicTopic(TrackChangeEto eto, string AppCode)
|
|
||||||
{
|
|
||||||
_rabbitClient.PublishByConfirmSelect(
|
|
||||||
GlobalConst.TrackChangeExchange,
|
GlobalConst.TrackChangeExchange,
|
||||||
|
ExchangeType.Topic,
|
||||||
$"TrackChange.{AppCode}",
|
$"TrackChange.{AppCode}",
|
||||||
Encoding.UTF8.GetBytes(eto.ToJson()),
|
Encoding.UTF8.GetBytes(eto.ToJson()),
|
||||||
prop => { prop.Persistent = true; }
|
prop => { prop.Persistent = true; });
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 轨迹推送完成广播(批量)
|
/// 轨迹推送完成广播(批量)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="list"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public void TrackPushCompletedPublicTopic(List<TrackPushRecordDto> list)
|
public void TrackPushCompletedPublicTopic(List<TrackPushRecordDto> list)
|
||||||
{
|
{
|
||||||
var data = list
|
var data = list
|
||||||
.Select(TrackPushRecordDtoToEvent)
|
.Select(TrackPushRecordDtoToEvent)
|
||||||
.Select(x => Encoding.UTF8.GetBytes(x.ToJson()));
|
.Select(x => Encoding.UTF8.GetBytes(x.ToJson()));
|
||||||
var log = list.First();
|
var log = list.First();
|
||||||
_rabbitClient.PublishByConfirmSelect(
|
PublishByConfirmSelect(
|
||||||
GlobalConst.TrackPushExchange,
|
GlobalConst.TrackPushExchange,
|
||||||
|
ExchangeType.Topic,
|
||||||
$"TrackPush.{log.AppKey}",
|
$"TrackPush.{log.AppKey}",
|
||||||
data,
|
data,
|
||||||
prop => { prop.Persistent = true; }
|
prop => { prop.Persistent = true; });
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 轨迹推送完成广播
|
/// 轨迹推送完成广播
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="log"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public void TrackPushCompletedPublicTopic(TrackPushRecordDto log)
|
public void TrackPushCompletedPublicTopic(TrackPushRecordDto log)
|
||||||
{
|
{
|
||||||
var data = TrackPushRecordDtoToEvent(log);
|
var data = TrackPushRecordDtoToEvent(log);
|
||||||
_rabbitClient.PublishByConfirmSelect(GlobalConst.TrackPushExchange, $"TrackPush.{log.AppKey}",
|
PublishByConfirmSelect(
|
||||||
Encoding.UTF8.GetBytes(data.ToJson()), prop => { prop.Persistent = true; });
|
GlobalConst.TrackPushExchange,
|
||||||
|
ExchangeType.Topic,
|
||||||
|
$"TrackPush.{log.AppKey}",
|
||||||
|
Encoding.UTF8.GetBytes(data.ToJson()),
|
||||||
|
prop => { prop.Persistent = true; });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 轨迹推送失败广播
|
/// 轨迹推送失败广播
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="log"></param>
|
|
||||||
public void TrackPushFailedPubilcTopic(TrackPushRecordDto log)
|
public void TrackPushFailedPubilcTopic(TrackPushRecordDto log)
|
||||||
{
|
{
|
||||||
//暂时使用推送完成模型,后续可能会出现有区分度的模型
|
//暂时使用推送完成模型,后续可能会出现有区分度的模型
|
||||||
TrackPushCompletedPublicTopic(log);
|
TrackPushCompletedPublicTopic(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void PublishByConfirmSelect(
|
||||||
|
string exchange,
|
||||||
|
string exchangeType,
|
||||||
|
string routingKey,
|
||||||
|
byte[] data,
|
||||||
|
Action<IBasicProperties>? options = null)
|
||||||
|
{
|
||||||
|
using var channelAccessor = channelPool.Acquire(routingKey);
|
||||||
|
var channel = channelAccessor.Channel;
|
||||||
|
channel.ExchangeDeclare(exchange, exchangeType, durable: true);
|
||||||
|
var props = channel.CreateBasicProperties();
|
||||||
|
options?.Invoke(props);
|
||||||
|
channel.ConfirmSelect();
|
||||||
|
channel.BasicPublish(exchange, routingKey, props, data);
|
||||||
|
channel.WaitForConfirmsOrDie();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PublishByConfirmSelect(
|
||||||
|
string exchange,
|
||||||
|
string exchangeType,
|
||||||
|
string routingKey,
|
||||||
|
IEnumerable<byte[]> datas,
|
||||||
|
Action<IBasicProperties>? options = null)
|
||||||
|
{
|
||||||
|
using var channelAccessor = channelPool.Acquire(routingKey);
|
||||||
|
var channel = channelAccessor.Channel;
|
||||||
|
channel.ExchangeDeclare(exchange, exchangeType, durable: true);
|
||||||
|
var props = channel.CreateBasicProperties();
|
||||||
|
options?.Invoke(props);
|
||||||
|
channel.ConfirmSelect();
|
||||||
|
foreach (var data in datas)
|
||||||
|
channel.BasicPublish(exchange, routingKey, props, data);
|
||||||
|
channel.WaitForConfirmsOrDie();
|
||||||
|
}
|
||||||
|
|
||||||
private static TrackPushCompletedEvent TrackPushRecordDtoToEvent(TrackPushRecordDto log)
|
private static TrackPushCompletedEvent TrackPushRecordDtoToEvent(TrackPushRecordDto log)
|
||||||
{
|
{
|
||||||
return new TrackPushCompletedEvent
|
return new TrackPushCompletedEvent
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using Fake.EventBus.Distributed;
|
using Fake.Messaging;
|
||||||
using Fake.UnitOfWork;
|
using Fake.UnitOfWork;
|
||||||
using TrackCenter.Application.Dtos.ProvideServices;
|
using TrackCenter.Application.Dtos.ProvideServices;
|
||||||
using TrackCenter.Application.Events;
|
using TrackCenter.Application.Events;
|
||||||
@ -13,7 +13,7 @@ namespace TrackCenter.Application.Services.ProvideServices;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class OrderService
|
public partial class OrderService
|
||||||
{
|
{
|
||||||
private readonly IDistributedEventBus _eventBus = eventBus;
|
private readonly IMessagePublisher _messagePublisher = messagePublisher;
|
||||||
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository = trackDetailsEsRepository;
|
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository = trackDetailsEsRepository;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -130,7 +130,7 @@ public partial class OrderService
|
|||||||
IsAdd = true // 存在则不新增
|
IsAdd = true // 存在则不新增
|
||||||
};
|
};
|
||||||
|
|
||||||
await _eventBus.PublishAsync(fillTrackEvent);
|
await _messagePublisher.PublishAsync(fillTrackEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
using Fake.EventBus.Distributed;
|
using Fake.Messaging;
|
||||||
using TrackCenter.Application.Dtos.ProvideServices;
|
using TrackCenter.Application.Dtos.ProvideServices;
|
||||||
using TrackCenter.Domain.Aggregates.OrderAggregate;
|
using TrackCenter.Domain.Aggregates.OrderAggregate;
|
||||||
using TrackCenter.Domain.Aggregates.TrackDetailsAggregate;
|
using TrackCenter.Domain.Aggregates.TrackDetailsAggregate;
|
||||||
@ -17,7 +17,7 @@ public partial class OrderService(
|
|||||||
IOrderRepository orderRepository,
|
IOrderRepository orderRepository,
|
||||||
IOrderOperationRecordEsRepository orderOperationRecordEsRepository,
|
IOrderOperationRecordEsRepository orderOperationRecordEsRepository,
|
||||||
ITrackPullConfigRepository trackPullConfigRepository,
|
ITrackPullConfigRepository trackPullConfigRepository,
|
||||||
IDistributedEventBus eventBus,
|
IMessagePublisher messagePublisher,
|
||||||
ITrackDetailsEsRepository trackDetailsEsRepository,
|
ITrackDetailsEsRepository trackDetailsEsRepository,
|
||||||
IServiceProvider serviceProvider)
|
IServiceProvider serviceProvider)
|
||||||
: ApplicationServiceBase
|
: ApplicationServiceBase
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using Fake.EventBus.Distributed;
|
using Fake.Messaging;
|
||||||
using Fake.UnitOfWork;
|
using Fake.UnitOfWork;
|
||||||
using TrackCenter.Application.Dtos.ProvideServices;
|
using TrackCenter.Application.Dtos.ProvideServices;
|
||||||
using TrackCenter.Application.Dtos.TrackOrder;
|
using TrackCenter.Application.Dtos.TrackOrder;
|
||||||
@ -20,20 +20,20 @@ namespace TrackCenter.Application.Services.ProvideServices;
|
|||||||
[Route("/ProviderService")]
|
[Route("/ProviderService")]
|
||||||
public class TrackPushService : ApplicationServiceBase
|
public class TrackPushService : ApplicationServiceBase
|
||||||
{
|
{
|
||||||
private readonly IDistributedEventBus _eventBus;
|
private readonly IMessagePublisher _messagePublisher;
|
||||||
private readonly IOrderRepository _orderRepository;
|
private readonly IOrderRepository _orderRepository;
|
||||||
private readonly ITrackPushConfigRepository _trackPushConfigRepository;
|
private readonly ITrackPushConfigRepository _trackPushConfigRepository;
|
||||||
private readonly ITrackPushRecordEsRepository _trackPushRecordEsRepository;
|
private readonly ITrackPushRecordEsRepository _trackPushRecordEsRepository;
|
||||||
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
|
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
|
||||||
|
|
||||||
public TrackPushService(IOrderRepository orderRepository
|
public TrackPushService(IOrderRepository orderRepository
|
||||||
, IDistributedEventBus eventBus
|
, IMessagePublisher messagePublisher
|
||||||
, ITrackPushRecordEsRepository trackPushRecordEsRepository
|
, ITrackPushRecordEsRepository trackPushRecordEsRepository
|
||||||
, ITrackPushConfigRepository trackPushConfigRepository,
|
, ITrackPushConfigRepository trackPushConfigRepository,
|
||||||
ITrackDetailsEsRepository trackDetailsEsRepository)
|
ITrackDetailsEsRepository trackDetailsEsRepository)
|
||||||
{
|
{
|
||||||
_orderRepository = orderRepository;
|
_orderRepository = orderRepository;
|
||||||
_eventBus = eventBus;
|
_messagePublisher = messagePublisher;
|
||||||
_trackPushRecordEsRepository = trackPushRecordEsRepository;
|
_trackPushRecordEsRepository = trackPushRecordEsRepository;
|
||||||
_trackPushConfigRepository = trackPushConfigRepository;
|
_trackPushConfigRepository = trackPushConfigRepository;
|
||||||
_trackDetailsEsRepository = trackDetailsEsRepository;
|
_trackDetailsEsRepository = trackDetailsEsRepository;
|
||||||
@ -155,7 +155,7 @@ public class TrackPushService : ApplicationServiceBase
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
await _eventBus.PublishAsync(trackPushEvent);
|
await _messagePublisher.PublishAsync(trackPushEvent);
|
||||||
pushedOrderNos.Add(order.OrderNo);
|
pushedOrderNos.Add(order.OrderNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using Fake.EventBus.Distributed;
|
using Fake.Messaging;
|
||||||
using Fake.UnitOfWork;
|
using Fake.UnitOfWork;
|
||||||
using InterfaceForward.Domain.Shared.Helpers;
|
using InterfaceForward.Domain.Shared.Helpers;
|
||||||
using TrackCenter.Application.Dtos.ProvideServices;
|
using TrackCenter.Application.Dtos.ProvideServices;
|
||||||
@ -19,7 +19,7 @@ namespace TrackCenter.Application.Services.ProvideServices;
|
|||||||
[Route("/ProviderService")]
|
[Route("/ProviderService")]
|
||||||
public partial class TrackService(
|
public partial class TrackService(
|
||||||
IOrderRepository orderRepository,
|
IOrderRepository orderRepository,
|
||||||
IDistributedEventBus eventBus,
|
IMessagePublisher messagePublisher,
|
||||||
ITrackDetailsEsRepository trackDetailsEsRepository,
|
ITrackDetailsEsRepository trackDetailsEsRepository,
|
||||||
ITrackContentRepository trackContentRepository)
|
ITrackContentRepository trackContentRepository)
|
||||||
: ApplicationServiceBase
|
: ApplicationServiceBase
|
||||||
@ -90,7 +90,7 @@ public partial class TrackService(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 删除轨迹(异步)
|
// 删除轨迹(异步)
|
||||||
await eventBus.PublishAsync(new TrackDeleteEvent
|
await messagePublisher.PublishAsync(new TrackDeleteEvent
|
||||||
{
|
{
|
||||||
EsIds = esIds,
|
EsIds = esIds,
|
||||||
OrderIds = new[] { orderId },
|
OrderIds = new[] { orderId },
|
||||||
@ -165,7 +165,7 @@ public partial class TrackService(
|
|||||||
AppKey = input.AppKey,
|
AppKey = input.AppKey,
|
||||||
OperationMan = CurrentUser.UserName
|
OperationMan = CurrentUser.UserName
|
||||||
};
|
};
|
||||||
await eventBus.PublishAsync(@event);
|
await messagePublisher.PublishAsync(@event);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -219,7 +219,7 @@ public partial class TrackService(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
@event.OperationMan = CurrentUser.UserName;
|
@event.OperationMan = CurrentUser.UserName;
|
||||||
await eventBus.PublishAsync(@event);
|
await messagePublisher.PublishAsync(@event);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -292,7 +292,7 @@ public partial class TrackService(
|
|||||||
ForcedPush = input.ForcedPush,
|
ForcedPush = input.ForcedPush,
|
||||||
IsToMq = input.IsToMq,
|
IsToMq = input.IsToMq,
|
||||||
};
|
};
|
||||||
await eventBus.PublishAsync(@event);
|
await messagePublisher.PublishAsync(@event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using Fake.EventBus.Distributed;
|
using Fake.Messaging;
|
||||||
using Fake.Domain.Dtos;
|
using Fake.Domain.Dtos;
|
||||||
using Fake.UnitOfWork;
|
using Fake.UnitOfWork;
|
||||||
using InterfaceForward.Domain.Shared.Helpers;
|
using InterfaceForward.Domain.Shared.Helpers;
|
||||||
@ -27,7 +27,7 @@ public class ReturnWarningService : ApplicationServiceBase
|
|||||||
private readonly IReturnWarningHandler _returnWarningHandler;
|
private readonly IReturnWarningHandler _returnWarningHandler;
|
||||||
private readonly IWarningRuleRepository _warningRuleRepository;
|
private readonly IWarningRuleRepository _warningRuleRepository;
|
||||||
private readonly IWarningDetailsEsRepository _warningDetailsEsRepository;
|
private readonly IWarningDetailsEsRepository _warningDetailsEsRepository;
|
||||||
private readonly IDistributedEventBus _eventBus;
|
private readonly IMessagePublisher _messagePublisher;
|
||||||
private readonly TrackStatusNameDictCache _trackStatusNameDictCache;
|
private readonly TrackStatusNameDictCache _trackStatusNameDictCache;
|
||||||
private readonly AppNameDictCache _appNameDictCache;
|
private readonly AppNameDictCache _appNameDictCache;
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ public class ReturnWarningService : ApplicationServiceBase
|
|||||||
IReturnWarningHandler returnWarningHandler,
|
IReturnWarningHandler returnWarningHandler,
|
||||||
IWarningRuleRepository warningRuleRepository,
|
IWarningRuleRepository warningRuleRepository,
|
||||||
IWarningDetailsEsRepository warningDetailsEsRepository,
|
IWarningDetailsEsRepository warningDetailsEsRepository,
|
||||||
IDistributedEventBus eventBus,
|
IMessagePublisher messagePublisher,
|
||||||
TrackStatusNameDictCache trackStatusNameDictCache,
|
TrackStatusNameDictCache trackStatusNameDictCache,
|
||||||
AppNameDictCache appNameDictCache
|
AppNameDictCache appNameDictCache
|
||||||
)
|
)
|
||||||
@ -45,7 +45,7 @@ public class ReturnWarningService : ApplicationServiceBase
|
|||||||
_returnWarningHandler = returnWarningHandler;
|
_returnWarningHandler = returnWarningHandler;
|
||||||
_warningRuleRepository = warningRuleRepository;
|
_warningRuleRepository = warningRuleRepository;
|
||||||
_warningDetailsEsRepository = warningDetailsEsRepository;
|
_warningDetailsEsRepository = warningDetailsEsRepository;
|
||||||
_eventBus = eventBus;
|
_messagePublisher = messagePublisher;
|
||||||
_trackStatusNameDictCache = trackStatusNameDictCache;
|
_trackStatusNameDictCache = trackStatusNameDictCache;
|
||||||
_appNameDictCache = appNameDictCache;
|
_appNameDictCache = appNameDictCache;
|
||||||
}
|
}
|
||||||
@ -279,7 +279,7 @@ public class ReturnWarningService : ApplicationServiceBase
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
await _eventBus.PublishAsync(trackPushEvent);
|
await _messagePublisher.PublishAsync(trackPushEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $"即将进行{filtered.Count}个回传推送!";
|
return $"即将进行{filtered.Count}个回传推送!";
|
||||||
|
|||||||
@ -9,8 +9,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Fake.AspNetCore" Version="$(FakePackageVersion)" />
|
<PackageReference Include="Fake.AspNetCore" Version="$(FakePackageVersion)" />
|
||||||
<PackageReference Include="Fake.EventBus.RabbitMQ" Version="$(FakePackageVersion)" />
|
<PackageReference Include="Fake.Messaging.RabbitMQ" Version="$(FakePackageVersion)" />
|
||||||
<PackageReference Include="Fake.EventBus.IntegrationEventLog" Version="$(FakePackageVersion)" />
|
|
||||||
<PackageReference Include="Fake.ObjectMapping.AutoMapper" Version="$(FakePackageVersion)" />
|
<PackageReference Include="Fake.ObjectMapping.AutoMapper" Version="$(FakePackageVersion)" />
|
||||||
<PackageReference Include="Fake.ObjectStorage.TencentCos" Version="$(FakePackageVersion)" />
|
<PackageReference Include="Fake.ObjectStorage.TencentCos" Version="$(FakePackageVersion)" />
|
||||||
|
|
||||||
|
|||||||
@ -1,28 +1,26 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Fake;
|
using Fake;
|
||||||
using Fake.EventBus.RabbitMQ;
|
using Fake.Messaging;
|
||||||
|
using Fake.Messaging.RabbitMQ;
|
||||||
using Fake.Modularity;
|
using Fake.Modularity;
|
||||||
using Fake.ObjectMapping.AutoMapper;
|
using Fake.ObjectMapping.AutoMapper;
|
||||||
using Fake.ObjectStorage;
|
using Fake.ObjectStorage;
|
||||||
using Fake.RabbitMQ;
|
|
||||||
using FreeRedis;
|
using FreeRedis;
|
||||||
using Hangfire;
|
using Hangfire;
|
||||||
using Hangfire.Redis.StackExchange;
|
using Hangfire.Redis.StackExchange;
|
||||||
using InterfaceForward.Domain.Shared.Helpers;
|
using InterfaceForward.Domain.Shared.Helpers;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using RabbitMQ.Client;
|
|
||||||
using TrackCenter.Application.Kafka;
|
|
||||||
using TrackCenter.Application.HostServices;
|
using TrackCenter.Application.HostServices;
|
||||||
|
using TrackCenter.Application.Kafka;
|
||||||
|
using TrackCenter.Application.Messaging;
|
||||||
using TrackCenter.Application.Options;
|
using TrackCenter.Application.Options;
|
||||||
using TrackCenter.Application.Rabbit;
|
|
||||||
|
|
||||||
namespace TrackCenter.Application;
|
namespace TrackCenter.Application;
|
||||||
|
|
||||||
[DependsOn(typeof(FakeRabbitMqModule))]
|
|
||||||
[DependsOn(typeof(FakeObjectMappingAutoMapperModule))]
|
[DependsOn(typeof(FakeObjectMappingAutoMapperModule))]
|
||||||
[DependsOn(typeof(FakeEventBusRabbitMqModule))]
|
[DependsOn(typeof(FakeMessagingRabbitMqModule))]
|
||||||
[DependsOn(typeof(FakeObjectStorageTencentCosModule))]
|
[DependsOn(typeof(FakeObjectStorageTencentCosModule))]
|
||||||
[DependsOn(typeof(TrackCenterDomainModule))]
|
[DependsOn(typeof(TrackCenterDomainModule))]
|
||||||
public class TrackCenterApplicationModule : FakeModule
|
public class TrackCenterApplicationModule : FakeModule
|
||||||
@ -36,50 +34,27 @@ public class TrackCenterApplicationModule : FakeModule
|
|||||||
options.ScanProfiles<TrackCenterApplicationModule>();
|
options.ScanProfiles<TrackCenterApplicationModule>();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Messaging:独立队列;PrefetchCount=0 → ProcessorCount;接口通可按 TrackApp:TrackRefreshFetchCount 覆盖
|
||||||
|
context.Services.Configure<MessagingOptions>(configuration.GetSection(MessagingOptions.SectionName));
|
||||||
|
context.Services.Configure<RabbitMessageOptions>(o =>
|
||||||
|
{
|
||||||
|
configuration.GetSection(RabbitMessageOptions.SectionName).Bind(o);
|
||||||
|
|
||||||
|
var refreshFetch = configuration.GetValue<ushort>("TrackApp:TrackRefreshFetchCount");
|
||||||
|
if (refreshFetch > 0)
|
||||||
|
{
|
||||||
|
o.Handlers[nameof(TrackRefreshEventHandler)] =
|
||||||
|
new RabbitMessageHandlerOptions { PrefetchCount = refreshFetch };
|
||||||
|
o.Handlers[nameof(TrackPushCompletedEventHandler)] =
|
||||||
|
new RabbitMessageHandlerOptions { PrefetchCount = refreshFetch };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var redisOptions = configuration.GetSection("Redis").Get<ConnectionStringBuilder>();
|
var redisOptions = configuration.GetSection("Redis").Get<ConnectionStringBuilder>();
|
||||||
if (redisOptions == null)
|
if (redisOptions == null)
|
||||||
throw new FakeException("未找到Redis相关配置,请检查配置文件中是否包含名为Redis的节点");
|
throw new FakeException("未找到Redis相关配置,请检查配置文件中是否包含名为Redis的节点");
|
||||||
RedisHelper.Init(redisOptions, showLogInfo: Debugger.IsAttached);
|
RedisHelper.Init(redisOptions, showLogInfo: Debugger.IsAttached);
|
||||||
|
|
||||||
context.Services.AddHostedService<RabbitClient>();
|
|
||||||
context.Services.Configure<RabbitOptions>(options =>
|
|
||||||
{
|
|
||||||
options.Declarations = new List<Action<IDeclaration>>()
|
|
||||||
{
|
|
||||||
o => o.ExchangeDeclare(GlobalConst.TrackChangeExchange, ExchangeType.Topic, true),
|
|
||||||
o => o.ExchangeDeclare(GlobalConst.TrackPushExchange, ExchangeType.Topic, true)
|
|
||||||
};
|
|
||||||
options.Consumes = new List<ConsumeOptions>
|
|
||||||
{
|
|
||||||
new()
|
|
||||||
{
|
|
||||||
Queue = GlobalConst.TrackRefreshSubscribe,
|
|
||||||
FetchCount = configuration.GetValue<ushort>("TrackApp:TrackRefreshFetchCount"),
|
|
||||||
FailedRequeue = false,
|
|
||||||
Declaration = o =>
|
|
||||||
{
|
|
||||||
o.ExchangeDeclare(GlobalConst.InterfaceRelayExchange, ExchangeType.Direct, true);
|
|
||||||
o.QueueDeclare(GlobalConst.TrackRefreshSubscribe, true);
|
|
||||||
o.QueueBind(GlobalConst.TrackRefreshSubscribe, GlobalConst.InterfaceRelayExchange,
|
|
||||||
GlobalConst.TrackRefreshSubscribe);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new()
|
|
||||||
{
|
|
||||||
Queue = GlobalConst.TrackPushCompletedSubscribe,
|
|
||||||
FetchCount = configuration.GetValue<ushort>("TrackApp:TrackRefreshFetchCount"),
|
|
||||||
FailedRequeue = false,
|
|
||||||
Declaration = o =>
|
|
||||||
{
|
|
||||||
o.ExchangeDeclare(GlobalConst.InterfaceRelayExchange, ExchangeType.Direct, true);
|
|
||||||
o.QueueDeclare(GlobalConst.TrackPushCompletedSubscribe, true);
|
|
||||||
o.QueueBind(GlobalConst.TrackPushCompletedSubscribe, GlobalConst.InterfaceRelayExchange,
|
|
||||||
GlobalConst.TrackPushCompletedSubscribe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
context.Services.Configure<TrackAppOptions>(configuration.GetSection("TrackApp"));
|
context.Services.Configure<TrackAppOptions>(configuration.GetSection("TrackApp"));
|
||||||
context.Services.Configure<InterfaceRelayParamsConfigOptions>(
|
context.Services.Configure<InterfaceRelayParamsConfigOptions>(
|
||||||
configuration.GetSection("InterfaceRelayParamsConfig"));
|
configuration.GetSection("InterfaceRelayParamsConfig"));
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user