Browse Source

feat(webhooks): added data access configuration

pull/532/head
cKey 4 years ago
parent
commit
5d525ea3ba
  1. 5
      aspnet-core/Directory.Build.props
  2. 9
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs
  3. 21
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/Extensions/WebhookSubscriptionExtensions.cs
  4. 4
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/NullWebhookSendAttemptStore.cs
  5. 12
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookManager.cs
  6. 6
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionManager.cs
  7. 4
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json
  8. 4
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json
  9. 8
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfiguration.cs
  10. 2
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfigurationDictionaryExtensions.cs
  11. 4
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConsts.cs
  12. 12
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookEventEto.cs
  13. 7
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookEventRecordConsts.cs
  14. 16
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSendAttemptEto.cs
  15. 6
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordConsts.cs
  16. 9
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionConsts.cs
  17. 14
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionEto.cs
  18. 4
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/DefaultWebhookManager.cs
  19. 29
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Extensions/WebhookSubscriptionExtensions.cs
  20. 175
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Extensions/WebhookSubscriptionInfoExtensions.cs
  21. 1
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookSendRecordRepository.cs
  22. 5
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookEventRecord.cs
  23. 9
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookEventStore.cs
  24. 69
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendAttemptStore.cs
  25. 3
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecord.cs
  26. 2
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordFilter.cs
  27. 24
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscription.cs
  28. 129
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionsStore.cs
  29. 9
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainMapperProfile.cs
  30. 29
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainModule.cs
  31. 15
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookEventRecordRepository.cs
  32. 58
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookSendRecordRepository.cs
  33. 16
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookSubscriptionRepository.cs
  34. 55
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs
  35. 15
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementEfCoreQueryableExtensions.cs
  36. 4
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementEntityFrameworkCoreModule.cs
  37. 2
      aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Controllers/HomeController.cs
  38. 2
      aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/DataSeeder/WebhooksManagementDataSeederWorker.cs
  39. 5
      aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContext.cs
  40. 2
      aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContextFactory.cs
  41. 10
      aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EventBus/Handlers/TenantSynchronizer.cs
  42. 9
      aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj
  43. 2
      aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Program.cs
  44. 9
      aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Properties/launchSettings.json
  45. 2
      aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/TenantHeaderParamter.cs
  46. 8
      aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs
  47. 4
      aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.DataSeeder.cs
  48. 11
      aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs

5
aspnet-core/Directory.Build.props

@ -12,6 +12,11 @@
<HangfireMySqlStoragePackageVersion>2.0.3</HangfireMySqlStoragePackageVersion> <HangfireMySqlStoragePackageVersion>2.0.3</HangfireMySqlStoragePackageVersion>
<HangfireMSSQLStoragePackageVersion>1.7.28</HangfireMSSQLStoragePackageVersion> <HangfireMSSQLStoragePackageVersion>1.7.28</HangfireMSSQLStoragePackageVersion>
<NESTPackageVersion>7.15.1</NESTPackageVersion> <NESTPackageVersion>7.15.1</NESTPackageVersion>
<OpenTelemetryExtensionsHostingPackageVersion>1.0.0-rc8</OpenTelemetryExtensionsHostingPackageVersion>
<OpenTelemetryExporterZipkinPackageVersion>1.2.0-rc1</OpenTelemetryExporterZipkinPackageVersion>
<OpenTelemetryInstrumentationAspNetCorePackageVersion>1.0.0-rc8</OpenTelemetryInstrumentationAspNetCorePackageVersion>
<OpenTelemetryInstrumentationHttpPackageVersion>1.0.0-rc8</OpenTelemetryInstrumentationHttpPackageVersion>
<OpenTelemetryContribInstrumentationEntityFrameworkCorePackageVersion>1.0.0-beta2</OpenTelemetryContribInstrumentationEntityFrameworkCorePackageVersion>
<QuartzNETPackageVersion>3.3.3</QuartzNETPackageVersion> <QuartzNETPackageVersion>3.3.3</QuartzNETPackageVersion>
<StackExchangeRedisPackageVersion>2.0.593</StackExchangeRedisPackageVersion> <StackExchangeRedisPackageVersion>2.0.593</StackExchangeRedisPackageVersion>
<SerilogPackageVersion>2.10.0</SerilogPackageVersion> <SerilogPackageVersion>2.10.0</SerilogPackageVersion>

9
aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs

@ -1,10 +1,10 @@
using System; using Newtonsoft.Json;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.BackgroundJobs; using Volo.Abp.BackgroundJobs;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Abp.Json;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.Webhooks namespace LINGYUN.Abp.Webhooks
@ -15,7 +15,6 @@ namespace LINGYUN.Abp.Webhooks
private readonly ICurrentTenant _currentTenant; private readonly ICurrentTenant _currentTenant;
private readonly IGuidGenerator _guidGenerator; private readonly IGuidGenerator _guidGenerator;
private readonly IJsonSerializer _jsonSerializer;
private readonly IBackgroundJobManager _backgroundJobManager; private readonly IBackgroundJobManager _backgroundJobManager;
private readonly IWebhookSubscriptionManager _webhookSubscriptionManager; private readonly IWebhookSubscriptionManager _webhookSubscriptionManager;
@ -23,12 +22,10 @@ namespace LINGYUN.Abp.Webhooks
IWebhookSubscriptionManager webhookSubscriptionManager, IWebhookSubscriptionManager webhookSubscriptionManager,
ICurrentTenant currentTenant, ICurrentTenant currentTenant,
IGuidGenerator guidGenerator, IGuidGenerator guidGenerator,
IJsonSerializer jsonSerializer,
IBackgroundJobManager backgroundJobManager) IBackgroundJobManager backgroundJobManager)
{ {
_currentTenant = currentTenant; _currentTenant = currentTenant;
_guidGenerator = guidGenerator; _guidGenerator = guidGenerator;
_jsonSerializer = jsonSerializer;
_backgroundJobManager = backgroundJobManager; _backgroundJobManager = backgroundJobManager;
_webhookSubscriptionManager = webhookSubscriptionManager; _webhookSubscriptionManager = webhookSubscriptionManager;
@ -114,7 +111,7 @@ namespace LINGYUN.Abp.Webhooks
{ {
Id = _guidGenerator.Create(), Id = _guidGenerator.Create(),
WebhookName = webhookName, WebhookName = webhookName,
Data = _jsonSerializer.Serialize(data), Data = JsonConvert.SerializeObject(data),
TenantId = tenantId TenantId = tenantId
}; };

21
aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/Extensions/WebhookSubscriptionExtensions.cs

@ -0,0 +1,21 @@
using System.Collections.Generic;
namespace LINGYUN.Abp.Webhooks.Extensions
{
public static class WebhookSubscriptionExtensions
{
/// <summary>
/// checks if subscribed to given webhook
/// </summary>
/// <returns></returns>
public static bool IsSubscribed(this WebhookSubscriptionInfo webhookSubscription, string webhookName)
{
if (webhookSubscription.Webhooks.IsNullOrEmpty())
{
return false;
}
return webhookSubscription.Webhooks.Contains(webhookName);
}
}
}

4
aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/NullWebhookSendAttemptStore.cs

@ -33,10 +33,10 @@ namespace LINGYUN.Abp.Webhooks
return default; return default;
} }
public Task<IReadOnlyCollection<WebhookSendAttempt>> GetAllSendAttemptsBySubscriptionAsPagedListAsync(Guid? tenantId, Guid subscriptionId, int maxResultCount, public Task<(int TotalCount, IReadOnlyCollection<WebhookSendAttempt> Webhooks)> GetAllSendAttemptsBySubscriptionAsPagedListAsync(Guid? tenantId, Guid subscriptionId, int maxResultCount,
int skipCount) int skipCount)
{ {
return Task.FromResult(new List<WebhookSendAttempt>() as IReadOnlyCollection<WebhookSendAttempt>); return Task.FromResult(ValueTuple.Create(0, new List<WebhookSendAttempt>() as IReadOnlyCollection<WebhookSendAttempt>));
} }
public Task<List<WebhookSendAttempt>> GetAllSendAttemptsByWebhookEventIdAsync(Guid? tenantId, Guid webhookEventId) public Task<List<WebhookSendAttempt>> GetAllSendAttemptsByWebhookEventIdAsync(Guid? tenantId, Guid webhookEventId)

