Browse Source

Publish `DistributedEventSent/Received` events in `LocalDistributedEventBus`.

And publish `DistributedEventSent` after publishing the distributed message.
pull/21985/head
maliming 1 year ago
parent
commit
489c74f1ff
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 11
      framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AzureDistributedEventBus.cs
  2. 8
      framework/src/Volo.Abp.EventBus.Dapr/Volo/Abp/EventBus/Dapr/DaprDistributedEventBus.cs
  3. 38
      framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs
  4. 18
      framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs
  5. 20
      framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs
  6. 6
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs
  7. 42
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/LocalDistributedEventBus.cs
  8. 22
      framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Distributed/DistributedEventHandles.cs
  9. 63
      framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Distributed/LocalDistributedEventBus_Test.cs
  10. 62
      framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Distributed/UnitTestLocalEventBus.cs

11
framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AzureDistributedEventBus.cs

@ -102,6 +102,8 @@ public class AzureDistributedEventBus : DistributedEventBusBase, ISingletonDepen
public async override Task PublishFromOutboxAsync(OutgoingEventInfo outgoingEvent, OutboxConfig outboxConfig)
{
await PublishAsync(outgoingEvent.EventName, outgoingEvent.EventData, outgoingEvent.GetCorrelationId(), outgoingEvent.Id);
using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
await TriggerDistributedEventSentAsync(new DistributedEventSent()
@ -111,8 +113,6 @@ public class AzureDistributedEventBus : DistributedEventBusBase, ISingletonDepen
EventData = outgoingEvent.EventData
});
}
await PublishAsync(outgoingEvent.EventName, outgoingEvent.EventData, outgoingEvent.GetCorrelationId(), outgoingEvent.Id);
}
public async override Task PublishManyFromOutboxAsync(IEnumerable<OutgoingEventInfo> outgoingEvents, OutboxConfig outboxConfig)
@ -141,7 +141,12 @@ public class AzureDistributedEventBus : DistributedEventBusBase, ISingletonDepen
throw new AbpException(
"The message is too large to fit in the batch. Set AbpEventBusBoxesOptions.OutboxWaitingEventMaxCount to reduce the number");
}
}
await publisher.SendMessagesAsync(messageBatch);
foreach (var outgoingEvent in outgoingEventArray)
{
using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
await TriggerDistributedEventSentAsync(new DistributedEventSent()
@ -152,8 +157,6 @@ public class AzureDistributedEventBus : DistributedEventBusBase, ISingletonDepen
});
}
}
await publisher.SendMessagesAsync(messageBatch);
}
public async override Task ProcessFromInboxAsync(IncomingEventInfo incomingEvent, InboxConfig inboxConfig)

8
framework/src/Volo.Abp.EventBus.Dapr/Volo/Abp/EventBus/Dapr/DaprDistributedEventBus.cs

@ -153,6 +153,8 @@ public class DaprDistributedEventBus : DistributedEventBusBase, ISingletonDepend
public async override Task PublishFromOutboxAsync(OutgoingEventInfo outgoingEvent, OutboxConfig outboxConfig)
{
await PublishToDaprAsync(outgoingEvent.EventName, Serializer.Deserialize(outgoingEvent.EventData, GetEventType(outgoingEvent.EventName)), outgoingEvent.Id, outgoingEvent.GetCorrelationId());
using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
await TriggerDistributedEventSentAsync(new DistributedEventSent()
@ -162,8 +164,6 @@ public class DaprDistributedEventBus : DistributedEventBusBase, ISingletonDepend
EventData = outgoingEvent.EventData
});
}
await PublishToDaprAsync(outgoingEvent.EventName, Serializer.Deserialize(outgoingEvent.EventData, GetEventType(outgoingEvent.EventName)), outgoingEvent.Id, outgoingEvent.GetCorrelationId());
}
public async override Task PublishManyFromOutboxAsync(IEnumerable<OutgoingEventInfo> outgoingEvents, OutboxConfig outboxConfig)
@ -172,6 +172,8 @@ public class DaprDistributedEventBus : DistributedEventBusBase, ISingletonDepend
foreach (var outgoingEvent in outgoingEventArray)
{
await PublishToDaprAsync(outgoingEvent.EventName, Serializer.Deserialize(outgoingEvent.EventData, GetEventType(outgoingEvent.EventName)), outgoingEvent.Id, outgoingEvent.GetCorrelationId());
using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
await TriggerDistributedEventSentAsync(new DistributedEventSent()
@ -181,8 +183,6 @@ public class DaprDistributedEventBus : DistributedEventBusBase, ISingletonDepend
EventData = outgoingEvent.EventData
});
}
await PublishToDaprAsync(outgoingEvent.EventName, Serializer.Deserialize(outgoingEvent.EventData, GetEventType(outgoingEvent.EventName)), outgoingEvent.Id, outgoingEvent.GetCorrelationId());
}
}