12
aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookManager.cs

@ -1,10 +1,10 @@
using System; using Newtonsoft.Json;
using System;
using System.Globalization; using System.Globalization;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Json;
namespace LINGYUN.Abp.Webhooks namespace LINGYUN.Abp.Webhooks
{ {
@ -13,21 +13,17 @@ namespace LINGYUN.Abp.Webhooks
private const string SignatureHeaderKey = "sha256"; private const string SignatureHeaderKey = "sha256";
private const string SignatureHeaderValueTemplate = SignatureHeaderKey + "={0}"; private const string SignatureHeaderValueTemplate = SignatureHeaderKey + "={0}";
private const string SignatureHeaderName = "abp-webhook-signature"; private const string SignatureHeaderName = "abp-webhook-signature";
protected IJsonSerializer JsonSerializer { get; }
protected IWebhookSendAttemptStore WebhookSendAttemptStore { get; } protected IWebhookSendAttemptStore WebhookSendAttemptStore { get; }
protected WebhookManager( protected WebhookManager(
IJsonSerializer jsonSerializer,
IWebhookSendAttemptStore webhookSendAttemptStore) IWebhookSendAttemptStore webhookSendAttemptStore)
{ {
JsonSerializer = jsonSerializer;
WebhookSendAttemptStore = webhookSendAttemptStore; WebhookSendAttemptStore = webhookSendAttemptStore;
} }
public virtual async Task<WebhookPayload> GetWebhookPayloadAsync(WebhookSenderArgs webhookSenderArgs) public virtual async Task<WebhookPayload> GetWebhookPayloadAsync(WebhookSenderArgs webhookSenderArgs)
{ {
var data = JsonSerializer.Serialize(webhookSenderArgs.Data); var data = JsonConvert.SerializeObject(webhookSenderArgs.Data);
var attemptNumber = await WebhookSendAttemptStore.GetSendAttemptCountAsync( var attemptNumber = await WebhookSendAttemptStore.GetSendAttemptCountAsync(
webhookSenderArgs.TenantId, webhookSenderArgs.TenantId,
@ -72,7 +68,7 @@ namespace LINGYUN.Abp.Webhooks
var payload = await GetWebhookPayloadAsync(webhookSenderArgs); var payload = await GetWebhookPayloadAsync(webhookSenderArgs);
var serializedBody = JsonSerializer.Serialize(payload); var serializedBody = JsonConvert.SerializeObject(payload);
return serializedBody; return serializedBody;
} }

6
aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionManager.cs

@ -93,11 +93,7 @@ namespace LINGYUN.Abp.Webhooks
} }
else else
{ {
var subscription = await WebhookSubscriptionsStore.GetAsync(webhookSubscription.Id); await WebhookSubscriptionsStore.UpdateAsync(webhookSubscription);
subscription.WebhookUri = webhookSubscription.WebhookUri;
subscription.Webhooks = webhookSubscription.Webhooks;
subscription.Headers = webhookSubscription.Headers;
await WebhookSubscriptionsStore.UpdateAsync(subscription);
} }
await uow.SaveChangesAsync(); await uow.SaveChangesAsync();

4
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json

@ -1,8 +1,8 @@
{ {
"culture": "en", "culture": "en",
"texts": { "texts": {
"Features:WebhooksManagement": "WebhooksManagement", "Features:WebhooksManagement": "Webhooks",
"Permission:WebhooksManagement": "WebhooksManagement", "Permission:WebhooksManagement": "Webhooks",
"Permission:ManageSettings": "Manage Settings" "Permission:ManageSettings": "Manage Settings"
} }
} }

4
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json

@ -1,8 +1,8 @@
{ {
"culture": "zh-Hans", "culture": "zh-Hans",
"texts": { "texts": {
"Features:WebhooksManagement": "WebhooksManagement", "Features:WebhooksManagement": "Webhooks",
"Permission:WebhooksManagement": "WebhooksManagement", "Permission:WebhooksManagement": "Webhooks",
"Permission:ManageSettings": "管理设置" "Permission:ManageSettings": "管理设置"
} }
} }

8
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfiguration.cs

@ -8,9 +8,9 @@ public class WebhooksManagementModuleExtensionConfiguration : ModuleExtensionCon
public WebhooksManagementModuleExtensionConfiguration ConfigureWebhooksManagement( public WebhooksManagementModuleExtensionConfiguration ConfigureWebhooksManagement(
Action<EntityExtensionConfiguration> configureAction) Action<EntityExtensionConfiguration> configureAction)
{ {
return this.ConfigureEntity( return this
WebhooksManagementModuleExtensionConsts.EntityNames.Entity, .ConfigureEntity(WebhooksManagementModuleExtensionConsts.EntityNames.WebhookEvent, configureAction)
configureAction .ConfigureEntity(WebhooksManagementModuleExtensionConsts.EntityNames.WebhookSendAttempt, configureAction)
); .ConfigureEntity(WebhooksManagementModuleExtensionConsts.EntityNames.WebhookSubscription, configureAction);
} }
} }

2
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfigurationDictionaryExtensions.cs

@ -1,6 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Text;
using Volo.Abp.ObjectExtending.Modularity; using Volo.Abp.ObjectExtending.Modularity;
namespace LINGYUN.Abp.WebhooksManagement.ObjectExtending; namespace LINGYUN.Abp.WebhooksManagement.ObjectExtending;

4
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConsts.cs

@ -6,6 +6,8 @@ public static class WebhooksManagementModuleExtensionConsts
public static class EntityNames public static class EntityNames
{ {
public const string Entity = "Entity"; public const string WebhookEvent = "WebhookEvent";
public const string WebhookSendAttempt = "WebhookSendAttempt";
public const string WebhookSubscription = "WebhookSubscription";
} }
} }

12
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookEventEto.cs

@ -0,0 +1,12 @@
using System;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.WebhooksManagement;
[Serializable]
public class WebhookEventEto : IMultiTenant
{
public Guid Id { get; set; }
public Guid? TenantId { get; set; }
public string WebhookName { get; set; }
}

7
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookEventRecordConsts.cs

@ -0,0 +1,7 @@
namespace LINGYUN.Abp.WebhooksManagement;
public static class WebhookEventRecordConsts
{
public static int MaxWebhookNameLength { get; set; } = 100;
public static int MaxDataLength { get; set; } = int.MaxValue;
}

16
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSendAttemptEto.cs

@ -0,0 +1,16 @@
using System;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.WebhooksManagement;
[Serializable]
public class WebhookSendAttemptEto : IMultiTenant
{
public Guid Id { get; set; }
public Guid? TenantId { get; set; }
public Guid WebhookEventId { get; set; }
public Guid WebhookSubscriptionId { get; set; }
}

6
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordConsts.cs

@ -0,0 +1,6 @@
namespace LINGYUN.Abp.WebhooksManagement;
public static class WebhookSendRecordConsts
{
public static int MaxResponseLength { get; set; } = int.MaxValue;
}

9
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionConsts.cs

@ -0,0 +1,9 @@
namespace LINGYUN.Abp.WebhooksManagement;
public static class WebhookSubscriptionConsts
{
public static int MaxWebhookUriLength { get; set; } = 255;
public static int MaxSecretLength { get; set; } = 128;
public static int MaxWebhooksLength { get; set; } = int.MaxValue;
public static int MaxHeadersLength { get; set; } = int.MaxValue;
}

14
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionEto.cs

@ -0,0 +1,14 @@
using System;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.WebhooksManagement;
[Serializable]
public class WebhookSubscriptionEto : IMultiTenant
{
public Guid Id { get; set; }
public Guid? TenantId { get; set; }
public string WebhookUri { get; set; }
}

4
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/DefaultWebhookManager.cs

@ -4,7 +4,6 @@ using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Abp.Json;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow; using Volo.Abp.Uow;
@ -19,11 +18,10 @@ public class DefaultWebhookManager : WebhookManager, ITransientDependency
public DefaultWebhookManager( public DefaultWebhookManager(
ICurrentTenant currentTenant, ICurrentTenant currentTenant,
IGuidGenerator guidGenerator, IGuidGenerator guidGenerator,
IJsonSerializer jsonSerializer,
IWebhookSendAttemptStore webhookSendAttemptStore, IWebhookSendAttemptStore webhookSendAttemptStore,
IUnitOfWorkManager unitOfWorkManager, IUnitOfWorkManager unitOfWorkManager,
IWebhookSendRecordRepository webhookSendAttemptRepository) IWebhookSendRecordRepository webhookSendAttemptRepository)
: base(jsonSerializer, webhookSendAttemptStore) : base(webhookSendAttemptStore)
{ {
CurrentTenant = currentTenant; CurrentTenant = currentTenant;
GuidGenerator = guidGenerator; GuidGenerator = guidGenerator;

29
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Extensions/WebhookSubscriptionExtensions.cs

@ -0,0 +1,29 @@
using LINGYUN.Abp.Webhooks;
using Newtonsoft.Json;
using System.Linq;
namespace LINGYUN.Abp.WebhooksManagement.Extensions
{
public static class WebhookSubscriptionExtensions
{
public static string ToSubscribedWebhooksString(this WebhookSubscriptionInfo webhookSubscription)
{
if (webhookSubscription.Webhooks.Any())
{
return JsonConvert.SerializeObject(webhookSubscription.Webhooks);
}
return null;
}
public static string ToWebhookHeadersString(this WebhookSubscriptionInfo webhookSubscription)
{
if (webhookSubscription.Headers.Any())
{
return JsonConvert.SerializeObject(webhookSubscription.Headers);
}
return null;
}
}
}

175
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Extensions/WebhookSubscriptionInfoExtensions.cs

@ -0,0 +1,175 @@
using LINGYUN.Abp.Webhooks;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace LINGYUN.Abp.WebhooksManagement.Extensions
{
public static class WebhookSubscriptionInfoExtensions
{
/// <summary>
/// Return List of subscribed webhooks definitions <see cref="WebhookSubscriptionInfo.Webhooks"/>
/// </summary>
/// <returns></returns>
public static List<string> GetSubscribedWebhooks(this WebhookSubscription webhookSubscription)
{
if (webhookSubscription.Webhooks.IsNullOrWhiteSpace())
{
return new List<string>();
}
return JsonConvert.DeserializeObject<List<string>>(webhookSubscription.Webhooks);
}
/// <summary>
/// Adds webhook subscription to <see cref="WebhookSubscriptionInfo.Webhooks"/> if not exists
/// </summary>
/// <param name="webhookSubscription"></param>
/// <param name="name">webhook unique name</param>
public static void SubscribeWebhook(this WebhookSubscription webhookSubscription, string name)
{
name = name.Trim();
if (name.IsNullOrWhiteSpace())
{
throw new ArgumentNullException(nameof(name), $"{nameof(name)} can not be null, empty or whitespace!");
}
var webhookDefinitions = webhookSubscription.GetSubscribedWebhooks();
if (webhookDefinitions.Contains(name))
{
return;
}
webhookDefinitions.Add(name);
webhookSubscription.SetWebhooks(JsonConvert.SerializeObject(webhookDefinitions));
}
/// <summary>
/// Removes webhook subscription from <see cref="WebhookSubscriptionInfo.Webhooks"/> if exists
/// </summary>
/// <param name="webhookSubscription"></param>
/// <param name="name">webhook unique name</param>
public static void UnsubscribeWebhook(this WebhookSubscription webhookSubscription, string name)
{
name = name.Trim();
if (name.IsNullOrWhiteSpace())
{
throw new ArgumentNullException(nameof(name), $"{nameof(name)} can not be null, empty or whitespace!");
}
var webhookDefinitions = webhookSubscription.GetSubscribedWebhooks();
if (!webhookDefinitions.Contains(name))
{
return;
}
webhookDefinitions.Remove(name);
webhookSubscription.SetWebhooks(JsonConvert.SerializeObject(webhookDefinitions));
}
/// <summary>
/// Clears all <see cref="WebhookSubscriptionInfo.Webhooks"/>
/// </summary>
/// <param name="webhookSubscription"></param>
public static void RemoveAllSubscribedWebhooks(this WebhookSubscription webhookSubscription)
{
webhookSubscription.SetWebhooks(null);
}
/// <summary>
/// if subscribed to given webhook
/// </summary>
/// <returns></returns>
public static bool IsSubscribed(this WebhookSubscription webhookSubscription, string webhookName)
{
if (webhookSubscription.Webhooks.IsNullOrWhiteSpace())
{
return false;
}
return webhookSubscription.GetSubscribedWebhooks().Contains(webhookName);
}
/// <summary>
/// Returns additional webhook headers <see cref="WebhookSubscriptionInfo.Headers"/>
/// </summary>
/// <returns></returns>
public static IDictionary<string, string> GetWebhookHeaders(this WebhookSubscription webhookSubscription)
{
if (webhookSubscription.Headers.IsNullOrWhiteSpace())
{
return new Dictionary<string, string>();
}
return JsonConvert.DeserializeObject<Dictionary<string, string>>(webhookSubscription.Headers);
}
/// <summary>
/// Adds webhook subscription to <see cref="WebhookSubscriptionInfo.Webhooks"/> if not exists
/// </summary>
public static void AddWebhookHeader(this WebhookSubscription webhookSubscription, string key, string value)
{
if (key.IsNullOrWhiteSpace() )
{
throw new ArgumentNullException(nameof(key), $"{nameof(key)} can not be null, empty or whitespace!");
}
if (value.IsNullOrWhiteSpace())
{
throw new ArgumentNullException(nameof(value), $"{nameof(value)} can not be null, empty or whitespace!");
}
var headers = webhookSubscription.GetWebhookHeaders();
headers[key] = value;
webhookSubscription.SetHeaders(JsonConvert.SerializeObject(headers));
}
/// <summary>
/// Adds webhook subscription to <see cref="WebhookSubscriptionInfo.Webhooks"/> if not exists
/// </summary>
/// <param name="webhookSubscription"></param>
/// <param name="header">Key of header</param>
public static void RemoveWebhookHeader(this WebhookSubscription webhookSubscription, string header)
{
if (header.IsNullOrWhiteSpace())
{
throw new ArgumentNullException(nameof(header), $"{nameof(header)} can not be null, empty or whitespace!");
}
var headers = webhookSubscription.GetWebhookHeaders();
if (!headers.ContainsKey(header))
{
return;
}
headers.Remove(header);
webhookSubscription.SetHeaders(JsonConvert.SerializeObject(headers));
}
/// <summary>
/// Clears all <see cref="WebhookSubscriptionInfo.Webhooks"/>
/// </summary>
/// <param name="webhookSubscription"></param>
public static void RemoveAllWebhookHeaders(this WebhookSubscription webhookSubscription)
{
webhookSubscription.SetHeaders(null);
}
public static WebhookSubscriptionInfo ToWebhookSubscriptionInfo(this WebhookSubscription webhookSubscription)
{
return new WebhookSubscriptionInfo
{
Id = webhookSubscription.Id,
TenantId = webhookSubscription.TenantId,
IsActive = webhookSubscription.IsActive,
Secret = webhookSubscription.Secret,
WebhookUri = webhookSubscription.WebhookUri,
Webhooks = webhookSubscription.GetSubscribedWebhooks(),
Headers = webhookSubscription.GetWebhookHeaders()
};
}
}
}

1
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookSendRecordRepository.cs

@ -17,5 +17,6 @@ public interface IWebhookSendRecordRepository : IRepository<WebhookSendRecord, G
string sorting = nameof(WebhookSendRecord.CreationTime), string sorting = nameof(WebhookSendRecord.CreationTime),
int maxResultCount = 10, int maxResultCount = 10,
int skipCount = 10, int skipCount = 10,
bool includeDetails = false,
CancellationToken cancellationToken = default); CancellationToken cancellationToken = default);
} }

5
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookEventRecord.cs

@ -1,4 +1,5 @@
using System; using System;
using Volo.Abp;
using Volo.Abp.Auditing; using Volo.Abp.Auditing;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
@ -23,8 +24,8 @@ public class WebhookEventRecord : Entity<Guid>, IMultiTenant, IHasCreationTime,
string data, string data,
Guid? tenantId = null) : base(id) Guid? tenantId = null) : base(id)
{ {
WebhookName = webhookName; WebhookName = Check.NotNullOrWhiteSpace(webhookName, nameof(webhookName), WebhookEventRecordConsts.MaxWebhookNameLength);
Data = data; Data = Check.Length(data, nameof(data), WebhookEventRecordConsts.MaxDataLength);
TenantId = tenantId; TenantId = tenantId;
} }
} }