38
framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs

@ -197,16 +197,6 @@ public class KafkaDistributedEventBus : DistributedEventBusBase, ISingletonDepen
OutgoingEventInfo outgoingEvent,
OutboxConfig outboxConfig)
{
using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
await TriggerDistributedEventSentAsync(new DistributedEventSent()
{
Source = DistributedEventSource.Outbox,
EventName = outgoingEvent.EventName,
EventData = outgoingEvent.EventData
});
}
var headers = new Headers
{
{ "messageId", System.Text.Encoding.UTF8.GetBytes(outgoingEvent.Id.ToString("N")) }
@ -222,6 +212,16 @@ public class KafkaDistributedEventBus : DistributedEventBusBase, ISingletonDepen
outgoingEvent.EventData,
headers
);
using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
await TriggerDistributedEventSentAsync(new DistributedEventSent()
{
Source = DistributedEventSource.Outbox,
EventName = outgoingEvent.EventName,
EventData = outgoingEvent.EventData
});
}
}
public async override Task PublishManyFromOutboxAsync(IEnumerable<OutgoingEventInfo> outgoingEvents, OutboxConfig outboxConfig)
@ -242,6 +242,15 @@ public class KafkaDistributedEventBus : DistributedEventBusBase, ISingletonDepen
headers.Add(EventBusConsts.CorrelationIdHeaderName, System.Text.Encoding.UTF8.GetBytes(outgoingEvent.GetCorrelationId()!));
}
producer.Produce(
AbpKafkaEventBusOptions.TopicName,
new Message<string, byte[]>
{
Key = outgoingEvent.EventName,
Value = outgoingEvent.EventData,
Headers = headers
});
using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
await TriggerDistributedEventSentAsync(new DistributedEventSent()
@ -251,15 +260,6 @@ public class KafkaDistributedEventBus : DistributedEventBusBase, ISingletonDepen
EventData = outgoingEvent.EventData
});
}
producer.Produce(
AbpKafkaEventBusOptions.TopicName,
new Message<string, byte[]>
{
Key = outgoingEvent.EventName,
Value = outgoingEvent.EventData,
Headers = headers
});
}
}

18
framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs

@ -207,6 +207,8 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
OutgoingEventInfo outgoingEvent,
OutboxConfig outboxConfig)
{
await PublishAsync(outgoingEvent.EventName, outgoingEvent.EventData, eventId: outgoingEvent.Id, correlationId: outgoingEvent.GetCorrelationId());
using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
await TriggerDistributedEventSentAsync(new DistributedEventSent()
@ -216,8 +218,6 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
EventData = outgoingEvent.EventData
});
}
await PublishAsync(outgoingEvent.EventName, outgoingEvent.EventData, eventId: outgoingEvent.Id, correlationId: outgoingEvent.GetCorrelationId());
}
public async override Task PublishManyFromOutboxAsync(
@ -231,6 +231,13 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
foreach (var outgoingEvent in outgoingEventArray)
{
await PublishAsync(
channel,
outgoingEvent.EventName,
outgoingEvent.EventData,
eventId: outgoingEvent.Id,
correlationId: outgoingEvent.GetCorrelationId());
using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
await TriggerDistributedEventSentAsync(new DistributedEventSent()
@ -240,13 +247,6 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
EventData = outgoingEvent.EventData
});
}
await PublishAsync(
channel,
outgoingEvent.EventName,
outgoingEvent.EventData,
eventId: outgoingEvent.Id,
correlationId: outgoingEvent.GetCorrelationId());
}
channel.WaitForConfirmsOrDie();