9
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookEventStore.cs

@ -11,20 +11,17 @@ public class WebhookEventStore : DomainService, IWebhookEventStore
{ {
protected IObjectMapper<WebhooksManagementDomainModule> ObjectMapper => LazyServiceProvider.LazyGetRequiredService<IObjectMapper<WebhooksManagementDomainModule>>(); protected IObjectMapper<WebhooksManagementDomainModule> ObjectMapper => LazyServiceProvider.LazyGetRequiredService<IObjectMapper<WebhooksManagementDomainModule>>();
protected IUnitOfWorkManager UnitOfWorkManager { get; }
protected IWebhookEventRecordRepository WebhookEventRepository { get; } protected IWebhookEventRecordRepository WebhookEventRepository { get; }
public WebhookEventStore( public WebhookEventStore(
IUnitOfWorkManager unitOfWorkManager,
IWebhookEventRecordRepository webhookEventRepository) IWebhookEventRecordRepository webhookEventRepository)
{ {
UnitOfWorkManager = unitOfWorkManager;
WebhookEventRepository = webhookEventRepository; WebhookEventRepository = webhookEventRepository;
} }
[UnitOfWork]
public async virtual Task<WebhookEvent> GetAsync(Guid? tenantId, Guid id) public async virtual Task<WebhookEvent> GetAsync(Guid? tenantId, Guid id)
{ {
using var uow = UnitOfWorkManager.Begin();
using (CurrentTenant.Change(tenantId)) using (CurrentTenant.Change(tenantId))
{ {
var record = await WebhookEventRepository.GetAsync(id); var record = await WebhookEventRepository.GetAsync(id);
@ -33,9 +30,9 @@ public class WebhookEventStore : DomainService, IWebhookEventStore
} }
} }
[UnitOfWork]
public async virtual Task<Guid> InsertAndGetIdAsync(WebhookEvent webhookEvent) public async virtual Task<Guid> InsertAndGetIdAsync(WebhookEvent webhookEvent)
{ {
using var uow = UnitOfWorkManager.Begin();
using (CurrentTenant.Change(webhookEvent.TenantId)) using (CurrentTenant.Change(webhookEvent.TenantId))
{ {
var record = new WebhookEventRecord( var record = new WebhookEventRecord(
@ -49,8 +46,6 @@ public class WebhookEventStore : DomainService, IWebhookEventStore
await WebhookEventRepository.InsertAsync(record); await WebhookEventRepository.InsertAsync(record);
await uow.SaveChangesAsync();
return record.Id; return record.Id;
} }
} }

69
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendAttemptStore.cs

@ -7,7 +7,6 @@ using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Repositories;
using Volo.Abp.Domain.Services; using Volo.Abp.Domain.Services;
using Volo.Abp.Linq;
using Volo.Abp.ObjectMapping; using Volo.Abp.ObjectMapping;
using Volo.Abp.Uow; using Volo.Abp.Uow;
@ -16,28 +15,21 @@ namespace LINGYUN.Abp.WebhooksManagement;
public class WebhookSendAttemptStore : DomainService, IWebhookSendAttemptStore public class WebhookSendAttemptStore : DomainService, IWebhookSendAttemptStore
{ {
protected IObjectMapper<WebhooksManagementDomainModule> ObjectMapper => LazyServiceProvider.LazyGetRequiredService<IObjectMapper<WebhooksManagementDomainModule>>(); protected IObjectMapper<WebhooksManagementDomainModule> ObjectMapper => LazyServiceProvider.LazyGetRequiredService<IObjectMapper<WebhooksManagementDomainModule>>();
protected IAsyncQueryableExecuter AsyncQueryableExecuter => LazyServiceProvider.LazyGetRequiredService<IAsyncQueryableExecuter>();
protected IUnitOfWorkManager UnitOfWorkManager { get; }
protected IWebhookSendRecordRepository WebhookSendAttemptRepository { get; } protected IWebhookSendRecordRepository WebhookSendAttemptRepository { get; }
public WebhookSendAttemptStore( public WebhookSendAttemptStore(
IUnitOfWorkManager unitOfWorkManager,
IWebhookSendRecordRepository webhookSendAttemptRepository) IWebhookSendRecordRepository webhookSendAttemptRepository)
{ {
UnitOfWorkManager = unitOfWorkManager;
WebhookSendAttemptRepository = webhookSendAttemptRepository; WebhookSendAttemptRepository = webhookSendAttemptRepository;
} }
[UnitOfWork]
public async virtual Task<(int TotalCount, IReadOnlyCollection<WebhookSendAttempt> Webhooks)> GetAllSendAttemptsBySubscriptionAsPagedListAsync( public async virtual Task<(int TotalCount, IReadOnlyCollection<WebhookSendAttempt> Webhooks)> GetAllSendAttemptsBySubscriptionAsPagedListAsync(
Guid? tenantId, Guid? tenantId,
Guid subscriptionId, Guid subscriptionId,
int maxResultCount, int maxResultCount,
int skipCount) int skipCount)
{
(int TotalCount, IReadOnlyCollection<WebhookSendAttempt> Webhooks) sendAttempts;
using (var uow = UnitOfWorkManager.Begin())
{ {
using (CurrentTenant.Change(tenantId)) using (CurrentTenant.Change(tenantId))
{ {
@ -54,112 +46,77 @@ public class WebhookSendAttemptStore : DomainService, IWebhookSendAttemptStore
var webHooks = ObjectMapper.Map<List<WebhookSendRecord>, List<WebhookSendAttempt>>(list); var webHooks = ObjectMapper.Map<List<WebhookSendRecord>, List<WebhookSendAttempt>>(list);
sendAttempts = ValueTuple.Create(totalCount, webHooks.ToImmutableList()); return ValueTuple.Create(totalCount, webHooks.ToImmutableList());
} }
await uow.CompleteAsync();
}
return sendAttempts;
} }
[UnitOfWork]
public async virtual Task<List<WebhookSendAttempt>> GetAllSendAttemptsByWebhookEventIdAsync( public async virtual Task<List<WebhookSendAttempt>> GetAllSendAttemptsByWebhookEventIdAsync(
Guid? tenantId, Guid? tenantId,
Guid webhookEventId) Guid webhookEventId)
{
List<WebhookSendAttempt> sendAttempts;
using (var uow = UnitOfWorkManager.Begin())
{ {
using (CurrentTenant.Change(tenantId)) using (CurrentTenant.Change(tenantId))
{ {
var queryable = await WebhookSendAttemptRepository.GetQueryableAsync(); var queryable = await WebhookSendAttemptRepository.GetQueryableAsync();
var list = await AsyncQueryableExecuter.ToListAsync(queryable var list = await AsyncExecuter.ToListAsync(queryable
.Where(attempt => attempt.WebhookEventId == webhookEventId) .Where(attempt => attempt.WebhookEventId == webhookEventId)
.OrderByDescending(attempt => attempt.CreationTime) .OrderByDescending(attempt => attempt.CreationTime)
); );
sendAttempts = ObjectMapper.Map<List<WebhookSendRecord>, List<WebhookSendAttempt>>(list); return ObjectMapper.Map<List<WebhookSendRecord>, List<WebhookSendAttempt>>(list);
} }
await uow.CompleteAsync();
}
return sendAttempts;
} }
[UnitOfWork]
public async virtual Task<WebhookSendAttempt> GetAsync( public async virtual Task<WebhookSendAttempt> GetAsync(
Guid? tenantId, Guid? tenantId,
Guid id) Guid id)
{
WebhookSendRecord sendAttempt;
using (var uow = UnitOfWorkManager.Begin())
{ {
using (CurrentTenant.Change(tenantId)) using (CurrentTenant.Change(tenantId))
{ {
sendAttempt = await WebhookSendAttemptRepository.GetAsync(id); var sendAttempt = await WebhookSendAttemptRepository.GetAsync(id);
}
await uow.CompleteAsync();
}
return ObjectMapper.Map<WebhookSendRecord, WebhookSendAttempt>(sendAttempt); return ObjectMapper.Map<WebhookSendRecord, WebhookSendAttempt>(sendAttempt);
} }
}
[UnitOfWork]
public async virtual Task<int> GetSendAttemptCountAsync( public async virtual Task<int> GetSendAttemptCountAsync(
Guid? tenantId, Guid? tenantId,
Guid webhookEventId, Guid webhookEventId,
Guid webhookSubscriptionId) Guid webhookSubscriptionId)
{
int sendAttemptCount;
using (var uow = UnitOfWorkManager.Begin())
{ {
using (CurrentTenant.Change(tenantId)) using (CurrentTenant.Change(tenantId))
{ {
sendAttemptCount = await WebhookSendAttemptRepository.CountAsync(attempt => return await WebhookSendAttemptRepository.CountAsync(attempt =>
attempt.WebhookEventId == webhookEventId && attempt.WebhookEventId == webhookEventId &&
attempt.WebhookSubscriptionId == webhookSubscriptionId); attempt.WebhookSubscriptionId == webhookSubscriptionId);
} }
await uow.CompleteAsync();
}
return sendAttemptCount;
} }
[UnitOfWork]
public async virtual Task<bool> HasXConsecutiveFailAsync( public async virtual Task<bool> HasXConsecutiveFailAsync(
Guid? tenantId, Guid? tenantId,
Guid subscriptionId, Guid subscriptionId,
int failCount) int failCount)
{
bool result;
using (var uow = UnitOfWorkManager.Begin())
{ {
using (CurrentTenant.Change(tenantId)) using (CurrentTenant.Change(tenantId))
{ {
if (await WebhookSendAttemptRepository.CountAsync(x => x.WebhookSubscriptionId == subscriptionId) < failCount) if (await WebhookSendAttemptRepository.CountAsync(x => x.WebhookSubscriptionId == subscriptionId) < failCount)
{ {
result = false; return false;
} }
else else
{ {
var queryable = await WebhookSendAttemptRepository.GetQueryableAsync(); var queryable = await WebhookSendAttemptRepository.GetQueryableAsync();
result = !await AsyncQueryableExecuter.AnyAsync(queryable return !await AsyncExecuter.AnyAsync(queryable
.OrderByDescending(attempt => attempt.CreationTime) .OrderByDescending(attempt => attempt.CreationTime)
.Take(failCount) .Take(failCount)
.Where(attempt => attempt.ResponseStatusCode == HttpStatusCode.OK) .Where(attempt => attempt.ResponseStatusCode == HttpStatusCode.OK)
); );
} }
} }
await uow.CompleteAsync();
}
return result;
} }
} }

3
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecord.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Net; using System.Net;
using Volo.Abp;
using Volo.Abp.Auditing; using Volo.Abp.Auditing;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
@ -44,7 +45,7 @@ public class WebhookSendRecord : Entity<Guid>, IHasCreationTime, IHasModificatio
string response, string response,
HttpStatusCode? statusCode = null) HttpStatusCode? statusCode = null)
{ {
Response = response; Response = Check.Length(response, nameof(response), WebhookSendRecordConsts.MaxResponseLength);
ResponseStatusCode = statusCode; ResponseStatusCode = statusCode;
} }
} }