20
framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs

@ -253,6 +253,14 @@ public class RebusDistributedEventBus : DistributedEventBusBase, ISingletonDepen
var eventType = EventTypes.GetOrDefault(outgoingEvent.EventName)!;
var eventData = Serializer.Deserialize(outgoingEvent.EventData, eventType);
var headers = new Dictionary<string, string>();
if (outgoingEvent.GetCorrelationId() != null)
{
headers.Add(EventBusConsts.CorrelationIdHeaderName, outgoingEvent.GetCorrelationId()!);
}
await PublishAsync(eventType, eventData, eventId: outgoingEvent.Id, headersArguments: headers);
using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
await TriggerDistributedEventSentAsync(new DistributedEventSent() {
@ -261,14 +269,6 @@ public class RebusDistributedEventBus : DistributedEventBusBase, ISingletonDepen
EventData = outgoingEvent.EventData
});
}
var headers = new Dictionary<string, string>();
if (outgoingEvent.GetCorrelationId() != null)
{
headers.Add(EventBusConsts.CorrelationIdHeaderName, outgoingEvent.GetCorrelationId()!);
}
await PublishAsync(eventType, eventData, eventId: outgoingEvent.Id, headersArguments: headers);
}
public async override Task PublishManyFromOutboxAsync(IEnumerable<OutgoingEventInfo> outgoingEvents, OutboxConfig outboxConfig)
@ -279,6 +279,8 @@ public class RebusDistributedEventBus : DistributedEventBusBase, ISingletonDepen
{
foreach (var outgoingEvent in outgoingEventArray)
{
await PublishFromOutboxAsync(outgoingEvent, outboxConfig);
using (CorrelationIdProvider.Change(outgoingEvent.GetCorrelationId()))
{
await TriggerDistributedEventSentAsync(new DistributedEventSent()
@ -288,8 +290,6 @@ public class RebusDistributedEventBus : DistributedEventBusBase, ISingletonDepen
EventData = outgoingEvent.EventData
});
}
await PublishFromOutboxAsync(outgoingEvent, outboxConfig);
}
await scope.CompleteAsync();

6
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@ -85,14 +85,14 @@ public abstract class DistributedEventBusBase : EventBusBase, IDistributedEventB
}
}
await PublishToEventBusAsync(eventType, eventData);
await TriggerDistributedEventSentAsync(new DistributedEventSent()
{
Source = DistributedEventSource.Direct,
EventName = EventNameAttribute.GetNameOrDefault(eventType),
EventData = eventData
});
await PublishToEventBusAsync(eventType, eventData);
}
public abstract Task PublishFromOutboxAsync(

42
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/LocalDistributedEventBus.cs

@ -122,24 +122,50 @@ public class LocalDistributedEventBus : IDistributedEventBus, ISingletonDependen
_localEventBus.UnsubscribeAll(eventType);
}
public Task PublishAsync<TEvent>(TEvent eventData, bool onUnitOfWorkComplete = true)
public async Task PublishAsync<TEvent>(TEvent eventData, bool onUnitOfWorkComplete = true)
where TEvent : class
{
return _localEventBus.PublishAsync(eventData, onUnitOfWorkComplete);
await _localEventBus.PublishAsync(eventData, onUnitOfWorkComplete);
await PublishDistributedEventSentReceivedAsync(typeof(TEvent), eventData, onUnitOfWorkComplete);
}
public Task PublishAsync(Type eventType, object eventData, bool onUnitOfWorkComplete = true)
public async Task PublishAsync(Type eventType, object eventData, bool onUnitOfWorkComplete = true)
{
return _localEventBus.PublishAsync(eventType, eventData, onUnitOfWorkComplete);
await _localEventBus.PublishAsync(eventType, eventData, onUnitOfWorkComplete);
await PublishDistributedEventSentReceivedAsync(eventType, eventData, onUnitOfWorkComplete);
}
public Task PublishAsync<TEvent>(TEvent eventData, bool onUnitOfWorkComplete = true, bool useOutbox = true) where TEvent : class
public async Task PublishAsync<TEvent>(TEvent eventData, bool onUnitOfWorkComplete = true, bool useOutbox = true) where TEvent : class
{
return _localEventBus.PublishAsync(eventData, onUnitOfWorkComplete);
await _localEventBus.PublishAsync(eventData, onUnitOfWorkComplete);
await PublishDistributedEventSentReceivedAsync(typeof(TEvent), eventData, onUnitOfWorkComplete);
}
public Task PublishAsync(Type eventType, object eventData, bool onUnitOfWorkComplete = true, bool useOutbox = true)
public async Task PublishAsync(Type eventType, object eventData, bool onUnitOfWorkComplete = true, bool useOutbox = true)
{
return _localEventBus.PublishAsync(eventType, eventData, onUnitOfWorkComplete);
await _localEventBus.PublishAsync(eventType, eventData, onUnitOfWorkComplete);
await PublishDistributedEventSentReceivedAsync(eventType, eventData, onUnitOfWorkComplete);
}
private async Task PublishDistributedEventSentReceivedAsync(Type eventType, object eventData, bool onUnitOfWorkComplete)
{
if (eventType == typeof(DistributedEventSent) || eventType == typeof(DistributedEventReceived))
{
return;
}
await _localEventBus.PublishAsync(new DistributedEventSent
{
Source = DistributedEventSource.Direct,
EventName = EventNameAttribute.GetNameOrDefault(eventType),
EventData = eventData
}, onUnitOfWorkComplete);
await _localEventBus.PublishAsync(new DistributedEventReceived
{
Source = DistributedEventSource.Direct,
EventName = EventNameAttribute.GetNameOrDefault(eventType),
EventData = eventData
}, onUnitOfWorkComplete);
}
}