2
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordFilter.cs

@ -11,8 +11,6 @@ public class WebhookSendRecordFilter
public Guid? SubscriptionId { get; set; } public Guid? SubscriptionId { get; set; }
public string Response { get; set; }
public HttpStatusCode? ResponseStatusCode { get; set; } public HttpStatusCode? ResponseStatusCode { get; set; }
public DateTime? BeginCreationTime { get; set; } public DateTime? BeginCreationTime { get; set; }

24
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscription.cs

@ -1,4 +1,5 @@
using System; using System;
using Volo.Abp;
using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.Domain.Entities.Auditing;
namespace LINGYUN.Abp.WebhooksManagement; namespace LINGYUN.Abp.WebhooksManagement;
@ -22,12 +23,27 @@ public class WebhookSubscription : CreationAuditedEntity<Guid>
string headers, string headers,
Guid? tenantId = null) : base(id) Guid? tenantId = null) : base(id)
{ {
WebhookUri = webhookUri; Secret = Check.NotNullOrWhiteSpace(secret, nameof(secret), WebhookSubscriptionConsts.MaxSecretLength);
Secret = secret; SetWebhookUri(webhookUri);
Webhooks = webhooks; SetWebhooks(webhooks);
Headers = headers; SetHeaders(headers);
TenantId = tenantId; TenantId = tenantId;
IsActive = true; IsActive = true;
} }
public void SetWebhookUri(string webhookUri)
{
WebhookUri = Check.NotNullOrWhiteSpace(webhookUri, nameof(webhookUri), WebhookSubscriptionConsts.MaxWebhookUriLength);
}
public void SetWebhooks(string webhooks)
{
Webhooks = Check.Length(webhooks, nameof(webhooks), WebhookSubscriptionConsts.MaxWebhooksLength);
}
public void SetHeaders(string headers)
{
Headers = Check.Length(headers, nameof(headers), WebhookSubscriptionConsts.MaxHeadersLength);
}
} }

129
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionsStore.cs

@ -1,55 +1,148 @@
using LINGYUN.Abp.Webhooks; using LINGYUN.Abp.Webhooks;
using LINGYUN.Abp.WebhooksManagement.Extensions;
using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Domain.Services; using Volo.Abp.Domain.Services;
using Volo.Abp.Uow;
namespace LINGYUN.Abp.WebhooksManagement; namespace LINGYUN.Abp.WebhooksManagement;
public class WebhookSubscriptionsStore : DomainService, IWebhookSubscriptionsStore public class WebhookSubscriptionsStore : DomainService, IWebhookSubscriptionsStore
{ {
public Task DeleteAsync(Guid id) protected IWebhookSubscriptionRepository SubscriptionRepository { get; }
public WebhookSubscriptionsStore(
IWebhookSubscriptionRepository subscriptionRepository)
{ {
throw new NotImplementedException(); SubscriptionRepository = subscriptionRepository;
} }
public Task<List<WebhookSubscriptionInfo>> GetAllSubscriptionsAsync(Guid? tenantId) [UnitOfWork]
public async virtual Task DeleteAsync(Guid id)
{
using (CurrentTenant.Change(null))
{ {
throw new NotImplementedException(); await SubscriptionRepository.DeleteAsync(id);
}
} }
public Task<List<WebhookSubscriptionInfo>> GetAllSubscriptionsAsync(Guid? tenantId, string webhookName) [UnitOfWork]
public async virtual Task<List<WebhookSubscriptionInfo>> GetAllSubscriptionsAsync(Guid? tenantId)
{ {
throw new NotImplementedException(); using (CurrentTenant.Change(null))
{
var queryable = await SubscriptionRepository.GetQueryableAsync();
var subscriptions = await AsyncExecuter.ToListAsync(queryable.Where(x => x.TenantId == tenantId));
return subscriptions.Select(subscription => subscription.ToWebhookSubscriptionInfo()).ToList();
}
} }
public Task<List<WebhookSubscriptionInfo>> GetAllSubscriptionsOfTenantsAsync(Guid?[] tenantIds) [UnitOfWork]
public async virtual Task<List<WebhookSubscriptionInfo>> GetAllSubscriptionsAsync(Guid? tenantId, string webhookName)
{ {
throw new NotImplementedException(); using (CurrentTenant.Change(null))
{
var queryable = await SubscriptionRepository.GetQueryableAsync();
var subscriptions = await AsyncExecuter.ToListAsync(
queryable.Where(x =>
x.TenantId == tenantId &&
x.IsActive &&
x.Webhooks.Contains("\"" + webhookName + "\"")));
return subscriptions.Select(subscription => subscription.ToWebhookSubscriptionInfo()).ToList();
}
}
[UnitOfWork]
public async virtual Task<List<WebhookSubscriptionInfo>> GetAllSubscriptionsOfTenantsAsync(Guid?[] tenantIds)
{
using (CurrentTenant.Change(null))
{
var queryable = await SubscriptionRepository.GetQueryableAsync();
var subscriptions = await AsyncExecuter.ToListAsync(queryable.Where(x => tenantIds.Contains(x.TenantId)));
return subscriptions.Select(subscription => subscription.ToWebhookSubscriptionInfo()).ToList();
}
} }
public Task<List<WebhookSubscriptionInfo>> GetAllSubscriptionsOfTenantsAsync(Guid?[] tenantIds, string webhookName) [UnitOfWork]
public async virtual Task<List<WebhookSubscriptionInfo>> GetAllSubscriptionsOfTenantsAsync(Guid?[] tenantIds, string webhookName)
{
using (CurrentTenant.Change(null))
{ {
throw new NotImplementedException(); var queryable = await SubscriptionRepository.GetQueryableAsync();
var subscriptions = await AsyncExecuter.ToListAsync(
queryable.Where(x =>
x.IsActive &&
tenantIds.Contains(x.TenantId) &&
x.Webhooks.Contains("\"" + webhookName + "\"")));
return subscriptions.Select(subscription => subscription.ToWebhookSubscriptionInfo()).ToList();
}
} }
public Task<WebhookSubscriptionInfo> GetAsync(Guid id) [UnitOfWork]
public async virtual Task<WebhookSubscriptionInfo> GetAsync(Guid id)
{ {
throw new NotImplementedException(); using (CurrentTenant.Change(null))
{
var subscription = await SubscriptionRepository.GetAsync(id);
return subscription.ToWebhookSubscriptionInfo();
}
} }
public Task InsertAsync(WebhookSubscriptionInfo webhookSubscription) [UnitOfWork]
public async virtual Task InsertAsync(WebhookSubscriptionInfo webhookSubscription)
{
using (CurrentTenant.Change(null))
{ {
throw new NotImplementedException(); var subscription = new WebhookSubscription(
webhookSubscription.Id,
webhookSubscription.WebhookUri,
webhookSubscription.Secret,
JsonConvert.SerializeObject(webhookSubscription.Webhooks),
JsonConvert.SerializeObject(webhookSubscription.Headers),
webhookSubscription.TenantId);
await SubscriptionRepository.InsertAsync(subscription);
}
} }
public Task<bool> IsSubscribedAsync(Guid? tenantId, string webhookName) [UnitOfWork]
public async virtual Task<bool> IsSubscribedAsync(Guid? tenantId, string webhookName)
{ {
throw new NotImplementedException(); using (CurrentTenant.Change(null))
{
var queryable = await SubscriptionRepository.GetQueryableAsync();
return await AsyncExecuter.AnyAsync(
queryable.Where(x =>
x.TenantId == tenantId &&
x.IsActive &&
x.Webhooks.Contains("\"" + webhookName + "\"")));
}
} }
public Task UpdateAsync(WebhookSubscriptionInfo webhookSubscription) [UnitOfWork]
public async virtual Task UpdateAsync(WebhookSubscriptionInfo webhookSubscription)
{
using (CurrentTenant.Change(webhookSubscription.TenantId))
{ {
throw new NotImplementedException(); var subscription = await SubscriptionRepository.GetAsync(webhookSubscription.Id);
subscription.SetWebhookUri(webhookSubscription.WebhookUri);
subscription.SetWebhooks(webhookSubscription.ToSubscribedWebhooksString());
subscription.SetHeaders(webhookSubscription.ToWebhookHeadersString());
await SubscriptionRepository.UpdateAsync(subscription);
}
} }
} }

9
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainMapperProfile.cs

@ -1,4 +1,8 @@
using AutoMapper; using AutoMapper;
using LINGYUN.Abp.Webhooks;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace LINGYUN.Abp.WebhooksManagement; namespace LINGYUN.Abp.WebhooksManagement;
@ -6,6 +10,11 @@ public class WebhooksManagementDomainMapperProfile : Profile
{ {
public WebhooksManagementDomainMapperProfile() public WebhooksManagementDomainMapperProfile()
{ {
CreateMap<WebhookEventRecord, WebhookEventEto>();
CreateMap<WebhookSendRecord, WebhookSendAttemptEto>();
CreateMap<WebhookSubscription, WebhookSubscriptionEto>();
CreateMap<WebhookEventRecord, WebhookEvent>();
CreateMap<WebhookSendRecord, WebhookSendAttempt>();
} }
} }

29
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainModule.cs

@ -1,8 +1,10 @@
using LINGYUN.Abp.Webhooks; using LINGYUN.Abp.Webhooks;
using LINGYUN.Abp.WebhooksManagement.ObjectExtending;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AutoMapper; using Volo.Abp.AutoMapper;
using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.ObjectExtending.Modularity;
using Volo.Abp.Threading; using Volo.Abp.Threading;
namespace LINGYUN.Abp.WebhooksManagement; namespace LINGYUN.Abp.WebhooksManagement;
@ -25,6 +27,13 @@ public class WebhooksManagementDomainModule : AbpModule
Configure<AbpDistributedEntityEventOptions>(options => Configure<AbpDistributedEntityEventOptions>(options =>
{ {
options.EtoMappings.Add<WebhookEventRecord, WebhookEventEto>();
options.EtoMappings.Add<WebhookSendRecord, WebhookSendAttemptEto>();
options.EtoMappings.Add<WebhookSubscription, WebhookSubscriptionEto>();
options.AutoEventSelectors.Add<WebhookEventRecord>();
options.AutoEventSelectors.Add<WebhookSendRecord>();
options.AutoEventSelectors.Add<WebhookSubscription>();
}); });
} }
@ -33,11 +42,21 @@ public class WebhooksManagementDomainModule : AbpModule
OneTimeRunner.Run(() => OneTimeRunner.Run(() =>
{ {
// 扩展实体配置 // 扩展实体配置
//ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity( ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity(
// WebhooksManagementModuleExtensionConsts.ModuleName, WebhooksManagementModuleExtensionConsts.ModuleName,
// WebhooksManagementModuleExtensionConsts.EntityNames.Entity, WebhooksManagementModuleExtensionConsts.EntityNames.WebhookEvent,
// typeof(Entity) typeof(WebhookEventRecord)
//); );
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity(
WebhooksManagementModuleExtensionConsts.ModuleName,
WebhooksManagementModuleExtensionConsts.EntityNames.WebhookSubscription,
typeof(WebhookSubscription)
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity(
WebhooksManagementModuleExtensionConsts.ModuleName,
WebhooksManagementModuleExtensionConsts.EntityNames.WebhookSendAttempt,
typeof(WebhookSendRecord)
);
}); });
} }
} }

15
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookEventRecordRepository.cs