22
framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Distributed/DistributedEventHandles.cs

@ -1,22 +0,0 @@
using System.Threading.Tasks;
namespace Volo.Abp.EventBus.Distributed;
public class DistributedEventHandles : ILocalEventHandler<DistributedEventSent>, ILocalEventHandler<DistributedEventReceived>
{
public static int SentCount { get; set; }
public static int ReceivedCount { get; set; }
public Task HandleEventAsync(DistributedEventSent eventData)
{
SentCount++;
return Task.CompletedTask;
}
public Task HandleEventAsync(DistributedEventReceived eventData)
{
ReceivedCount++;
return Task.CompletedTask;
}
}

63
framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Distributed/LocalDistributedEventBus_Test.cs

@ -1,7 +1,6 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Shouldly;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.EventBus.Local;
using Volo.Abp.Uow;
@ -11,12 +10,6 @@ namespace Volo.Abp.EventBus.Distributed;
public class LocalDistributedEventBus_Test : LocalDistributedEventBusTestBase
{
protected override void AfterAddApplication(IServiceCollection services)
{
services.Replace(ServiceDescriptor.Singleton<ILocalEventBus, UnitTestLocalEventBus>());
base.AfterAddApplication(services);
}
[Fact]
public async Task Should_Call_Handler_AndDispose()
{
@ -76,60 +69,56 @@ public class LocalDistributedEventBus_Test : LocalDistributedEventBusTestBase
public async Task DistributedEventSentAndReceived_Test()
{
var localEventBus = GetRequiredService<ILocalEventBus>();
if (localEventBus is UnitTestLocalEventBus eventBus)
{
eventBus.OnEventHandleInvoking = async (eventType, eventData) =>
{
await localEventBus.PublishAsync(new DistributedEventReceived()
{
Source = DistributedEventSource.Direct,
EventName = EventNameAttribute.GetNameOrDefault(eventType),
EventData = eventData
}, onUnitOfWorkComplete: false);
};
eventBus.OnPublishing = async (eventType, eventData) =>
{
await localEventBus.PublishAsync(new DistributedEventSent()
{
Source = DistributedEventSource.Direct,
EventName = EventNameAttribute.GetNameOrDefault(eventType),
EventData = eventData
}, onUnitOfWorkComplete: false);
};
}
GetRequiredService<ILocalEventBus>().Subscribe<DistributedEventSent, DistributedEventHandles>();
GetRequiredService<ILocalEventBus>().Subscribe<DistributedEventReceived, DistributedEventHandles>();
localEventBus.Subscribe<DistributedEventSent, DistributedEventHandles>();
localEventBus.Subscribe<DistributedEventReceived, DistributedEventHandles>();
DistributedEventBus.Subscribe<MyEventDate, MyEventHandle>();
using (var uow = GetRequiredService<IUnitOfWorkManager>().Begin())
{
MyEventDate.Order = string.Empty;
await DistributedEventBus.PublishAsync(new MyEventDate(), onUnitOfWorkComplete: false);
Assert.Equal(1, DistributedEventHandles.SentCount);
Assert.Equal(1, DistributedEventHandles.ReceivedCount);
MyEventDate.Order.ShouldBe(nameof(MyEventHandle) + nameof(DistributedEventSent) + nameof(DistributedEventReceived));
MyEventDate.Order = string.Empty;
await DistributedEventBus.PublishAsync(new MyEventDate(), onUnitOfWorkComplete: true);
MyEventDate.Order.ShouldBe(string.Empty);
await uow.CompleteAsync();
Assert.Equal(2, DistributedEventHandles.SentCount);
Assert.Equal(2, DistributedEventHandles.ReceivedCount);
MyEventDate.Order.ShouldBe(nameof(MyEventHandle) + nameof(DistributedEventSent) + nameof(DistributedEventReceived));
}
}
class MyEventDate
{
public static string Order { get; set; } = string.Empty;
}
class MyEventHandle : IDistributedEventHandler<MyEventDate>
{
public Task HandleEventAsync(MyEventDate eventData)
{
MyEventDate.Order += nameof(MyEventHandle);
return Task.CompletedTask;
}
}
class DistributedEventHandles : ILocalEventHandler<DistributedEventSent>, ILocalEventHandler<DistributedEventReceived>
{
public Task HandleEventAsync(DistributedEventSent eventData)
{
MyEventDate.Order += nameof(DistributedEventSent);
return Task.CompletedTask;
}
public Task HandleEventAsync(DistributedEventReceived eventData)
{
MyEventDate.Order += nameof(DistributedEventReceived);
return Task.CompletedTask;
}
}
}

62
framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Distributed/UnitTestLocalEventBus.cs

@ -1,62 +0,0 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.EventBus.Local;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
namespace Volo.Abp.EventBus.Distributed;
/// <summary>
/// This class is used in unit tests and supports to publish DistributedEventSent and DistributedEventReceived events.
/// </summary>
public class UnitTestLocalEventBus : LocalEventBus
{
public UnitTestLocalEventBus(
[NotNull] IOptions<AbpLocalEventBusOptions> options,
[NotNull] IServiceScopeFactory serviceScopeFactory,
[NotNull] ICurrentTenant currentTenant,
[NotNull] IUnitOfWorkManager unitOfWorkManager,
[NotNull] IEventHandlerInvoker eventHandlerInvoker)
: base(options, serviceScopeFactory, currentTenant, unitOfWorkManager, eventHandlerInvoker)
{
}
public Func<Type, object, Task> OnEventHandleInvoking { get; set; }
protected async override Task InvokeEventHandlerAsync(IEventHandler eventHandler, object eventData, Type eventType)
{
if (OnEventHandleInvoking != null && eventType != typeof(DistributedEventSent) && eventType != typeof(DistributedEventReceived))
{
await OnEventHandleInvoking(eventType, eventData);
}
await base.InvokeEventHandlerAsync(eventHandler, eventData, eventType);
}
public Func<Type, object, Task> OnPublishing { get; set; }
public async override Task PublishAsync(
Type eventType,
object eventData,
bool onUnitOfWorkComplete = true)
{
if (onUnitOfWorkComplete && UnitOfWorkManager.Current != null)
{
AddToUnitOfWork(
UnitOfWorkManager.Current,
new UnitOfWorkEventRecord(eventType, eventData, EventOrderGenerator.GetNext())
);
return;
}
if (OnPublishing != null && eventType != typeof(DistributedEventSent) && eventType != typeof(DistributedEventReceived))
{
await OnPublishing(eventType, eventData);
}
await PublishToEventBusAsync(eventType, eventData);
}
}
Loading…
Cancel
Save