@ -0,0 +1,15 @@
using System;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore;
public class EfCoreWebhookEventRecordRepository :
EfCoreRepository<IWebhooksManagementDbContext, WebhookEventRecord, Guid>,
IWebhookEventRecordRepository
{
public EfCoreWebhookEventRecordRepository(IDbContextProvider<IWebhooksManagementDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
}

58
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookSendRecordRepository.cs

@ -0,0 +1,58 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore;
public class EfCoreWebhookSendRecordRepository :
EfCoreRepository<IWebhooksManagementDbContext, WebhookSendRecord, Guid>,
IWebhookSendRecordRepository
{
public EfCoreWebhookSendRecordRepository(
IDbContextProvider<IWebhooksManagementDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public async virtual Task<int> GetCountAsync(
WebhookSendRecordFilter filter,
CancellationToken cancellationToken = default)
{
return await ApplyFilter(await GetDbSetAsync(), filter)
.CountAsync(GetCancellationToken(cancellationToken));
}
public async virtual Task<List<WebhookSendRecord>> GetListAsync(
WebhookSendRecordFilter filter,
string sorting = "CreationTime",
int maxResultCount = 10,
int skipCount = 10,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await ApplyFilter((await GetDbSetAsync()).IncludeDetails(includeDetails), filter)
.OrderBy(sorting ?? $"{nameof(WebhookSendRecord.CreationTime)} DESC")
.PageBy(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
}
protected virtual IQueryable<WebhookSendRecord> ApplyFilter(
IQueryable<WebhookSendRecord> queryable,
WebhookSendRecordFilter filter)
{
return queryable
.WhereIf(filter.WebhookEventId.HasValue, x => x.WebhookEventId == filter.WebhookEventId)
.WhereIf(filter.SubscriptionId.HasValue, x => x.WebhookSubscriptionId == filter.SubscriptionId)
.WhereIf(filter.ResponseStatusCode.HasValue, x => x.ResponseStatusCode == filter.ResponseStatusCode)
.WhereIf(filter.BeginCreationTime.HasValue, x => x.CreationTime.CompareTo(filter.BeginCreationTime) >= 0)
.WhereIf(filter.EndCreationTime.HasValue, x => x.CreationTime.CompareTo(filter.EndCreationTime) <= 0)
.WhereIf(!filter.Filter.IsNullOrWhiteSpace(), x => x.Response.Contains(filter.Filter));
}
}

16
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookSubscriptionRepository.cs

@ -0,0 +1,16 @@
using System;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore;
public class EfCoreWebhookSubscriptionRepository :
EfCoreRepository<IWebhooksManagementDbContext, WebhookSubscription, Guid>,
IWebhookSubscriptionRepository
{
public EfCoreWebhookSubscriptionRepository(
IDbContextProvider<IWebhooksManagementDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
}

55
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System; using System;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;
namespace LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore; namespace LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore;
@ -17,5 +18,59 @@ public static class WebhooksManagementDbContextModelCreatingExtensions
WebhooksManagementDbProperties.DbSchema WebhooksManagementDbProperties.DbSchema
); );
optionsAction?.Invoke(options); optionsAction?.Invoke(options);
builder.Entity<WebhookEventRecord>(b =>
{
b.ToTable(options.TablePrefix + "WebhookEvents", options.Schema);
b.Property(p => p.WebhookName)
.IsRequired()
.HasColumnName(nameof(WebhookEventRecord.WebhookName))
.HasMaxLength(WebhookEventRecordConsts.MaxWebhookNameLength);
b.Property(p => p.Data)
.HasColumnName(nameof(WebhookEventRecord.Data))
.HasMaxLength(WebhookEventRecordConsts.MaxDataLength);
b.ConfigureByConvention();
});
builder.Entity<WebhookSendRecord>(b =>
{
b.ToTable(options.TablePrefix + "WebhookSendAttempts", options.Schema);
b.Property(p => p.Response)
.HasColumnName(nameof(WebhookSendRecord.Response))
.HasMaxLength(WebhookSendRecordConsts.MaxResponseLength);
b.ConfigureByConvention();
b.HasOne(p => p.WebhookEvent)
.WithOne()
.HasForeignKey<WebhookSendRecord>(fk => fk.WebhookEventId)
.HasPrincipalKey<WebhookEventRecord>(pk => pk.Id );
});
builder.Entity<WebhookSubscription>(b =>
{
b.ToTable(options.TablePrefix + "WebhookSubscriptions", options.Schema);
b.Property(p => p.WebhookUri)
.IsRequired()
.HasColumnName(nameof(WebhookSubscription.WebhookUri))
.HasMaxLength(WebhookSubscriptionConsts.MaxWebhookUriLength);
b.Property(p => p.Secret)
.IsRequired()
.HasColumnName(nameof(WebhookSubscription.Secret))
.HasMaxLength(WebhookSubscriptionConsts.MaxSecretLength);
b.Property(p => p.Webhooks)
.HasColumnName(nameof(WebhookSubscription.Webhooks))
.HasMaxLength(WebhookSubscriptionConsts.MaxWebhooksLength);
b.Property(p => p.Headers)
.HasColumnName(nameof(WebhookSubscription.Headers))
.HasMaxLength(WebhookSubscriptionConsts.MaxHeadersLength);
b.ConfigureByConvention();
});
} }
} }

15
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementEfCoreQueryableExtensions.cs

@ -1,6 +1,19 @@
namespace LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System.Linq;
namespace LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore;
public static class WebhooksManagementEfCoreQueryableExtensions public static class WebhooksManagementEfCoreQueryableExtensions
{ {
// 在此聚合仓储服务的扩展方法 // 在此聚合仓储服务的扩展方法
public static IQueryable<WebhookSendRecord> IncludeDetails(this IQueryable<WebhookSendRecord> queryable, bool include = true)
{
if (!include)
{
return queryable;
}
return queryable
.Include(x => x.WebhookEvent);
}
} }

4
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementEntityFrameworkCoreModule.cs

@ -13,6 +13,10 @@ public class WebhooksManagementEntityFrameworkCoreModule : AbpModule
{ {
context.Services.AddAbpDbContext<WebhooksManagementDbContext>(options => context.Services.AddAbpDbContext<WebhooksManagementDbContext>(options =>
{ {
options.AddRepository<WebhookSendRecord, EfCoreWebhookSendRecordRepository>();
options.AddRepository<WebhookEventRecord, EfCoreWebhookEventRecordRepository>();
options.AddRepository<WebhookSubscription, EfCoreWebhookSubscriptionRepository>();
options.AddDefaultRepositories<IWebhooksManagementDbContext>(); options.AddDefaultRepositories<IWebhooksManagementDbContext>();
}); });
} }

2
aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Controllers/HomeController.cs

@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc;
namespace LY..WebhooksManagement.Controllers; namespace LY.MicroService.WebhooksManagement.Controllers;
public class HomeController : AbpController public class HomeController : AbpController
{ {

2
aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/DataSeeder/WebhooksManagementDataSeederWorker.cs

@ -3,7 +3,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Data; using Volo.Abp.Data;
namespace LY..WebhooksManagement.DataSeeder; namespace LY.MicroService.WebhooksManagement.DataSeeder;
public class WebhooksManagementDataSeederWorker : BackgroundService public class WebhooksManagementDataSeederWorker : BackgroundService
{ {

5
aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContext.cs

@ -1,7 +1,8 @@
using Microsoft.EntityFrameworkCore; using LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
namespace LY..WebhooksManagement.EntityFrameworkCore; namespace LY.MicroService.WebhooksManagement.EntityFrameworkCore;
public class WebhooksManagementMigrationsDbContext : AbpDbContext<WebhooksManagementMigrationsDbContext> public class WebhooksManagementMigrationsDbContext : AbpDbContext<WebhooksManagementMigrationsDbContext>
{ {

2
aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContextFactory.cs

@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using System.IO; using System.IO;
namespace LY..WebhooksManagement.EntityFrameworkCore; namespace LY.MicroService.WebhooksManagement.EntityFrameworkCore;
public class WebhooksManagementMigrationsDbContextFactory : IDesignTimeDbContextFactory<WebhooksManagementMigrationsDbContext> public class WebhooksManagementMigrationsDbContextFactory : IDesignTimeDbContextFactory<WebhooksManagementMigrationsDbContext>
{ {

10
aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EventBus/Handlers/TenantSynchronizer.cs

@ -1,6 +1,6 @@
using LY..WebhooksManagement.EntityFrameworkCore; using LINGYUN.Abp.Data.DbMigrator;
using LINGYUN.Abp.Data.DbMigrator;
using LINGYUN.Abp.MultiTenancy; using LINGYUN.Abp.MultiTenancy;
using LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -10,7 +10,7 @@ using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow; using Volo.Abp.Uow;
namespace LY..WebhooksManagement.EventBus.Handlers; namespace LY.MicroService.WebhooksManagement.EventBus.Handlers;
public class TenantSynchronizer : public class TenantSynchronizer :
IDistributedEventHandler<CreateEventData>, IDistributedEventHandler<CreateEventData>,
@ -49,7 +49,7 @@ public class TenantSynchronizer :
{ {
using (CurrentTenant.Change(eventData.Id, eventData.Name)) using (CurrentTenant.Change(eventData.Id, eventData.Name))
{ {
Logger.LogInformation("Migrating the new tenant database with LY..WebhooksManagement..."); Logger.LogInformation("Migrating the new tenant database with WebhooksManagement...");
// 迁移租户数据 // 迁移租户数据
await DbSchemaMigrator.MigrateAsync<WebhooksManagementDbContext>( await DbSchemaMigrator.MigrateAsync<WebhooksManagementDbContext>(
(connectionString, builder) => (connectionString, builder) =>
@ -58,7 +58,7 @@ public class TenantSynchronizer :
return new WebhooksManagementDbContext(builder.Options); return new WebhooksManagementDbContext(builder.Options);
}); });
Logger.LogInformation("Migrated the new tenant database with LY..WebhooksManagement..."); Logger.LogInformation("Migrated the new tenant database with WebhooksManagement...");
await DataSeeder.SeedAsync(new DataSeedContext(eventData.Id)); await DataSeeder.SeedAsync(new DataSeedContext(eventData.Id));

9
aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<RootNamespace>LY..WebhooksManagement</RootNamespace> <RootNamespace>LY.MicroService.WebhooksManagement</RootNamespace>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@ -57,10 +57,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\LY..WebhooksManagement.Application\LY..WebhooksManagement.Application.csproj" /> <ProjectReference Include="..\..\modules\webhooks\LINGYUN.Abp.WebhooksManagement.Application\LINGYUN.Abp.WebhooksManagement.Application.csproj" />
<ProjectReference Include="..\..\src\LY..WebhooksManagement.EntityFrameworkCore\LY..WebhooksManagement.EntityFrameworkCore.csproj" /> <ProjectReference Include="..\..\modules\webhooks\LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore\LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\src\LY..WebhooksManagement.HttpApi\LY..WebhooksManagement.HttpApi.csproj" /> <ProjectReference Include="..\..\modules\webhooks\LINGYUN.Abp.WebhooksManagement.HttpApi\LINGYUN.Abp.WebhooksManagement.HttpApi.csproj" />
<ProjectReference Include="..\..\src\LY..WebhooksManagement.SettingManagement\LY..WebhooksManagement.SettingManagement.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

2
aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Program.cs

@ -9,7 +9,7 @@ using System.Threading.Tasks;
using Volo.Abp.IO; using Volo.Abp.IO;
using Volo.Abp.Modularity.PlugIns; using Volo.Abp.Modularity.PlugIns;
namespace LY..WebhooksManagement; namespace LY.MicroService.WebhooksManagement;
public class Program public class Program
{ {

9
aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Properties/launchSettings.json

@ -14,15 +14,8 @@
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
}, },
"applicationUrl": "http://localhost:57264", "applicationUrl": "http://127.0.0.1:30045",
"dotnetRunMessages": "true" "dotnetRunMessages": "true"
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": false,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
} }
} }
} }

2
aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/TenantHeaderParamter.cs

@ -4,7 +4,7 @@ using Swashbuckle.AspNetCore.SwaggerGen;
using System.Collections.Generic; using System.Collections.Generic;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
namespace LY..WebhooksManagement; namespace LY.MicroService.WebhooksManagement;
public class TenantHeaderParamter : IOperationFilter public class TenantHeaderParamter : IOperationFilter
{ {

8
aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs

@ -31,7 +31,7 @@ using Volo.Abp.MultiTenancy;
using Volo.Abp.Threading; using Volo.Abp.Threading;
using Volo.Abp.VirtualFileSystem; using Volo.Abp.VirtualFileSystem;
namespace LY..WebhooksManagement; namespace LY.MicroService.WebhooksManagement;
public partial class WebhooksManagementHttpApiHostModule public partial class WebhooksManagementHttpApiHostModule
{ {
@ -53,7 +53,7 @@ public partial class WebhooksManagementHttpApiHostModule
PreConfigure<AbpSerilogEnrichersUniqueIdOptions>(options => PreConfigure<AbpSerilogEnrichersUniqueIdOptions>(options =>
{ {
// 以开放端口区别 // 以开放端口区别
options.SnowflakeIdOptions.WorkerId = 5000; options.SnowflakeIdOptions.WorkerId = 30045;
options.SnowflakeIdOptions.WorkerIdBits = 5; options.SnowflakeIdOptions.WorkerIdBits = 5;
options.SnowflakeIdOptions.DatacenterId = 1; options.SnowflakeIdOptions.DatacenterId = 1;
}); });
@ -160,7 +160,7 @@ public partial class WebhooksManagementHttpApiHostModule
{ {
Configure<AbpAuditingOptions>(options => Configure<AbpAuditingOptions>(options =>
{ {
options.ApplicationName = "WebhooksManagement"; options.ApplicationName = ApplicationName;
// 是否启用实体变更记录 // 是否启用实体变更记录
var entitiesChangedConfig = configuration.GetSection("App:TrackingEntitiesChanged"); var entitiesChangedConfig = configuration.GetSection("App:TrackingEntitiesChanged");
if (entitiesChangedConfig.Exists() && entitiesChangedConfig.Get<bool>()) if (entitiesChangedConfig.Exists() && entitiesChangedConfig.Get<bool>())
@ -196,7 +196,7 @@ public partial class WebhooksManagementHttpApiHostModule
{ {
Configure<AbpVirtualFileSystemOptions>(options => Configure<AbpVirtualFileSystemOptions>(options =>
{ {
options.FileSets.AddEmbedded<WebhooksManagementHttpApiHostModule>("LY..WebhooksManagement"); options.FileSets.AddEmbedded<WebhooksManagementHttpApiHostModule>("LY.MicroService.WebhooksManagement");
}); });
} }

4
aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.DataSeeder.cs

@ -1,7 +1,7 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using LY..WebhooksManagement.DataSeeder; using LY.MicroService.WebhooksManagement.DataSeeder;
namespace LY..WebhooksManagement; namespace LY.MicroService.WebhooksManagement;
public partial class WebhooksManagementHttpApiHostModule public partial class WebhooksManagementHttpApiHostModule
{ {

11
aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs

@ -1,4 +1,5 @@
using LINGYUN.Abp.AspNetCore.Mvc.Wrapper; using DotNetCore.CAP;
using LINGYUN.Abp.AspNetCore.Mvc.Wrapper;
using LINGYUN.Abp.AuditLogging.Elasticsearch; using LINGYUN.Abp.AuditLogging.Elasticsearch;
using LINGYUN.Abp.EventBus.CAP; using LINGYUN.Abp.EventBus.CAP;
using LINGYUN.Abp.ExceptionHandling.Emailing; using LINGYUN.Abp.ExceptionHandling.Emailing;
@ -6,12 +7,12 @@ using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore;
using LINGYUN.Abp.Saas.EntityFrameworkCore; using LINGYUN.Abp.Saas.EntityFrameworkCore;
using LINGYUN.Abp.Serilog.Enrichers.Application; using LINGYUN.Abp.Serilog.Enrichers.Application;
using LINGYUN.Abp.Serilog.Enrichers.UniqueId; using LINGYUN.Abp.Serilog.Enrichers.UniqueId;
using LINGYUN.Abp.WebhooksManagement;
using LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using LY..WebhooksManagement.EntityFrameworkCore;
using LY..WebhooksManagement.SettingManagement;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.AspNetCore.Authentication.JwtBearer; using Volo.Abp.AspNetCore.Authentication.JwtBearer;
using Volo.Abp.AspNetCore.MultiTenancy; using Volo.Abp.AspNetCore.MultiTenancy;
@ -27,7 +28,7 @@ using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.SettingManagement.EntityFrameworkCore; using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.Swashbuckle; using Volo.Abp.Swashbuckle;
namespace LY.WebhooksManagement; namespace LY.MicroService.WebhooksManagement;
[DependsOn( [DependsOn(
typeof(AbpSerilogEnrichersApplicationModule), typeof(AbpSerilogEnrichersApplicationModule),
@ -37,7 +38,6 @@ namespace LY.WebhooksManagement;
typeof(WebhooksManagementApplicationModule), typeof(WebhooksManagementApplicationModule),
typeof(WebhooksManagementHttpApiModule), typeof(WebhooksManagementHttpApiModule),
typeof(WebhooksManagementEntityFrameworkCoreModule), typeof(WebhooksManagementEntityFrameworkCoreModule),
typeof(WebhooksManagementSettingManagementModule),
typeof(AbpEntityFrameworkCoreMySQLModule), typeof(AbpEntityFrameworkCoreMySQLModule),
typeof(AbpAspNetCoreAuthenticationJwtBearerModule), typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
typeof(AbpEmailingExceptionHandlingModule), typeof(AbpEmailingExceptionHandlingModule),
@ -101,6 +101,7 @@ public partial class WebhooksManagementHttpApiHostModule : AbpModule
app.UseMultiTenancy(); app.UseMultiTenancy();
app.UseMapRequestLocalization(); app.UseMapRequestLocalization();
app.UseAuthorization(); app.UseAuthorization();
app.UseCapDashboard();
app.UseSwagger(); app.UseSwagger();
app.UseAbpSwaggerUI(options => app.UseAbpSwaggerUI(options =>
{ {

Loading…
Cancel
Save