From fef1eb61ebc4e19f6818e213091cf98ad92d4962 Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Fri, 25 Mar 2022 18:23:02 +0800 Subject: [PATCH 01/17] feat(webhooks): added support webhooks. --- aspnet-core/LINGYUN.MicroService.All.sln | 10 + aspnet-core/LINGYUN.MicroService.Common.sln | 10 + .../LINGYUN.Abp.WebHooks/FodyWeavers.xml | 3 + .../LINGYUN.Abp.WebHooks/FodyWeavers.xsd | 30 ++ .../LINGYUN.Abp.WebHooks.csproj | 18 + .../LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs | 18 + .../Abp/Webhooks/AbpWebhooksOptions.cs | 26 ++ .../BackgroundWorker/WebhookSenderJob.cs | 125 +++++++ .../Abp/Webhooks/DefaultWebhookPublisher.cs | 125 +++++++ .../Abp/Webhooks/DefaultWebhookSender.cs | 133 ++++++++ .../Abp/Webhooks/IWebhookDefinitionContext.cs | 22 ++ .../Abp/Webhooks/IWebhookDefinitionManager.cs | 31 ++ .../Abp/Webhooks/IWebhookEventStore.cs | 18 + .../LINGYUN/Abp/Webhooks/IWebhookManager.cs | 22 ++ .../LINGYUN/Abp/Webhooks/IWebhookPublisher.cs | 56 ++++ .../Abp/Webhooks/IWebhookSendAttemptStore.cs | 25 ++ .../LINGYUN/Abp/Webhooks/IWebhookSender.cs | 16 + .../Webhooks/IWebhookSubscriptionManager.cs | 74 +++++ .../Webhooks/IWebhookSubscriptionsStore.cs | 83 +++++ .../Abp/Webhooks/NullWebhookEventStore.cs | 24 ++ .../Webhooks/NullWebhookSendAttemptStore.cs | 47 +++ .../Webhooks/NullWebhookSubscriptionsStore.cs | 65 ++++ .../LINGYUN/Abp/Webhooks/WebhookDefinition.cs | 57 ++++ .../Abp/Webhooks/WebhookDefinitionContext.cs | 54 +++ .../Abp/Webhooks/WebhookDefinitionManager.cs | 109 +++++++ .../Abp/Webhooks/WebhookDefinitionProvider.cs | 13 + .../LINGYUN/Abp/Webhooks/WebhookEvent.cs | 30 ++ .../LINGYUN/Abp/Webhooks/WebhookHeader.cs | 18 + .../LINGYUN/Abp/Webhooks/WebhookManager.cs | 84 +++++ .../LINGYUN/Abp/Webhooks/WebhookPayload.cs | 35 ++ .../Abp/Webhooks/WebhookSendAttempt.cs | 39 +++ .../LINGYUN/Abp/Webhooks/WebhookSenderArgs.cs | 67 ++++ .../Abp/Webhooks/WebhookSubscriptionInfo.cs | 60 ++++ .../Webhooks/WebhookSubscriptionManager.cs | 175 ++++++++++ .../System/AbpStringCryptographyExtensions.cs | 13 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...oksManagement.Application.Contracts.csproj | 21 ++ ...sManagementPermissionDefinitionProvider.cs | 22 ++ .../WebhooksManagementPermissions.cs | 8 + ...ooksManagementFeatureDefinitionProvider.cs | 18 + .../WebhooksManagementFeatureNames.cs | 6 + ...oksManagementApplicationContractsModule.cs | 15 + .../WebhooksManagementRemoteServiceConsts.cs | 7 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ....Abp.WebhooksManagement.Application.csproj | 20 ++ .../WebhooksManagementAppServiceBase.cs | 13 + ...hooksManagementApplicationMapperProfile.cs | 10 + .../WebhooksManagementApplicationModule.cs | 24 ++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ....Abp.WebhooksManagement.Dapr.Client.csproj | 16 + .../WebhooksManagementDaprClientModule.cs | 18 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...bp.WebhooksManagement.Domain.Shared.csproj | 25 ++ .../Localization/Resources/en.json | 8 + .../Localization/Resources/zh-Hans.json | 8 + .../WebhooksManagementResource.cs | 8 + ...sManagementModuleExtensionConfiguration.cs | 16 + ...ensionConfigurationDictionaryExtensions.cs | 19 ++ ...WebhooksManagementModuleExtensionConsts.cs | 11 + .../WebhooksManagementDomainSharedModule.cs | 32 ++ .../WebhooksManagementErrorCodes.cs | 6 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...NGYUN.Abp.WebhooksManagement.Domain.csproj | 22 ++ .../DefaultWebhookManager.cs | 70 ++++ .../IWebhookEventRecordRepository.cs | 8 + .../IWebhookSendRecordRepository.cs | 21 ++ .../IWebhookSubscriptionRepository.cs | 8 + ...ooksManagementSettingDefinitionProvider.cs | 11 + .../Settings/WebhooksManagementSettings.cs | 7 + .../WebhooksManagement/WebhookEventRecord.cs | 30 ++ .../WebhooksManagement/WebhookEventStore.cs | 57 ++++ .../WebhookSendAttemptStore.cs | 165 ++++++++++ .../WebhooksManagement/WebhookSendRecord.cs | 50 +++ .../WebhookSendRecordFilter.cs | 21 ++ .../WebhooksManagement/WebhookSubscription.cs | 33 ++ .../WebhookSubscriptionsStore.cs | 55 ++++ .../WebhooksManagementDbProperties.cs | 11 + .../WebhooksManagementDomainMapperProfile.cs | 11 + .../WebhooksManagementDomainModule.cs | 43 +++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...hooksManagement.EntityFrameworkCore.csproj | 19 ++ .../IWebhooksManagementDbContext.cs | 9 + .../WebhooksManagementDbContext.cs | 21 ++ ...agementDbContextModelCreatingExtensions.cs | 21 ++ ...ooksManagementEfCoreQueryableExtensions.cs | 6 + ...ooksManagementEntityFrameworkCoreModule.cs | 19 ++ ...agementModelBuilderConfigurationOptions.cs | 17 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...p.WebhooksManagement.HttpApi.Client.csproj | 19 ++ .../WebhooksManagementHttpApiClientModule.cs | 18 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...GYUN.Abp.WebhooksManagement.HttpApi.csproj | 19 ++ .../WebhooksManagementControllerBase.cs | 12 + .../WebhooksManagementHttpApiModule.cs | 40 +++ .../Dockerfile | 4 + ...Service.TaskManagement.HttpApi.Host.csproj | 2 + .../Controllers/HomeController.cs | 12 + .../WebhooksManagementDataSeederWorker.cs | 21 ++ .../Dockerfile | 15 + .../WebhooksManagementMigrationsDbContext.cs | 20 ++ ...oksManagementMigrationsDbContextFactory.cs | 32 ++ .../EventBus/Handlers/TenantSynchronizer.cs | 69 ++++ ...ice.WebhooksManagement.HttpApi.Host.csproj | 66 ++++ .../Program.cs | 58 ++++ .../Properties/launchSettings.json | 28 ++ .../TenantHeaderParamter.cs | 31 ++ ...ksManagementHttpApiHostModule.Configure.cs | 307 ++++++++++++++++++ ...sManagementHttpApiHostModule.DataSeeder.cs | 15 + .../WebhooksManagementHttpApiHostModule.cs | 118 +++++++ .../appsettings.Development.json | 132 ++++++++ .../appsettings.json | 80 +++++ .../dapr.sh | 1 + 120 files changed, 4184 insertions(+) create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/FodyWeavers.xml create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/FodyWeavers.xsd create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN.Abp.WebHooks.csproj create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksOptions.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/BackgroundWorker/WebhookSenderJob.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookDefinitionContext.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookDefinitionManager.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookEventStore.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookManager.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookPublisher.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookSendAttemptStore.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookSender.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookSubscriptionManager.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookSubscriptionsStore.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/NullWebhookEventStore.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/NullWebhookSendAttemptStore.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/NullWebhookSubscriptionsStore.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinition.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionContext.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionManager.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionProvider.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookEvent.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookHeader.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookManager.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookPayload.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSendAttempt.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSenderArgs.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionInfo.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionManager.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/System/AbpStringCryptographyExtensions.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/FodyWeavers.xml create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/FodyWeavers.xsd create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN.Abp.WebhooksManagement.Application.Contracts.csproj create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissions.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Features/WebhooksManagementFeatureDefinitionProvider.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Features/WebhooksManagementFeatureNames.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksManagementApplicationContractsModule.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksManagementRemoteServiceConsts.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/FodyWeavers.xml create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/FodyWeavers.xsd create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN.Abp.WebhooksManagement.Application.csproj create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksManagementAppServiceBase.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksManagementApplicationMapperProfile.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksManagementApplicationModule.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Dapr.Client/FodyWeavers.xml create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Dapr.Client/FodyWeavers.xsd create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Dapr.Client/LINGYUN.Abp.WebhooksManagement.Dapr.Client.csproj create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Dapr.Client/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDaprClientModule.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/FodyWeavers.xml create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/FodyWeavers.xsd create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN.Abp.WebhooksManagement.Domain.Shared.csproj create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/WebhooksManagementResource.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfiguration.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfigurationDictionaryExtensions.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConsts.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainSharedModule.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhooksManagementErrorCodes.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/FodyWeavers.xml create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/FodyWeavers.xsd create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN.Abp.WebhooksManagement.Domain.csproj create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/DefaultWebhookManager.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookEventRecordRepository.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookSendRecordRepository.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionRepository.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Settings/WebhooksManagementSettingDefinitionProvider.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Settings/WebhooksManagementSettings.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookEventRecord.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookEventStore.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendAttemptStore.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecord.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordFilter.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscription.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionsStore.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDbProperties.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainMapperProfile.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainModule.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/FodyWeavers.xml create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/FodyWeavers.xsd create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore.csproj create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/IWebhooksManagementDbContext.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContext.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementEfCoreQueryableExtensions.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementEntityFrameworkCoreModule.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementModelBuilderConfigurationOptions.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi.Client/FodyWeavers.xml create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi.Client/FodyWeavers.xsd create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi.Client/LINGYUN.Abp.WebhooksManagement.HttpApi.Client.csproj create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi.Client/LINGYUN/Abp/WebhooksManagement/WebhooksManagementHttpApiClientModule.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/FodyWeavers.xml create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/FodyWeavers.xsd create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN.Abp.WebhooksManagement.HttpApi.csproj create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksManagementControllerBase.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksManagementHttpApiModule.cs create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Controllers/HomeController.cs create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/DataSeeder/WebhooksManagementDataSeederWorker.cs create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Dockerfile create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContext.cs create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContextFactory.cs create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EventBus/Handlers/TenantSynchronizer.cs create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Program.cs create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Properties/launchSettings.json create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/TenantHeaderParamter.cs create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.DataSeeder.cs create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/appsettings.Development.json create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/appsettings.json create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/dapr.sh diff --git a/aspnet-core/LINGYUN.MicroService.All.sln b/aspnet-core/LINGYUN.MicroService.All.sln index 2d20d15c8..3bda2e147 100644 --- a/aspnet-core/LINGYUN.MicroService.All.sln +++ b/aspnet-core/LINGYUN.MicroService.All.sln @@ -394,6 +394,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Saas.HttpApi.Cl EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MultiTenancy.Saas", "modules\tenants\LINGYUN.Abp.MultiTenancy.Saas\LINGYUN.Abp.MultiTenancy.Saas.csproj", "{F57594AA-10C2-4DFF-87F6-19F2548099EA}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "webhooks", "webhooks", "{13ACF670-F109-404E-B252-2FA34A4EA061}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WebHooks", "modules\webhooks\LINGYUN.Abp.WebHooks\LINGYUN.Abp.WebHooks.csproj", "{91AE01B1-CC82-40E2-8290-B8A84C6E90D1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1020,6 +1024,10 @@ Global {F57594AA-10C2-4DFF-87F6-19F2548099EA}.Debug|Any CPU.Build.0 = Debug|Any CPU {F57594AA-10C2-4DFF-87F6-19F2548099EA}.Release|Any CPU.ActiveCfg = Release|Any CPU {F57594AA-10C2-4DFF-87F6-19F2548099EA}.Release|Any CPU.Build.0 = Release|Any CPU + {91AE01B1-CC82-40E2-8290-B8A84C6E90D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {91AE01B1-CC82-40E2-8290-B8A84C6E90D1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {91AE01B1-CC82-40E2-8290-B8A84C6E90D1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {91AE01B1-CC82-40E2-8290-B8A84C6E90D1}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1212,6 +1220,8 @@ Global {8DF50094-6791-4C7C-B07D-C3E995B69C49} = {D01D859E-4B72-478A-BABD-90F0981652D5} {96EF6CDD-CD29-4E7B-B86A-3EBEE6AC9FDC} = {D01D859E-4B72-478A-BABD-90F0981652D5} {F57594AA-10C2-4DFF-87F6-19F2548099EA} = {A5543E56-DA53-494D-A531-DA75091D46FF} + {13ACF670-F109-404E-B252-2FA34A4EA061} = {C5CAD011-DF84-4914-939C-0C029DCEF26F} + {91AE01B1-CC82-40E2-8290-B8A84C6E90D1} = {13ACF670-F109-404E-B252-2FA34A4EA061} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718} diff --git a/aspnet-core/LINGYUN.MicroService.Common.sln b/aspnet-core/LINGYUN.MicroService.Common.sln index e2fdcc2f0..edeb3b22c 100644 --- a/aspnet-core/LINGYUN.MicroService.Common.sln +++ b/aspnet-core/LINGYUN.MicroService.Common.sln @@ -226,6 +226,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Dapr.Actors.Asp EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MultiTenancy.Editions", "modules\tenants\LINGYUN.Abp.MultiTenancy.Editions\LINGYUN.Abp.MultiTenancy.Editions.csproj", "{3FF4CEA0-1555-4D62-AA81-B3B599253F8D}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "webhooks", "webhooks", "{BD97C98B-0B4B-443D-AB29-145A344F46D3}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WebHooks", "modules\webhooks\LINGYUN.Abp.WebHooks\LINGYUN.Abp.WebHooks.csproj", "{AFE75D2B-8853-488B-B5D5-277B58C5DBB2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -580,6 +584,10 @@ Global {3FF4CEA0-1555-4D62-AA81-B3B599253F8D}.Debug|Any CPU.Build.0 = Debug|Any CPU {3FF4CEA0-1555-4D62-AA81-B3B599253F8D}.Release|Any CPU.ActiveCfg = Release|Any CPU {3FF4CEA0-1555-4D62-AA81-B3B599253F8D}.Release|Any CPU.Build.0 = Release|Any CPU + {AFE75D2B-8853-488B-B5D5-277B58C5DBB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AFE75D2B-8853-488B-B5D5-277B58C5DBB2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AFE75D2B-8853-488B-B5D5-277B58C5DBB2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AFE75D2B-8853-488B-B5D5-277B58C5DBB2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -692,6 +700,8 @@ Global {FF518E10-C9AB-440C-8E8D-9CFF67A926AC} = {3A0784A6-AFBF-406F-B79E-9505EB100445} {49E0B90B-8635-43D0-B0AB-9D484CAE68B5} = {7FDFB22F-1BFF-4E05-9427-78B7A8461D50} {3FF4CEA0-1555-4D62-AA81-B3B599253F8D} = {38E21687-5F19-42C9-9D11-4B1D2EF64EDB} + {BD97C98B-0B4B-443D-AB29-145A344F46D3} = {02EA4E78-5891-43BC-944F-3E52FEE032E4} + {AFE75D2B-8853-488B-B5D5-277B58C5DBB2} = {BD97C98B-0B4B-443D-AB29-145A344F46D3} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {06C707C6-02C0-411A-AD3B-2D0E13787CB8} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/FodyWeavers.xml b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/FodyWeavers.xml new file mode 100644 index 000000000..17d32672d --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/FodyWeavers.xsd b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN.Abp.WebHooks.csproj b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN.Abp.WebHooks.csproj new file mode 100644 index 000000000..ca6031c7a --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN.Abp.WebHooks.csproj @@ -0,0 +1,18 @@ + + + + + + + netstandard2.0 + + + + + + + + + + + diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs new file mode 100644 index 000000000..03af8e4ef --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs @@ -0,0 +1,18 @@ +using Volo.Abp.BackgroundJobs; +using Volo.Abp.Features; +using Volo.Abp.Guids; +using Volo.Abp.Http.Client; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.Webhooks; + +[DependsOn(typeof(AbpBackgroundJobsAbstractionsModule))] +[DependsOn(typeof(AbpFeaturesModule))] +[DependsOn(typeof(AbpGuidsModule))] +[DependsOn(typeof(AbpHttpClientModule))] +public class AbpWebhooksModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksOptions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksOptions.cs new file mode 100644 index 000000000..7ac2ec457 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksOptions.cs @@ -0,0 +1,26 @@ +using System; +using Volo.Abp.Collections; + +namespace LINGYUN.Abp.Webhooks; + +public class AbpWebhooksOptions +{ + public TimeSpan TimeoutDuration { get; set; } + + public int MaxSendAttemptCount { get; set; } + + public bool IsAutomaticSubscriptionDeactivationEnabled { get; set; } + + public int MaxConsecutiveFailCountBeforeDeactivateSubscription { get; set; } + + public ITypeList DefinitionProviders { get; } + + public AbpWebhooksOptions() + { + TimeoutDuration = TimeSpan.FromSeconds(60); + MaxSendAttemptCount = 5; + MaxConsecutiveFailCountBeforeDeactivateSubscription = MaxSendAttemptCount * 3; + + DefinitionProviders = new TypeList(); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/BackgroundWorker/WebhookSenderJob.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/BackgroundWorker/WebhookSenderJob.cs new file mode 100644 index 000000000..4d18cb209 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/BackgroundWorker/WebhookSenderJob.cs @@ -0,0 +1,125 @@ +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using System; +using System.Threading.Tasks; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Uow; + +namespace LINGYUN.Abp.Webhooks.BackgroundWorker +{ + public class WebhookSenderJob : AsyncBackgroundJob, ITransientDependency + { + private readonly IUnitOfWorkManager _unitOfWorkManager; + private readonly IWebhookSubscriptionManager _webhookSubscriptionManager; + private readonly IWebhookSendAttemptStore _webhookSendAttemptStore; + private readonly IWebhookSender _webhookSender; + + private readonly AbpWebhooksOptions _options; + + public WebhookSenderJob( + IUnitOfWorkManager unitOfWorkManager, + IWebhookSubscriptionManager webhookSubscriptionManager, + IWebhookSendAttemptStore webhookSendAttemptStore, + IWebhookSender webhookSender, + IOptions options) + { + _unitOfWorkManager = unitOfWorkManager; + _webhookSubscriptionManager = webhookSubscriptionManager; + _webhookSendAttemptStore = webhookSendAttemptStore; + _webhookSender = webhookSender; + _options = options.Value; + } + + public override async Task ExecuteAsync(WebhookSenderArgs args) + { + if (args.TryOnce) + { + try + { + await SendWebhook(args); + } + catch (Exception e) + { + Logger.LogWarning("An error occured while sending webhook with try once.", e); + // ignored + } + } + else + { + await SendWebhook(args); + } + } + + private async Task SendWebhook(WebhookSenderArgs args) + { + if (args.WebhookEventId == default) + { + return; + } + + if (args.WebhookSubscriptionId == default) + { + return; + } + + if (!args.TryOnce) + { + var sendAttemptCount = await _webhookSendAttemptStore.GetSendAttemptCountAsync( + args.TenantId, + args.WebhookEventId, + args.WebhookSubscriptionId + ); + + if (sendAttemptCount > _options.MaxSendAttemptCount) + { + return; + } + } + + try + { + await _webhookSender.SendWebhookAsync(args); + } + catch (Exception) + { + // no need to retry to send webhook since subscription disabled + if (!await TryDeactivateSubscriptionIfReachedMaxConsecutiveFailCount( + args.TenantId, + args.WebhookSubscriptionId)) + { + throw; //Throw exception to re-try sending webhook + } + } + } + + private async Task TryDeactivateSubscriptionIfReachedMaxConsecutiveFailCount( + Guid? tenantId, + Guid subscriptionId) + { + if (!_options.IsAutomaticSubscriptionDeactivationEnabled) + { + return false; + } + + var hasXConsecutiveFail = await _webhookSendAttemptStore + .HasXConsecutiveFailAsync( + tenantId, + subscriptionId, + _options.MaxConsecutiveFailCountBeforeDeactivateSubscription + ); + + if (!hasXConsecutiveFail) + { + return false; + } + + using (var uow = _unitOfWorkManager.Begin()) + { + await _webhookSubscriptionManager.ActivateWebhookSubscriptionAsync(subscriptionId, false); + await uow.CompleteAsync(); + return true; + } + } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs new file mode 100644 index 000000000..d466ee0f8 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.Guids; +using Volo.Abp.Json; +using Volo.Abp.MultiTenancy; + +namespace LINGYUN.Abp.Webhooks +{ + public class DefaultWebhookPublisher : IWebhookPublisher + { + public IWebhookEventStore WebhookEventStore { get; set; } + + private readonly ICurrentTenant _currentTenant; + private readonly IGuidGenerator _guidGenerator; + private readonly IJsonSerializer _jsonSerializer; + private readonly IBackgroundJobManager _backgroundJobManager; + private readonly IWebhookSubscriptionManager _webhookSubscriptionManager; + + public DefaultWebhookPublisher( + IWebhookSubscriptionManager webhookSubscriptionManager, + ICurrentTenant currentTenant, + IGuidGenerator guidGenerator, + IJsonSerializer jsonSerializer, + IBackgroundJobManager backgroundJobManager) + { + _currentTenant = currentTenant; + _guidGenerator = guidGenerator; + _jsonSerializer = jsonSerializer; + _backgroundJobManager = backgroundJobManager; + _webhookSubscriptionManager = webhookSubscriptionManager; + + WebhookEventStore = NullWebhookEventStore.Instance; + } + + #region Async Publish Methods + public virtual async Task PublishAsync(string webhookName, object data, bool sendExactSameData = false, WebhookHeader headers = null) + { + var subscriptions = await _webhookSubscriptionManager.GetAllSubscriptionsIfFeaturesGrantedAsync(_currentTenant.Id, webhookName); + await PublishAsync(webhookName, data, subscriptions, sendExactSameData, headers); + } + + public virtual async Task PublishAsync(string webhookName, object data, Guid? tenantId, + bool sendExactSameData = false, WebhookHeader headers = null) + { + var subscriptions = await _webhookSubscriptionManager.GetAllSubscriptionsIfFeaturesGrantedAsync(tenantId, webhookName); + await PublishAsync(webhookName, data, subscriptions, sendExactSameData, headers); + } + + public virtual async Task PublishAsync(Guid?[] tenantIds, string webhookName, object data, + bool sendExactSameData = false, WebhookHeader headers = null) + { + var subscriptions = await _webhookSubscriptionManager.GetAllSubscriptionsOfTenantsIfFeaturesGrantedAsync(tenantIds, webhookName); + await PublishAsync(webhookName, data, subscriptions, sendExactSameData, headers); + } + + private async Task PublishAsync(string webhookName, object data, List webhookSubscriptions, + bool sendExactSameData = false, WebhookHeader headers = null) + { + if (webhookSubscriptions.IsNullOrEmpty()) + { + return; + } + + var subscriptionsGroupedByTenant = webhookSubscriptions.GroupBy(x => x.TenantId); + + foreach (var subscriptionGroupedByTenant in subscriptionsGroupedByTenant) + { + var webhookInfo = await SaveAndGetWebhookAsync(subscriptionGroupedByTenant.Key, webhookName, data); + + foreach (var webhookSubscription in subscriptionGroupedByTenant) + { + var headersToSend = webhookSubscription.Headers; + if (headers != null) + { + if (headers.UseOnlyGivenHeaders)//do not use the headers defined in subscription + { + headersToSend = headers.Headers; + } + else + { + //use the headers defined in subscription. If additional headers has same header, use additional headers value. + foreach (var additionalHeader in headers.Headers) + { + headersToSend[additionalHeader.Key] = additionalHeader.Value; + } + } + } + + await _backgroundJobManager.EnqueueAsync(new WebhookSenderArgs + { + TenantId = webhookSubscription.TenantId, + WebhookEventId = webhookInfo.Id, + Data = webhookInfo.Data, + WebhookName = webhookInfo.WebhookName, + WebhookSubscriptionId = webhookSubscription.Id, + Headers = headersToSend, + Secret = webhookSubscription.Secret, + WebhookUri = webhookSubscription.WebhookUri, + SendExactSameData = sendExactSameData + }); + } + } + } + + #endregion + + protected virtual async Task SaveAndGetWebhookAsync(Guid? tenantId, string webhookName, + object data) + { + var webhookInfo = new WebhookEvent + { + Id = _guidGenerator.Create(), + WebhookName = webhookName, + Data = _jsonSerializer.Serialize(data), + TenantId = tenantId + }; + + await WebhookEventStore.InsertAndGetIdAsync(webhookInfo); + return webhookInfo; + } + } +} \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs new file mode 100644 index 000000000..2dc939dc7 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs @@ -0,0 +1,133 @@ +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using System; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Webhooks +{ + public class DefaultWebhookSender : IWebhookSender + { + public ILogger Logger { protected get; set; } + + private readonly AbpWebhooksOptions _options; + private readonly IWebhookManager _webhookManager; + + private const string FailedRequestDefaultContent = "Webhook Send Request Failed"; + + public DefaultWebhookSender( + IOptions options, + IWebhookManager webhookManager) + { + _options = options.Value; + _webhookManager = webhookManager; + + Logger = NullLogger.Instance; + } + + public async Task SendWebhookAsync(WebhookSenderArgs webhookSenderArgs) + { + if (webhookSenderArgs.WebhookEventId == default) + { + throw new ArgumentNullException(nameof(webhookSenderArgs.WebhookEventId)); + } + + if (webhookSenderArgs.WebhookSubscriptionId == default) + { + throw new ArgumentNullException(nameof(webhookSenderArgs.WebhookSubscriptionId)); + } + + var webhookSendAttemptId = await _webhookManager.InsertAndGetIdWebhookSendAttemptAsync(webhookSenderArgs); + + var request = CreateWebhookRequestMessage(webhookSenderArgs); + + var serializedBody = await _webhookManager.GetSerializedBodyAsync(webhookSenderArgs); + + _webhookManager.SignWebhookRequest(request, serializedBody, webhookSenderArgs.Secret); + + AddAdditionalHeaders(request, webhookSenderArgs); + + var isSucceed = false; + HttpStatusCode? statusCode = null; + var content = FailedRequestDefaultContent; + + try + { + var response = await SendHttpRequest(request); + isSucceed = response.isSucceed; + statusCode = response.statusCode; + content = response.content; + } + catch (TaskCanceledException) + { + statusCode = HttpStatusCode.RequestTimeout; + content = "Request Timeout"; + } + catch (HttpRequestException e) + { + content = e.Message; + } + catch (Exception e) + { + Logger.LogError("An error occured while sending a webhook request", e); + } + finally + { + await _webhookManager.StoreResponseOnWebhookSendAttemptAsync(webhookSendAttemptId, webhookSenderArgs.TenantId, statusCode, content); + } + + if (!isSucceed) + { + throw new Exception($"Webhook sending attempt failed. WebhookSendAttempt id: {webhookSendAttemptId}"); + } + + return webhookSendAttemptId; + } + + /// + /// You can override this to change request message + /// + /// + protected virtual HttpRequestMessage CreateWebhookRequestMessage(WebhookSenderArgs webhookSenderArgs) + { + return new HttpRequestMessage(HttpMethod.Post, webhookSenderArgs.WebhookUri); + } + + protected virtual void AddAdditionalHeaders(HttpRequestMessage request, WebhookSenderArgs webhookSenderArgs) + { + foreach (var header in webhookSenderArgs.Headers) + { + if (request.Headers.TryAddWithoutValidation(header.Key, header.Value)) + { + continue; + } + + if (request.Content.Headers.TryAddWithoutValidation(header.Key, header.Value)) + { + continue; + } + + throw new Exception($"Invalid Header. SubscriptionId:{webhookSenderArgs.WebhookSubscriptionId},Header: {header.Key}:{header.Value}"); + } + } + + protected virtual async Task<(bool isSucceed, HttpStatusCode statusCode, string content)> SendHttpRequest(HttpRequestMessage request) + { + using (var client = new HttpClient + { + Timeout = _options.TimeoutDuration + }) + { + var response = await client.SendAsync(request); + + var isSucceed = response.IsSuccessStatusCode; + var statusCode = response.StatusCode; + var content = await response.Content.ReadAsStringAsync(); + + return (isSucceed, statusCode, content); + } + } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookDefinitionContext.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookDefinitionContext.cs new file mode 100644 index 000000000..328c214bd --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookDefinitionContext.cs @@ -0,0 +1,22 @@ +namespace LINGYUN.Abp.Webhooks +{ + public interface IWebhookDefinitionContext + { + /// + /// Adds the specified webhook definition. Throws exception if it is already added + /// + void Add(params WebhookDefinition[] definitions); + + /// + /// Gets a webhook definition by name. + /// Returns null if there is no webhook definition with given name. + /// + WebhookDefinition GetOrNull(string name); + + /// + /// Remove webhook with given name + /// + /// webhook definition name + void Remove(string name); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookDefinitionManager.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookDefinitionManager.cs new file mode 100644 index 000000000..057b0b984 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookDefinitionManager.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Webhooks +{ + public interface IWebhookDefinitionManager + { + /// + /// Gets a webhook definition by name. + /// Returns null if there is no webhook definition with given name. + /// + WebhookDefinition GetOrNull(string name); + + /// + /// Gets a webhook definition by name. + /// Throws exception if there is no webhook definition with given name. + /// + WebhookDefinition Get(string name); + + /// + /// Gets all webhook definitions. + /// + IReadOnlyList GetAll(); + + /// + /// Checks if given webhook name is available for given tenant. + /// + Task IsAvailableAsync(Guid? tenantId, string name); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookEventStore.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookEventStore.cs new file mode 100644 index 000000000..1fb8f5c21 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookEventStore.cs @@ -0,0 +1,18 @@ +using System; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Webhooks +{ + public interface IWebhookEventStore + { + /// + /// Inserts to persistent store + /// + Task InsertAndGetIdAsync(WebhookEvent webhookEvent); + + /// + /// Gets Webhook info by id + /// + Task GetAsync(Guid? tenantId, Guid id); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookManager.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookManager.cs new file mode 100644 index 000000000..1e8e5fd0c --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookManager.cs @@ -0,0 +1,22 @@ +using System; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Webhooks +{ + public interface IWebhookManager + { + Task GetWebhookPayloadAsync(WebhookSenderArgs webhookSenderArgs); + + void SignWebhookRequest(HttpRequestMessage request, string serializedBody, string secret); + + Task GetSerializedBodyAsync(WebhookSenderArgs webhookSenderArgs); + + Task InsertAndGetIdWebhookSendAttemptAsync(WebhookSenderArgs webhookSenderArgs); + + Task StoreResponseOnWebhookSendAttemptAsync( + Guid webhookSendAttemptId, Guid? tenantId, + HttpStatusCode? statusCode, string content); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookPublisher.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookPublisher.cs new file mode 100644 index 000000000..3b53fec83 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookPublisher.cs @@ -0,0 +1,56 @@ +using System; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Webhooks +{ + public interface IWebhookPublisher + { + /// + /// Sends webhooks to current tenant subscriptions (). with given data, (Checks permissions) + /// + /// + /// data to send + /// + /// True: It sends the exact same data as the parameter to clients. + /// + /// False: It sends data in . It is recommended way. + /// + /// + /// Headers to send. Publisher uses subscription defined webhook by default. You can add additional headers from here. If subscription already has given header, publisher uses the one you give here. + Task PublishAsync(string webhookName, object data, bool sendExactSameData = false, WebhookHeader headers = null); + + /// + /// Sends webhooks to given tenant's subscriptions + /// + /// + /// data to send + /// + /// Target tenant id + /// + /// + /// True: It sends the exact same data as the parameter to clients. + /// + /// False: It sends data in . It is recommended way. + /// + /// + /// Headers to send. Publisher uses subscription defined webhook by default. You can add additional headers from here. If subscription already has given header, publisher uses the one you give here. + Task PublishAsync(string webhookName, object data, Guid? tenantId, bool sendExactSameData = false, WebhookHeader headers = null); + + /// + /// Sends webhooks to given tenant's subscriptions + /// + /// + /// data to send + /// + /// Target tenant id(s) + /// + /// + /// True: It sends the exact same data as the parameter to clients. + /// + /// False: It sends data in . It is recommended way. + /// + /// + /// Headers to send. Publisher uses subscription defined webhook by default. You can add additional headers from here. If subscription already has given header, publisher uses the one you give here. + Task PublishAsync(Guid?[] tenantIds, string webhookName, object data, bool sendExactSameData = false, WebhookHeader headers = null); + } +} \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookSendAttemptStore.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookSendAttemptStore.cs new file mode 100644 index 000000000..2e32bc63f --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookSendAttemptStore.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Webhooks +{ + public interface IWebhookSendAttemptStore + { + Task GetAsync(Guid? tenantId, Guid id); + + /// + /// Returns work item count by given web hook id and subscription id, (How many times publisher tried to send web hook) + /// + Task GetSendAttemptCountAsync(Guid? tenantId, Guid webhookId, Guid webhookSubscriptionId); + + /// + /// Checks is there any successful webhook attempt in last items. Should return true if there are not X number items + /// + Task HasXConsecutiveFailAsync(Guid? tenantId, Guid subscriptionId, int searchCount); + + Task<(int TotalCount, IReadOnlyCollection Webhooks)> GetAllSendAttemptsBySubscriptionAsPagedListAsync(Guid? tenantId, Guid subscriptionId, int maxResultCount, int skipCount); + + Task> GetAllSendAttemptsByWebhookEventIdAsync(Guid? tenantId, Guid webhookEventId); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookSender.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookSender.cs new file mode 100644 index 000000000..d30e110e6 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookSender.cs @@ -0,0 +1,16 @@ +using System; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Webhooks +{ + public interface IWebhookSender + { + /// + /// Tries to send webhook with given transactionId and stores process in + /// Should throw exception if fails or response status not succeed + /// + /// arguments + /// Webhook send attempt id + Task SendWebhookAsync(WebhookSenderArgs webhookSenderArgs); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookSubscriptionManager.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookSubscriptionManager.cs new file mode 100644 index 000000000..956b2dbd3 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookSubscriptionManager.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Webhooks +{ + public interface IWebhookSubscriptionManager + { + /// + /// Returns subscription for given id. + /// + /// Unique identifier of + Task GetAsync(Guid id); + + /// + /// Returns all subscriptions of tenant + /// + /// + /// Target tenant id. + /// + Task> GetAllSubscriptionsAsync(Guid? tenantId); + + /// + /// Returns all subscriptions for given webhook. + /// + /// + /// + /// Target tenant id. + /// + Task> GetAllSubscriptionsIfFeaturesGrantedAsync(Guid? tenantId, string webhookName); + + /// + /// Returns all subscriptions of tenant + /// + /// + Task> GetAllSubscriptionsOfTenantsAsync(Guid?[] tenantIds); + + /// + /// Returns all subscriptions for given webhook. + /// + /// + /// + /// Target tenant id(s). + /// + Task> GetAllSubscriptionsOfTenantsIfFeaturesGrantedAsync(Guid?[] tenantIds, string webhookName); + + /// + /// Checks if tenant subscribed for a webhook. (Checks if webhook features are granted) + /// + /// + /// Target tenant id(s). + /// + /// + Task IsSubscribedAsync(Guid? tenantId, string webhookName); + + /// + /// If id is the default(Guid) adds new subscription, else updates current one. (Checks if webhook features are granted) + /// + Task AddOrUpdateSubscriptionAsync(WebhookSubscriptionInfo webhookSubscription); + + /// + /// Activates/Deactivates given webhook subscription + /// + /// unique identifier of + /// IsActive + Task ActivateWebhookSubscriptionAsync(Guid id, bool active); + + /// + /// Delete given webhook subscription. + /// + /// unique identifier of + Task DeleteSubscriptionAsync(Guid id); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookSubscriptionsStore.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookSubscriptionsStore.cs new file mode 100644 index 000000000..23849ad4e --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookSubscriptionsStore.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Webhooks +{ + /// + /// This interface should be implemented by vendors to make webhooks working. + /// + public interface IWebhookSubscriptionsStore + { + /// + /// returns subscription + /// + /// webhook subscription id + /// + Task GetAsync(Guid id); + + /// + /// Saves webhook subscription to a persistent store. + /// + /// webhook subscription information + Task InsertAsync(WebhookSubscriptionInfo webhookSubscription); + + /// + /// Updates webhook subscription to a persistent store. + /// + /// webhook subscription information + Task UpdateAsync(WebhookSubscriptionInfo webhookSubscription); + + /// + /// Deletes subscription if exists + /// + /// primary key + /// + Task DeleteAsync(Guid id); + + /// + /// Returns all subscriptions of given tenant including deactivated + /// + /// + /// Target tenant id. + /// + Task> GetAllSubscriptionsAsync(Guid? tenantId); + + /// + /// Returns webhook subscriptions which subscribe to given webhook on tenant(s) + /// + /// + /// Target tenant id. + /// + /// + /// + Task> GetAllSubscriptionsAsync(Guid? tenantId, string webhookName); + + /// + /// Returns all subscriptions of given tenant including deactivated + /// + /// + /// Target tenant id(s). + /// + Task> GetAllSubscriptionsOfTenantsAsync(Guid?[] tenantIds); + + /// + /// Returns webhook subscriptions which subscribe to given webhook on tenant(s) + /// + /// + /// Target tenant id(s). + /// + /// + /// + Task> GetAllSubscriptionsOfTenantsAsync(Guid?[] tenantIds, string webhookName); + + /// + /// Checks if tenant subscribed for a webhook + /// + /// + /// Target tenant id(s). + /// + /// Name of the webhook + Task IsSubscribedAsync(Guid? tenantId, string webhookName); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/NullWebhookEventStore.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/NullWebhookEventStore.cs new file mode 100644 index 000000000..069726e67 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/NullWebhookEventStore.cs @@ -0,0 +1,24 @@ +using System; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Webhooks +{ + /// + /// Null pattern implementation of . + /// It's used if is not implemented by actual persistent store + /// + public class NullWebhookEventStore : IWebhookEventStore + { + public static NullWebhookEventStore Instance { get; } = new NullWebhookEventStore(); + + public Task InsertAndGetIdAsync(WebhookEvent webhookEvent) + { + return Task.FromResult(default); + } + + public Task GetAsync(Guid? tenantId, Guid id) + { + return Task.FromResult(default); + } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/NullWebhookSendAttemptStore.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/NullWebhookSendAttemptStore.cs new file mode 100644 index 000000000..75749401b --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/NullWebhookSendAttemptStore.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Webhooks +{ + public class NullWebhookSendAttemptStore : IWebhookSendAttemptStore + { + public static NullWebhookSendAttemptStore Instance = new NullWebhookSendAttemptStore(); + + public Task InsertAsync(WebhookSendAttempt webhookSendAttempt) + { + return Task.CompletedTask; + } + + public Task UpdateAsync(WebhookSendAttempt webhookSendAttempt) + { + return Task.CompletedTask; + } + + public Task GetAsync(Guid? tenantId, Guid id) + { + return Task.FromResult(default); + } + + public Task GetSendAttemptCountAsync(Guid? tenantId, Guid webhookId, Guid webhookSubscriptionId) + { + return Task.FromResult(int.MaxValue); + } + + public Task HasXConsecutiveFailAsync(Guid? tenantId, Guid subscriptionId, int searchCount) + { + return default; + } + + public Task> GetAllSendAttemptsBySubscriptionAsPagedListAsync(Guid? tenantId, Guid subscriptionId, int maxResultCount, + int skipCount) + { + return Task.FromResult(new List() as IReadOnlyCollection); + } + + public Task> GetAllSendAttemptsByWebhookEventIdAsync(Guid? tenantId, Guid webhookEventId) + { + return Task.FromResult(new List()); + } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/NullWebhookSubscriptionsStore.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/NullWebhookSubscriptionsStore.cs new file mode 100644 index 000000000..4214d1d25 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/NullWebhookSubscriptionsStore.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Webhooks +{ + /// + /// Null pattern implementation of . + /// It's used if is not implemented by actual persistent store + /// + public class NullWebhookSubscriptionsStore : IWebhookSubscriptionsStore + { + public static NullWebhookSubscriptionsStore Instance { get; } = new NullWebhookSubscriptionsStore(); + + public Task GetAsync(Guid id) + { + return Task.FromResult(default); + } + + public WebhookSubscriptionInfo Get(Guid id) + { + return default; + } + + public Task InsertAsync(WebhookSubscriptionInfo webhookSubscription) + { + return Task.CompletedTask; + } + + public Task UpdateAsync(WebhookSubscriptionInfo webhookSubscription) + { + return Task.CompletedTask; + } + + public Task DeleteAsync(Guid id) + { + return Task.CompletedTask; + } + + public Task> GetAllSubscriptionsAsync(Guid? tenantId) + { + return Task.FromResult(new List()); + } + + public Task> GetAllSubscriptionsAsync(Guid? tenantId, string webhookName) + { + return Task.FromResult(new List()); + } + + public Task> GetAllSubscriptionsOfTenantsAsync(Guid?[] tenantIds) + { + return Task.FromResult(new List()); + } + + public Task> GetAllSubscriptionsOfTenantsAsync(Guid?[] tenantIds, string webhookName) + { + return Task.FromResult(new List()); + } + + public Task IsSubscribedAsync(Guid? tenantId, string webhookName) + { + return Task.FromResult(false); + } + } +} \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinition.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinition.cs new file mode 100644 index 000000000..88f3a074d --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinition.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Localization; + +namespace LINGYUN.Abp.Webhooks +{ + public class WebhookDefinition + { + /// + /// Unique name of the webhook. + /// + public string Name { get; } + + /// + /// Display name of the webhook. + /// Optional. + /// + public ILocalizableString DisplayName { get; set; } + + /// + /// Description for the webhook. + /// Optional. + /// + public ILocalizableString Description { get; set; } + + public List RequiredFeatures { get; set; } + + public WebhookDefinition(string name, ILocalizableString displayName = null, ILocalizableString description = null) + { + if (name.IsNullOrWhiteSpace()) + { + throw new ArgumentNullException(nameof(name), $"{nameof(name)} can not be null, empty or whitespace!"); + } + + Name = name.Trim(); + DisplayName = displayName; + Description = description; + + RequiredFeatures = new List(); + } + + public WebhookDefinition WithFeature(params string[] features) + { + if (!features.IsNullOrEmpty()) + { + RequiredFeatures.AddRange(features); + } + + return this; + } + + public override string ToString() + { + return $"[{nameof(WebhookDefinition)} {Name}]"; + } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionContext.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionContext.cs new file mode 100644 index 000000000..4176fc785 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionContext.cs @@ -0,0 +1,54 @@ +using JetBrains.Annotations; +using System.Collections.Generic; +using Volo.Abp; +using Volo.Abp.Localization; + +namespace LINGYUN.Abp.Webhooks +{ + public class WebhookDefinitionContext : IWebhookDefinitionContext + { + protected Dictionary Webhooks { get; } + + public WebhookDefinitionContext(Dictionary webhooks) + { + Webhooks = webhooks; + } + + public void Add(params WebhookDefinition[] definitions) + { + if (definitions.IsNullOrEmpty()) + { + return; + } + + foreach (var definition in definitions) + { + Webhooks[definition.Name] = definition; + } + } + + public WebhookDefinition GetOrNull([NotNull] string name) + { + Check.NotNull(name, nameof(name)); + + if (!Webhooks.ContainsKey(name)) + { + return null; + } + + return Webhooks[name]; + } + + public void Remove(string name) + { + Check.NotNull(name, nameof(name)); + + if (!Webhooks.ContainsKey(name)) + { + throw new AbpException($"Undefined notification webhook: '{name}'."); + } + + Webhooks.Remove(name); + } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionManager.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionManager.cs new file mode 100644 index 000000000..bf70017be --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionManager.cs @@ -0,0 +1,109 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Features; +using Volo.Abp.MultiTenancy; + +namespace LINGYUN.Abp.Webhooks +{ + internal class WebhookDefinitionManager : IWebhookDefinitionManager, ISingletonDependency + { + protected IDictionary WebhookDefinitions => _lazyWebhookDefinitions.Value; + private readonly Lazy> _lazyWebhookDefinitions; + + private readonly IServiceProvider _serviceProvider; + private readonly AbpWebhooksOptions _options; + + public WebhookDefinitionManager( + IServiceProvider serviceProvider, + IOptions options) + { + _serviceProvider = serviceProvider; + _options = options.Value; + + _lazyWebhookDefinitions = new Lazy>(CreateWebhookDefinitions); + } + + public WebhookDefinition GetOrNull(string name) + { + if (!WebhookDefinitions.ContainsKey(name)) + { + return null; + } + + return WebhookDefinitions[name]; + } + + public WebhookDefinition Get(string name) + { + if (!WebhookDefinitions.ContainsKey(name)) + { + throw new KeyNotFoundException($"Webhook definitions does not contain a definition with the key \"{name}\"."); + } + + return WebhookDefinitions[name]; + } + + public IReadOnlyList GetAll() + { + return WebhookDefinitions.Values.ToImmutableList(); + } + + public async Task IsAvailableAsync(Guid? tenantId, string name) + { + if (tenantId == null) // host allowed to subscribe all webhooks + { + return true; + } + + var webhookDefinition = GetOrNull(name); + + if (webhookDefinition == null) + { + return false; + } + + if (webhookDefinition.RequiredFeatures?.Any() == false) + { + return true; + } + + var currentTenant = _serviceProvider.GetRequiredService(); + var featureChecker = _serviceProvider.GetRequiredService(); + using (currentTenant.Change(tenantId)) + { + if (!await featureChecker.IsEnabledAsync(true, webhookDefinition.RequiredFeatures.ToArray())) + { + return false; + } + } + + return true; + } + + protected virtual Dictionary CreateWebhookDefinitions() + { + var definitions = new Dictionary(); + + using (var scope = _serviceProvider.CreateScope()) + { + var providers = _options + .DefinitionProviders + .Select(p => scope.ServiceProvider.GetRequiredService(p) as WebhookDefinitionProvider) + .ToList(); + + foreach (var provider in providers) + { + provider.Define(new WebhookDefinitionContext(definitions)); + } + } + + return definitions; + } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionProvider.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionProvider.cs new file mode 100644 index 000000000..ead9ab679 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionProvider.cs @@ -0,0 +1,13 @@ +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.Webhooks +{ + public abstract class WebhookDefinitionProvider : ITransientDependency + { + /// + /// Used to add/manipulate webhook definitions. + /// + /// Context, + public abstract void Define(IWebhookDefinitionContext context); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookEvent.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookEvent.cs new file mode 100644 index 000000000..bd32fa76d --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookEvent.cs @@ -0,0 +1,30 @@ +using System; + +namespace LINGYUN.Abp.Webhooks +{ + /// + /// Store created web hooks. To see who get that webhook check with and you can get + /// + public class WebhookEvent + { + public Guid Id { get; set; } + + /// + /// Webhook unique name + /// + public string WebhookName { get; set; } + + /// + /// Webhook data as JSON string. + /// + public string Data { get; set; } + + public DateTime CreationTime { get; set; } + + public Guid? TenantId { get; set; } + + public bool IsDeleted { get; set; } + + public DateTime? DeletionTime { get; set; } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookHeader.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookHeader.cs new file mode 100644 index 000000000..91442552f --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookHeader.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; + +namespace LINGYUN.Abp.Webhooks +{ + public class WebhookHeader + { + /// + /// If true, webhook will only contain given headers. If false given headers will be added to predefined headers in subscription. + /// Default is false + /// + public bool UseOnlyGivenHeaders { get; set; } + + /// + /// That headers will be sent with the webhook. + /// + public IDictionary Headers { get; set; } + } +} \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookManager.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookManager.cs new file mode 100644 index 000000000..29389e15e --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookManager.cs @@ -0,0 +1,84 @@ +using System; +using System.Globalization; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Json; + +namespace LINGYUN.Abp.Webhooks +{ + public abstract class WebhookManager : IWebhookManager + { + private const string SignatureHeaderKey = "sha256"; + private const string SignatureHeaderValueTemplate = SignatureHeaderKey + "={0}"; + private const string SignatureHeaderName = "abp-webhook-signature"; + + protected IJsonSerializer JsonSerializer { get; } + protected IWebhookSendAttemptStore WebhookSendAttemptStore { get; } + + protected WebhookManager( + IJsonSerializer jsonSerializer, + IWebhookSendAttemptStore webhookSendAttemptStore) + { + JsonSerializer = jsonSerializer; + WebhookSendAttemptStore = webhookSendAttemptStore; + } + + public virtual async Task GetWebhookPayloadAsync(WebhookSenderArgs webhookSenderArgs) + { + var data = JsonSerializer.Serialize(webhookSenderArgs.Data); + + var attemptNumber = await WebhookSendAttemptStore.GetSendAttemptCountAsync( + webhookSenderArgs.TenantId, + webhookSenderArgs.WebhookEventId, + webhookSenderArgs.WebhookSubscriptionId); + + return new WebhookPayload( + webhookSenderArgs.WebhookEventId.ToString(), + webhookSenderArgs.WebhookName, + attemptNumber) + { + Data = data + }; + } + + public virtual void SignWebhookRequest(HttpRequestMessage request, string serializedBody, string secret) + { + if (request == null) + { + throw new ArgumentNullException(nameof(request)); + } + + if (string.IsNullOrWhiteSpace(serializedBody)) + { + throw new ArgumentNullException(nameof(serializedBody)); + } + + request.Content = new StringContent(serializedBody, Encoding.UTF8, "application/json"); + + var secretBytes = Encoding.UTF8.GetBytes(secret); + var headerValue = string.Format(CultureInfo.InvariantCulture, SignatureHeaderValueTemplate, serializedBody.Sha256(secretBytes)); + + request.Headers.Add(SignatureHeaderName, headerValue); + } + + public virtual async Task GetSerializedBodyAsync(WebhookSenderArgs webhookSenderArgs) + { + if (webhookSenderArgs.SendExactSameData) + { + return webhookSenderArgs.Data; + } + + var payload = await GetWebhookPayloadAsync(webhookSenderArgs); + + var serializedBody = JsonSerializer.Serialize(payload); + + return serializedBody; + } + + public abstract Task InsertAndGetIdWebhookSendAttemptAsync(WebhookSenderArgs webhookSenderArgs); + + public abstract Task StoreResponseOnWebhookSendAttemptAsync(Guid webhookSendAttemptId, Guid? tenantId, HttpStatusCode? statusCode, string content); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookPayload.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookPayload.cs new file mode 100644 index 000000000..ff287cbd0 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookPayload.cs @@ -0,0 +1,35 @@ +using System; + +namespace LINGYUN.Abp.Webhooks +{ + public class WebhookPayload + { + public string Id { get; set; } + + public string WebhookEvent { get; set; } + + public int Attempt { get; set; } + + public dynamic Data { get; set; } + + public DateTime CreationTimeUtc { get; set; } + + public WebhookPayload(string id, string webhookEvent, int attempt) + { + if (id.IsNullOrWhiteSpace()) + { + throw new ArgumentNullException(nameof(id)); + } + + if (webhookEvent.IsNullOrWhiteSpace()) + { + throw new ArgumentNullException(nameof(webhookEvent)); + } + + Id = id; + WebhookEvent = webhookEvent; + Attempt = attempt; + CreationTimeUtc = DateTime.UtcNow; + } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSendAttempt.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSendAttempt.cs new file mode 100644 index 000000000..8189f8f72 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSendAttempt.cs @@ -0,0 +1,39 @@ +using System; +using System.Net; + +namespace LINGYUN.Abp.Webhooks +{ + /// + /// Table for store webhook work items. Each item stores web hook send attempt of to subscribed tenants + /// + public class WebhookSendAttempt + { + public Guid Id { get; set; } + + /// + /// foreign id + /// + public Guid WebhookEventId { get; set; } + + /// + /// foreign id + /// + public Guid WebhookSubscriptionId { get; set; } + + /// + /// Webhook response content that webhook endpoint send back + /// + public string Response { get; set; } + + /// + /// Webhook response status code that webhook endpoint send back + /// + public HttpStatusCode? ResponseStatusCode { get; set; } + + public DateTime CreationTime { get; set; } + + public DateTime? LastModificationTime { get; set; } + + public Guid? TenantId { get; set; } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSenderArgs.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSenderArgs.cs new file mode 100644 index 000000000..7910ba0b1 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSenderArgs.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; + +namespace LINGYUN.Abp.Webhooks +{ + public class WebhookSenderArgs + { + public Guid? TenantId { get; set; } + + //Webhook information + + /// + /// foreign id + /// + public Guid WebhookEventId { get; set; } + + /// + /// Webhook unique name + /// + public string WebhookName { get; set; } + + /// + /// Webhook data as JSON string. + /// + public string Data { get; set; } + + //Subscription information + + /// + /// foreign id + /// + public Guid WebhookSubscriptionId { get; set; } + + /// + /// Subscription webhook endpoint + /// + public string WebhookUri { get; set; } + + /// + /// Webhook secret + /// + public string Secret { get; set; } + + /// + /// Gets a set of additional HTTP headers.That headers will be sent with the webhook. + /// + public IDictionary Headers { get; set; } + + /// + /// Tries to send webhook only one time without checking to send attempt count + /// + public bool TryOnce { get; set; } + + /// + /// True: It sends the exact same data as the parameter to clients. + /// + /// False: It sends data in . It is recommended way. + /// + /// + public bool SendExactSameData { get; set; } + + public WebhookSenderArgs() + { + Headers = new Dictionary(); + } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionInfo.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionInfo.cs new file mode 100644 index 000000000..9e4e3bf2a --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionInfo.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; + +namespace LINGYUN.Abp.Webhooks +{ + public class WebhookSubscriptionInfo + { + public Guid Id { get; set; } + /// + /// Subscribed Tenant's id . + /// + public Guid? TenantId { get; set; } + + /// + /// Subscription webhook endpoint + /// + public string WebhookUri { get; set; } + + /// + /// Webhook secret + /// + public string Secret { get; set; } + + /// + /// Is subscription active + /// + public bool IsActive { get; set; } + + /// + /// Subscribed webhook definitions unique names.It contains webhook definitions list as json + /// + /// Do not change it manually. + /// Use , + /// , + /// and + /// to change it. + /// + /// + public List Webhooks { get; set; } + + /// + /// Gets a set of additional HTTP headers.That headers will be sent with the webhook. It contains webhook header dictionary as json + /// + /// Do not change it manually. + /// Use , + /// , + /// , + /// to change it. + /// + /// + public IDictionary Headers { get; set; } + + public WebhookSubscriptionInfo() + { + IsActive = true; + Headers = new Dictionary(); + Webhooks = new List(); + } + } +} \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionManager.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionManager.cs new file mode 100644 index 000000000..4ed53d52b --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionManager.cs @@ -0,0 +1,175 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Authorization; +using Volo.Abp.Guids; +using Volo.Abp.Uow; + +namespace LINGYUN.Abp.Webhooks +{ + public class WebhookSubscriptionManager : IWebhookSubscriptionManager + { + public IWebhookSubscriptionsStore WebhookSubscriptionsStore { get; set; } + + private readonly IGuidGenerator _guidGenerator; + private readonly IUnitOfWorkManager _unitOfWorkManager; + private readonly IWebhookDefinitionManager _webhookDefinitionManager; + + private const string WebhookSubscriptionSecretPrefix = "whs_"; + + public WebhookSubscriptionManager( + IGuidGenerator guidGenerator, + IUnitOfWorkManager unitOfWorkManager, + IWebhookDefinitionManager webhookDefinitionManager) + { + _guidGenerator = guidGenerator; + _unitOfWorkManager = unitOfWorkManager; + _webhookDefinitionManager = webhookDefinitionManager; + + WebhookSubscriptionsStore = NullWebhookSubscriptionsStore.Instance; + } + + public virtual async Task GetAsync(Guid id) + { + return await WebhookSubscriptionsStore.GetAsync(id); + } + + public virtual async Task> GetAllSubscriptionsAsync(Guid? tenantId) + { + return await WebhookSubscriptionsStore.GetAllSubscriptionsAsync(tenantId); + } + + public virtual async Task> GetAllSubscriptionsIfFeaturesGrantedAsync(Guid? tenantId, string webhookName) + { + if (!await _webhookDefinitionManager.IsAvailableAsync(tenantId, webhookName)) + { + return new List(); + } + + return (await WebhookSubscriptionsStore.GetAllSubscriptionsAsync(tenantId, webhookName)).ToList(); + } + + public virtual async Task> GetAllSubscriptionsOfTenantsAsync(Guid?[] tenantIds) + { + return (await WebhookSubscriptionsStore.GetAllSubscriptionsOfTenantsAsync(tenantIds)).ToList(); + } + + public virtual async Task> GetAllSubscriptionsOfTenantsIfFeaturesGrantedAsync(Guid?[] tenantIds, string webhookName) + { + var featureGrantedTenants = new List(); + foreach (var tenantId in tenantIds) + { + if (await _webhookDefinitionManager.IsAvailableAsync(tenantId, webhookName)) + { + featureGrantedTenants.Add(tenantId); + } + } + + return (await WebhookSubscriptionsStore.GetAllSubscriptionsOfTenantsAsync(featureGrantedTenants.ToArray(), webhookName)).ToList(); + } + + public virtual async Task IsSubscribedAsync(Guid? tenantId, string webhookName) + { + if (!await _webhookDefinitionManager.IsAvailableAsync(tenantId, webhookName)) + { + return false; + } + + return await WebhookSubscriptionsStore.IsSubscribedAsync(tenantId, webhookName); + } + + public virtual async Task AddOrUpdateSubscriptionAsync(WebhookSubscriptionInfo webhookSubscription) + { + using (var uow = _unitOfWorkManager.Begin()) + { + await CheckIfPermissionsGrantedAsync(webhookSubscription); + + if (webhookSubscription.Id == default) + { + webhookSubscription.Id = _guidGenerator.Create(); + webhookSubscription.Secret = WebhookSubscriptionSecretPrefix + Guid.NewGuid().ToString("N"); + await WebhookSubscriptionsStore.InsertAsync(webhookSubscription); + } + else + { + var subscription = await WebhookSubscriptionsStore.GetAsync(webhookSubscription.Id); + subscription.WebhookUri = webhookSubscription.WebhookUri; + subscription.Webhooks = webhookSubscription.Webhooks; + subscription.Headers = webhookSubscription.Headers; + await WebhookSubscriptionsStore.UpdateAsync(subscription); + } + + await uow.SaveChangesAsync(); + } + } + + public virtual async Task ActivateWebhookSubscriptionAsync(Guid id, bool active) + { + using (var uow = _unitOfWorkManager.Begin()) + { + var webhookSubscription = await WebhookSubscriptionsStore.GetAsync(id); + webhookSubscription.IsActive = active; + + await uow.SaveChangesAsync(); + } + } + + public virtual async Task DeleteSubscriptionAsync(Guid id) + { + using (var uow = _unitOfWorkManager.Begin()) + { + await WebhookSubscriptionsStore.DeleteAsync(id); + + await uow.SaveChangesAsync(); + } + } + + public virtual async Task AddWebhookAsync(WebhookSubscriptionInfo subscription, string webhookName) + { + using (var uow = _unitOfWorkManager.Begin()) + { + await CheckPermissionsAsync(subscription.TenantId, webhookName); + webhookName = webhookName.Trim(); + if (webhookName.IsNullOrWhiteSpace()) + { + throw new ArgumentNullException(nameof(webhookName), $"{nameof(webhookName)} can not be null, empty or whitespace!"); + } + + if (!subscription.Webhooks.Contains(webhookName)) + { + subscription.Webhooks.Add(webhookName); + + await WebhookSubscriptionsStore.UpdateAsync(subscription); + } + + await uow.SaveChangesAsync(); + } + } + + #region PermissionCheck + + protected virtual async Task CheckIfPermissionsGrantedAsync(WebhookSubscriptionInfo webhookSubscription) + { + if (webhookSubscription.Webhooks.IsNullOrEmpty()) + { + return; + } + + foreach (var webhookDefinition in webhookSubscription.Webhooks) + { + await CheckPermissionsAsync(webhookSubscription.TenantId, webhookDefinition); + } + } + + protected virtual async Task CheckPermissionsAsync(Guid? tenantId, string webhookName) + { + if (!await _webhookDefinitionManager.IsAvailableAsync(tenantId, webhookName)) + { + throw new AbpAuthorizationException($"Tenant \"{tenantId}\" must have necessary feature(s) to use webhook \"{webhookName}\""); + } + } + + #endregion + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/System/AbpStringCryptographyExtensions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/System/AbpStringCryptographyExtensions.cs new file mode 100644 index 000000000..f4202f6e2 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/System/AbpStringCryptographyExtensions.cs @@ -0,0 +1,13 @@ +using System.Security.Cryptography; + +namespace System; + +internal static class AbpStringCryptographyExtensions +{ + public static string Sha256(this string planText, byte[] salt) + { + var data = planText.GetBytes(); + using var hmacsha256 = new HMACSHA256(salt); + return BitConverter.ToString(hmacsha256.ComputeHash(data)); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/FodyWeavers.xml b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/FodyWeavers.xml new file mode 100644 index 000000000..be0de3a90 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/FodyWeavers.xsd b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN.Abp.WebhooksManagement.Application.Contracts.csproj b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN.Abp.WebhooksManagement.Application.Contracts.csproj new file mode 100644 index 000000000..70d317b54 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN.Abp.WebhooksManagement.Application.Contracts.csproj @@ -0,0 +1,21 @@ + + + + + + + netstandard2.0 + + + + + + + + + + + + + + diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs new file mode 100644 index 000000000..b9295955e --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs @@ -0,0 +1,22 @@ +using LINGYUN.Abp.WebhooksManagement.Localization; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Localization; + +namespace LINGYUN.Abp.WebhooksManagement.Authorization; + +public class WebhooksManagementPermissionDefinitionProvider : PermissionDefinitionProvider +{ + public override void Define(IPermissionDefinitionContext context) + { + var group = context.AddGroup(WebhooksManagementPermissions.GroupName, L("Permission:WebhooksManagement")); + + group.AddPermission( + WebhooksManagementPermissions.ManageSettings, + L("Permission:ManageSettings")); + } + + private static LocalizableString L(string name) + { + return LocalizableString.Create(name); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissions.cs new file mode 100644 index 000000000..0a1d9b0f7 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissions.cs @@ -0,0 +1,8 @@ +namespace LINGYUN.Abp.WebhooksManagement.Authorization; + +public static class WebhooksManagementPermissions +{ + public const string GroupName = "WebhooksManagement"; + + public const string ManageSettings = GroupName + ".ManageSettings"; +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Features/WebhooksManagementFeatureDefinitionProvider.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Features/WebhooksManagementFeatureDefinitionProvider.cs new file mode 100644 index 000000000..22d14bd79 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Features/WebhooksManagementFeatureDefinitionProvider.cs @@ -0,0 +1,18 @@ +using LINGYUN.Abp.WebhooksManagement.Localization; +using Volo.Abp.Features; +using Volo.Abp.Localization; + +namespace LINGYUN.Abp.WebhooksManagement.Features; + +public class WebhooksManagementFeatureDefinitionProvider : FeatureDefinitionProvider +{ + public override void Define(IFeatureDefinitionContext context) + { + var group = context.AddGroup(WebhooksManagementFeatureNames.GroupName, L("Features:WebhooksManagement")); + } + + private static ILocalizableString L(string name) + { + return LocalizableString.Create(name); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Features/WebhooksManagementFeatureNames.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Features/WebhooksManagementFeatureNames.cs new file mode 100644 index 000000000..6cb71bf6d --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Features/WebhooksManagementFeatureNames.cs @@ -0,0 +1,6 @@ +namespace LINGYUN.Abp.WebhooksManagement.Features; + +public static class WebhooksManagementFeatureNames +{ + public const string GroupName = "WebhooksManagement"; +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksManagementApplicationContractsModule.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksManagementApplicationContractsModule.cs new file mode 100644 index 000000000..977589b9c --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksManagementApplicationContractsModule.cs @@ -0,0 +1,15 @@ +using Volo.Abp.Application; +using Volo.Abp.Authorization; +using Volo.Abp.Features; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.WebhooksManagement; + +[DependsOn( + typeof(AbpFeaturesModule), + typeof(AbpAuthorizationModule), + typeof(AbpDddApplicationContractsModule), + typeof(WebhooksManagementDomainSharedModule))] +public class WebhooksManagementApplicationContractsModule : AbpModule +{ +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksManagementRemoteServiceConsts.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksManagementRemoteServiceConsts.cs new file mode 100644 index 000000000..f05d02644 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksManagementRemoteServiceConsts.cs @@ -0,0 +1,7 @@ +namespace LINGYUN.Abp.WebhooksManagement; + +public static class WebhooksManagementRemoteServiceConsts +{ + public const string RemoteServiceName = "WebhooksManagement"; + public const string ModuleName = "WebhooksManagement"; +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/FodyWeavers.xml b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/FodyWeavers.xml new file mode 100644 index 000000000..be0de3a90 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/FodyWeavers.xsd b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN.Abp.WebhooksManagement.Application.csproj b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN.Abp.WebhooksManagement.Application.csproj new file mode 100644 index 000000000..24d0a91e7 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN.Abp.WebhooksManagement.Application.csproj @@ -0,0 +1,20 @@ + + + + + + + netstandard2.0 + + + + + + + + + + + + + diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksManagementAppServiceBase.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksManagementAppServiceBase.cs new file mode 100644 index 000000000..3953ab3e0 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksManagementAppServiceBase.cs @@ -0,0 +1,13 @@ +using LINGYUN.Abp.WebhooksManagement.Localization; +using Volo.Abp.Application.Services; + +namespace LINGYUN.Abp.WebhooksManagement; + +public abstract class WebhooksManagementAppServiceBase : ApplicationService +{ + protected WebhooksManagementAppServiceBase() + { + LocalizationResource = typeof(WebhooksManagementResource); + ObjectMapperContext = typeof(WebhooksManagementApplicationModule); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksManagementApplicationMapperProfile.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksManagementApplicationMapperProfile.cs new file mode 100644 index 000000000..dd3323fec --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksManagementApplicationMapperProfile.cs @@ -0,0 +1,10 @@ +using AutoMapper; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhooksManagementApplicationMapperProfile : Profile +{ + public WebhooksManagementApplicationMapperProfile() + { + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksManagementApplicationModule.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksManagementApplicationModule.cs new file mode 100644 index 000000000..eef27929b --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksManagementApplicationModule.cs @@ -0,0 +1,24 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Application; +using Volo.Abp.Authorization; +using Volo.Abp.AutoMapper; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.WebhooksManagement; + +[DependsOn( + typeof(AbpAuthorizationModule), + typeof(AbpDddApplicationModule), + typeof(WebhooksManagementDomainModule))] +public class WebhooksManagementApplicationModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAutoMapperObjectMapper(); + + Configure(options => + { + options.AddProfile(validate: true); + }); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Dapr.Client/FodyWeavers.xml b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Dapr.Client/FodyWeavers.xml new file mode 100644 index 000000000..be0de3a90 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Dapr.Client/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Dapr.Client/FodyWeavers.xsd b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Dapr.Client/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Dapr.Client/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Dapr.Client/LINGYUN.Abp.WebhooksManagement.Dapr.Client.csproj b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Dapr.Client/LINGYUN.Abp.WebhooksManagement.Dapr.Client.csproj new file mode 100644 index 000000000..e07d4c79d --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Dapr.Client/LINGYUN.Abp.WebhooksManagement.Dapr.Client.csproj @@ -0,0 +1,16 @@ + + + + + + + net6.0 + + + + + + + + + diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Dapr.Client/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDaprClientModule.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Dapr.Client/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDaprClientModule.cs new file mode 100644 index 000000000..bb89de573 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Dapr.Client/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDaprClientModule.cs @@ -0,0 +1,18 @@ +using LINGYUN.Abp.Dapr.Client; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.WebhooksManagement; + +[DependsOn( + typeof(AbpDaprClientModule), + typeof(WebhooksManagementApplicationContractsModule))] +public class WebhooksManagementDaprClientModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddDaprClientProxies( + typeof(WebhooksManagementApplicationContractsModule).Assembly, + WebhooksManagementRemoteServiceConsts.RemoteServiceName); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/FodyWeavers.xml b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/FodyWeavers.xml new file mode 100644 index 000000000..be0de3a90 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/FodyWeavers.xsd b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN.Abp.WebhooksManagement.Domain.Shared.csproj b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN.Abp.WebhooksManagement.Domain.Shared.csproj new file mode 100644 index 000000000..682b8eff5 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN.Abp.WebhooksManagement.Domain.Shared.csproj @@ -0,0 +1,25 @@ + + + + + + + netstandard2.0 + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json new file mode 100644 index 000000000..f31721006 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json @@ -0,0 +1,8 @@ +{ + "culture": "en", + "texts": { + "Features:WebhooksManagement": "WebhooksManagement", + "Permission:WebhooksManagement": "WebhooksManagement", + "Permission:ManageSettings": "Manage Settings" + } +} \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json new file mode 100644 index 000000000..759c3f745 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json @@ -0,0 +1,8 @@ +{ + "culture": "zh-Hans", + "texts": { + "Features:WebhooksManagement": "WebhooksManagement", + "Permission:WebhooksManagement": "WebhooksManagement", + "Permission:ManageSettings": "管理设置" + } +} \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/WebhooksManagementResource.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/WebhooksManagementResource.cs new file mode 100644 index 000000000..c95515cad --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/WebhooksManagementResource.cs @@ -0,0 +1,8 @@ +using Volo.Abp.Localization; + +namespace LINGYUN.Abp.WebhooksManagement.Localization; + +[LocalizationResourceName("WebhooksManagement")] +public class WebhooksManagementResource +{ +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfiguration.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfiguration.cs new file mode 100644 index 000000000..9b810dd32 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfiguration.cs @@ -0,0 +1,16 @@ +using System; +using Volo.Abp.ObjectExtending.Modularity; + +namespace LINGYUN.Abp.WebhooksManagement.ObjectExtending; + +public class WebhooksManagementModuleExtensionConfiguration : ModuleExtensionConfiguration +{ + public WebhooksManagementModuleExtensionConfiguration ConfigureWebhooksManagement( + Action configureAction) + { + return this.ConfigureEntity( + WebhooksManagementModuleExtensionConsts.EntityNames.Entity, + configureAction + ); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfigurationDictionaryExtensions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfigurationDictionaryExtensions.cs new file mode 100644 index 000000000..b41e10ccb --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfigurationDictionaryExtensions.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Volo.Abp.ObjectExtending.Modularity; + +namespace LINGYUN.Abp.WebhooksManagement.ObjectExtending; + +public static class WebhooksManagementModuleExtensionConfigurationDictionaryExtensions +{ + public static ModuleExtensionConfigurationDictionary ConfigureWebhooksManagement( + this ModuleExtensionConfigurationDictionary modules, + Action configureAction) + { + return modules.ConfigureModule( + WebhooksManagementModuleExtensionConsts.ModuleName, + configureAction + ); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConsts.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConsts.cs new file mode 100644 index 000000000..b16fe772e --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConsts.cs @@ -0,0 +1,11 @@ +namespace LINGYUN.Abp.WebhooksManagement.ObjectExtending; + +public static class WebhooksManagementModuleExtensionConsts +{ + public const string ModuleName = "WebhooksManagement"; + + public static class EntityNames + { + public const string Entity = "Entity"; + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainSharedModule.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainSharedModule.cs new file mode 100644 index 000000000..1e9234e7a --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainSharedModule.cs @@ -0,0 +1,32 @@ +using LINGYUN.Abp.WebhooksManagement.Localization; +using Volo.Abp.Localization; +using Volo.Abp.Localization.ExceptionHandling; +using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; + +namespace LINGYUN.Abp.WebhooksManagement; + +[DependsOn( + typeof(AbpLocalizationModule))] +public class WebhooksManagementDomainSharedModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + + Configure(options => + { + options.Resources + .Add() + .AddVirtualJson("/LINGYUN/Abp/WebhooksManagement/Localization/Resources"); + }); + + Configure(options => + { + options.MapCodeNamespace(WebhooksManagementErrorCodes.Namespace, typeof(WebhooksManagementResource)); + }); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhooksManagementErrorCodes.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhooksManagementErrorCodes.cs new file mode 100644 index 000000000..a7d2af4f9 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhooksManagementErrorCodes.cs @@ -0,0 +1,6 @@ +namespace LINGYUN.Abp.WebhooksManagement; + +public static class WebhooksManagementErrorCodes +{ + public const string Namespace = "WebhooksManagement"; +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/FodyWeavers.xml b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/FodyWeavers.xml new file mode 100644 index 000000000..be0de3a90 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/FodyWeavers.xsd b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN.Abp.WebhooksManagement.Domain.csproj b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN.Abp.WebhooksManagement.Domain.csproj new file mode 100644 index 000000000..2ba7caa77 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN.Abp.WebhooksManagement.Domain.csproj @@ -0,0 +1,22 @@ + + + + + + + netstandard2.0 + + + + + + + + + + + + + + + diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/DefaultWebhookManager.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/DefaultWebhookManager.cs new file mode 100644 index 000000000..c2535823c --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/DefaultWebhookManager.cs @@ -0,0 +1,70 @@ +using LINGYUN.Abp.Webhooks; +using System; +using System.Net; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Guids; +using Volo.Abp.Json; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Uow; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class DefaultWebhookManager : WebhookManager, ITransientDependency +{ + protected ICurrentTenant CurrentTenant { get; } + protected IGuidGenerator GuidGenerator { get; } + protected IUnitOfWorkManager UnitOfWorkManager { get; } + protected IWebhookSendRecordRepository WebhookSendAttemptRepository { get; } + public DefaultWebhookManager( + ICurrentTenant currentTenant, + IGuidGenerator guidGenerator, + IJsonSerializer jsonSerializer, + IWebhookSendAttemptStore webhookSendAttemptStore, + IUnitOfWorkManager unitOfWorkManager, + IWebhookSendRecordRepository webhookSendAttemptRepository) + : base(jsonSerializer, webhookSendAttemptStore) + { + CurrentTenant = currentTenant; + GuidGenerator = guidGenerator; + UnitOfWorkManager = unitOfWorkManager; + WebhookSendAttemptRepository = webhookSendAttemptRepository; + } + + public async override Task InsertAndGetIdWebhookSendAttemptAsync(WebhookSenderArgs webhookSenderArgs) + { + using (var uow = UnitOfWorkManager.Begin()) + { + using (CurrentTenant.Change(webhookSenderArgs.TenantId)) + { + var record = new WebhookSendRecord( + GuidGenerator.Create(), + webhookSenderArgs.WebhookEventId, + webhookSenderArgs.WebhookSubscriptionId, + webhookSenderArgs.TenantId); + + await WebhookSendAttemptRepository.InsertAsync(record); + + await uow.SaveChangesAsync(); + + return record.Id; + } + } + } + + public async override Task StoreResponseOnWebhookSendAttemptAsync(Guid webhookSendAttemptId, Guid? tenantId, HttpStatusCode? statusCode, string content) + { + using (var uow = UnitOfWorkManager.Begin()) + { + using (CurrentTenant.Change(tenantId)) + { + var record = await WebhookSendAttemptRepository.GetAsync(webhookSendAttemptId); + record.SetResponse(content, statusCode); + + await WebhookSendAttemptRepository.UpdateAsync(record); + + await uow.SaveChangesAsync(); + } + } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookEventRecordRepository.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookEventRecordRepository.cs new file mode 100644 index 000000000..45a69d4f2 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookEventRecordRepository.cs @@ -0,0 +1,8 @@ +using System; +using Volo.Abp.Domain.Repositories; + +namespace LINGYUN.Abp.WebhooksManagement; + +public interface IWebhookEventRecordRepository : IRepository +{ +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookSendRecordRepository.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookSendRecordRepository.cs new file mode 100644 index 000000000..4cf97509f --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookSendRecordRepository.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories; + +namespace LINGYUN.Abp.WebhooksManagement; + +public interface IWebhookSendRecordRepository : IRepository +{ + Task GetCountAsync( + WebhookSendRecordFilter filter, + CancellationToken cancellationToken = default); + + Task> GetListAsync( + WebhookSendRecordFilter filter, + string sorting = nameof(WebhookSendRecord.CreationTime), + int maxResultCount = 10, + int skipCount = 10, + CancellationToken cancellationToken = default); +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionRepository.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionRepository.cs new file mode 100644 index 000000000..faf4dbbee --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionRepository.cs @@ -0,0 +1,8 @@ +using System; +using Volo.Abp.Domain.Repositories; + +namespace LINGYUN.Abp.WebhooksManagement; + +public interface IWebhookSubscriptionRepository : IRepository +{ +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Settings/WebhooksManagementSettingDefinitionProvider.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Settings/WebhooksManagementSettingDefinitionProvider.cs new file mode 100644 index 000000000..e3aa21264 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Settings/WebhooksManagementSettingDefinitionProvider.cs @@ -0,0 +1,11 @@ +using Volo.Abp.Settings; + +namespace LINGYUN.Abp.WebhooksManagement.Settings +{ + public class WebhooksManagementSettingDefinitionProvider : SettingDefinitionProvider + { + public override void Define(ISettingDefinitionContext context) + { + } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Settings/WebhooksManagementSettings.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Settings/WebhooksManagementSettings.cs new file mode 100644 index 000000000..1de9fcda9 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Settings/WebhooksManagementSettings.cs @@ -0,0 +1,7 @@ +namespace LINGYUN.Abp.WebhooksManagement.Settings +{ + public static class WebhooksManagementSettings + { + public const string GroupName = "WebhooksManagement"; + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookEventRecord.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookEventRecord.cs new file mode 100644 index 000000000..e48bacf8c --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookEventRecord.cs @@ -0,0 +1,30 @@ +using System; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; +using Volo.Abp.MultiTenancy; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhookEventRecord : Entity, IMultiTenant, IHasCreationTime, IHasDeletionTime +{ + public virtual Guid? TenantId { get; protected set; } + public virtual string WebhookName { get; protected set; } + public virtual string Data { get; protected set; } + public virtual DateTime CreationTime { get; set; } + public virtual DateTime? DeletionTime { get; set; } + public virtual bool IsDeleted { get; set; } + protected WebhookEventRecord() + { + } + + public WebhookEventRecord( + Guid id, + string webhookName, + string data, + Guid? tenantId = null) : base(id) + { + WebhookName = webhookName; + Data = data; + TenantId = tenantId; + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookEventStore.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookEventStore.cs new file mode 100644 index 000000000..62d864e8b --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookEventStore.cs @@ -0,0 +1,57 @@ +using LINGYUN.Abp.Webhooks; +using System; +using System.Threading.Tasks; +using Volo.Abp.Domain.Services; +using Volo.Abp.ObjectMapping; +using Volo.Abp.Uow; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhookEventStore : DomainService, IWebhookEventStore +{ + protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetRequiredService>(); + + protected IUnitOfWorkManager UnitOfWorkManager { get; } + protected IWebhookEventRecordRepository WebhookEventRepository { get; } + + public WebhookEventStore( + IUnitOfWorkManager unitOfWorkManager, + IWebhookEventRecordRepository webhookEventRepository) + { + UnitOfWorkManager = unitOfWorkManager; + WebhookEventRepository = webhookEventRepository; + } + + public async virtual Task GetAsync(Guid? tenantId, Guid id) + { + using var uow = UnitOfWorkManager.Begin(); + using (CurrentTenant.Change(tenantId)) + { + var record = await WebhookEventRepository.GetAsync(id); + + return ObjectMapper.Map(record); + } + } + + public async virtual Task InsertAndGetIdAsync(WebhookEvent webhookEvent) + { + using var uow = UnitOfWorkManager.Begin(); + using (CurrentTenant.Change(webhookEvent.TenantId)) + { + var record = new WebhookEventRecord( + GuidGenerator.Create(), + webhookEvent.WebhookName, + webhookEvent.Data, + webhookEvent.TenantId) + { + CreationTime = Clock.Now, + }; + + await WebhookEventRepository.InsertAsync(record); + + await uow.SaveChangesAsync(); + + return record.Id; + } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendAttemptStore.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendAttemptStore.cs new file mode 100644 index 000000000..8e024decf --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendAttemptStore.cs @@ -0,0 +1,165 @@ +using LINGYUN.Abp.Webhooks; +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Net; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Domain.Services; +using Volo.Abp.Linq; +using Volo.Abp.ObjectMapping; +using Volo.Abp.Uow; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhookSendAttemptStore : DomainService, IWebhookSendAttemptStore +{ + protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetRequiredService>(); + protected IAsyncQueryableExecuter AsyncQueryableExecuter => LazyServiceProvider.LazyGetRequiredService(); + + protected IUnitOfWorkManager UnitOfWorkManager { get; } + protected IWebhookSendRecordRepository WebhookSendAttemptRepository { get; } + + public WebhookSendAttemptStore( + IUnitOfWorkManager unitOfWorkManager, + IWebhookSendRecordRepository webhookSendAttemptRepository) + { + UnitOfWorkManager = unitOfWorkManager; + WebhookSendAttemptRepository = webhookSendAttemptRepository; + } + + public async virtual Task<(int TotalCount, IReadOnlyCollection Webhooks)> GetAllSendAttemptsBySubscriptionAsPagedListAsync( + Guid? tenantId, + Guid subscriptionId, + int maxResultCount, + int skipCount) + { + (int TotalCount, IReadOnlyCollection Webhooks) sendAttempts; + + using (var uow = UnitOfWorkManager.Begin()) + { + using (CurrentTenant.Change(tenantId)) + { + var filter = new WebhookSendRecordFilter + { + SubscriptionId = subscriptionId, + }; + var totalCount = await WebhookSendAttemptRepository.GetCountAsync(filter); + + var list = await WebhookSendAttemptRepository.GetListAsync( + filter, + maxResultCount: maxResultCount, + skipCount: skipCount); + + var webHooks = ObjectMapper.Map, List>(list); + + sendAttempts = ValueTuple.Create(totalCount, webHooks.ToImmutableList()); + } + + await uow.CompleteAsync(); + } + + return sendAttempts; + } + + public async virtual Task> GetAllSendAttemptsByWebhookEventIdAsync( + Guid? tenantId, + Guid webhookEventId) + { + List sendAttempts; + + using (var uow = UnitOfWorkManager.Begin()) + { + using (CurrentTenant.Change(tenantId)) + { + var queryable = await WebhookSendAttemptRepository.GetQueryableAsync(); + + var list = await AsyncQueryableExecuter.ToListAsync(queryable + .Where(attempt => attempt.WebhookEventId == webhookEventId) + .OrderByDescending(attempt => attempt.CreationTime) + ); + + sendAttempts = ObjectMapper.Map, List>(list); + } + + await uow.CompleteAsync(); + } + + return sendAttempts; + } + + public async virtual Task GetAsync( + Guid? tenantId, + Guid id) + { + WebhookSendRecord sendAttempt; + + using (var uow = UnitOfWorkManager.Begin()) + { + using (CurrentTenant.Change(tenantId)) + { + sendAttempt = await WebhookSendAttemptRepository.GetAsync(id); + } + + await uow.CompleteAsync(); + } + + return ObjectMapper.Map(sendAttempt); + } + + public async virtual Task GetSendAttemptCountAsync( + Guid? tenantId, + Guid webhookEventId, + Guid webhookSubscriptionId) + { + int sendAttemptCount; + + using (var uow = UnitOfWorkManager.Begin()) + { + using (CurrentTenant.Change(tenantId)) + { + sendAttemptCount = await WebhookSendAttemptRepository.CountAsync(attempt => + attempt.WebhookEventId == webhookEventId && + attempt.WebhookSubscriptionId == webhookSubscriptionId); + } + + await uow.CompleteAsync(); + } + + return sendAttemptCount; + } + + public async virtual Task HasXConsecutiveFailAsync( + Guid? tenantId, + Guid subscriptionId, + int failCount) + { + bool result; + + using (var uow = UnitOfWorkManager.Begin()) + { + using (CurrentTenant.Change(tenantId)) + { + if (await WebhookSendAttemptRepository.CountAsync(x => x.WebhookSubscriptionId == subscriptionId) < failCount) + { + result = false; + } + else + { + var queryable = await WebhookSendAttemptRepository.GetQueryableAsync(); + + result = !await AsyncQueryableExecuter.AnyAsync(queryable + .OrderByDescending(attempt => attempt.CreationTime) + .Take(failCount) + .Where(attempt => attempt.ResponseStatusCode == HttpStatusCode.OK) + ); + } + } + + await uow.CompleteAsync(); + } + + return result; + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecord.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecord.cs new file mode 100644 index 000000000..91c3c8a97 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecord.cs @@ -0,0 +1,50 @@ +using System; +using System.Net; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; +using Volo.Abp.MultiTenancy; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhookSendRecord : Entity, IHasCreationTime, IHasModificationTime, IMultiTenant +{ + public virtual Guid? TenantId { get; protected set; } + + public virtual Guid WebhookEventId { get; protected set; } + + public virtual Guid WebhookSubscriptionId { get; protected set; } + + public virtual string Response { get; protected set; } + + public virtual HttpStatusCode? ResponseStatusCode { get; set; } + + public virtual DateTime CreationTime { get; set; } + + public virtual DateTime? LastModificationTime { get; set; } + + public virtual WebhookEventRecord WebhookEvent { get; protected set; } + + protected WebhookSendRecord() + { + } + + public WebhookSendRecord( + Guid id, + Guid eventId, + Guid subscriptionId, + Guid? tenantId = null) : base(id) + { + WebhookEventId = eventId; + WebhookSubscriptionId = subscriptionId; + + TenantId = tenantId; + } + + public void SetResponse( + string response, + HttpStatusCode? statusCode = null) + { + Response = response; + ResponseStatusCode = statusCode; + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordFilter.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordFilter.cs new file mode 100644 index 000000000..075a6152b --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordFilter.cs @@ -0,0 +1,21 @@ +using System; +using System.Net; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhookSendRecordFilter +{ + public string Filter { get; set; } + + public Guid? WebhookEventId { get; set; } + + public Guid? SubscriptionId { get; set; } + + public string Response { get; set; } + + public HttpStatusCode? ResponseStatusCode { get; set; } + + public DateTime? BeginCreationTime { get; set; } + + public DateTime? EndCreationTime { get; set; } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscription.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscription.cs new file mode 100644 index 000000000..be342aaa3 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscription.cs @@ -0,0 +1,33 @@ +using System; +using Volo.Abp.Domain.Entities.Auditing; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhookSubscription : CreationAuditedEntity +{ + public virtual Guid? TenantId { get; protected set; } + public virtual string WebhookUri { get; protected set; } + public virtual string Secret { get; protected set; } + public virtual bool IsActive { get; set; } + public virtual string Webhooks { get; protected set; } + public virtual string Headers { get; protected set; } + protected WebhookSubscription() + { + } + public WebhookSubscription( + Guid id, + string webhookUri, + string secret, + string webhooks, + string headers, + Guid? tenantId = null) : base(id) + { + WebhookUri = webhookUri; + Secret = secret; + Webhooks = webhooks; + Headers = headers; + TenantId = tenantId; + + IsActive = true; + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionsStore.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionsStore.cs new file mode 100644 index 000000000..abdbf33be --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionsStore.cs @@ -0,0 +1,55 @@ +using LINGYUN.Abp.Webhooks; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Domain.Services; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhookSubscriptionsStore : DomainService, IWebhookSubscriptionsStore +{ + public Task DeleteAsync(Guid id) + { + throw new NotImplementedException(); + } + + public Task> GetAllSubscriptionsAsync(Guid? tenantId) + { + throw new NotImplementedException(); + } + + public Task> GetAllSubscriptionsAsync(Guid? tenantId, string webhookName) + { + throw new NotImplementedException(); + } + + public Task> GetAllSubscriptionsOfTenantsAsync(Guid?[] tenantIds) + { + throw new NotImplementedException(); + } + + public Task> GetAllSubscriptionsOfTenantsAsync(Guid?[] tenantIds, string webhookName) + { + throw new NotImplementedException(); + } + + public Task GetAsync(Guid id) + { + throw new NotImplementedException(); + } + + public Task InsertAsync(WebhookSubscriptionInfo webhookSubscription) + { + throw new NotImplementedException(); + } + + public Task IsSubscribedAsync(Guid? tenantId, string webhookName) + { + throw new NotImplementedException(); + } + + public Task UpdateAsync(WebhookSubscriptionInfo webhookSubscription) + { + throw new NotImplementedException(); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDbProperties.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDbProperties.cs new file mode 100644 index 000000000..685cccb3e --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDbProperties.cs @@ -0,0 +1,11 @@ +namespace LINGYUN.Abp.WebhooksManagement; + +public static class WebhooksManagementDbProperties +{ + public static string DbTablePrefix { get; set; } = "WebhooksManagement_"; + + public static string DbSchema { get; set; } = null; + + + public const string ConnectionStringName = "WebhooksManagement"; +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainMapperProfile.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainMapperProfile.cs new file mode 100644 index 000000000..cbef9c444 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainMapperProfile.cs @@ -0,0 +1,11 @@ +using AutoMapper; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhooksManagementDomainMapperProfile : Profile +{ + public WebhooksManagementDomainMapperProfile() + { + + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainModule.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainModule.cs new file mode 100644 index 000000000..bdeb77779 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainModule.cs @@ -0,0 +1,43 @@ +using LINGYUN.Abp.Webhooks; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AutoMapper; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.Modularity; +using Volo.Abp.Threading; + +namespace LINGYUN.Abp.WebhooksManagement; + +[DependsOn( + typeof(AbpAutoMapperModule), + typeof(AbpWebhooksModule), + typeof(WebhooksManagementDomainSharedModule))] +public class WebhooksManagementDomainModule : AbpModule +{ + private static readonly OneTimeRunner OneTimeRunner = new(); + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAutoMapperObjectMapper(); + + Configure(options => + { + options.AddProfile(validate: true); + }); + + Configure(options => + { + }); + } + + public override void PostConfigureServices(ServiceConfigurationContext context) + { + OneTimeRunner.Run(() => + { + // 扩展实体配置 + //ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity( + // WebhooksManagementModuleExtensionConsts.ModuleName, + // WebhooksManagementModuleExtensionConsts.EntityNames.Entity, + // typeof(Entity) + //); + }); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/FodyWeavers.xml b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/FodyWeavers.xml new file mode 100644 index 000000000..be0de3a90 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/FodyWeavers.xsd b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore.csproj b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore.csproj new file mode 100644 index 000000000..6eb433ff2 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore.csproj @@ -0,0 +1,19 @@ + + + + + + + net6.0 + + + + + + + + + + + + diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/IWebhooksManagementDbContext.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/IWebhooksManagementDbContext.cs new file mode 100644 index 000000000..f6d9c17a8 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/IWebhooksManagementDbContext.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Data; +using Volo.Abp.EntityFrameworkCore; + +namespace LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore; + +[ConnectionStringName(WebhooksManagementDbProperties.ConnectionStringName)] +public interface IWebhooksManagementDbContext : IEfCoreDbContext +{ +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContext.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContext.cs new file mode 100644 index 000000000..de73188aa --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContext.cs @@ -0,0 +1,21 @@ +using Microsoft.EntityFrameworkCore; +using Volo.Abp.Data; +using Volo.Abp.EntityFrameworkCore; + +namespace LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore; + +[ConnectionStringName(WebhooksManagementDbProperties.ConnectionStringName)] +public class WebhooksManagementDbContext : AbpDbContext, IWebhooksManagementDbContext +{ + public WebhooksManagementDbContext( + DbContextOptions options) : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.ConfigureWebhooksManagement(); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs new file mode 100644 index 000000000..fcf22d3e6 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs @@ -0,0 +1,21 @@ +using Microsoft.EntityFrameworkCore; +using System; +using Volo.Abp; + +namespace LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore; + +public static class WebhooksManagementDbContextModelCreatingExtensions +{ + public static void ConfigureWebhooksManagement( + this ModelBuilder builder, + Action optionsAction = null) + { + Check.NotNull(builder, nameof(builder)); + + var options = new WebhooksManagementModelBuilderConfigurationOptions( + WebhooksManagementDbProperties.DbTablePrefix, + WebhooksManagementDbProperties.DbSchema + ); + optionsAction?.Invoke(options); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementEfCoreQueryableExtensions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementEfCoreQueryableExtensions.cs new file mode 100644 index 000000000..5751f330f --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementEfCoreQueryableExtensions.cs @@ -0,0 +1,6 @@ +namespace LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore; + +public static class WebhooksManagementEfCoreQueryableExtensions +{ + // 在此聚合仓储服务的扩展方法 +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementEntityFrameworkCoreModule.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementEntityFrameworkCoreModule.cs new file mode 100644 index 000000000..c64b2bb15 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementEntityFrameworkCoreModule.cs @@ -0,0 +1,19 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore; + +[DependsOn( + typeof(WebhooksManagementDomainModule), + typeof(AbpEntityFrameworkCoreModule))] +public class WebhooksManagementEntityFrameworkCoreModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAbpDbContext(options => + { + options.AddDefaultRepositories(); + }); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementModelBuilderConfigurationOptions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementModelBuilderConfigurationOptions.cs new file mode 100644 index 000000000..dc8a2e564 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementModelBuilderConfigurationOptions.cs @@ -0,0 +1,17 @@ +using JetBrains.Annotations; +using Volo.Abp.EntityFrameworkCore.Modeling; + +namespace LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore; + +public class WebhooksManagementModelBuilderConfigurationOptions : AbpModelBuilderConfigurationOptions +{ + public WebhooksManagementModelBuilderConfigurationOptions( + [NotNull] string tablePrefix = "", + [CanBeNull] string schema = null) + : base( + tablePrefix, + schema) + { + + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi.Client/FodyWeavers.xml b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi.Client/FodyWeavers.xml new file mode 100644 index 000000000..be0de3a90 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi.Client/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi.Client/FodyWeavers.xsd b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi.Client/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi.Client/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi.Client/LINGYUN.Abp.WebhooksManagement.HttpApi.Client.csproj b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi.Client/LINGYUN.Abp.WebhooksManagement.HttpApi.Client.csproj new file mode 100644 index 000000000..5cee3e037 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi.Client/LINGYUN.Abp.WebhooksManagement.HttpApi.Client.csproj @@ -0,0 +1,19 @@ + + + + + + + netstandard2.0 + + + + + + + + + + + + diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi.Client/LINGYUN/Abp/WebhooksManagement/WebhooksManagementHttpApiClientModule.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi.Client/LINGYUN/Abp/WebhooksManagement/WebhooksManagementHttpApiClientModule.cs new file mode 100644 index 000000000..1fff62168 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi.Client/LINGYUN/Abp/WebhooksManagement/WebhooksManagementHttpApiClientModule.cs @@ -0,0 +1,18 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Http.Client; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.WebhooksManagement; + +[DependsOn( + typeof(AbpHttpClientModule), + typeof(WebhooksManagementApplicationContractsModule))] +public class WebhooksManagementHttpApiClientModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddHttpClientProxies( + typeof(WebhooksManagementApplicationContractsModule).Assembly, + WebhooksManagementRemoteServiceConsts.RemoteServiceName); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/FodyWeavers.xml b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/FodyWeavers.xml new file mode 100644 index 000000000..be0de3a90 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/FodyWeavers.xsd b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN.Abp.WebhooksManagement.HttpApi.csproj b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN.Abp.WebhooksManagement.HttpApi.csproj new file mode 100644 index 000000000..e2556eb0b --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN.Abp.WebhooksManagement.HttpApi.csproj @@ -0,0 +1,19 @@ + + + + + + + net6.0 + + + + + + + + + + + + diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksManagementControllerBase.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksManagementControllerBase.cs new file mode 100644 index 000000000..5eef82130 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksManagementControllerBase.cs @@ -0,0 +1,12 @@ +using LINGYUN.Abp.WebhooksManagement.Localization; +using Volo.Abp.AspNetCore.Mvc; + +namespace LINGYUN.Abp.WebhooksManagement; + +public abstract class WebhooksManagementControllerBase : AbpControllerBase +{ + protected WebhooksManagementControllerBase() + { + LocalizationResource = typeof(WebhooksManagementResource); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksManagementHttpApiModule.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksManagementHttpApiModule.cs new file mode 100644 index 000000000..e4e4699a7 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksManagementHttpApiModule.cs @@ -0,0 +1,40 @@ +using LINGYUN.Abp.WebhooksManagement.Localization; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.Localization; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; +using Volo.Abp.Validation.Localization; + +namespace LINGYUN.Abp.WebhooksManagement; + +[DependsOn( + typeof(AbpAspNetCoreMvcModule), + typeof(WebhooksManagementApplicationContractsModule))] +public class WebhooksManagementHttpApiModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(mvcBuilder => + { + mvcBuilder.AddApplicationPartIfNotExists(typeof(WebhooksManagementHttpApiModule).Assembly); + }); + + PreConfigure(options => + { + options.AddAssemblyResource( + typeof(WebhooksManagementResource), + typeof(WebhooksManagementApplicationContractsModule).Assembly); + }); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.Resources + .Get() + .AddBaseTypes(typeof(AbpValidationResource)); + }); + } +} diff --git a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Dockerfile b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Dockerfile index a38f2b0c8..3e9c90691 100644 --- a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Dockerfile +++ b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Dockerfile @@ -7,6 +7,10 @@ COPY . /app #东8区 ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo '$TZ' > /etc/timezone +## 有些定时作业可能需要建立独立的数据库连接, 可能跨不同的数据库, 配置一下MSSQL +## 解决连接SqlServer TLS版本过高问题 +RUN sed -i 's/TLSv1.2/TLSv1.0/g' /etc/ssl/openssl.cnf +RUN sed -i 's/TLSv1.2/TLSv1.0/g' /usr/lib/ssl/openssl.cnf EXPOSE 80/tcp VOLUME [ "./app/Logs" ] diff --git a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/LY.MicroService.TaskManagement.HttpApi.Host.csproj b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/LY.MicroService.TaskManagement.HttpApi.Host.csproj index 98bc88491..293653249 100644 --- a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/LY.MicroService.TaskManagement.HttpApi.Host.csproj +++ b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/LY.MicroService.TaskManagement.HttpApi.Host.csproj @@ -45,6 +45,8 @@ + + diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Controllers/HomeController.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Controllers/HomeController.cs new file mode 100644 index 000000000..5084440c9 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Controllers/HomeController.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; + +namespace LY..WebhooksManagement.Controllers; + +public class HomeController : AbpController +{ + public IActionResult Index() + { + return Redirect("/swagger/index.html"); + } +} diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/DataSeeder/WebhooksManagementDataSeederWorker.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/DataSeeder/WebhooksManagementDataSeederWorker.cs new file mode 100644 index 000000000..77ffbf33f --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/DataSeeder/WebhooksManagementDataSeederWorker.cs @@ -0,0 +1,21 @@ +using Microsoft.Extensions.Hosting; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Data; + +namespace LY..WebhooksManagement.DataSeeder; + +public class WebhooksManagementDataSeederWorker : BackgroundService +{ + protected IDataSeeder DataSeeder { get; } + + public WebhooksManagementDataSeederWorker(IDataSeeder dataSeeder) + { + DataSeeder = dataSeeder; + } + + protected async override Task ExecuteAsync(CancellationToken stoppingToken) + { + await DataSeeder.SeedAsync(); + } +} diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Dockerfile b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Dockerfile new file mode 100644 index 000000000..0d02e98ca --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Dockerfile @@ -0,0 +1,15 @@ +FROM mcr.microsoft.com/dotnet/aspnet:6.0 +LABEL maintainer="colin.in@foxmail.com" +WORKDIR /app + +COPY . /app + +#�Ϻ�ʱ�� +#ENV TZ=Asia/Shanghai +#RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo '$TZ' > /etc/timezone + +EXPOSE 80/tcp +VOLUME [ "./app/Logs" ] +VOLUME [ "./app/Modules" ] + +ENTRYPOINT ["dotnet", "LY..WebhooksManagement.HttpApi.Host.dll"] diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContext.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContext.cs new file mode 100644 index 000000000..61e3ae739 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContext.cs @@ -0,0 +1,20 @@ +using Microsoft.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; + +namespace LY..WebhooksManagement.EntityFrameworkCore; + +public class WebhooksManagementMigrationsDbContext : AbpDbContext +{ + public WebhooksManagementMigrationsDbContext(DbContextOptions options) + : base(options) + { + + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.ConfigureWebhooksManagement(); + } +} diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContextFactory.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContextFactory.cs new file mode 100644 index 000000000..cd4432128 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContextFactory.cs @@ -0,0 +1,32 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Microsoft.Extensions.Configuration; +using System.IO; + +namespace LY..WebhooksManagement.EntityFrameworkCore; + +public class WebhooksManagementMigrationsDbContextFactory : IDesignTimeDbContextFactory +{ + public WebhooksManagementMigrationsDbContext CreateDbContext(string[] args) + { + var configuration = BuildConfiguration(); + var connectionString = configuration.GetConnectionString("WebhooksManagement"); + + DbContextOptionsBuilder builder = null; + + builder = new DbContextOptionsBuilder() + .UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)); + + return new WebhooksManagementMigrationsDbContext(builder.Options); + } + + private static IConfigurationRoot BuildConfiguration() + { + var builder = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json", optional: false) + .AddJsonFile("appsettings.Development.json", optional: true); + + return builder.Build(); + } +} diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EventBus/Handlers/TenantSynchronizer.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EventBus/Handlers/TenantSynchronizer.cs new file mode 100644 index 000000000..ccdd31c65 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EventBus/Handlers/TenantSynchronizer.cs @@ -0,0 +1,69 @@ +using LY..WebhooksManagement.EntityFrameworkCore; +using LINGYUN.Abp.Data.DbMigrator; +using LINGYUN.Abp.MultiTenancy; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using System.Threading.Tasks; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Uow; + +namespace LY..WebhooksManagement.EventBus.Handlers; + +public class TenantSynchronizer : + IDistributedEventHandler, + ITransientDependency +{ + protected IDataSeeder DataSeeder { get; } + protected ICurrentTenant CurrentTenant { get; } + protected IDbSchemaMigrator DbSchemaMigrator { get; } + protected IUnitOfWorkManager UnitOfWorkManager { get; } + + protected ILogger Logger { get; } + + public TenantSynchronizer( + IDataSeeder dataSeeder, + ICurrentTenant currentTenant, + IDbSchemaMigrator dbSchemaMigrator, + IUnitOfWorkManager unitOfWorkManager, + ILogger logger) + { + DataSeeder = dataSeeder; + CurrentTenant = currentTenant; + DbSchemaMigrator = dbSchemaMigrator; + UnitOfWorkManager = unitOfWorkManager; + + Logger = logger; + } + + /// + /// 租户创建之后需要预置种子数据 + /// + /// + /// + public virtual async Task HandleEventAsync(CreateEventData eventData) + { + using (var unitOfWork = UnitOfWorkManager.Begin()) + { + using (CurrentTenant.Change(eventData.Id, eventData.Name)) + { + Logger.LogInformation("Migrating the new tenant database with LY..WebhooksManagement..."); + // 迁移租户数据 + await DbSchemaMigrator.MigrateAsync( + (connectionString, builder) => + { + builder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)); + + return new WebhooksManagementDbContext(builder.Options); + }); + Logger.LogInformation("Migrated the new tenant database with LY..WebhooksManagement..."); + + await DataSeeder.SeedAsync(new DataSeedContext(eventData.Id)); + + await unitOfWork.SaveChangesAsync(); + } + } + } +} diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj new file mode 100644 index 000000000..b108df60e --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj @@ -0,0 +1,66 @@ + + + + net6.0 + LY..WebhooksManagement + + + + + + + + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Program.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Program.cs new file mode 100644 index 000000000..f55da1841 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Program.cs @@ -0,0 +1,58 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Serilog; +using System.IO; +using System.Threading.Tasks; +using Volo.Abp.IO; +using Volo.Abp.Modularity.PlugIns; + +namespace LY..WebhooksManagement; + +public class Program +{ + public async static Task Main(string[] args) + { + try + { + Log.Information("Starting web host."); + + var builder = WebApplication.CreateBuilder(args); + builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .ConfigureAppConfiguration((context, config) => + { + var configuration = config.Build(); + if (configuration.GetSection("AgileConfig").Exists()) + { + config.AddAgileConfig(new AgileConfig.Client.ConfigClient(configuration)); + } + }) + .UseSerilog((context, provider, config) => + { + config.ReadFrom.Configuration(context.Configuration); + }); + await builder.AddApplicationAsync(options => + { + // 搜索 Modules 目录下所有文件作为插件 + // 取消显示引用所有其他项目的模块,改为通过插件的形式引用 + var pluginFolder = Path.Combine( + Directory.GetCurrentDirectory(), "Modules"); + DirectoryHelper.CreateIfNotExists(pluginFolder); + options.PlugInSources.AddFolder( + pluginFolder, + SearchOption.AllDirectories); + }); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); + return 0; + } + finally + { + Log.CloseAndFlush(); + } + } +} diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Properties/launchSettings.json b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Properties/launchSettings.json new file mode 100644 index 000000000..6a691ee60 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Properties/launchSettings.json @@ -0,0 +1,28 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:20890", + "sslPort": 0 + } + }, + "profiles": { + "LY..WebhooksManagement.HttpApi.Host": { + "commandName": "Project", + "launchBrowser": false, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:57264", + "dotnetRunMessages": "true" + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": false, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/TenantHeaderParamter.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/TenantHeaderParamter.cs new file mode 100644 index 000000000..e793c0e5c --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/TenantHeaderParamter.cs @@ -0,0 +1,31 @@ +using Microsoft.Extensions.Options; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; +using System.Collections.Generic; +using Volo.Abp.MultiTenancy; + +namespace LY..WebhooksManagement; + +public class TenantHeaderParamter : IOperationFilter +{ + private readonly AbpMultiTenancyOptions _options; + public TenantHeaderParamter( + IOptions options) + { + _options = options.Value; + } + public void Apply(OpenApiOperation operation, OperationFilterContext context) + { + if (_options.IsEnabled) + { + operation.Parameters = operation.Parameters ?? new List(); + operation.Parameters.Add(new OpenApiParameter + { + Name = TenantResolverConsts.DefaultTenantKey, + In = ParameterLocation.Header, + Description = "Tenant Id/Name", + Required = false + }); + } + } +} diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs new file mode 100644 index 000000000..95705fa29 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs @@ -0,0 +1,307 @@ +using DotNetCore.CAP; +using LINGYUN.Abp.Dapr.Client.DynamicProxying; +using LINGYUN.Abp.ExceptionHandling; +using LINGYUN.Abp.ExceptionHandling.Emailing; +using LINGYUN.Abp.Serilog.Enrichers.Application; +using LINGYUN.Abp.Serilog.Enrichers.UniqueId; +using LINGYUN.Abp.Wrapper; +using Medallion.Threading; +using Medallion.Threading.Redis; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.Extensions.Caching.StackExchangeRedis; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OpenApi.Models; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; +using StackExchange.Redis; +using System; +using System.Text.Encodings.Web; +using System.Text.Unicode; +using Volo.Abp; +using Volo.Abp.Auditing; +using Volo.Abp.Caching; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.GlobalFeatures; +using Volo.Abp.Json; +using Volo.Abp.Json.SystemTextJson; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Threading; +using Volo.Abp.VirtualFileSystem; + +namespace LY..WebhooksManagement; + +public partial class WebhooksManagementHttpApiHostModule +{ + protected const string ApplicationName = "WebhooksManagement"; + private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); + + private void PreConfigureFeature() + { + OneTimeRunner.Run(() => + { + GlobalFeatureManager.Instance.Modules.Editions().EnableAll(); + }); + } + + private void PreConfigureApp() + { + AbpSerilogEnrichersConsts.ApplicationName = ApplicationName; + + PreConfigure(options => + { + // 以开放端口区别 + options.SnowflakeIdOptions.WorkerId = 5000; + options.SnowflakeIdOptions.WorkerIdBits = 5; + options.SnowflakeIdOptions.DatacenterId = 1; + }); + } + + private void PreConfigureCAP(IConfiguration configuration) + { + PreConfigure(options => + { + options + .UseMySql(sqlOptions => + { + configuration.GetSection("CAP:MySql").Bind(sqlOptions); + }) + .UseRabbitMQ(rabbitMQOptions => + { + configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions); + }) + .UseDashboard(); + }); + } + + private void ConfigureDbContext() + { + // 配置Ef + Configure(options => + { + options.UseMySQL(); + }); + } + + private void ConfigureJsonSerializer() + { + // 解决某些不支持类型的序列化 + Configure(options => + { + options.DefaultDateTimeFormat = "yyyy-MM-dd HH:mm:ss"; + }); + // 中文序列化的编码问题 + Configure(options => + { + options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); + }); + } + + private void ConfigureDistributedLock(IServiceCollection services, IConfiguration configuration) + { + if (configuration.GetSection("DistributedLock").Exists()) + { + var redis = ConnectionMultiplexer.Connect(configuration["DistributedLock:Redis:Configuration"]); + services.AddSingleton(_ => new RedisDistributedSynchronizationProvider(redis.GetDatabase())); + } + } + + private void ConfigureOpenTelemetry(IServiceCollection services, IConfiguration configuration) + { + if (configuration.GetSection("OpenTelemetry").Exists()) + { + services.AddOpenTelemetryTracing(cfg => + { + cfg.AddSource(ApplicationName) + .SetResourceBuilder( + ResourceBuilder.CreateDefault().AddService(ApplicationName)) + .AddHttpClientInstrumentation() + .AddAspNetCoreInstrumentation() + .AddEntityFrameworkCoreInstrumentation() + .AddCapInstrumentation() + .AddZipkinExporter(zipKinOptions => + { + var endpoint = configuration["OpenTelemetry:ZipKin:Endpoint"]; + if (!endpoint.IsNullOrWhiteSpace()) + { + zipKinOptions.Endpoint = new Uri(configuration["OpenTelemetry:ZipKin:Endpoint"]); + } + }); + }); + } + } + + private void ConfigureExceptionHandling() + { + // 自定义需要处理的异常 + Configure(options => + { + // 加入需要处理的异常类型 + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + }); + // 自定义需要发送邮件通知的异常类型 + Configure(options => + { + // 是否发送堆栈信息 + options.SendStackTrace = true; + // 未指定异常接收者的默认接收邮件 + // 指定自己的邮件地址 + }); + } + + private void ConfigureAuditing(IConfiguration configuration) + { + Configure(options => + { + options.ApplicationName = "WebhooksManagement"; + // 是否启用实体变更记录 + var entitiesChangedConfig = configuration.GetSection("App:TrackingEntitiesChanged"); + if (entitiesChangedConfig.Exists() && entitiesChangedConfig.Get()) + { + options + .EntityHistorySelectors + .AddAllEntities(); + } + }); + } + + private void ConfigureCaching(IConfiguration configuration) + { + Configure(options => + { + // 最好统一命名,不然某个缓存变动其他应用服务有例外发生 + options.KeyPrefix = "LINGYUN.Abp.Application"; + // 滑动过期30天 + options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30d); + // 绝对过期60天 + options.GlobalCacheEntryOptions.AbsoluteExpiration = DateTimeOffset.Now.AddDays(60d); + }); + + Configure(options => + { + var redisConfig = ConfigurationOptions.Parse(options.Configuration); + options.ConfigurationOptions = redisConfig; + options.InstanceName = configuration["Redis:InstanceName"]; + }); + } + + private void ConfigureVirtualFileSystem() + { + Configure(options => + { + options.FileSets.AddEmbedded("LY..WebhooksManagement"); + }); + } + + private void ConfigureMultiTenancy(IConfiguration configuration) + { + // 多租户 + Configure(options => + { + options.IsEnabled = true; + }); + + var tenantResolveCfg = configuration.GetSection("App:Domains"); + if (tenantResolveCfg.Exists()) + { + Configure(options => + { + var domains = tenantResolveCfg.Get(); + foreach (var domain in domains) + { + options.AddDomainTenantResolver(domain); + } + }); + } + } + + private void ConfigureSwagger(IServiceCollection services) + { + // Swagger + services.AddSwaggerGen( + options => + { + options.SwaggerDoc("v1", new OpenApiInfo { Title = "WebhooksManagement API", Version = "v1" }); + options.DocInclusionPredicate((docName, description) => true); + options.CustomSchemaIds(type => type.FullName); + options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme + { + Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", + Name = "Authorization", + In = ParameterLocation.Header, + Scheme = "bearer", + Type = SecuritySchemeType.Http, + BearerFormat = "JWT" + }); + options.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } + }, + new string[] { } + } + }); + options.OperationFilter(); + }); + } + + private void ConfigureLocalization() + { + // 支持本地化语言类型 + Configure(options => + { + options.Languages.Add(new LanguageInfo("en", "en", "English")); + options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); + // 动态语言支持 + options.Resources.AddDynamic(); + }); + } + + private void ConfigureSecurity(IServiceCollection services, IConfiguration configuration, bool isDevelopment = false) + { + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => + { + options.Authority = configuration["AuthServer:Authority"]; + options.RequireHttpsMetadata = false; + options.Audience = configuration["AuthServer:ApiName"]; + }); + + if (!isDevelopment) + { + var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); + services + .AddDataProtection() + .SetApplicationName("LINGYUN.Abp.Application") + .PersistKeysToStackExchangeRedis(redis, "LINGYUN.Abp.Application:DataProtection:Protection-Keys"); + } + } + + private void ConfigureWrapper() + { + Configure(options => + { + // 取消注释包装结果 + // options.IsEnabled = true; + }); + + Configure(options => + { + // dapr服务间调用发送不需要包装结果的请求头 + options.ProxyRequestActions.Add( + (appId, httpRequestMessage) => + { + httpRequestMessage.Headers.TryAddWithoutValidation(AbpHttpWrapConsts.AbpDontWrapResult, "true"); + }); + }); + } +} diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.DataSeeder.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.DataSeeder.cs new file mode 100644 index 000000000..8c2982179 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.DataSeeder.cs @@ -0,0 +1,15 @@ +using Microsoft.Extensions.DependencyInjection; +using LY..WebhooksManagement.DataSeeder; + +namespace LY..WebhooksManagement; + +public partial class WebhooksManagementHttpApiHostModule +{ + private static void ConfigureSeedWorker(IServiceCollection services, bool isDevelopment = false) + { + if (isDevelopment) + { + services.AddHostedService(); + } + } +} diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs new file mode 100644 index 000000000..4dac2cea9 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs @@ -0,0 +1,118 @@ +using LINGYUN.Abp.AspNetCore.Mvc.Wrapper; +using LINGYUN.Abp.AuditLogging.Elasticsearch; +using LINGYUN.Abp.EventBus.CAP; +using LINGYUN.Abp.ExceptionHandling.Emailing; +using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; +using LINGYUN.Abp.Saas.EntityFrameworkCore; +using LINGYUN.Abp.Serilog.Enrichers.Application; +using LINGYUN.Abp.Serilog.Enrichers.UniqueId; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using LY..WebhooksManagement.EntityFrameworkCore; +using LY..WebhooksManagement.SettingManagement; +using Volo.Abp; +using Volo.Abp.AspNetCore.Authentication.JwtBearer; +using Volo.Abp.AspNetCore.MultiTenancy; +using Volo.Abp.AspNetCore.Serilog; +using Volo.Abp.Autofac; +using Volo.Abp.Caching.StackExchangeRedis; +using Volo.Abp.DistributedLocking; +using Volo.Abp.EntityFrameworkCore.MySQL; +using Volo.Abp.FeatureManagement.EntityFrameworkCore; +using Volo.Abp.Http.Client.IdentityModel.Web; +using Volo.Abp.Modularity; +using Volo.Abp.PermissionManagement.EntityFrameworkCore; +using Volo.Abp.SettingManagement.EntityFrameworkCore; +using Volo.Abp.Swashbuckle; + +namespace LY.WebhooksManagement; + +[DependsOn( + typeof(AbpSerilogEnrichersApplicationModule), + typeof(AbpSerilogEnrichersUniqueIdModule), + typeof(AbpAuditLoggingElasticsearchModule), + typeof(AbpAspNetCoreSerilogModule), + typeof(WebhooksManagementApplicationModule), + typeof(WebhooksManagementHttpApiModule), + typeof(WebhooksManagementEntityFrameworkCoreModule), + typeof(WebhooksManagementSettingManagementModule), + typeof(AbpEntityFrameworkCoreMySQLModule), + typeof(AbpAspNetCoreAuthenticationJwtBearerModule), + typeof(AbpEmailingExceptionHandlingModule), + typeof(AbpCAPEventBusModule), + typeof(AbpHttpClientIdentityModelWebModule), + typeof(AbpAspNetCoreMultiTenancyModule), + typeof(AbpSaasEntityFrameworkCoreModule), + typeof(AbpFeatureManagementEntityFrameworkCoreModule), + typeof(AbpPermissionManagementEntityFrameworkCoreModule), + typeof(AbpSettingManagementEntityFrameworkCoreModule), + typeof(AbpLocalizationManagementEntityFrameworkCoreModule), + typeof(AbpCachingStackExchangeRedisModule), + typeof(AbpDistributedLockingModule), + typeof(AbpAspNetCoreMvcWrapperModule), + typeof(AbpSwashbuckleModule), + typeof(AbpAutofacModule) + )] +public partial class WebhooksManagementHttpApiHostModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + + PreConfigureApp(); + PreConfigureFeature(); + PreConfigureCAP(configuration); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + var hostingEnvironment = context.Services.GetHostingEnvironment(); + var configuration = context.Services.GetConfiguration(); + + ConfigureWrapper(); + ConfigureDbContext(); + ConfigureLocalization(); + ConfigureJsonSerializer(); + ConfigureExceptionHandling(); + ConfigureVirtualFileSystem(); + ConfigureCaching(configuration); + ConfigureAuditing(configuration); + ConfigureMultiTenancy(configuration); + ConfigureSwagger(context.Services); + ConfigureOpenTelemetry(context.Services, configuration); + ConfigureDistributedLock(context.Services, configuration); + ConfigureSeedWorker(context.Services, hostingEnvironment.IsDevelopment()); + ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var app = context.GetApplicationBuilder(); + var env = context.GetEnvironment(); + + app.UseCorrelationId(); + app.UseStaticFiles(); + app.UseRouting(); + app.UseCors(); + app.UseAuthentication(); + app.UseJwtTokenMiddleware(); + app.UseMultiTenancy(); + app.UseMapRequestLocalization(); + app.UseAuthorization(); + app.UseSwagger(); + app.UseAbpSwaggerUI(options => + { + options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support APP API"); + + var configuration = context.GetConfiguration(); + options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); + options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]); + options.OAuthScopes("WebhooksManagement"); + }); + app.UseAuditing(); + app.UseAbpSerilogEnrichers(); + app.UseConfiguredEndpoints(); + } +} diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/appsettings.Development.json b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/appsettings.Development.json new file mode 100644 index 000000000..7c28c17fe --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/appsettings.Development.json @@ -0,0 +1,132 @@ +{ + "AgileConfig": { + "env": "DEV", + "appId": "LY.MicroService.WebhooksManagement", + "secret": "1q2w3E*", + "nodes": "http://127.0.0.1:15000", + "name": "LY.MicroService.WebhooksManagement", + "tag": "LY.MicroService.WebhooksManagement" + }, + "App": { + "TrackingEntitiesChanged": true + }, + "ConnectionStrings": { + "Default": "Server=127.0.0.1;Database=WebhooksManagement;User Id=root;Password=123456", + "WebhooksManagement": "Server=127.0.0.1;Database=WebhooksManagement;User Id=root;Password=123456", + "AbpSaas": "Server=127.0.0.1;Database=WebhooksManagement;User Id=root;Password=123456", + "AbpFeatureManagement": "Server=127.0.0.1;Database=WebhooksManagement;User Id=root;Password=123456", + "AbpPermissionManagement": "Server=127.0.0.1;Database=WebhooksManagement;User Id=root;Password=123456", + "AbpSettingManagement": "Server=127.0.0.1;Database=WebhooksManagement;User Id=root;Password=123456" + }, + "DistributedLock": { + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=15" + } + }, + "OpenTelemetry": { + "ZipKin": { + "Endpoint": "http://127.0.0.1:9411/api/v2/spans" + } + }, + "RemoteServices": {}, + "IdentityClients": { + "InternalServiceClient": { + "Authority": "http://127.0.0.1:44385", + "RequireHttps": false, + "GrantType": "client_credentials", + "Scope": "lingyun-abp-application", + "ClientId": "InternalServiceClient", + "ClientSecret": "1q2w3E*" + } + }, + "CAP": { + "EventBus": { + "DefaultGroupName": "WebhooksManagement", + "GroupNamePrefix": "Dev", + "Version": "v1", + "FailedRetryInterval": 300, + "FailedRetryCount": 10 + }, + "MySql": { + "TableNamePrefix": "WebhooksManagement_cap", + "ConnectionString": "Server=127.0.0.1;Database=WebhooksManagement;User Id=root;Password=123456" + }, + "SqlServer": { + "TableNamePrefix": "WebhooksManagement_cap", + "ConnectionString": "Server=127.0.0.1;Database=WebhooksManagement;User Id=root;Password=123456" + }, + "Sqlite": { + "TableNamePrefix": "WebhooksManagement_cap", + "ConnectionString": "Data Source=./cap.db" + }, + "Oracle": { + "TableNamePrefix": "WebhooksManagement_cap", + "ConnectionString": "Data Source=WebhooksManagement;Integrated Security=yes;" + }, + "PostgreSql": { + "TableNamePrefix": "WebhooksManagement_cap", + "ConnectionString": "Host=localhost;Port=5432;Database=WebhooksManagement;User ID=root;Password=123456;" + }, + "RabbitMQ": { + "HostName": "127.0.0.1", + "Port": 5672, + "UserName": "admin", + "Password": "123456", + "ExchangeName": "LINGYUN.Abp.Application", + "VirtualHost": "/" + } + }, + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=10", + "InstanceName": "LINGYUN.Abp.Application" + }, + "AuthServer": { + "Authority": "http://127.0.0.1:44385/", + "ApiName": "lingyun-abp-application", + "SwaggerClientId": "InternalServiceClient", + "SwaggerClientSecret": "1q2w3E*" + }, + "Logging": { + "Serilog": { + "Elasticsearch": { + "IndexFormat": "abp.dev.logging-{0:yyyy.MM.dd}" + } + } + }, + "AuditLogging": { + "Elasticsearch": { + "IndexPrefix": "abp.dev.auditing" + } + }, + "Elasticsearch": { + "NodeUris": "http://127.0.0.1:9200" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Debug", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "DotNetCore": "Debug" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "restrictedToMinimumLevel": "Debug", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "Elasticsearch", + "Args": { + "nodeUris": "http://127.0.0.1:9200", + "indexFormat": "abp.dev.logging-{0:yyyy.MM.dd}", + "autoRegisterTemplate": true, + "autoRegisterTemplateVersion": "ESv7" + } + } + ] + } +} diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/appsettings.json b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/appsettings.json new file mode 100644 index 000000000..67e1bc4bd --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/appsettings.json @@ -0,0 +1,80 @@ +{ + "StringEncryption": { + "DefaultPassPhrase": "s46c5q55nxpeS8Ra", + "InitVectorBytes": "s83ng0abvd02js84", + "DefaultSalt": "sf&5)s3#" + }, + "AllowedHosts": "*", + "Serilog": { + "MinimumLevel": { + "Default": "Debug", + "Override": { + "Microsoft.EntityFrameworkCore": "Debug", + "System": "Information", + "Microsoft": "Information" + } + }, + "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId", "WithEnvironmentName", "WithMachineName", "WithApplicationName", "WithUniqueId" ], + "WriteTo": [ + { + "Name": "Console", + "Args": { + "initialMinimumLevel": "Verbose", + "standardErrorFromLevel": "Verbose", + "restrictedToMinimumLevel": "Verbose", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Debug-.log", + "restrictedToMinimumLevel": "Debug", + "rollingInterval": "Day", + "fileSizeLimitBytes": 5242880, + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Info-.log", + "restrictedToMinimumLevel": "Information", + "rollingInterval": "Day", + "fileSizeLimitBytes": 5242880, + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Warn-.log", + "restrictedToMinimumLevel": "Warning", + "rollingInterval": "Day", + "fileSizeLimitBytes": 5242880, + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Error-.log", + "restrictedToMinimumLevel": "Error", + "rollingInterval": "Day", + "fileSizeLimitBytes": 5242880, + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Fatal-.log", + "restrictedToMinimumLevel": "Fatal", + "rollingInterval": "Day", + "fileSizeLimitBytes": 5242880, + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + } + ] + } +} diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/dapr.sh b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/dapr.sh new file mode 100644 index 000000000..ddfd59d01 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/dapr.sh @@ -0,0 +1 @@ +dapr run --app-id WebhooksManagement --app-port 57264 -H 63751 -- dotnet run --no-build \ No newline at end of file From 5d525ea3ba2bce9889368c06c2ea4388fccdaa7a Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Sat, 26 Mar 2022 10:59:40 +0800 Subject: [PATCH 02/17] feat(webhooks): added data access configuration --- aspnet-core/Directory.Build.props | 5 + .../Abp/Webhooks/DefaultWebhookPublisher.cs | 9 +- .../WebhookSubscriptionExtensions.cs | 21 +++ .../Webhooks/NullWebhookSendAttemptStore.cs | 4 +- .../LINGYUN/Abp/Webhooks/WebhookManager.cs | 12 +- .../Webhooks/WebhookSubscriptionManager.cs | 6 +- .../Localization/Resources/en.json | 4 +- .../Localization/Resources/zh-Hans.json | 4 +- ...sManagementModuleExtensionConfiguration.cs | 8 +- ...ensionConfigurationDictionaryExtensions.cs | 2 - ...WebhooksManagementModuleExtensionConsts.cs | 4 +- .../Abp/WebhooksManagement/WebhookEventEto.cs | 12 ++ .../WebhookEventRecordConsts.cs | 7 + .../WebhookSendAttemptEto.cs | 16 ++ .../WebhookSendRecordConsts.cs | 6 + .../WebhookSubscriptionConsts.cs | 9 + .../WebhookSubscriptionEto.cs | 14 ++ .../DefaultWebhookManager.cs | 4 +- .../WebhookSubscriptionExtensions.cs | 29 +++ .../WebhookSubscriptionInfoExtensions.cs | 175 ++++++++++++++++++ .../IWebhookSendRecordRepository.cs | 1 + .../WebhooksManagement/WebhookEventRecord.cs | 5 +- .../WebhooksManagement/WebhookEventStore.cs | 9 +- .../WebhookSendAttemptStore.cs | 127 +++++-------- .../WebhooksManagement/WebhookSendRecord.cs | 3 +- .../WebhookSendRecordFilter.cs | 2 - .../WebhooksManagement/WebhookSubscription.cs | 24 ++- .../WebhookSubscriptionsStore.cs | 129 +++++++++++-- .../WebhooksManagementDomainMapperProfile.cs | 9 + .../WebhooksManagementDomainModule.cs | 29 ++- .../EfCoreWebhookEventRecordRepository.cs | 15 ++ .../EfCoreWebhookSendRecordRepository.cs | 58 ++++++ .../EfCoreWebhookSubscriptionRepository.cs | 16 ++ ...agementDbContextModelCreatingExtensions.cs | 55 ++++++ ...ooksManagementEfCoreQueryableExtensions.cs | 15 +- ...ooksManagementEntityFrameworkCoreModule.cs | 4 + .../Controllers/HomeController.cs | 2 +- .../WebhooksManagementDataSeederWorker.cs | 2 +- .../WebhooksManagementMigrationsDbContext.cs | 5 +- ...oksManagementMigrationsDbContextFactory.cs | 2 +- .../EventBus/Handlers/TenantSynchronizer.cs | 10 +- ...ice.WebhooksManagement.HttpApi.Host.csproj | 9 +- .../Program.cs | 2 +- .../Properties/launchSettings.json | 9 +- .../TenantHeaderParamter.cs | 2 +- ...ksManagementHttpApiHostModule.Configure.cs | 8 +- ...sManagementHttpApiHostModule.DataSeeder.cs | 4 +- .../WebhooksManagementHttpApiHostModule.cs | 11 +- 48 files changed, 722 insertions(+), 196 deletions(-) create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/Extensions/WebhookSubscriptionExtensions.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookEventEto.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookEventRecordConsts.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSendAttemptEto.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordConsts.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionConsts.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionEto.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Extensions/WebhookSubscriptionExtensions.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Extensions/WebhookSubscriptionInfoExtensions.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookEventRecordRepository.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookSendRecordRepository.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookSubscriptionRepository.cs diff --git a/aspnet-core/Directory.Build.props b/aspnet-core/Directory.Build.props index 969253fd5..9f9403ebe 100644 --- a/aspnet-core/Directory.Build.props +++ b/aspnet-core/Directory.Build.props @@ -12,6 +12,11 @@ 2.0.3 1.7.28 7.15.1 + 1.0.0-rc8 + 1.2.0-rc1 + 1.0.0-rc8 + 1.0.0-rc8 + 1.0.0-beta2 3.3.3 2.0.593 2.10.0 diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs index d466ee0f8..5b2d38c71 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs +++ b/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.Linq; using System.Threading.Tasks; using Volo.Abp.BackgroundJobs; using Volo.Abp.Guids; -using Volo.Abp.Json; using Volo.Abp.MultiTenancy; namespace LINGYUN.Abp.Webhooks @@ -15,7 +15,6 @@ namespace LINGYUN.Abp.Webhooks private readonly ICurrentTenant _currentTenant; private readonly IGuidGenerator _guidGenerator; - private readonly IJsonSerializer _jsonSerializer; private readonly IBackgroundJobManager _backgroundJobManager; private readonly IWebhookSubscriptionManager _webhookSubscriptionManager; @@ -23,12 +22,10 @@ namespace LINGYUN.Abp.Webhooks IWebhookSubscriptionManager webhookSubscriptionManager, ICurrentTenant currentTenant, IGuidGenerator guidGenerator, - IJsonSerializer jsonSerializer, IBackgroundJobManager backgroundJobManager) { _currentTenant = currentTenant; _guidGenerator = guidGenerator; - _jsonSerializer = jsonSerializer; _backgroundJobManager = backgroundJobManager; _webhookSubscriptionManager = webhookSubscriptionManager; @@ -114,7 +111,7 @@ namespace LINGYUN.Abp.Webhooks { Id = _guidGenerator.Create(), WebhookName = webhookName, - Data = _jsonSerializer.Serialize(data), + Data = JsonConvert.SerializeObject(data), TenantId = tenantId }; diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/Extensions/WebhookSubscriptionExtensions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/Extensions/WebhookSubscriptionExtensions.cs new file mode 100644 index 000000000..8cf48f520 --- /dev/null +++ b/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 + { + /// + /// checks if subscribed to given webhook + /// + /// + public static bool IsSubscribed(this WebhookSubscriptionInfo webhookSubscription, string webhookName) + { + if (webhookSubscription.Webhooks.IsNullOrEmpty()) + { + return false; + } + + return webhookSubscription.Webhooks.Contains(webhookName); + } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/NullWebhookSendAttemptStore.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/NullWebhookSendAttemptStore.cs index 75749401b..7254b1ae6 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/NullWebhookSendAttemptStore.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/NullWebhookSendAttemptStore.cs @@ -33,10 +33,10 @@ namespace LINGYUN.Abp.Webhooks return default; } - public Task> GetAllSendAttemptsBySubscriptionAsPagedListAsync(Guid? tenantId, Guid subscriptionId, int maxResultCount, + public Task<(int TotalCount, IReadOnlyCollection Webhooks)> GetAllSendAttemptsBySubscriptionAsPagedListAsync(Guid? tenantId, Guid subscriptionId, int maxResultCount, int skipCount) { - return Task.FromResult(new List() as IReadOnlyCollection); + return Task.FromResult(ValueTuple.Create(0, new List() as IReadOnlyCollection)); } public Task> GetAllSendAttemptsByWebhookEventIdAsync(Guid? tenantId, Guid webhookEventId) diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookManager.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookManager.cs index 29389e15e..854795786 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookManager.cs +++ b/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.Net; using System.Net.Http; using System.Text; using System.Threading.Tasks; -using Volo.Abp.Json; namespace LINGYUN.Abp.Webhooks { @@ -13,21 +13,17 @@ namespace LINGYUN.Abp.Webhooks private const string SignatureHeaderKey = "sha256"; private const string SignatureHeaderValueTemplate = SignatureHeaderKey + "={0}"; private const string SignatureHeaderName = "abp-webhook-signature"; - - protected IJsonSerializer JsonSerializer { get; } protected IWebhookSendAttemptStore WebhookSendAttemptStore { get; } protected WebhookManager( - IJsonSerializer jsonSerializer, IWebhookSendAttemptStore webhookSendAttemptStore) { - JsonSerializer = jsonSerializer; WebhookSendAttemptStore = webhookSendAttemptStore; } public virtual async Task GetWebhookPayloadAsync(WebhookSenderArgs webhookSenderArgs) { - var data = JsonSerializer.Serialize(webhookSenderArgs.Data); + var data = JsonConvert.SerializeObject(webhookSenderArgs.Data); var attemptNumber = await WebhookSendAttemptStore.GetSendAttemptCountAsync( webhookSenderArgs.TenantId, @@ -72,7 +68,7 @@ namespace LINGYUN.Abp.Webhooks var payload = await GetWebhookPayloadAsync(webhookSenderArgs); - var serializedBody = JsonSerializer.Serialize(payload); + var serializedBody = JsonConvert.SerializeObject(payload); return serializedBody; } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionManager.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionManager.cs index 4ed53d52b..9db42f506 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionManager.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionManager.cs @@ -93,11 +93,7 @@ namespace LINGYUN.Abp.Webhooks } else { - var subscription = await WebhookSubscriptionsStore.GetAsync(webhookSubscription.Id); - subscription.WebhookUri = webhookSubscription.WebhookUri; - subscription.Webhooks = webhookSubscription.Webhooks; - subscription.Headers = webhookSubscription.Headers; - await WebhookSubscriptionsStore.UpdateAsync(subscription); + await WebhookSubscriptionsStore.UpdateAsync(webhookSubscription); } await uow.SaveChangesAsync(); diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json index f31721006..653188d9b 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json @@ -1,8 +1,8 @@ { "culture": "en", "texts": { - "Features:WebhooksManagement": "WebhooksManagement", - "Permission:WebhooksManagement": "WebhooksManagement", + "Features:WebhooksManagement": "Webhooks", + "Permission:WebhooksManagement": "Webhooks", "Permission:ManageSettings": "Manage Settings" } } \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json index 759c3f745..bfcd4d2a2 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json @@ -1,8 +1,8 @@ { "culture": "zh-Hans", "texts": { - "Features:WebhooksManagement": "WebhooksManagement", - "Permission:WebhooksManagement": "WebhooksManagement", + "Features:WebhooksManagement": "Webhooks", + "Permission:WebhooksManagement": "Webhooks", "Permission:ManageSettings": "管理设置" } } \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfiguration.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfiguration.cs index 9b810dd32..bf7e418ce 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfiguration.cs +++ b/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( Action configureAction) { - return this.ConfigureEntity( - WebhooksManagementModuleExtensionConsts.EntityNames.Entity, - configureAction - ); + return this + .ConfigureEntity(WebhooksManagementModuleExtensionConsts.EntityNames.WebhookEvent, configureAction) + .ConfigureEntity(WebhooksManagementModuleExtensionConsts.EntityNames.WebhookSendAttempt, configureAction) + .ConfigureEntity(WebhooksManagementModuleExtensionConsts.EntityNames.WebhookSubscription, configureAction); } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfigurationDictionaryExtensions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfigurationDictionaryExtensions.cs index b41e10ccb..fe0bff94b 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfigurationDictionaryExtensions.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConfigurationDictionaryExtensions.cs @@ -1,6 +1,4 @@ using System; -using System.Collections.Generic; -using System.Text; using Volo.Abp.ObjectExtending.Modularity; namespace LINGYUN.Abp.WebhooksManagement.ObjectExtending; diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConsts.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConsts.cs index b16fe772e..a51d51035 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/ObjectExtending/WebhooksManagementModuleExtensionConsts.cs +++ b/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 const string Entity = "Entity"; + public const string WebhookEvent = "WebhookEvent"; + public const string WebhookSendAttempt = "WebhookSendAttempt"; + public const string WebhookSubscription = "WebhookSubscription"; } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookEventEto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookEventEto.cs new file mode 100644 index 000000000..f6625a851 --- /dev/null +++ b/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; } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookEventRecordConsts.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookEventRecordConsts.cs new file mode 100644 index 000000000..31f4cf431 --- /dev/null +++ b/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; +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSendAttemptEto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSendAttemptEto.cs new file mode 100644 index 000000000..12f1cb812 --- /dev/null +++ b/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; } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordConsts.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordConsts.cs new file mode 100644 index 000000000..464658f04 --- /dev/null +++ b/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; +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionConsts.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionConsts.cs new file mode 100644 index 000000000..70a51fc17 --- /dev/null +++ b/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; +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionEto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionEto.cs new file mode 100644 index 000000000..157d6bc04 --- /dev/null +++ b/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; } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/DefaultWebhookManager.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/DefaultWebhookManager.cs index c2535823c..8b8b56129 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/DefaultWebhookManager.cs +++ b/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 Volo.Abp.DependencyInjection; using Volo.Abp.Guids; -using Volo.Abp.Json; using Volo.Abp.MultiTenancy; using Volo.Abp.Uow; @@ -19,11 +18,10 @@ public class DefaultWebhookManager : WebhookManager, ITransientDependency public DefaultWebhookManager( ICurrentTenant currentTenant, IGuidGenerator guidGenerator, - IJsonSerializer jsonSerializer, IWebhookSendAttemptStore webhookSendAttemptStore, IUnitOfWorkManager unitOfWorkManager, IWebhookSendRecordRepository webhookSendAttemptRepository) - : base(jsonSerializer, webhookSendAttemptStore) + : base(webhookSendAttemptStore) { CurrentTenant = currentTenant; GuidGenerator = guidGenerator; diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Extensions/WebhookSubscriptionExtensions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Extensions/WebhookSubscriptionExtensions.cs new file mode 100644 index 000000000..3630b3760 --- /dev/null +++ b/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; + } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Extensions/WebhookSubscriptionInfoExtensions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Extensions/WebhookSubscriptionInfoExtensions.cs new file mode 100644 index 000000000..8068dfa10 --- /dev/null +++ b/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 + { + /// + /// Return List of subscribed webhooks definitions + /// + /// + public static List GetSubscribedWebhooks(this WebhookSubscription webhookSubscription) + { + if (webhookSubscription.Webhooks.IsNullOrWhiteSpace()) + { + return new List(); + } + + return JsonConvert.DeserializeObject>(webhookSubscription.Webhooks); + } + + /// + /// Adds webhook subscription to if not exists + /// + /// + /// webhook unique name + 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)); + } + + /// + /// Removes webhook subscription from if exists + /// + /// + /// webhook unique name + 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)); + } + + /// + /// Clears all + /// + /// + public static void RemoveAllSubscribedWebhooks(this WebhookSubscription webhookSubscription) + { + webhookSubscription.SetWebhooks(null); + } + + /// + /// if subscribed to given webhook + /// + /// + public static bool IsSubscribed(this WebhookSubscription webhookSubscription, string webhookName) + { + if (webhookSubscription.Webhooks.IsNullOrWhiteSpace()) + { + return false; + } + + return webhookSubscription.GetSubscribedWebhooks().Contains(webhookName); + } + + /// + /// Returns additional webhook headers + /// + /// + public static IDictionary GetWebhookHeaders(this WebhookSubscription webhookSubscription) + { + if (webhookSubscription.Headers.IsNullOrWhiteSpace()) + { + return new Dictionary(); + } + + return JsonConvert.DeserializeObject>(webhookSubscription.Headers); + } + + /// + /// Adds webhook subscription to if not exists + /// + 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)); + } + + /// + /// Adds webhook subscription to if not exists + /// + /// + /// Key of header + 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)); + } + + /// + /// Clears all + /// + /// + 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() + }; + } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookSendRecordRepository.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookSendRecordRepository.cs index 4cf97509f..a94eb35ee 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookSendRecordRepository.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookSendRecordRepository.cs @@ -17,5 +17,6 @@ public interface IWebhookSendRecordRepository : IRepository, IMultiTenant, IHasCreationTime, string data, Guid? tenantId = null) : base(id) { - WebhookName = webhookName; - Data = data; + WebhookName = Check.NotNullOrWhiteSpace(webhookName, nameof(webhookName), WebhookEventRecordConsts.MaxWebhookNameLength); + Data = Check.Length(data, nameof(data), WebhookEventRecordConsts.MaxDataLength); TenantId = tenantId; } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookEventStore.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookEventStore.cs index 62d864e8b..ff14e571a 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookEventStore.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookEventStore.cs @@ -11,20 +11,17 @@ public class WebhookEventStore : DomainService, IWebhookEventStore { protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetRequiredService>(); - protected IUnitOfWorkManager UnitOfWorkManager { get; } protected IWebhookEventRecordRepository WebhookEventRepository { get; } public WebhookEventStore( - IUnitOfWorkManager unitOfWorkManager, IWebhookEventRecordRepository webhookEventRepository) { - UnitOfWorkManager = unitOfWorkManager; WebhookEventRepository = webhookEventRepository; } + [UnitOfWork] public async virtual Task GetAsync(Guid? tenantId, Guid id) { - using var uow = UnitOfWorkManager.Begin(); using (CurrentTenant.Change(tenantId)) { var record = await WebhookEventRepository.GetAsync(id); @@ -33,9 +30,9 @@ public class WebhookEventStore : DomainService, IWebhookEventStore } } + [UnitOfWork] public async virtual Task InsertAndGetIdAsync(WebhookEvent webhookEvent) { - using var uow = UnitOfWorkManager.Begin(); using (CurrentTenant.Change(webhookEvent.TenantId)) { var record = new WebhookEventRecord( @@ -49,8 +46,6 @@ public class WebhookEventStore : DomainService, IWebhookEventStore await WebhookEventRepository.InsertAsync(record); - await uow.SaveChangesAsync(); - return record.Id; } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendAttemptStore.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendAttemptStore.cs index 8e024decf..1b469c105 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendAttemptStore.cs +++ b/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 Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Services; -using Volo.Abp.Linq; using Volo.Abp.ObjectMapping; using Volo.Abp.Uow; @@ -16,150 +15,108 @@ namespace LINGYUN.Abp.WebhooksManagement; public class WebhookSendAttemptStore : DomainService, IWebhookSendAttemptStore { protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetRequiredService>(); - protected IAsyncQueryableExecuter AsyncQueryableExecuter => LazyServiceProvider.LazyGetRequiredService(); - protected IUnitOfWorkManager UnitOfWorkManager { get; } protected IWebhookSendRecordRepository WebhookSendAttemptRepository { get; } public WebhookSendAttemptStore( - IUnitOfWorkManager unitOfWorkManager, IWebhookSendRecordRepository webhookSendAttemptRepository) { - UnitOfWorkManager = unitOfWorkManager; WebhookSendAttemptRepository = webhookSendAttemptRepository; } + [UnitOfWork] public async virtual Task<(int TotalCount, IReadOnlyCollection Webhooks)> GetAllSendAttemptsBySubscriptionAsPagedListAsync( Guid? tenantId, Guid subscriptionId, int maxResultCount, int skipCount) { - (int TotalCount, IReadOnlyCollection Webhooks) sendAttempts; - - using (var uow = UnitOfWorkManager.Begin()) + using (CurrentTenant.Change(tenantId)) { - using (CurrentTenant.Change(tenantId)) + var filter = new WebhookSendRecordFilter { - var filter = new WebhookSendRecordFilter - { - SubscriptionId = subscriptionId, - }; - var totalCount = await WebhookSendAttemptRepository.GetCountAsync(filter); - - var list = await WebhookSendAttemptRepository.GetListAsync( - filter, - maxResultCount: maxResultCount, - skipCount: skipCount); + SubscriptionId = subscriptionId, + }; + var totalCount = await WebhookSendAttemptRepository.GetCountAsync(filter); - var webHooks = ObjectMapper.Map, List>(list); + var list = await WebhookSendAttemptRepository.GetListAsync( + filter, + maxResultCount: maxResultCount, + skipCount: skipCount); - sendAttempts = ValueTuple.Create(totalCount, webHooks.ToImmutableList()); - } + var webHooks = ObjectMapper.Map, List>(list); - await uow.CompleteAsync(); + return ValueTuple.Create(totalCount, webHooks.ToImmutableList()); } - - return sendAttempts; } + [UnitOfWork] public async virtual Task> GetAllSendAttemptsByWebhookEventIdAsync( Guid? tenantId, Guid webhookEventId) { - List 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 - .Where(attempt => attempt.WebhookEventId == webhookEventId) - .OrderByDescending(attempt => attempt.CreationTime) - ); - - sendAttempts = ObjectMapper.Map, List>(list); - } + var list = await AsyncExecuter.ToListAsync(queryable + .Where(attempt => attempt.WebhookEventId == webhookEventId) + .OrderByDescending(attempt => attempt.CreationTime) + ); - await uow.CompleteAsync(); + return ObjectMapper.Map, List>(list); } - - return sendAttempts; } + [UnitOfWork] public async virtual Task GetAsync( Guid? tenantId, 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(sendAttempt); } - - return ObjectMapper.Map(sendAttempt); } + [UnitOfWork] public async virtual Task GetSendAttemptCountAsync( Guid? tenantId, Guid webhookEventId, Guid webhookSubscriptionId) { - int sendAttemptCount; - - using (var uow = UnitOfWorkManager.Begin()) + using (CurrentTenant.Change(tenantId)) { - using (CurrentTenant.Change(tenantId)) - { - sendAttemptCount = await WebhookSendAttemptRepository.CountAsync(attempt => - attempt.WebhookEventId == webhookEventId && - attempt.WebhookSubscriptionId == webhookSubscriptionId); - } - - await uow.CompleteAsync(); + return await WebhookSendAttemptRepository.CountAsync(attempt => + attempt.WebhookEventId == webhookEventId && + attempt.WebhookSubscriptionId == webhookSubscriptionId); } - - return sendAttemptCount; } + [UnitOfWork] public async virtual Task HasXConsecutiveFailAsync( Guid? tenantId, Guid subscriptionId, 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; - } - else - { - var queryable = await WebhookSendAttemptRepository.GetQueryableAsync(); - - result = !await AsyncQueryableExecuter.AnyAsync(queryable - .OrderByDescending(attempt => attempt.CreationTime) - .Take(failCount) - .Where(attempt => attempt.ResponseStatusCode == HttpStatusCode.OK) - ); - } + return false; } + else + { + var queryable = await WebhookSendAttemptRepository.GetQueryableAsync(); - await uow.CompleteAsync(); + return !await AsyncExecuter.AnyAsync(queryable + .OrderByDescending(attempt => attempt.CreationTime) + .Take(failCount) + .Where(attempt => attempt.ResponseStatusCode == HttpStatusCode.OK) + ); + } } - - return result; } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecord.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecord.cs index 91c3c8a97..0d0d0115a 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecord.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecord.cs @@ -1,5 +1,6 @@ using System; using System.Net; +using Volo.Abp; using Volo.Abp.Auditing; using Volo.Abp.Domain.Entities; using Volo.Abp.MultiTenancy; @@ -44,7 +45,7 @@ public class WebhookSendRecord : Entity, IHasCreationTime, IHasModificatio string response, HttpStatusCode? statusCode = null) { - Response = response; + Response = Check.Length(response, nameof(response), WebhookSendRecordConsts.MaxResponseLength); ResponseStatusCode = statusCode; } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordFilter.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordFilter.cs index 075a6152b..44f034c30 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordFilter.cs +++ b/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 string Response { get; set; } - public HttpStatusCode? ResponseStatusCode { get; set; } public DateTime? BeginCreationTime { get; set; } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscription.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscription.cs index be342aaa3..4d637e88a 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscription.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscription.cs @@ -1,4 +1,5 @@ using System; +using Volo.Abp; using Volo.Abp.Domain.Entities.Auditing; namespace LINGYUN.Abp.WebhooksManagement; @@ -22,12 +23,27 @@ public class WebhookSubscription : CreationAuditedEntity string headers, Guid? tenantId = null) : base(id) { - WebhookUri = webhookUri; - Secret = secret; - Webhooks = webhooks; - Headers = headers; + Secret = Check.NotNullOrWhiteSpace(secret, nameof(secret), WebhookSubscriptionConsts.MaxSecretLength); + SetWebhookUri(webhookUri); + SetWebhooks(webhooks); + SetHeaders(headers); TenantId = tenantId; 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); + } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionsStore.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionsStore.cs index abdbf33be..c25467ef6 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionsStore.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionsStore.cs @@ -1,55 +1,148 @@ using LINGYUN.Abp.Webhooks; +using LINGYUN.Abp.WebhooksManagement.Extensions; +using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Volo.Abp.Domain.Services; +using Volo.Abp.Uow; namespace LINGYUN.Abp.WebhooksManagement; public class WebhookSubscriptionsStore : DomainService, IWebhookSubscriptionsStore { - public Task DeleteAsync(Guid id) + protected IWebhookSubscriptionRepository SubscriptionRepository { get; } + + public WebhookSubscriptionsStore( + IWebhookSubscriptionRepository subscriptionRepository) + { + SubscriptionRepository = subscriptionRepository; + } + + [UnitOfWork] + public async virtual Task DeleteAsync(Guid id) { - throw new NotImplementedException(); + using (CurrentTenant.Change(null)) + { + await SubscriptionRepository.DeleteAsync(id); + } } - public Task> GetAllSubscriptionsAsync(Guid? tenantId) + [UnitOfWork] + public async virtual Task> 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> GetAllSubscriptionsAsync(Guid? tenantId, string webhookName) + [UnitOfWork] + public async virtual Task> 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(); + } } - public Task> GetAllSubscriptionsOfTenantsAsync(Guid?[] tenantIds) + [UnitOfWork] + public async virtual Task> GetAllSubscriptionsOfTenantsAsync(Guid?[] tenantIds) { - throw new NotImplementedException(); + 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> GetAllSubscriptionsOfTenantsAsync(Guid?[] tenantIds, string webhookName) + [UnitOfWork] + public async virtual Task> GetAllSubscriptionsOfTenantsAsync(Guid?[] tenantIds, string webhookName) { - throw new NotImplementedException(); + using (CurrentTenant.Change(null)) + { + 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 GetAsync(Guid id) + [UnitOfWork] + public async virtual Task 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) { - throw new NotImplementedException(); + using (CurrentTenant.Change(null)) + { + 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 IsSubscribedAsync(Guid? tenantId, string webhookName) + [UnitOfWork] + public async virtual Task 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) { - throw new NotImplementedException(); + using (CurrentTenant.Change(webhookSubscription.TenantId)) + { + var subscription = await SubscriptionRepository.GetAsync(webhookSubscription.Id); + subscription.SetWebhookUri(webhookSubscription.WebhookUri); + subscription.SetWebhooks(webhookSubscription.ToSubscribedWebhooksString()); + subscription.SetHeaders(webhookSubscription.ToWebhookHeadersString()); + + await SubscriptionRepository.UpdateAsync(subscription); + } } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainMapperProfile.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainMapperProfile.cs index cbef9c444..231739e73 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainMapperProfile.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainMapperProfile.cs @@ -1,4 +1,8 @@ using AutoMapper; +using LINGYUN.Abp.Webhooks; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; namespace LINGYUN.Abp.WebhooksManagement; @@ -6,6 +10,11 @@ public class WebhooksManagementDomainMapperProfile : Profile { public WebhooksManagementDomainMapperProfile() { + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainModule.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainModule.cs index bdeb77779..18903b4b3 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainModule.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDomainModule.cs @@ -1,8 +1,10 @@ using LINGYUN.Abp.Webhooks; +using LINGYUN.Abp.WebhooksManagement.ObjectExtending; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AutoMapper; using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.Modularity; +using Volo.Abp.ObjectExtending.Modularity; using Volo.Abp.Threading; namespace LINGYUN.Abp.WebhooksManagement; @@ -25,6 +27,13 @@ public class WebhooksManagementDomainModule : AbpModule Configure(options => { + options.EtoMappings.Add(); + options.EtoMappings.Add(); + options.EtoMappings.Add(); + + options.AutoEventSelectors.Add(); + options.AutoEventSelectors.Add(); + options.AutoEventSelectors.Add(); }); } @@ -33,11 +42,21 @@ public class WebhooksManagementDomainModule : AbpModule OneTimeRunner.Run(() => { // 扩展实体配置 - //ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity( - // WebhooksManagementModuleExtensionConsts.ModuleName, - // WebhooksManagementModuleExtensionConsts.EntityNames.Entity, - // typeof(Entity) - //); + ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity( + WebhooksManagementModuleExtensionConsts.ModuleName, + WebhooksManagementModuleExtensionConsts.EntityNames.WebhookEvent, + typeof(WebhookEventRecord) + ); + ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity( + WebhooksManagementModuleExtensionConsts.ModuleName, + WebhooksManagementModuleExtensionConsts.EntityNames.WebhookSubscription, + typeof(WebhookSubscription) + ); + ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity( + WebhooksManagementModuleExtensionConsts.ModuleName, + WebhooksManagementModuleExtensionConsts.EntityNames.WebhookSendAttempt, + typeof(WebhookSendRecord) + ); }); } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookEventRecordRepository.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookEventRecordRepository.cs new file mode 100644 index 000000000..606b69aff --- /dev/null +++ b/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, + IWebhookEventRecordRepository +{ + public EfCoreWebhookEventRecordRepository(IDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookSendRecordRepository.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookSendRecordRepository.cs new file mode 100644 index 000000000..f7ba0d433 --- /dev/null +++ b/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, + IWebhookSendRecordRepository +{ + public EfCoreWebhookSendRecordRepository( + IDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } + + public async virtual Task GetCountAsync( + WebhookSendRecordFilter filter, + CancellationToken cancellationToken = default) + { + return await ApplyFilter(await GetDbSetAsync(), filter) + .CountAsync(GetCancellationToken(cancellationToken)); + + } + + public async virtual Task> 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 ApplyFilter( + IQueryable 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)); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookSubscriptionRepository.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookSubscriptionRepository.cs new file mode 100644 index 000000000..4931d6eaf --- /dev/null +++ b/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, + IWebhookSubscriptionRepository +{ + public EfCoreWebhookSubscriptionRepository( + IDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs index fcf22d3e6..628ffd329 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs @@ -1,6 +1,7 @@ using Microsoft.EntityFrameworkCore; using System; using Volo.Abp; +using Volo.Abp.EntityFrameworkCore.Modeling; namespace LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore; @@ -17,5 +18,59 @@ public static class WebhooksManagementDbContextModelCreatingExtensions WebhooksManagementDbProperties.DbSchema ); optionsAction?.Invoke(options); + + builder.Entity(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(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(fk => fk.WebhookEventId) + .HasPrincipalKey(pk => pk.Id ); + }); + + builder.Entity(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(); + }); } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementEfCoreQueryableExtensions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementEfCoreQueryableExtensions.cs index 5751f330f..c5baeadb9 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementEfCoreQueryableExtensions.cs +++ b/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 IQueryable IncludeDetails(this IQueryable queryable, bool include = true) + { + if (!include) + { + return queryable; + } + + return queryable + .Include(x => x.WebhookEvent); + } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementEntityFrameworkCoreModule.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementEntityFrameworkCoreModule.cs index c64b2bb15..c175c4007 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementEntityFrameworkCoreModule.cs +++ b/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(options => { + options.AddRepository(); + options.AddRepository(); + options.AddRepository(); + options.AddDefaultRepositories(); }); } diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Controllers/HomeController.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Controllers/HomeController.cs index 5084440c9..97e94bcfe 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Controllers/HomeController.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Controllers/HomeController.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc; -namespace LY..WebhooksManagement.Controllers; +namespace LY.MicroService.WebhooksManagement.Controllers; public class HomeController : AbpController { diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/DataSeeder/WebhooksManagementDataSeederWorker.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/DataSeeder/WebhooksManagementDataSeederWorker.cs index 77ffbf33f..6a683b100 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/DataSeeder/WebhooksManagementDataSeederWorker.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/DataSeeder/WebhooksManagementDataSeederWorker.cs @@ -3,7 +3,7 @@ using System.Threading; using System.Threading.Tasks; using Volo.Abp.Data; -namespace LY..WebhooksManagement.DataSeeder; +namespace LY.MicroService.WebhooksManagement.DataSeeder; public class WebhooksManagementDataSeederWorker : BackgroundService { diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContext.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContext.cs index 61e3ae739..d0f8b1cec 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContext.cs +++ b/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; -namespace LY..WebhooksManagement.EntityFrameworkCore; +namespace LY.MicroService.WebhooksManagement.EntityFrameworkCore; public class WebhooksManagementMigrationsDbContext : AbpDbContext { diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContextFactory.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContextFactory.cs index cd4432128..88755770b 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContextFactory.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EntityFrameworkCore/WebhooksManagementMigrationsDbContextFactory.cs @@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Design; using Microsoft.Extensions.Configuration; using System.IO; -namespace LY..WebhooksManagement.EntityFrameworkCore; +namespace LY.MicroService.WebhooksManagement.EntityFrameworkCore; public class WebhooksManagementMigrationsDbContextFactory : IDesignTimeDbContextFactory { diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EventBus/Handlers/TenantSynchronizer.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EventBus/Handlers/TenantSynchronizer.cs index ccdd31c65..ded6862ab 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EventBus/Handlers/TenantSynchronizer.cs +++ b/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.WebhooksManagement.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using System.Threading.Tasks; @@ -10,7 +10,7 @@ using Volo.Abp.EventBus.Distributed; using Volo.Abp.MultiTenancy; using Volo.Abp.Uow; -namespace LY..WebhooksManagement.EventBus.Handlers; +namespace LY.MicroService.WebhooksManagement.EventBus.Handlers; public class TenantSynchronizer : IDistributedEventHandler, @@ -49,7 +49,7 @@ public class TenantSynchronizer : { 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( (connectionString, builder) => @@ -58,7 +58,7 @@ public class TenantSynchronizer : 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)); diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj index b108df60e..85571cc58 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj @@ -2,7 +2,7 @@ net6.0 - LY..WebhooksManagement + LY.MicroService.WebhooksManagement @@ -57,10 +57,9 @@ - - - - + + + diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Program.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Program.cs index f55da1841..26693716a 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Program.cs +++ b/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.Modularity.PlugIns; -namespace LY..WebhooksManagement; +namespace LY.MicroService.WebhooksManagement; public class Program { diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Properties/launchSettings.json b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Properties/launchSettings.json index 6a691ee60..c269dc698 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Properties/launchSettings.json +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Properties/launchSettings.json @@ -14,15 +14,8 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, - "applicationUrl": "http://localhost:57264", + "applicationUrl": "http://127.0.0.1:30045", "dotnetRunMessages": "true" - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": false, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } } } } \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/TenantHeaderParamter.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/TenantHeaderParamter.cs index e793c0e5c..492957abe 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/TenantHeaderParamter.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/TenantHeaderParamter.cs @@ -4,7 +4,7 @@ using Swashbuckle.AspNetCore.SwaggerGen; using System.Collections.Generic; using Volo.Abp.MultiTenancy; -namespace LY..WebhooksManagement; +namespace LY.MicroService.WebhooksManagement; public class TenantHeaderParamter : IOperationFilter { diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs index 95705fa29..be2cbca09 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs +++ b/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.VirtualFileSystem; -namespace LY..WebhooksManagement; +namespace LY.MicroService.WebhooksManagement; public partial class WebhooksManagementHttpApiHostModule { @@ -53,7 +53,7 @@ public partial class WebhooksManagementHttpApiHostModule PreConfigure(options => { // 以开放端口区别 - options.SnowflakeIdOptions.WorkerId = 5000; + options.SnowflakeIdOptions.WorkerId = 30045; options.SnowflakeIdOptions.WorkerIdBits = 5; options.SnowflakeIdOptions.DatacenterId = 1; }); @@ -160,7 +160,7 @@ public partial class WebhooksManagementHttpApiHostModule { Configure(options => { - options.ApplicationName = "WebhooksManagement"; + options.ApplicationName = ApplicationName; // 是否启用实体变更记录 var entitiesChangedConfig = configuration.GetSection("App:TrackingEntitiesChanged"); if (entitiesChangedConfig.Exists() && entitiesChangedConfig.Get()) @@ -196,7 +196,7 @@ public partial class WebhooksManagementHttpApiHostModule { Configure(options => { - options.FileSets.AddEmbedded("LY..WebhooksManagement"); + options.FileSets.AddEmbedded("LY.MicroService.WebhooksManagement"); }); } diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.DataSeeder.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.DataSeeder.cs index 8c2982179..ddbbf21ba 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.DataSeeder.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.DataSeeder.cs @@ -1,7 +1,7 @@ using Microsoft.Extensions.DependencyInjection; -using LY..WebhooksManagement.DataSeeder; +using LY.MicroService.WebhooksManagement.DataSeeder; -namespace LY..WebhooksManagement; +namespace LY.MicroService.WebhooksManagement; public partial class WebhooksManagementHttpApiHostModule { diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs index 4dac2cea9..5d89fbec0 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs +++ b/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.EventBus.CAP; using LINGYUN.Abp.ExceptionHandling.Emailing; @@ -6,12 +7,12 @@ using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; using LINGYUN.Abp.Saas.EntityFrameworkCore; using LINGYUN.Abp.Serilog.Enrichers.Application; using LINGYUN.Abp.Serilog.Enrichers.UniqueId; +using LINGYUN.Abp.WebhooksManagement; +using LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using LY..WebhooksManagement.EntityFrameworkCore; -using LY..WebhooksManagement.SettingManagement; using Volo.Abp; using Volo.Abp.AspNetCore.Authentication.JwtBearer; using Volo.Abp.AspNetCore.MultiTenancy; @@ -27,7 +28,7 @@ using Volo.Abp.PermissionManagement.EntityFrameworkCore; using Volo.Abp.SettingManagement.EntityFrameworkCore; using Volo.Abp.Swashbuckle; -namespace LY.WebhooksManagement; +namespace LY.MicroService.WebhooksManagement; [DependsOn( typeof(AbpSerilogEnrichersApplicationModule), @@ -37,7 +38,6 @@ namespace LY.WebhooksManagement; typeof(WebhooksManagementApplicationModule), typeof(WebhooksManagementHttpApiModule), typeof(WebhooksManagementEntityFrameworkCoreModule), - typeof(WebhooksManagementSettingManagementModule), typeof(AbpEntityFrameworkCoreMySQLModule), typeof(AbpAspNetCoreAuthenticationJwtBearerModule), typeof(AbpEmailingExceptionHandlingModule), @@ -101,6 +101,7 @@ public partial class WebhooksManagementHttpApiHostModule : AbpModule app.UseMultiTenancy(); app.UseMapRequestLocalization(); app.UseAuthorization(); + app.UseCapDashboard(); app.UseSwagger(); app.UseAbpSwaggerUI(options => { From efdd916e6fd1dc84fdf6cdc923bc23d4f559a1be Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Sat, 26 Mar 2022 11:10:13 +0800 Subject: [PATCH 03/17] feat(webhooks): added ef migrations --- ...Add-Module-WebHooks-Management.Designer.cs | 166 ++++++++++++++++++ ...26030345_Add-Module-WebHooks-Management.cs | 104 +++++++++++ ...agementMigrationsDbContextModelSnapshot.cs | 164 +++++++++++++++++ .../Properties/launchSettings.json | 2 +- .../WebhooksManagementHttpApiHostModule.cs | 2 + .../appsettings.Development.json | 42 ++--- 6 files changed, 450 insertions(+), 30 deletions(-) create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326030345_Add-Module-WebHooks-Management.Designer.cs create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326030345_Add-Module-WebHooks-Management.cs create mode 100644 aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/WebhooksManagementMigrationsDbContextModelSnapshot.cs diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326030345_Add-Module-WebHooks-Management.Designer.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326030345_Add-Module-WebHooks-Management.Designer.cs new file mode 100644 index 000000000..bdf69d7be --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326030345_Add-Module-WebHooks-Management.Designer.cs @@ -0,0 +1,166 @@ +// +using System; +using LY.MicroService.WebhooksManagement.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; + +#nullable disable + +namespace LY.MicroService.WebhooksManagement.Migrations +{ + [DbContext(typeof(WebhooksManagementMigrationsDbContext))] + [Migration("20220326030345_Add-Module-WebHooks-Management")] + partial class AddModuleWebHooksManagement + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql) + .HasAnnotation("ProductVersion", "6.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookEventRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("Data") + .HasMaxLength(2147483647) + .HasColumnType("longtext") + .HasColumnName("Data"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("WebhookName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("varchar(100)") + .HasColumnName("WebhookName"); + + b.HasKey("Id"); + + b.ToTable("WebhooksManagement_WebhookEvents", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookSendRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("Response") + .HasMaxLength(2147483647) + .HasColumnType("longtext") + .HasColumnName("Response"); + + b.Property("ResponseStatusCode") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("WebhookEventId") + .HasColumnType("char(36)"); + + b.Property("WebhookSubscriptionId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("WebhookEventId") + .IsUnique(); + + b.ToTable("WebhooksManagement_WebhookSendAttempts", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("Headers") + .HasMaxLength(2147483647) + .HasColumnType("longtext") + .HasColumnName("Headers"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Secret") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("Secret"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("WebhookUri") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasColumnName("WebhookUri"); + + b.Property("Webhooks") + .HasMaxLength(2147483647) + .HasColumnType("longtext") + .HasColumnName("Webhooks"); + + b.HasKey("Id"); + + b.ToTable("WebhooksManagement_WebhookSubscriptions", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookSendRecord", b => + { + b.HasOne("LINGYUN.Abp.WebhooksManagement.WebhookEventRecord", "WebhookEvent") + .WithOne() + .HasForeignKey("LINGYUN.Abp.WebhooksManagement.WebhookSendRecord", "WebhookEventId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("WebhookEvent"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326030345_Add-Module-WebHooks-Management.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326030345_Add-Module-WebHooks-Management.cs new file mode 100644 index 000000000..ca7fd42f9 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326030345_Add-Module-WebHooks-Management.cs @@ -0,0 +1,104 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace LY.MicroService.WebhooksManagement.Migrations +{ + public partial class AddModuleWebHooksManagement : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterDatabase() + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "WebhooksManagement_WebhookEvents", + columns: table => new + { + Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + TenantId = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + WebhookName = table.Column(type: "varchar(100)", maxLength: 100, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Data = table.Column(type: "longtext", maxLength: 2147483647, nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + CreationTime = table.Column(type: "datetime(6)", nullable: false), + DeletionTime = table.Column(type: "datetime(6)", nullable: true), + IsDeleted = table.Column(type: "tinyint(1)", nullable: false, defaultValue: false) + }, + constraints: table => + { + table.PrimaryKey("PK_WebhooksManagement_WebhookEvents", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "WebhooksManagement_WebhookSubscriptions", + columns: table => new + { + Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + TenantId = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + WebhookUri = table.Column(type: "varchar(255)", maxLength: 255, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Secret = table.Column(type: "varchar(128)", maxLength: 128, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + IsActive = table.Column(type: "tinyint(1)", nullable: false), + Webhooks = table.Column(type: "longtext", maxLength: 2147483647, nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + Headers = table.Column(type: "longtext", maxLength: 2147483647, nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + CreationTime = table.Column(type: "datetime(6)", nullable: false), + CreatorId = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci") + }, + constraints: table => + { + table.PrimaryKey("PK_WebhooksManagement_WebhookSubscriptions", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "WebhooksManagement_WebhookSendAttempts", + columns: table => new + { + Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + TenantId = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + WebhookEventId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + WebhookSubscriptionId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + Response = table.Column(type: "longtext", maxLength: 2147483647, nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + ResponseStatusCode = table.Column(type: "int", nullable: true), + CreationTime = table.Column(type: "datetime(6)", nullable: false), + LastModificationTime = table.Column(type: "datetime(6)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_WebhooksManagement_WebhookSendAttempts", x => x.Id); + table.ForeignKey( + name: "FK_WebhooksManagement_WebhookSendAttempts_WebhooksManagement_We~", + column: x => x.WebhookEventId, + principalTable: "WebhooksManagement_WebhookEvents", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateIndex( + name: "IX_WebhooksManagement_WebhookSendAttempts_WebhookEventId", + table: "WebhooksManagement_WebhookSendAttempts", + column: "WebhookEventId", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "WebhooksManagement_WebhookSendAttempts"); + + migrationBuilder.DropTable( + name: "WebhooksManagement_WebhookSubscriptions"); + + migrationBuilder.DropTable( + name: "WebhooksManagement_WebhookEvents"); + } + } +} diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/WebhooksManagementMigrationsDbContextModelSnapshot.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/WebhooksManagementMigrationsDbContextModelSnapshot.cs new file mode 100644 index 000000000..966262d85 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/WebhooksManagementMigrationsDbContextModelSnapshot.cs @@ -0,0 +1,164 @@ +// +using System; +using LY.MicroService.WebhooksManagement.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; + +#nullable disable + +namespace LY.MicroService.WebhooksManagement.Migrations +{ + [DbContext(typeof(WebhooksManagementMigrationsDbContext))] + partial class WebhooksManagementMigrationsDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql) + .HasAnnotation("ProductVersion", "6.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookEventRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("Data") + .HasMaxLength(2147483647) + .HasColumnType("longtext") + .HasColumnName("Data"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("WebhookName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("varchar(100)") + .HasColumnName("WebhookName"); + + b.HasKey("Id"); + + b.ToTable("WebhooksManagement_WebhookEvents", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookSendRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("Response") + .HasMaxLength(2147483647) + .HasColumnType("longtext") + .HasColumnName("Response"); + + b.Property("ResponseStatusCode") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("WebhookEventId") + .HasColumnType("char(36)"); + + b.Property("WebhookSubscriptionId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("WebhookEventId") + .IsUnique(); + + b.ToTable("WebhooksManagement_WebhookSendAttempts", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("Headers") + .HasMaxLength(2147483647) + .HasColumnType("longtext") + .HasColumnName("Headers"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Secret") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("Secret"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("WebhookUri") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasColumnName("WebhookUri"); + + b.Property("Webhooks") + .HasMaxLength(2147483647) + .HasColumnType("longtext") + .HasColumnName("Webhooks"); + + b.HasKey("Id"); + + b.ToTable("WebhooksManagement_WebhookSubscriptions", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookSendRecord", b => + { + b.HasOne("LINGYUN.Abp.WebhooksManagement.WebhookEventRecord", "WebhookEvent") + .WithOne() + .HasForeignKey("LINGYUN.Abp.WebhooksManagement.WebhookSendRecord", "WebhookEventId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("WebhookEvent"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Properties/launchSettings.json b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Properties/launchSettings.json index c269dc698..7e93c505e 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Properties/launchSettings.json +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Properties/launchSettings.json @@ -8,7 +8,7 @@ } }, "profiles": { - "LY..WebhooksManagement.HttpApi.Host": { + "LY.MicroService.WebhooksManagement.HttpApi.Host": { "commandName": "Project", "launchBrowser": false, "environmentVariables": { diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs index 5d89fbec0..ec561d610 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs @@ -85,6 +85,8 @@ public partial class WebhooksManagementHttpApiHostModule : AbpModule ConfigureDistributedLock(context.Services, configuration); ConfigureSeedWorker(context.Services, hostingEnvironment.IsDevelopment()); ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); + + // context.Services.AddAlwaysAllowAuthorization(); } public override void OnApplicationInitialization(ApplicationInitializationContext context) diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/appsettings.Development.json b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/appsettings.Development.json index 7c28c17fe..4a816c0c1 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/appsettings.Development.json +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/appsettings.Development.json @@ -1,22 +1,22 @@ { "AgileConfig": { "env": "DEV", - "appId": "LY.MicroService.WebhooksManagement", + "appId": "LINGYUN.Abp.WebhooksManagement", "secret": "1q2w3E*", "nodes": "http://127.0.0.1:15000", - "name": "LY.MicroService.WebhooksManagement", - "tag": "LY.MicroService.WebhooksManagement" + "name": "LINGYUN.Abp.WebhooksManagement", + "tag": "LINGYUN.Abp.WebhooksManagement" }, "App": { "TrackingEntitiesChanged": true }, "ConnectionStrings": { - "Default": "Server=127.0.0.1;Database=WebhooksManagement;User Id=root;Password=123456", - "WebhooksManagement": "Server=127.0.0.1;Database=WebhooksManagement;User Id=root;Password=123456", - "AbpSaas": "Server=127.0.0.1;Database=WebhooksManagement;User Id=root;Password=123456", - "AbpFeatureManagement": "Server=127.0.0.1;Database=WebhooksManagement;User Id=root;Password=123456", - "AbpPermissionManagement": "Server=127.0.0.1;Database=WebhooksManagement;User Id=root;Password=123456", - "AbpSettingManagement": "Server=127.0.0.1;Database=WebhooksManagement;User Id=root;Password=123456" + "Default": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", + "WebhooksManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", + "AbpSaas": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", + "AbpFeatureManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", + "AbpPermissionManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", + "AbpSettingManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456" }, "DistributedLock": { "Redis": { @@ -48,30 +48,14 @@ "FailedRetryCount": 10 }, "MySql": { - "TableNamePrefix": "WebhooksManagement_cap", - "ConnectionString": "Server=127.0.0.1;Database=WebhooksManagement;User Id=root;Password=123456" - }, - "SqlServer": { - "TableNamePrefix": "WebhooksManagement_cap", - "ConnectionString": "Server=127.0.0.1;Database=WebhooksManagement;User Id=root;Password=123456" - }, - "Sqlite": { - "TableNamePrefix": "WebhooksManagement_cap", - "ConnectionString": "Data Source=./cap.db" - }, - "Oracle": { - "TableNamePrefix": "WebhooksManagement_cap", - "ConnectionString": "Data Source=WebhooksManagement;Integrated Security=yes;" - }, - "PostgreSql": { - "TableNamePrefix": "WebhooksManagement_cap", - "ConnectionString": "Host=localhost;Port=5432;Database=WebhooksManagement;User ID=root;Password=123456;" + "TableNamePrefix": "wkm", + "ConnectionString": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456" }, "RabbitMQ": { "HostName": "127.0.0.1", "Port": 5672, - "UserName": "admin", - "Password": "123456", + "UserName": "guest", + "Password": "guest", "ExchangeName": "LINGYUN.Abp.Application", "VirtualHost": "/" } From 3e7c232e76015436436e1381006b0be4976659ea Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Sat, 26 Mar 2022 11:56:24 +0800 Subject: [PATCH 04/17] feat(webhooks): add a client proxy publishing module to address layered module calls --- .../LINGYUN.Abp.WebHooks.ClientProxies.csproj | 16 ++++ .../AbpWebHooksClientProxiesModule.cs | 10 ++ .../ClientProxiesWebhookPublisher.cs | 91 +++++++++++++++++++ .../Abp/Webhooks/DefaultWebhookPublisher.cs | 35 +++++-- ...sManagementPermissionDefinitionProvider.cs | 5 + .../WebhooksManagementPermissions.cs | 5 + .../IWebhooksPublishAppService.cs | 9 ++ .../WebhooksManagementRemoteServiceConsts.cs | 2 +- .../WebhooksPublishInput.cs | 30 ++++++ .../WebhooksPublishAppService.cs | 45 +++++++++ ...NGYUN.Abp.WebhooksManagement.Domain.csproj | 2 +- .../WebhooksPublishController.cs | 27 ++++++ 12 files changed, 267 insertions(+), 10 deletions(-) create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks.ClientProxies/LINGYUN.Abp.WebHooks.ClientProxies.csproj create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks.ClientProxies/LINGYUN/Abp/WebHooks/ClientProxies/AbpWebHooksClientProxiesModule.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks.ClientProxies/LINGYUN/Abp/WebHooks/ClientProxies/ClientProxiesWebhookPublisher.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksPublishAppService.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksPublishInput.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksPublishAppService.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksPublishController.cs diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks.ClientProxies/LINGYUN.Abp.WebHooks.ClientProxies.csproj b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks.ClientProxies/LINGYUN.Abp.WebHooks.ClientProxies.csproj new file mode 100644 index 000000000..251dd53d3 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks.ClientProxies/LINGYUN.Abp.WebHooks.ClientProxies.csproj @@ -0,0 +1,16 @@ + + + + + + + netstandard2.0 + + + + + + + + + diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks.ClientProxies/LINGYUN/Abp/WebHooks/ClientProxies/AbpWebHooksClientProxiesModule.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks.ClientProxies/LINGYUN/Abp/WebHooks/ClientProxies/AbpWebHooksClientProxiesModule.cs new file mode 100644 index 000000000..41e08a4a7 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks.ClientProxies/LINGYUN/Abp/WebHooks/ClientProxies/AbpWebHooksClientProxiesModule.cs @@ -0,0 +1,10 @@ +using LINGYUN.Abp.WebhooksManagement; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.Webhooks.ClientProxies; + +[DependsOn(typeof(AbpWebhooksModule))] +[DependsOn(typeof(WebhooksManagementHttpApiClientModule))] +public class AbpWebHooksClientProxiesModule : AbpModule +{ +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks.ClientProxies/LINGYUN/Abp/WebHooks/ClientProxies/ClientProxiesWebhookPublisher.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks.ClientProxies/LINGYUN/Abp/WebHooks/ClientProxies/ClientProxiesWebhookPublisher.cs new file mode 100644 index 000000000..85b25db61 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks.ClientProxies/LINGYUN/Abp/WebHooks/ClientProxies/ClientProxiesWebhookPublisher.cs @@ -0,0 +1,91 @@ +using LINGYUN.Abp.WebhooksManagement; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.Webhooks.ClientProxies; + +[Dependency(ReplaceServices = true)] +public class ClientProxiesWebhookPublisher : IWebhookPublisher, ITransientDependency +{ + protected IWebhooksPublishAppService PublishAppService { get; } + + public ClientProxiesWebhookPublisher( + IWebhooksPublishAppService publishAppService) + { + PublishAppService = publishAppService; + } + + public async virtual Task PublishAsync(string webhookName, object data, bool sendExactSameData = false, WebhookHeader headers = null) + { + var input = new WebhooksPublishInput + { + WebhookName = webhookName, + Data = JsonConvert.SerializeObject(data), + SendExactSameData = sendExactSameData, + }; + if (headers != null) + { + input.Header = new WebhooksHeaderInput + { + UseOnlyGivenHeaders = headers.UseOnlyGivenHeaders, + Headers = headers.Headers + }; + } + + await PublishAsync(input); + } + + public async virtual Task PublishAsync(string webhookName, object data, Guid? tenantId, bool sendExactSameData = false, WebhookHeader headers = null) + { + var input = new WebhooksPublishInput + { + WebhookName = webhookName, + Data = JsonConvert.SerializeObject(data), + SendExactSameData = sendExactSameData, + TenantIds = new List + { + tenantId + }, + }; + if (headers != null) + { + input.Header = new WebhooksHeaderInput + { + UseOnlyGivenHeaders = headers.UseOnlyGivenHeaders, + Headers = headers.Headers + }; + } + + await PublishAsync(input); + } + + public async virtual Task PublishAsync(Guid?[] tenantIds, string webhookName, object data, bool sendExactSameData = false, WebhookHeader headers = null) + { + var input = new WebhooksPublishInput + { + WebhookName = webhookName, + Data = JsonConvert.SerializeObject(data), + SendExactSameData = sendExactSameData, + TenantIds = tenantIds.ToList(), + }; + if (headers != null) + { + input.Header = new WebhooksHeaderInput + { + UseOnlyGivenHeaders = headers.UseOnlyGivenHeaders, + Headers = headers.Headers + }; + } + + await PublishAsync(input); + } + + protected virtual async Task PublishAsync(WebhooksPublishInput input) + { + await PublishAppService.PublishAsync(input); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs index 5b2d38c71..176614535 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs @@ -33,28 +33,45 @@ namespace LINGYUN.Abp.Webhooks } #region Async Publish Methods - public virtual async Task PublishAsync(string webhookName, object data, bool sendExactSameData = false, WebhookHeader headers = null) + + public virtual async Task PublishAsync( + string webhookName, + object data, + bool sendExactSameData = false, + WebhookHeader headers = null) { var subscriptions = await _webhookSubscriptionManager.GetAllSubscriptionsIfFeaturesGrantedAsync(_currentTenant.Id, webhookName); await PublishAsync(webhookName, data, subscriptions, sendExactSameData, headers); } - public virtual async Task PublishAsync(string webhookName, object data, Guid? tenantId, - bool sendExactSameData = false, WebhookHeader headers = null) + public virtual async Task PublishAsync( + string webhookName, + object data, + Guid? tenantId, + bool sendExactSameData = false, + WebhookHeader headers = null) { var subscriptions = await _webhookSubscriptionManager.GetAllSubscriptionsIfFeaturesGrantedAsync(tenantId, webhookName); await PublishAsync(webhookName, data, subscriptions, sendExactSameData, headers); } - public virtual async Task PublishAsync(Guid?[] tenantIds, string webhookName, object data, - bool sendExactSameData = false, WebhookHeader headers = null) + public virtual async Task PublishAsync( + Guid?[] tenantIds, + string webhookName, + object data, + bool sendExactSameData = false, + WebhookHeader headers = null) { var subscriptions = await _webhookSubscriptionManager.GetAllSubscriptionsOfTenantsIfFeaturesGrantedAsync(tenantIds, webhookName); await PublishAsync(webhookName, data, subscriptions, sendExactSameData, headers); } - private async Task PublishAsync(string webhookName, object data, List webhookSubscriptions, - bool sendExactSameData = false, WebhookHeader headers = null) + protected virtual async Task PublishAsync( + string webhookName, + object data, + List webhookSubscriptions, + bool sendExactSameData = false, + WebhookHeader headers = null) { if (webhookSubscriptions.IsNullOrEmpty()) { @@ -104,7 +121,9 @@ namespace LINGYUN.Abp.Webhooks #endregion - protected virtual async Task SaveAndGetWebhookAsync(Guid? tenantId, string webhookName, + protected virtual async Task SaveAndGetWebhookAsync( + Guid? tenantId, + string webhookName, object data) { var webhookInfo = new WebhookEvent diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs index b9295955e..3570b8a63 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs @@ -10,6 +10,11 @@ public class WebhooksManagementPermissionDefinitionProvider : PermissionDefiniti { var group = context.AddGroup(WebhooksManagementPermissions.GroupName, L("Permission:WebhooksManagement")); + group.AddPermission( + WebhooksManagementPermissions.Publish, + L("Permission:Publish")) + .WithProviders(ClientPermissionValueProvider.ProviderName); + group.AddPermission( WebhooksManagementPermissions.ManageSettings, L("Permission:ManageSettings")); diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissions.cs index 0a1d9b0f7..307d94b49 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissions.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissions.cs @@ -4,5 +4,10 @@ public static class WebhooksManagementPermissions { public const string GroupName = "WebhooksManagement"; + /// + /// 授权允许发布Webhooks事件, 建议客户端授权 + /// + public const string Publish = GroupName + ".Publish"; + public const string ManageSettings = GroupName + ".ManageSettings"; } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksPublishAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksPublishAppService.cs new file mode 100644 index 000000000..b3236f244 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksPublishAppService.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; +using Volo.Abp.Application.Services; + +namespace LINGYUN.Abp.WebhooksManagement; + +public interface IWebhooksPublishAppService : IApplicationService +{ + Task PublishAsync(WebhooksPublishInput input); +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksManagementRemoteServiceConsts.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksManagementRemoteServiceConsts.cs index f05d02644..3d5a2b9f6 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksManagementRemoteServiceConsts.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksManagementRemoteServiceConsts.cs @@ -3,5 +3,5 @@ public static class WebhooksManagementRemoteServiceConsts { public const string RemoteServiceName = "WebhooksManagement"; - public const string ModuleName = "WebhooksManagement"; + public const string ModuleName = "webhooks-management"; } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksPublishInput.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksPublishInput.cs new file mode 100644 index 000000000..a7879d87f --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksPublishInput.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Validation; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhooksPublishInput +{ + [Required] + [DynamicStringLength(typeof(WebhookEventRecordConsts), nameof(WebhookEventRecordConsts.MaxWebhookNameLength))] + public string WebhookName { get; set; } + + [Required] + [DynamicStringLength(typeof(WebhookEventRecordConsts), nameof(WebhookEventRecordConsts.MaxDataLength))] + public string Data { get; set; } + + public bool SendExactSameData { get; set; } + + public WebhooksHeaderInput Header { get; set; } = new WebhooksHeaderInput(); + + public List TenantIds { get; set; } = new List(); +} + +public class WebhooksHeaderInput +{ + public bool UseOnlyGivenHeaders { get; set; } + + public IDictionary Headers { get; set; } = new Dictionary(); +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksPublishAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksPublishAppService.cs new file mode 100644 index 000000000..7e2bee65e --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksPublishAppService.cs @@ -0,0 +1,45 @@ +using LINGYUN.Abp.Webhooks; +using LINGYUN.Abp.WebhooksManagement.Authorization; +using Microsoft.AspNetCore.Authorization; +using Newtonsoft.Json; +using System.Linq; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.WebhooksManagement; + +[Authorize(WebhooksManagementPermissions.Publish)] +public class WebhooksPublishAppService : WebhooksManagementAppServiceBase, IWebhooksPublishAppService +{ + protected IWebhookPublisher InnerPublisher { get; } + + public WebhooksPublishAppService(IWebhookPublisher innerPublisher) + { + InnerPublisher = innerPublisher; + } + + public async virtual Task PublishAsync(WebhooksPublishInput input) + { + var webhookHeader = new WebhookHeader + { + UseOnlyGivenHeaders = input.Header.UseOnlyGivenHeaders, + Headers = input.Header.Headers, + }; + var inputData = JsonConvert.DeserializeObject(input.Data); + + if (input.TenantIds.Any()) + { + await InnerPublisher.PublishAsync( + input.TenantIds.ToArray(), + input.WebhookName, + inputData, + input.SendExactSameData, + webhookHeader); + return; + } + await InnerPublisher.PublishAsync( + input.WebhookName, + inputData, + input.SendExactSameData, + webhookHeader); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN.Abp.WebhooksManagement.Domain.csproj b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN.Abp.WebhooksManagement.Domain.csproj index 2ba7caa77..5234b20c6 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN.Abp.WebhooksManagement.Domain.csproj +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN.Abp.WebhooksManagement.Domain.csproj @@ -16,7 +16,7 @@ - + diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksPublishController.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksPublishController.cs new file mode 100644 index 000000000..e9b3275f9 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksPublishController.cs @@ -0,0 +1,27 @@ +using LINGYUN.Abp.WebhooksManagement.Authorization; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System.Threading.Tasks; +using Volo.Abp; + +namespace LINGYUN.Abp.WebhooksManagement; + +[RemoteService(Name = WebhooksManagementRemoteServiceConsts.RemoteServiceName)] +[Area(WebhooksManagementRemoteServiceConsts.ModuleName)] +[Authorize(WebhooksManagementPermissions.Publish)] +[Route("api/webhooks/publish")] +public class WebhooksPublishController : WebhooksManagementControllerBase, IWebhooksPublishAppService +{ + protected IWebhooksPublishAppService PublishAppService { get; } + + public WebhooksPublishController(IWebhooksPublishAppService publishAppService) + { + PublishAppService = publishAppService; + } + + [HttpPost] + public virtual Task PublishAsync(WebhooksPublishInput input) + { + return PublishAppService.PublishAsync(input); + } +} From 444ef0b563271e68c4b1553120949725757f382f Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Sat, 26 Mar 2022 13:34:28 +0800 Subject: [PATCH 05/17] perf(webhooks): renames the table prefix --- .../WebhooksManagementDbProperties.cs | 2 +- ...agementDbContextModelCreatingExtensions.cs | 6 ++--- ...dd-Module-WebHooks-Management.Designer.cs} | 8 +++--- ...6052244_Add-Module-WebHooks-Management.cs} | 26 +++++++++---------- ...agementMigrationsDbContextModelSnapshot.cs | 6 ++--- 5 files changed, 24 insertions(+), 24 deletions(-) rename aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/{20220326030345_Add-Module-WebHooks-Management.Designer.cs => 20220326052244_Add-Module-WebHooks-Management.Designer.cs} (92%) rename aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/{20220326030345_Add-Module-WebHooks-Management.cs => 20220326052244_Add-Module-WebHooks-Management.cs} (81%) diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDbProperties.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDbProperties.cs index 685cccb3e..33ddda08e 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDbProperties.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhooksManagementDbProperties.cs @@ -2,7 +2,7 @@ public static class WebhooksManagementDbProperties { - public static string DbTablePrefix { get; set; } = "WebhooksManagement_"; + public static string DbTablePrefix { get; set; } = "AbpWebhooks"; public static string DbSchema { get; set; } = null; diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs index 628ffd329..6b6080dbe 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs @@ -21,7 +21,7 @@ public static class WebhooksManagementDbContextModelCreatingExtensions builder.Entity(b => { - b.ToTable(options.TablePrefix + "WebhookEvents", options.Schema); + b.ToTable(options.TablePrefix + "Events", options.Schema); b.Property(p => p.WebhookName) .IsRequired() @@ -36,7 +36,7 @@ public static class WebhooksManagementDbContextModelCreatingExtensions builder.Entity(b => { - b.ToTable(options.TablePrefix + "WebhookSendAttempts", options.Schema); + b.ToTable(options.TablePrefix + "SendAttempts", options.Schema); b.Property(p => p.Response) .HasColumnName(nameof(WebhookSendRecord.Response)) @@ -52,7 +52,7 @@ public static class WebhooksManagementDbContextModelCreatingExtensions builder.Entity(b => { - b.ToTable(options.TablePrefix + "WebhookSubscriptions", options.Schema); + b.ToTable(options.TablePrefix + "Subscriptions", options.Schema); b.Property(p => p.WebhookUri) .IsRequired() diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326030345_Add-Module-WebHooks-Management.Designer.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326052244_Add-Module-WebHooks-Management.Designer.cs similarity index 92% rename from aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326030345_Add-Module-WebHooks-Management.Designer.cs rename to aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326052244_Add-Module-WebHooks-Management.Designer.cs index bdf69d7be..51f1c05d3 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326030345_Add-Module-WebHooks-Management.Designer.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326052244_Add-Module-WebHooks-Management.Designer.cs @@ -12,7 +12,7 @@ using Volo.Abp.EntityFrameworkCore; namespace LY.MicroService.WebhooksManagement.Migrations { [DbContext(typeof(WebhooksManagementMigrationsDbContext))] - [Migration("20220326030345_Add-Module-WebHooks-Management")] + [Migration("20220326052244_Add-Module-WebHooks-Management")] partial class AddModuleWebHooksManagement { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -60,7 +60,7 @@ namespace LY.MicroService.WebhooksManagement.Migrations b.HasKey("Id"); - b.ToTable("WebhooksManagement_WebhookEvents", (string)null); + b.ToTable("AbpWebhooksEvents", (string)null); }); modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookSendRecord", b => @@ -100,7 +100,7 @@ namespace LY.MicroService.WebhooksManagement.Migrations b.HasIndex("WebhookEventId") .IsUnique(); - b.ToTable("WebhooksManagement_WebhookSendAttempts", (string)null); + b.ToTable("AbpWebhooksSendAttempts", (string)null); }); modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookSubscription", b => @@ -147,7 +147,7 @@ namespace LY.MicroService.WebhooksManagement.Migrations b.HasKey("Id"); - b.ToTable("WebhooksManagement_WebhookSubscriptions", (string)null); + b.ToTable("AbpWebhooksSubscriptions", (string)null); }); modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookSendRecord", b => diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326030345_Add-Module-WebHooks-Management.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326052244_Add-Module-WebHooks-Management.cs similarity index 81% rename from aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326030345_Add-Module-WebHooks-Management.cs rename to aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326052244_Add-Module-WebHooks-Management.cs index ca7fd42f9..e2065582a 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326030345_Add-Module-WebHooks-Management.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326052244_Add-Module-WebHooks-Management.cs @@ -13,7 +13,7 @@ namespace LY.MicroService.WebhooksManagement.Migrations .Annotation("MySql:CharSet", "utf8mb4"); migrationBuilder.CreateTable( - name: "WebhooksManagement_WebhookEvents", + name: "AbpWebhooksEvents", columns: table => new { Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), @@ -28,12 +28,12 @@ namespace LY.MicroService.WebhooksManagement.Migrations }, constraints: table => { - table.PrimaryKey("PK_WebhooksManagement_WebhookEvents", x => x.Id); + table.PrimaryKey("PK_AbpWebhooksEvents", x => x.Id); }) .Annotation("MySql:CharSet", "utf8mb4"); migrationBuilder.CreateTable( - name: "WebhooksManagement_WebhookSubscriptions", + name: "AbpWebhooksSubscriptions", columns: table => new { Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), @@ -52,12 +52,12 @@ namespace LY.MicroService.WebhooksManagement.Migrations }, constraints: table => { - table.PrimaryKey("PK_WebhooksManagement_WebhookSubscriptions", x => x.Id); + table.PrimaryKey("PK_AbpWebhooksSubscriptions", x => x.Id); }) .Annotation("MySql:CharSet", "utf8mb4"); migrationBuilder.CreateTable( - name: "WebhooksManagement_WebhookSendAttempts", + name: "AbpWebhooksSendAttempts", columns: table => new { Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), @@ -72,19 +72,19 @@ namespace LY.MicroService.WebhooksManagement.Migrations }, constraints: table => { - table.PrimaryKey("PK_WebhooksManagement_WebhookSendAttempts", x => x.Id); + table.PrimaryKey("PK_AbpWebhooksSendAttempts", x => x.Id); table.ForeignKey( - name: "FK_WebhooksManagement_WebhookSendAttempts_WebhooksManagement_We~", + name: "FK_AbpWebhooksSendAttempts_AbpWebhooksEvents_WebhookEventId", column: x => x.WebhookEventId, - principalTable: "WebhooksManagement_WebhookEvents", + principalTable: "AbpWebhooksEvents", principalColumn: "Id", onDelete: ReferentialAction.Cascade); }) .Annotation("MySql:CharSet", "utf8mb4"); migrationBuilder.CreateIndex( - name: "IX_WebhooksManagement_WebhookSendAttempts_WebhookEventId", - table: "WebhooksManagement_WebhookSendAttempts", + name: "IX_AbpWebhooksSendAttempts_WebhookEventId", + table: "AbpWebhooksSendAttempts", column: "WebhookEventId", unique: true); } @@ -92,13 +92,13 @@ namespace LY.MicroService.WebhooksManagement.Migrations protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable( - name: "WebhooksManagement_WebhookSendAttempts"); + name: "AbpWebhooksSendAttempts"); migrationBuilder.DropTable( - name: "WebhooksManagement_WebhookSubscriptions"); + name: "AbpWebhooksSubscriptions"); migrationBuilder.DropTable( - name: "WebhooksManagement_WebhookEvents"); + name: "AbpWebhooksEvents"); } } } diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/WebhooksManagementMigrationsDbContextModelSnapshot.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/WebhooksManagementMigrationsDbContextModelSnapshot.cs index 966262d85..aeb9e8c96 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/WebhooksManagementMigrationsDbContextModelSnapshot.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/WebhooksManagementMigrationsDbContextModelSnapshot.cs @@ -58,7 +58,7 @@ namespace LY.MicroService.WebhooksManagement.Migrations b.HasKey("Id"); - b.ToTable("WebhooksManagement_WebhookEvents", (string)null); + b.ToTable("AbpWebhooksEvents", (string)null); }); modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookSendRecord", b => @@ -98,7 +98,7 @@ namespace LY.MicroService.WebhooksManagement.Migrations b.HasIndex("WebhookEventId") .IsUnique(); - b.ToTable("WebhooksManagement_WebhookSendAttempts", (string)null); + b.ToTable("AbpWebhooksSendAttempts", (string)null); }); modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookSubscription", b => @@ -145,7 +145,7 @@ namespace LY.MicroService.WebhooksManagement.Migrations b.HasKey("Id"); - b.ToTable("WebhooksManagement_WebhookSubscriptions", (string)null); + b.ToTable("AbpWebhooksSubscriptions", (string)null); }); modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookSendRecord", b => From 68009f37ab236f0e05e76a62c135685def6048a5 Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Sat, 26 Mar 2022 15:09:21 +0800 Subject: [PATCH 06/17] fix: remove the unique constraint for foreign keys --- .../LINGYUN.Abp.WebHooks.csproj | 2 +- .../LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs | 28 +++++++++++++-- .../Abp/Webhooks/DefaultWebhookPublisher.cs | 8 +++-- .../Abp/Webhooks/DefaultWebhookSender.cs | 3 +- .../Webhooks/WebhookSubscriptionManager.cs | 3 +- .../Localization/Resources/en.json | 4 ++- .../Localization/Resources/zh-Hans.json | 4 ++- .../DefaultWebhookManager.cs | 36 ++++++++----------- .../WebhookSubscriptionsStore.cs | 25 +++++++------ .../Webhooks/WebhooksDefinitionProvider.cs | 22 ++++++++++++ .../Webhooks/WebhooksNames.cs | 6 ++++ ...agementDbContextModelCreatingExtensions.cs | 3 ++ ...dd-Module-WebHooks-Management.Designer.cs} | 5 ++- ...6064231_Add-Module-WebHooks-Management.cs} | 3 +- ...agementMigrationsDbContextModelSnapshot.cs | 3 +- ...ksManagementHttpApiHostModule.Configure.cs | 7 +++- .../WebhooksManagementHttpApiHostModule.cs | 2 +- 17 files changed, 113 insertions(+), 51 deletions(-) create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksDefinitionProvider.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksNames.cs rename aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/{20220326052244_Add-Module-WebHooks-Management.Designer.cs => 20220326064231_Add-Module-WebHooks-Management.Designer.cs} (95%) rename aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/{20220326052244_Add-Module-WebHooks-Management.cs => 20220326064231_Add-Module-WebHooks-Management.cs} (96%) diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN.Abp.WebHooks.csproj b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN.Abp.WebHooks.csproj index ca6031c7a..2cd64673f 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN.Abp.WebHooks.csproj +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN.Abp.WebHooks.csproj @@ -9,7 +9,7 @@ - + diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs index 03af8e4ef..deabfcd79 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs @@ -1,4 +1,7 @@ -using Volo.Abp.BackgroundJobs; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using Volo.Abp.BackgroundJobs; using Volo.Abp.Features; using Volo.Abp.Guids; using Volo.Abp.Http.Client; @@ -6,7 +9,9 @@ using Volo.Abp.Modularity; namespace LINGYUN.Abp.Webhooks; -[DependsOn(typeof(AbpBackgroundJobsAbstractionsModule))] +//[DependsOn(typeof(AbpBackgroundJobsAbstractionsModule))] +// 防止未引用实现无法发布到后台作业 +[DependsOn(typeof(AbpBackgroundJobsModule))] [DependsOn(typeof(AbpFeaturesModule))] [DependsOn(typeof(AbpGuidsModule))] [DependsOn(typeof(AbpHttpClientModule))] @@ -14,5 +19,24 @@ public class AbpWebhooksModule : AbpModule { public override void PreConfigureServices(ServiceConfigurationContext context) { + AutoAddDefinitionProviders(context.Services); + } + + private static void AutoAddDefinitionProviders(IServiceCollection services) + { + var definitionProviders = new List(); + + services.OnRegistred(context => + { + if (typeof(WebhookDefinitionProvider).IsAssignableFrom(context.ImplementationType)) + { + definitionProviders.Add(context.ImplementationType); + } + }); + + services.Configure(options => + { + options.DefinitionProviders.AddIfNotContains(definitionProviders); + }); } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs index 176614535..59ed0b102 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs @@ -6,10 +6,11 @@ using System.Threading.Tasks; using Volo.Abp.BackgroundJobs; using Volo.Abp.Guids; using Volo.Abp.MultiTenancy; +using Volo.Abp.DependencyInjection; namespace LINGYUN.Abp.Webhooks { - public class DefaultWebhookPublisher : IWebhookPublisher + public class DefaultWebhookPublisher : IWebhookPublisher, ITransientDependency { public IWebhookEventStore WebhookEventStore { get; set; } @@ -128,13 +129,14 @@ namespace LINGYUN.Abp.Webhooks { var webhookInfo = new WebhookEvent { - Id = _guidGenerator.Create(), WebhookName = webhookName, Data = JsonConvert.SerializeObject(data), TenantId = tenantId }; - await WebhookEventStore.InsertAndGetIdAsync(webhookInfo); + var webhookId = await WebhookEventStore.InsertAndGetIdAsync(webhookInfo); + webhookInfo.Id = webhookId; + return webhookInfo; } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs index 2dc939dc7..29ce6cb96 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs @@ -5,10 +5,11 @@ using System; using System.Net; using System.Net.Http; using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; namespace LINGYUN.Abp.Webhooks { - public class DefaultWebhookSender : IWebhookSender + public class DefaultWebhookSender : IWebhookSender, ITransientDependency { public ILogger Logger { protected get; set; } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionManager.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionManager.cs index 9db42f506..fe1a9c697 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionManager.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSubscriptionManager.cs @@ -3,12 +3,13 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Volo.Abp.Authorization; +using Volo.Abp.DependencyInjection; using Volo.Abp.Guids; using Volo.Abp.Uow; namespace LINGYUN.Abp.Webhooks { - public class WebhookSubscriptionManager : IWebhookSubscriptionManager + public class WebhookSubscriptionManager : IWebhookSubscriptionManager, ITransientDependency { public IWebhookSubscriptionsStore WebhookSubscriptionsStore { get; set; } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json index 653188d9b..5e4cfe7f2 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json @@ -3,6 +3,8 @@ "texts": { "Features:WebhooksManagement": "Webhooks", "Permission:WebhooksManagement": "Webhooks", - "Permission:ManageSettings": "Manage Settings" + "Permission:ManageSettings": "Manage Settings", + "DisplayName:CheckConnect": "Check Connect", + "Description:CheckConnect": "When a third-party service is connected, it is used to check whether the communication is normal." } } \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json index bfcd4d2a2..bd1941dd4 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json @@ -3,6 +3,8 @@ "texts": { "Features:WebhooksManagement": "Webhooks", "Permission:WebhooksManagement": "Webhooks", - "Permission:ManageSettings": "管理设置" + "Permission:ManageSettings": "管理设置", + "DisplayName:CheckConnect": "检查连接", + "Description:CheckConnect": "第三方服务接入时,用于检查是否通讯正常." } } \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/DefaultWebhookManager.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/DefaultWebhookManager.cs index 8b8b56129..c0ab03de1 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/DefaultWebhookManager.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/DefaultWebhookManager.cs @@ -29,40 +29,32 @@ public class DefaultWebhookManager : WebhookManager, ITransientDependency WebhookSendAttemptRepository = webhookSendAttemptRepository; } + [UnitOfWork] public async override Task InsertAndGetIdWebhookSendAttemptAsync(WebhookSenderArgs webhookSenderArgs) { - using (var uow = UnitOfWorkManager.Begin()) + using (CurrentTenant.Change(webhookSenderArgs.TenantId)) { - using (CurrentTenant.Change(webhookSenderArgs.TenantId)) - { - var record = new WebhookSendRecord( - GuidGenerator.Create(), - webhookSenderArgs.WebhookEventId, - webhookSenderArgs.WebhookSubscriptionId, - webhookSenderArgs.TenantId); + var record = new WebhookSendRecord( + GuidGenerator.Create(), + webhookSenderArgs.WebhookEventId, + webhookSenderArgs.WebhookSubscriptionId, + webhookSenderArgs.TenantId); - await WebhookSendAttemptRepository.InsertAsync(record); + await WebhookSendAttemptRepository.InsertAsync(record); - await uow.SaveChangesAsync(); - - return record.Id; - } + return record.Id; } } + [UnitOfWork] public async override Task StoreResponseOnWebhookSendAttemptAsync(Guid webhookSendAttemptId, Guid? tenantId, HttpStatusCode? statusCode, string content) { - using (var uow = UnitOfWorkManager.Begin()) + using (CurrentTenant.Change(tenantId)) { - using (CurrentTenant.Change(tenantId)) - { - var record = await WebhookSendAttemptRepository.GetAsync(webhookSendAttemptId); - record.SetResponse(content, statusCode); - - await WebhookSendAttemptRepository.UpdateAsync(record); + var record = await WebhookSendAttemptRepository.GetAsync(webhookSendAttemptId); + record.SetResponse(content, statusCode); - await uow.SaveChangesAsync(); - } + await WebhookSendAttemptRepository.UpdateAsync(record); } } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionsStore.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionsStore.cs index c25467ef6..fb14c7bae 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionsStore.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionsStore.cs @@ -36,7 +36,9 @@ public class WebhookSubscriptionsStore : DomainService, IWebhookSubscriptionsSto { var queryable = await SubscriptionRepository.GetQueryableAsync(); - var subscriptions = await AsyncExecuter.ToListAsync(queryable.Where(x => x.TenantId == tenantId)); + queryable = queryable.Where(x => x.TenantId == tenantId); + + var subscriptions = await AsyncExecuter.ToListAsync(queryable); return subscriptions.Select(subscription => subscription.ToWebhookSubscriptionInfo()).ToList(); } @@ -49,11 +51,12 @@ public class WebhookSubscriptionsStore : DomainService, IWebhookSubscriptionsSto { var queryable = await SubscriptionRepository.GetQueryableAsync(); - var subscriptions = await AsyncExecuter.ToListAsync( - queryable.Where(x => + queryable = queryable.Where(x => x.TenantId == tenantId && x.IsActive && - x.Webhooks.Contains("\"" + webhookName + "\""))); + x.Webhooks.Contains("\"" + webhookName + "\"")); + + var subscriptions = await AsyncExecuter.ToListAsync(queryable); return subscriptions.Select(subscription => subscription.ToWebhookSubscriptionInfo()).ToList(); } @@ -79,11 +82,12 @@ public class WebhookSubscriptionsStore : DomainService, IWebhookSubscriptionsSto { var queryable = await SubscriptionRepository.GetQueryableAsync(); - var subscriptions = await AsyncExecuter.ToListAsync( - queryable.Where(x => + queryable = queryable.Where(x => x.IsActive && tenantIds.Contains(x.TenantId) && - x.Webhooks.Contains("\"" + webhookName + "\""))); + x.Webhooks.Contains("\"" + webhookName + "\"")); + + var subscriptions = await AsyncExecuter.ToListAsync(queryable); return subscriptions.Select(subscription => subscription.ToWebhookSubscriptionInfo()).ToList(); } @@ -124,11 +128,12 @@ public class WebhookSubscriptionsStore : DomainService, IWebhookSubscriptionsSto { var queryable = await SubscriptionRepository.GetQueryableAsync(); - return await AsyncExecuter.AnyAsync( - queryable.Where(x => + queryable = queryable.Where(x => x.TenantId == tenantId && x.IsActive && - x.Webhooks.Contains("\"" + webhookName + "\""))); + x.Webhooks.Contains("\"" + webhookName + "\"")); + + return await AsyncExecuter.AnyAsync(queryable); } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksDefinitionProvider.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksDefinitionProvider.cs new file mode 100644 index 000000000..9b5e7ce48 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksDefinitionProvider.cs @@ -0,0 +1,22 @@ +using LINGYUN.Abp.Webhooks; +using LINGYUN.Abp.WebhooksManagement.Localization; +using Volo.Abp.Localization; + +namespace LINGYUN.Abp.WebhooksManagement.Webhooks; + +public class WebhooksDefinitionProvider : WebhookDefinitionProvider +{ + public override void Define(IWebhookDefinitionContext context) + { + context.Add( + new WebhookDefinition( + WebhooksNames.CheckConnect, + L("DisplayName:CheckConnect"), + L("Description:CheckConnect"))); + } + + private static ILocalizableString L(string name) + { + return LocalizableString.Create(name); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksNames.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksNames.cs new file mode 100644 index 000000000..8b185a686 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksNames.cs @@ -0,0 +1,6 @@ +namespace LINGYUN.Abp.WebhooksManagement.Webhooks; + +public static class WebhooksNames +{ + public const string CheckConnect = "Abp.Webhooks.CheckConnect"; +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs index 6b6080dbe..a7b9a96e7 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs @@ -48,6 +48,9 @@ public static class WebhooksManagementDbContextModelCreatingExtensions .WithOne() .HasForeignKey(fk => fk.WebhookEventId) .HasPrincipalKey(pk => pk.Id ); + + b.HasIndex(p => p.WebhookEventId) + .IsUnique(false); }); builder.Entity(b => diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326052244_Add-Module-WebHooks-Management.Designer.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326064231_Add-Module-WebHooks-Management.Designer.cs similarity index 95% rename from aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326052244_Add-Module-WebHooks-Management.Designer.cs rename to aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326064231_Add-Module-WebHooks-Management.Designer.cs index 51f1c05d3..1da62c921 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326052244_Add-Module-WebHooks-Management.Designer.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326064231_Add-Module-WebHooks-Management.Designer.cs @@ -12,7 +12,7 @@ using Volo.Abp.EntityFrameworkCore; namespace LY.MicroService.WebhooksManagement.Migrations { [DbContext(typeof(WebhooksManagementMigrationsDbContext))] - [Migration("20220326052244_Add-Module-WebHooks-Management")] + [Migration("20220326064231_Add-Module-WebHooks-Management")] partial class AddModuleWebHooksManagement { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -97,8 +97,7 @@ namespace LY.MicroService.WebhooksManagement.Migrations b.HasKey("Id"); - b.HasIndex("WebhookEventId") - .IsUnique(); + b.HasIndex("WebhookEventId"); b.ToTable("AbpWebhooksSendAttempts", (string)null); }); diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326052244_Add-Module-WebHooks-Management.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326064231_Add-Module-WebHooks-Management.cs similarity index 96% rename from aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326052244_Add-Module-WebHooks-Management.cs rename to aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326064231_Add-Module-WebHooks-Management.cs index e2065582a..e11276c96 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326052244_Add-Module-WebHooks-Management.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220326064231_Add-Module-WebHooks-Management.cs @@ -85,8 +85,7 @@ namespace LY.MicroService.WebhooksManagement.Migrations migrationBuilder.CreateIndex( name: "IX_AbpWebhooksSendAttempts_WebhookEventId", table: "AbpWebhooksSendAttempts", - column: "WebhookEventId", - unique: true); + column: "WebhookEventId"); } protected override void Down(MigrationBuilder migrationBuilder) diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/WebhooksManagementMigrationsDbContextModelSnapshot.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/WebhooksManagementMigrationsDbContextModelSnapshot.cs index aeb9e8c96..6acaca8a1 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/WebhooksManagementMigrationsDbContextModelSnapshot.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/WebhooksManagementMigrationsDbContextModelSnapshot.cs @@ -95,8 +95,7 @@ namespace LY.MicroService.WebhooksManagement.Migrations b.HasKey("Id"); - b.HasIndex("WebhookEventId") - .IsUnique(); + b.HasIndex("WebhookEventId"); b.ToTable("AbpWebhooksSendAttempts", (string)null); }); diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs index be2cbca09..72ff2bbef 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs @@ -81,7 +81,12 @@ public partial class WebhooksManagementHttpApiHostModule // 配置Ef Configure(options => { - options.UseMySQL(); + //options.UseMySQL(); + options.Configure(cfg => + { + cfg.UseMySQL(); + cfg.DbContextOptions.EnableSensitiveDataLogging(); + }); }); } diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs index ec561d610..cd3d2e9be 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs @@ -86,7 +86,7 @@ public partial class WebhooksManagementHttpApiHostModule : AbpModule ConfigureSeedWorker(context.Services, hostingEnvironment.IsDevelopment()); ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); - // context.Services.AddAlwaysAllowAuthorization(); + context.Services.AddAlwaysAllowAuthorization(); } public override void OnApplicationInitialization(ApplicationInitializationContext context) From 8fa525360101ea0f2ff3ff8e0cd05fced9e9b56c Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Sat, 26 Mar 2022 15:21:56 +0800 Subject: [PATCH 07/17] perf: users can customize the number of Webhook send count --- .../BackgroundWorker/WebhookSenderJob.cs | 18 ++++++++++++------ .../Abp/Webhooks/DefaultWebhookPublisher.cs | 5 +---- .../LINGYUN/Abp/Webhooks/WebhookDefinition.cs | 10 ++++++++++ .../LINGYUN/Abp/Webhooks/WebhookSenderArgs.cs | 5 ----- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/BackgroundWorker/WebhookSenderJob.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/BackgroundWorker/WebhookSenderJob.cs index 4d18cb209..b411e3a84 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/BackgroundWorker/WebhookSenderJob.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/BackgroundWorker/WebhookSenderJob.cs @@ -11,6 +11,7 @@ namespace LINGYUN.Abp.Webhooks.BackgroundWorker public class WebhookSenderJob : AsyncBackgroundJob, ITransientDependency { private readonly IUnitOfWorkManager _unitOfWorkManager; + private readonly IWebhookDefinitionManager _webhookDefinitionManager; private readonly IWebhookSubscriptionManager _webhookSubscriptionManager; private readonly IWebhookSendAttemptStore _webhookSendAttemptStore; private readonly IWebhookSender _webhookSender; @@ -19,12 +20,14 @@ namespace LINGYUN.Abp.Webhooks.BackgroundWorker public WebhookSenderJob( IUnitOfWorkManager unitOfWorkManager, + IWebhookDefinitionManager webhookDefinitionManager, IWebhookSubscriptionManager webhookSubscriptionManager, IWebhookSendAttemptStore webhookSendAttemptStore, IWebhookSender webhookSender, IOptions options) { _unitOfWorkManager = unitOfWorkManager; + _webhookDefinitionManager = webhookDefinitionManager; _webhookSubscriptionManager = webhookSubscriptionManager; _webhookSendAttemptStore = webhookSendAttemptStore; _webhookSender = webhookSender; @@ -33,11 +36,13 @@ namespace LINGYUN.Abp.Webhooks.BackgroundWorker public override async Task ExecuteAsync(WebhookSenderArgs args) { - if (args.TryOnce) + var webhookDefinition = _webhookDefinitionManager.Get(args.WebhookName); + + if (webhookDefinition.TryOnce) { try { - await SendWebhook(args); + await SendWebhook(args, webhookDefinition); } catch (Exception e) { @@ -47,11 +52,11 @@ namespace LINGYUN.Abp.Webhooks.BackgroundWorker } else { - await SendWebhook(args); + await SendWebhook(args, webhookDefinition); } } - private async Task SendWebhook(WebhookSenderArgs args) + private async Task SendWebhook(WebhookSenderArgs args, WebhookDefinition webhookDefinition) { if (args.WebhookEventId == default) { @@ -63,7 +68,7 @@ namespace LINGYUN.Abp.Webhooks.BackgroundWorker return; } - if (!args.TryOnce) + if (!webhookDefinition.TryOnce) { var sendAttemptCount = await _webhookSendAttemptStore.GetSendAttemptCountAsync( args.TenantId, @@ -71,7 +76,8 @@ namespace LINGYUN.Abp.Webhooks.BackgroundWorker args.WebhookSubscriptionId ); - if (sendAttemptCount > _options.MaxSendAttemptCount) + if ((webhookDefinition.MaxSendAttemptCount > 0 && sendAttemptCount > webhookDefinition.MaxSendAttemptCount) || + sendAttemptCount > _options.MaxSendAttemptCount) { return; } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs index 59ed0b102..be46197ae 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookPublisher.cs @@ -15,18 +15,15 @@ namespace LINGYUN.Abp.Webhooks public IWebhookEventStore WebhookEventStore { get; set; } private readonly ICurrentTenant _currentTenant; - private readonly IGuidGenerator _guidGenerator; private readonly IBackgroundJobManager _backgroundJobManager; private readonly IWebhookSubscriptionManager _webhookSubscriptionManager; public DefaultWebhookPublisher( IWebhookSubscriptionManager webhookSubscriptionManager, ICurrentTenant currentTenant, - IGuidGenerator guidGenerator, IBackgroundJobManager backgroundJobManager) { _currentTenant = currentTenant; - _guidGenerator = guidGenerator; _backgroundJobManager = backgroundJobManager; _webhookSubscriptionManager = webhookSubscriptionManager; @@ -103,7 +100,7 @@ namespace LINGYUN.Abp.Webhooks } } } - + await _backgroundJobManager.EnqueueAsync(new WebhookSenderArgs { TenantId = webhookSubscription.TenantId, diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinition.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinition.cs index 88f3a074d..1c1461e8a 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinition.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinition.cs @@ -11,6 +11,16 @@ namespace LINGYUN.Abp.Webhooks /// public string Name { get; } + /// + /// Tries to send webhook only one time without checking to send attempt count + /// + public bool TryOnce { get; set; } + + /// + /// Defined maximum number of sending times + /// + public int MaxSendAttemptCount { get; set; } + /// /// Display name of the webhook. /// Optional. diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSenderArgs.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSenderArgs.cs index 7910ba0b1..cb30acbf9 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSenderArgs.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookSenderArgs.cs @@ -46,11 +46,6 @@ namespace LINGYUN.Abp.Webhooks /// public IDictionary Headers { get; set; } - /// - /// Tries to send webhook only one time without checking to send attempt count - /// - public bool TryOnce { get; set; } - /// /// True: It sends the exact same data as the parameter to clients. /// From b64e10a9326743ddf22dab7e23da35738a1e20fe Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Sat, 26 Mar 2022 15:29:54 +0800 Subject: [PATCH 08/17] perf: Use IHttpClientFactory instead of HttpClient --- .../LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs | 12 ++++++++++ .../Abp/Webhooks/AbpWebhooksOptions.cs | 15 +++++++++--- .../Abp/Webhooks/DefaultWebhookSender.cs | 23 +++++++++---------- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs index deabfcd79..768eacd41 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs @@ -17,11 +17,23 @@ namespace LINGYUN.Abp.Webhooks; [DependsOn(typeof(AbpHttpClientModule))] public class AbpWebhooksModule : AbpModule { + internal const string WebhooksClient = "Abp.Webhooks.HttpClient"; + public override void PreConfigureServices(ServiceConfigurationContext context) { AutoAddDefinitionProviders(context.Services); } + public override void ConfigureServices(ServiceConfigurationContext context) + { + var options = context.Services.ExecutePreConfiguredActions(); + + context.Services.AddHttpClient(WebhooksClient, client => + { + client.Timeout = options.TimeoutDuration; + }); + } + private static void AutoAddDefinitionProviders(IServiceCollection services) { var definitionProviders = new List(); diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksOptions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksOptions.cs index 7ac2ec457..072a76bcc 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksOptions.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksOptions.cs @@ -5,12 +5,21 @@ namespace LINGYUN.Abp.Webhooks; public class AbpWebhooksOptions { + /// + /// 默认超时时间 + /// public TimeSpan TimeoutDuration { get; set; } - + /// + /// 默认最大发送次数 + /// public int MaxSendAttemptCount { get; set; } - + /// + /// 是否达到最大连续失败次数时自动取消订阅 + /// public bool IsAutomaticSubscriptionDeactivationEnabled { get; set; } - + /// + /// 取消订阅前最大连续失败次数 + /// public int MaxConsecutiveFailCountBeforeDeactivateSubscription { get; set; } public ITypeList DefinitionProviders { get; } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs index 29ce6cb96..d400800bf 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs @@ -15,15 +15,18 @@ namespace LINGYUN.Abp.Webhooks private readonly AbpWebhooksOptions _options; private readonly IWebhookManager _webhookManager; + private readonly IHttpClientFactory _httpClientFactory; private const string FailedRequestDefaultContent = "Webhook Send Request Failed"; public DefaultWebhookSender( IOptions options, - IWebhookManager webhookManager) + IWebhookManager webhookManager, + IHttpClientFactory httpClientFactory) { _options = options.Value; _webhookManager = webhookManager; + _httpClientFactory = httpClientFactory; Logger = NullLogger.Instance; } @@ -116,19 +119,15 @@ namespace LINGYUN.Abp.Webhooks protected virtual async Task<(bool isSucceed, HttpStatusCode statusCode, string content)> SendHttpRequest(HttpRequestMessage request) { - using (var client = new HttpClient - { - Timeout = _options.TimeoutDuration - }) - { - var response = await client.SendAsync(request); + var client = _httpClientFactory.CreateClient(AbpWebhooksModule.WebhooksClient); - var isSucceed = response.IsSuccessStatusCode; - var statusCode = response.StatusCode; - var content = await response.Content.ReadAsStringAsync(); + var response = await client.SendAsync(request); - return (isSucceed, statusCode, content); - } + var isSucceed = response.IsSuccessStatusCode; + var statusCode = response.StatusCode; + var content = await response.Content.ReadAsStringAsync(); + + return (isSucceed, statusCode, content); } } } From 911373db05fc013de7ba89b08b5e08aeeb4e67d4 Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Sat, 26 Mar 2022 16:35:50 +0800 Subject: [PATCH 09/17] feat: added subscription api --- .../LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs | 2 +- .../Abp/Webhooks/DefaultWebhookSender.cs | 4 - ...sManagementPermissionDefinitionProvider.cs | 22 ++++ .../WebhooksManagementPermissions.cs | 10 +- .../IWebhookSubscriptionAppService.cs | 14 +++ .../WebhookSubscriptionCreateOrUpdateInput.cs | 32 +++++ .../WebhookSubscriptionDto.cs | 15 +++ .../WebhookSubscriptionGetListInput.cs | 26 ++++ .../WebhookSubscriptionExtensions.cs | 44 +++++++ .../WebhookSubscriptionAppService.cs | 111 ++++++++++++++++++ .../Localization/Resources/en.json | 3 +- .../Localization/Resources/zh-Hans.json | 3 +- .../WebhooksManagementErrorCodes.cs | 9 +- .../IWebhookSubscriptionRepository.cs | 19 +++ .../WebhookSubscriptionFilter.cs | 22 ++++ .../EfCoreWebhookSubscriptionRepository.cs | 58 ++++++++- .../WebhookSubscriptionController.cs | 59 ++++++++++ 17 files changed, 443 insertions(+), 10 deletions(-) create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionAppService.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionCreateOrUpdateInput.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionDto.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionGetListInput.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/Extensions/WebhookSubscriptionExtensions.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionAppService.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionFilter.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionController.cs diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs index 768eacd41..84798d8d2 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs @@ -17,7 +17,7 @@ namespace LINGYUN.Abp.Webhooks; [DependsOn(typeof(AbpHttpClientModule))] public class AbpWebhooksModule : AbpModule { - internal const string WebhooksClient = "Abp.Webhooks.HttpClient"; + internal const string WebhooksClient = "__Abp_Webhooks_HttpClient"; public override void PreConfigureServices(ServiceConfigurationContext context) { diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs index d400800bf..19982a68e 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs @@ -1,6 +1,5 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; -using Microsoft.Extensions.Options; using System; using System.Net; using System.Net.Http; @@ -13,18 +12,15 @@ namespace LINGYUN.Abp.Webhooks { public ILogger Logger { protected get; set; } - private readonly AbpWebhooksOptions _options; private readonly IWebhookManager _webhookManager; private readonly IHttpClientFactory _httpClientFactory; private const string FailedRequestDefaultContent = "Webhook Send Request Failed"; public DefaultWebhookSender( - IOptions options, IWebhookManager webhookManager, IHttpClientFactory httpClientFactory) { - _options = options.Value; _webhookManager = webhookManager; _httpClientFactory = httpClientFactory; diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs index 3570b8a63..3af3d870a 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs @@ -1,6 +1,7 @@ using LINGYUN.Abp.WebhooksManagement.Localization; using Volo.Abp.Authorization.Permissions; using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; namespace LINGYUN.Abp.WebhooksManagement.Authorization; @@ -10,6 +11,27 @@ public class WebhooksManagementPermissionDefinitionProvider : PermissionDefiniti { var group = context.AddGroup(WebhooksManagementPermissions.GroupName, L("Permission:WebhooksManagement")); + var subscription = group.AddPermission( + WebhooksManagementPermissions.WebhookSubscription.Default, + L("Permission:Subscriptions"), + MultiTenancySides.Host) + .WithProviders(ClientPermissionValueProvider.ProviderName); + subscription.AddChild( + WebhooksManagementPermissions.WebhookSubscription.Create, + L("Permission:Create"), + MultiTenancySides.Host) + .WithProviders(ClientPermissionValueProvider.ProviderName); + subscription.AddChild( + WebhooksManagementPermissions.WebhookSubscription.Update, + L("Permission:Update"), + MultiTenancySides.Host) + .WithProviders(ClientPermissionValueProvider.ProviderName); + subscription.AddChild( + WebhooksManagementPermissions.WebhookSubscription.Delete, + L("Permission:Delete"), + MultiTenancySides.Host) + .WithProviders(ClientPermissionValueProvider.ProviderName); + group.AddPermission( WebhooksManagementPermissions.Publish, L("Permission:Publish")) diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissions.cs index 307d94b49..bdabbfa8c 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissions.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissions.cs @@ -2,7 +2,7 @@ public static class WebhooksManagementPermissions { - public const string GroupName = "WebhooksManagement"; + public const string GroupName = "AbpWebhooks"; /// /// 授权允许发布Webhooks事件, 建议客户端授权 @@ -10,4 +10,12 @@ public static class WebhooksManagementPermissions public const string Publish = GroupName + ".Publish"; public const string ManageSettings = GroupName + ".ManageSettings"; + + public static class WebhookSubscription + { + public const string Default = GroupName + ".Subscriptions"; + public const string Create = Default + ".Create"; + public const string Update = Default + ".Update"; + public const string Delete = Default + ".Delete"; + } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionAppService.cs new file mode 100644 index 000000000..f25ede15b --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionAppService.cs @@ -0,0 +1,14 @@ +using System; +using Volo.Abp.Application.Services; + +namespace LINGYUN.Abp.WebhooksManagement; + +public interface IWebhookSubscriptionAppService : + ICrudAppService< + WebhookSubscriptionDto, + Guid, + WebhookSubscriptionGetListInput, + WebhookSubscriptionCreateInput, + WebhookSubscriptionUpdateInput> +{ +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionCreateOrUpdateInput.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionCreateOrUpdateInput.cs new file mode 100644 index 000000000..94897417d --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionCreateOrUpdateInput.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Validation; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhookSubscriptionCreateInput : WebhookSubscriptionCreateOrUpdateInput +{ + +} + +public class WebhookSubscriptionUpdateInput : WebhookSubscriptionCreateOrUpdateInput +{ + +} + +public abstract class WebhookSubscriptionCreateOrUpdateInput +{ + [Required] + [DynamicStringLength(typeof(WebhookSubscriptionConsts), nameof(WebhookSubscriptionConsts.MaxWebhookUriLength))] + public string WebhookUri { get; set; } + + [Required] + [DynamicStringLength(typeof(WebhookSubscriptionConsts), nameof(WebhookSubscriptionConsts.MaxSecretLength))] + public string Secret { get; set; } + + public bool IsActive { get; set; } + + public List Webhooks { get; set; } = new List(); + + public Dictionary Headers { get; set; } = new Dictionary(); +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionDto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionDto.cs new file mode 100644 index 000000000..204ffd2f9 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionDto.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Application.Dtos; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhookSubscriptionDto : CreationAuditedEntityDto +{ + public Guid? TenantId { get; set; } + public string WebhookUri { get; set; } + public string Secret { get; set; } + public bool IsActive { get; set; } + public List Webhooks { get; set; } = new List(); + public IDictionary Headers { get; set; } = new Dictionary(); +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionGetListInput.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionGetListInput.cs new file mode 100644 index 000000000..9e9060184 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionGetListInput.cs @@ -0,0 +1,26 @@ +using System; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Validation; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhookSubscriptionGetListInput : PagedAndSortedResultRequestDto +{ + public string Filter { get; set; } + + public Guid? TenantId { get; set; } + + [DynamicStringLength(typeof(WebhookSubscriptionConsts), nameof(WebhookSubscriptionConsts.MaxWebhookUriLength))] + public string WebhookUri { get; set; } + + [DynamicStringLength(typeof(WebhookSubscriptionConsts), nameof(WebhookSubscriptionConsts.MaxSecretLength))] + public string Secret { get; set; } + + public bool? IsActive { get; set; } + + public string Webhooks { get; set; } + + public DateTime? BeginCreationTime { get; set; } + + public DateTime? EndCreationTime { get; set; } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/Extensions/WebhookSubscriptionExtensions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/Extensions/WebhookSubscriptionExtensions.cs new file mode 100644 index 000000000..49c190f0a --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/Extensions/WebhookSubscriptionExtensions.cs @@ -0,0 +1,44 @@ +using Newtonsoft.Json; +using System.Linq; + +namespace LINGYUN.Abp.WebhooksManagement.Extensions +{ + public static class WebhookSubscriptionExtensions + { + public static WebhookSubscriptionDto ToWebhookSubscriptionDto(this WebhookSubscription webhookSubscription) + { + return new WebhookSubscriptionDto + { + Id = webhookSubscription.Id, + TenantId = webhookSubscription.TenantId, + IsActive = webhookSubscription.IsActive, + Secret = webhookSubscription.Secret, + WebhookUri = webhookSubscription.WebhookUri, + Webhooks = webhookSubscription.GetSubscribedWebhooks(), + Headers = webhookSubscription.GetWebhookHeaders(), + CreationTime = webhookSubscription.CreationTime, + CreatorId = webhookSubscription.CreatorId + }; + } + + public static string ToSubscribedWebhooksString(this WebhookSubscriptionUpdateInput webhookSubscription) + { + if (webhookSubscription.Webhooks.Any()) + { + return JsonConvert.SerializeObject(webhookSubscription.Webhooks); + } + + return null; + } + + public static string ToWebhookHeadersString(this WebhookSubscriptionUpdateInput webhookSubscription) + { + if (webhookSubscription.Headers.Any()) + { + return JsonConvert.SerializeObject(webhookSubscription.Headers); + } + + return null; + } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionAppService.cs new file mode 100644 index 000000000..7f984fc4d --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionAppService.cs @@ -0,0 +1,111 @@ +using LINGYUN.Abp.WebhooksManagement.Authorization; +using LINGYUN.Abp.WebhooksManagement.Extensions; +using Microsoft.AspNetCore.Authorization; +using Newtonsoft.Json; +using System; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Application.Dtos; + +namespace LINGYUN.Abp.WebhooksManagement; + +[Authorize(WebhooksManagementPermissions.WebhookSubscription.Default)] +public class WebhookSubscriptionAppService : WebhooksManagementAppServiceBase, IWebhookSubscriptionAppService +{ + protected IWebhookSubscriptionRepository SubscriptionRepository { get; } + + public WebhookSubscriptionAppService( + IWebhookSubscriptionRepository subscriptionRepository) + { + SubscriptionRepository = subscriptionRepository; + } + + [Authorize(WebhooksManagementPermissions.WebhookSubscription.Create)] + public async virtual Task CreateAsync(WebhookSubscriptionCreateInput input) + { + await CheckSubscribedAsync(input); + + var subscription = new WebhookSubscription( + GuidGenerator.Create(), + input.WebhookUri, + input.Secret, + JsonConvert.SerializeObject(input.Webhooks), + JsonConvert.SerializeObject(input.Headers), + CurrentTenant.Id); + + await SubscriptionRepository.InsertAsync(subscription); + + await CurrentUnitOfWork.SaveChangesAsync(); + + return subscription.ToWebhookSubscriptionDto(); + } + + [Authorize(WebhooksManagementPermissions.WebhookSubscription.Delete)] + public virtual Task DeleteAsync(Guid id) + { + return SubscriptionRepository.DeleteAsync(id); + } + + public async virtual Task GetAsync(Guid id) + { + var subscription = await SubscriptionRepository.GetAsync(id); + + return subscription.ToWebhookSubscriptionDto(); + } + + public async virtual Task> GetListAsync(WebhookSubscriptionGetListInput input) + { + var filter = new WebhookSubscriptionFilter + { + Filter = input.Filter, + BeginCreationTime = input.BeginCreationTime, + EndCreationTime = input.EndCreationTime, + IsActive = input.IsActive, + Secret = input.Secret, + TenantId = input.TenantId, + Webhooks = input.Webhooks, + WebhookUri = input.WebhookUri + }; + + var totalCount = await SubscriptionRepository.GetCountAsync(filter); + var subscriptions = await SubscriptionRepository.GetListAsync(filter, + input.Sorting, input.MaxResultCount, input.SkipCount); + + return new PagedResultDto(totalCount, + subscriptions.Select(subscription => subscription.ToWebhookSubscriptionDto()).ToList()); + } + + [Authorize(WebhooksManagementPermissions.WebhookSubscription.Update)] + public async virtual Task UpdateAsync(Guid id, WebhookSubscriptionUpdateInput input) + { + var subscription = await SubscriptionRepository.GetAsync(id); + if (!string.Equals(subscription.WebhookUri, input.WebhookUri)) + { + await CheckSubscribedAsync(input); + } + + subscription.SetWebhookUri(input.WebhookUri); + subscription.SetWebhooks(input.ToSubscribedWebhooksString()); + subscription.SetHeaders(input.ToWebhookHeadersString()); + + await SubscriptionRepository.UpdateAsync(subscription); + + await CurrentUnitOfWork.SaveChangesAsync(); + + return subscription.ToWebhookSubscriptionDto(); + } + + protected async virtual Task CheckSubscribedAsync(WebhookSubscriptionCreateOrUpdateInput input) + { + foreach (var webhookName in input.Webhooks) + { + if (await SubscriptionRepository.IsSubscribedAsync(CurrentTenant.Id, input.WebhookUri, webhookName)) + { + throw new BusinessException(WebhooksManagementErrorCodes.WebhookSubscription.DuplicateSubscribed) + .WithData(nameof(WebhookSubscription.WebhookUri), input.WebhookUri) + .WithData(nameof(WebhookSubscription.Webhooks), webhookName); + } + } + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json index 5e4cfe7f2..10f87c775 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json @@ -5,6 +5,7 @@ "Permission:WebhooksManagement": "Webhooks", "Permission:ManageSettings": "Manage Settings", "DisplayName:CheckConnect": "Check Connect", - "Description:CheckConnect": "When a third-party service is connected, it is used to check whether the communication is normal." + "Description:CheckConnect": "When a third-party service is connected, it is used to check whether the communication is normal.", + "Webhooks:010001": "Payload address {WebhookUri} has been mounted event {Webhooks}!" } } \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json index bd1941dd4..0e89e364a 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json @@ -5,6 +5,7 @@ "Permission:WebhooksManagement": "Webhooks", "Permission:ManageSettings": "管理设置", "DisplayName:CheckConnect": "检查连接", - "Description:CheckConnect": "第三方服务接入时,用于检查是否通讯正常." + "Description:CheckConnect": "第三方服务接入时,用于检查是否通讯正常.", + "Webhooks:010001": "载荷地址 {WebhookUri} 已经挂载事件 {Webhooks}!" } } \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhooksManagementErrorCodes.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhooksManagementErrorCodes.cs index a7d2af4f9..5c13db31c 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhooksManagementErrorCodes.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhooksManagementErrorCodes.cs @@ -2,5 +2,12 @@ public static class WebhooksManagementErrorCodes { - public const string Namespace = "WebhooksManagement"; + public const string Namespace = "Webhooks"; + + public static class WebhookSubscription + { + public const string Prefix = Namespace + ":010"; + + public const string DuplicateSubscribed = Prefix + "001"; + } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionRepository.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionRepository.cs index faf4dbbee..069e8375c 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionRepository.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionRepository.cs @@ -1,8 +1,27 @@ using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; using Volo.Abp.Domain.Repositories; namespace LINGYUN.Abp.WebhooksManagement; public interface IWebhookSubscriptionRepository : IRepository { + Task IsSubscribedAsync( + Guid? tenantId, + string webhookUri, + string webhookName, + CancellationToken cancellationToken = default); + + Task GetCountAsync( + WebhookSubscriptionFilter filter, + CancellationToken cancellationToken = default); + + Task> GetListAsync( + WebhookSubscriptionFilter filter, + string sorting = $"{nameof(WebhookSubscription.CreationTime)} DESC", + int maxResultCount = 10, + int skipCount = 0, + CancellationToken cancellationToken = default); } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionFilter.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionFilter.cs new file mode 100644 index 000000000..adbd92c7d --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionFilter.cs @@ -0,0 +1,22 @@ +using System; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhookSubscriptionFilter +{ + public string Filter { get; set; } + + public Guid? TenantId { get; set; } + + public string WebhookUri { get; set; } + + public string Secret { get; set; } + + public bool? IsActive { get; set; } + + public string Webhooks { get; set; } + + public DateTime? BeginCreationTime { get; set; } + + public DateTime? EndCreationTime { get; set; } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookSubscriptionRepository.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookSubscriptionRepository.cs index 4931d6eaf..035fc0591 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookSubscriptionRepository.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookSubscriptionRepository.cs @@ -1,4 +1,10 @@ -using System; +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; @@ -13,4 +19,54 @@ public class EfCoreWebhookSubscriptionRepository : : base(dbContextProvider) { } + + public async virtual Task IsSubscribedAsync( + Guid? tenantId, + string webhookUri, + string webhookName, + CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .AnyAsync(x => x.TenantId == tenantId && + x.WebhookUri == webhookUri && + x.Webhooks.Contains("\"" + webhookName + "\""), + GetCancellationToken(cancellationToken)); + } + + public async virtual Task GetCountAsync( + WebhookSubscriptionFilter filter, + CancellationToken cancellationToken = default) + { + return await ApplyFilter(await GetDbSetAsync(), filter) + .CountAsync(GetCancellationToken(cancellationToken)); + } + + public async virtual Task> GetListAsync( + WebhookSubscriptionFilter filter, + string sorting = $"{nameof(WebhookSubscription.CreationTime)} DESC", + int maxResultCount = 10, + int skipCount = 0, + CancellationToken cancellationToken = default) + { + return await ApplyFilter(await GetDbSetAsync(), filter) + .OrderBy(sorting ?? $"{nameof(WebhookSubscription.CreationTime)} DESC") + .PageBy(skipCount, maxResultCount) + .ToListAsync(GetCancellationToken(cancellationToken)); + } + + protected virtual IQueryable ApplyFilter( + IQueryable queryable, + WebhookSubscriptionFilter filter) + { + return queryable + .WhereIf(filter.TenantId.HasValue, x => x.TenantId == filter.TenantId) + .WhereIf(filter.IsActive.HasValue, x => x.IsActive == filter.IsActive) + .WhereIf(!filter.WebhookUri.IsNullOrWhiteSpace(), x => x.WebhookUri == filter.WebhookUri) + .WhereIf(!filter.Secret.IsNullOrWhiteSpace(), x => x.Secret == filter.Secret) + .WhereIf(!filter.Webhooks.IsNullOrWhiteSpace(), x => x.Webhooks.Contains("\"" + filter.Webhooks + "\"")) + .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.WebhookUri.Contains(filter.Filter) || + x.Secret.Contains(filter.Filter) || x.Webhooks.Contains(filter.Filter)); + } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionController.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionController.cs new file mode 100644 index 000000000..5b7d91e6c --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionController.cs @@ -0,0 +1,59 @@ +using LINGYUN.Abp.WebhooksManagement.Authorization; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Application.Dtos; + +namespace LINGYUN.Abp.WebhooksManagement; + +[RemoteService(Name = WebhooksManagementRemoteServiceConsts.RemoteServiceName)] +[Area(WebhooksManagementRemoteServiceConsts.ModuleName)] +[Authorize(WebhooksManagementPermissions.WebhookSubscription.Default)] +[Route("api/webhooks/subscriptions")] +public class WebhookSubscriptionController : WebhooksManagementControllerBase, IWebhookSubscriptionAppService +{ + protected IWebhookSubscriptionAppService SubscriptionAppService { get; } + + public WebhookSubscriptionController(IWebhookSubscriptionAppService subscriptionAppService) + { + SubscriptionAppService = subscriptionAppService; + } + + [HttpPost] + [Authorize(WebhooksManagementPermissions.WebhookSubscription.Create)] + public Task CreateAsync(WebhookSubscriptionCreateInput input) + { + return SubscriptionAppService.CreateAsync(input); + } + + [HttpDelete] + [Route("{id}")] + [Authorize(WebhooksManagementPermissions.WebhookSubscription.Delete)] + public Task DeleteAsync(Guid id) + { + return SubscriptionAppService.DeleteAsync(id); + } + + [HttpGet] + [Route("{id}")] + public Task GetAsync(Guid id) + { + return SubscriptionAppService.GetAsync(id); + } + + [HttpGet] + public Task> GetListAsync(WebhookSubscriptionGetListInput input) + { + return SubscriptionAppService.GetListAsync(input); + } + + [HttpPut] + [Route("{id}")] + [Authorize(WebhooksManagementPermissions.WebhookSubscription.Update)] + public Task UpdateAsync(Guid id, WebhookSubscriptionUpdateInput input) + { + return SubscriptionAppService.UpdateAsync(id, input); + } +} From 6a6eca46084a718b561bad03fb0088ff1deae881 Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Sat, 26 Mar 2022 16:52:37 +0800 Subject: [PATCH 10/17] feat: add webHooks definition queries that are available --- .../IWebhookSubscriptionAppService.cs | 3 ++ .../WebhooksAvailableDto.cs | 8 +++++ .../WebhookSubscriptionAppService.cs | 30 ++++++++++++++++++- .../WebhooksManagement/WebhookSubscription.cs | 7 ++++- .../WebhookSubscriptionController.cs | 7 +++++ 5 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksAvailableDto.cs diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionAppService.cs index f25ede15b..f250b6418 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionAppService.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionAppService.cs @@ -1,4 +1,6 @@ using System; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; namespace LINGYUN.Abp.WebhooksManagement; @@ -11,4 +13,5 @@ public interface IWebhookSubscriptionAppService : WebhookSubscriptionCreateInput, WebhookSubscriptionUpdateInput> { + Task> GetAllAvailableWebhooksAsync(); } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksAvailableDto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksAvailableDto.cs new file mode 100644 index 000000000..47b254b64 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksAvailableDto.cs @@ -0,0 +1,8 @@ +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhooksAvailableDto +{ + public string Name { get; set; } + public string DisplayName { get; set; } + public string Description { get; set; } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionAppService.cs index 7f984fc4d..6502b4725 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionAppService.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionAppService.cs @@ -1,8 +1,10 @@ -using LINGYUN.Abp.WebhooksManagement.Authorization; +using LINGYUN.Abp.Webhooks; +using LINGYUN.Abp.WebhooksManagement.Authorization; using LINGYUN.Abp.WebhooksManagement.Extensions; using Microsoft.AspNetCore.Authorization; using Newtonsoft.Json; using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Volo.Abp; @@ -13,11 +15,14 @@ namespace LINGYUN.Abp.WebhooksManagement; [Authorize(WebhooksManagementPermissions.WebhookSubscription.Default)] public class WebhookSubscriptionAppService : WebhooksManagementAppServiceBase, IWebhookSubscriptionAppService { + protected IWebhookDefinitionManager WebhookDefinitionManager { get; } protected IWebhookSubscriptionRepository SubscriptionRepository { get; } public WebhookSubscriptionAppService( + IWebhookDefinitionManager webhookDefinitionManager, IWebhookSubscriptionRepository subscriptionRepository) { + WebhookDefinitionManager = webhookDefinitionManager; SubscriptionRepository = subscriptionRepository; } @@ -85,9 +90,11 @@ public class WebhookSubscriptionAppService : WebhooksManagementAppServiceBase, I await CheckSubscribedAsync(input); } + subscription.SetSecret(input.Secret); subscription.SetWebhookUri(input.WebhookUri); subscription.SetWebhooks(input.ToSubscribedWebhooksString()); subscription.SetHeaders(input.ToWebhookHeadersString()); + subscription.IsActive = input.IsActive; await SubscriptionRepository.UpdateAsync(subscription); @@ -96,6 +103,27 @@ public class WebhookSubscriptionAppService : WebhooksManagementAppServiceBase, I return subscription.ToWebhookSubscriptionDto(); } + public async virtual Task> GetAllAvailableWebhooksAsync() + { + var webhooks = WebhookDefinitionManager.GetAll(); + var definitions = new List(); + + foreach (var webhookDefinition in webhooks) + { + if (await WebhookDefinitionManager.IsAvailableAsync(CurrentTenant.Id, webhookDefinition.Name)) + { + definitions.Add(new WebhooksAvailableDto + { + Name = webhookDefinition.Name, + Description = webhookDefinition.Description?.Localize(StringLocalizerFactory), + DisplayName = webhookDefinition.DisplayName?.Localize(StringLocalizerFactory) + }); + } + } + + return new ListResultDto(definitions.OrderBy(d => d.Name).ToList()); + } + protected async virtual Task CheckSubscribedAsync(WebhookSubscriptionCreateOrUpdateInput input) { foreach (var webhookName in input.Webhooks) diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscription.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscription.cs index 4d637e88a..50476fce4 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscription.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSubscription.cs @@ -23,7 +23,7 @@ public class WebhookSubscription : CreationAuditedEntity string headers, Guid? tenantId = null) : base(id) { - Secret = Check.NotNullOrWhiteSpace(secret, nameof(secret), WebhookSubscriptionConsts.MaxSecretLength); + SetSecret(secret); SetWebhookUri(webhookUri); SetWebhooks(webhooks); SetHeaders(headers); @@ -32,6 +32,11 @@ public class WebhookSubscription : CreationAuditedEntity IsActive = true; } + public void SetSecret(string secret) + { + Secret = Check.NotNullOrWhiteSpace(secret, nameof(secret), WebhookSubscriptionConsts.MaxSecretLength); + } + public void SetWebhookUri(string webhookUri) { WebhookUri = Check.NotNullOrWhiteSpace(webhookUri, nameof(webhookUri), WebhookSubscriptionConsts.MaxWebhookUriLength); diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionController.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionController.cs index 5b7d91e6c..8a94ce6fb 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionController.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionController.cs @@ -56,4 +56,11 @@ public class WebhookSubscriptionController : WebhooksManagementControllerBase, I { return SubscriptionAppService.UpdateAsync(id, input); } + + [HttpGet] + [Route("availables")] + public Task> GetAllAvailableWebhooksAsync() + { + return SubscriptionAppService.GetAllAvailableWebhooksAsync(); + } } From d53e34cd6a307c1d0afb75a351a719ec063781ed Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Mon, 28 Mar 2022 08:57:58 +0800 Subject: [PATCH 11/17] feat: added send attempts api --- ...sManagementPermissionDefinitionProvider.cs | 11 +++ .../WebhooksManagementPermissions.cs | 6 ++ .../IWebhooksSendRecordAppService.cs | 15 ++++ ....cs => IWebhooksSubscriptionAppService.cs} | 2 +- .../WebhookEventRecordDto.cs | 12 +++ .../WebhookSendRecordDto.cs | 24 ++++++ .../WebhookSendRecordGetListInput.cs | 20 +++++ ...hooksManagementApplicationMapperProfile.cs | 2 + .../WebhooksSendRecordAppService.cs | 74 +++++++++++++++++++ ...e.cs => WebhooksSubscriptionAppService.cs} | 4 +- .../Localization/Resources/en.json | 7 ++ .../Localization/Resources/zh-Hans.json | 7 ++ .../EfCoreWebhookSendRecordRepository.cs | 5 ++ .../WebhooksSendRecordController.cs | 44 +++++++++++ ...r.cs => WebhooksSubscriptionController.cs} | 6 +- 15 files changed, 233 insertions(+), 6 deletions(-) create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksSendRecordAppService.cs rename aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/{IWebhookSubscriptionAppService.cs => IWebhooksSubscriptionAppService.cs} (86%) create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookEventRecordDto.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordDto.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordGetListInput.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksSendRecordAppService.cs rename aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/{WebhookSubscriptionAppService.cs => WebhooksSubscriptionAppService.cs} (94%) create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksSendRecordController.cs rename aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/{WebhookSubscriptionController.cs => WebhooksSubscriptionController.cs} (84%) diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs index 3af3d870a..7d15875c3 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs @@ -32,6 +32,17 @@ public class WebhooksManagementPermissionDefinitionProvider : PermissionDefiniti MultiTenancySides.Host) .WithProviders(ClientPermissionValueProvider.ProviderName); + var sendAttempts = group.AddPermission( + WebhooksManagementPermissions.WebhooksSendAttempts.Default, + L("Permission:SendAttempts"), + MultiTenancySides.Host) + .WithProviders(ClientPermissionValueProvider.ProviderName); + sendAttempts.AddChild( + WebhooksManagementPermissions.WebhooksSendAttempts.Resend, + L("Permission:Resend"), + MultiTenancySides.Host) + .WithProviders(ClientPermissionValueProvider.ProviderName); + group.AddPermission( WebhooksManagementPermissions.Publish, L("Permission:Publish")) diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissions.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissions.cs index bdabbfa8c..6f6ab9c47 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissions.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissions.cs @@ -18,4 +18,10 @@ public static class WebhooksManagementPermissions public const string Update = Default + ".Update"; public const string Delete = Default + ".Delete"; } + + public static class WebhooksSendAttempts + { + public const string Default = GroupName + ".SendAttempts"; + public const string Resend = Default + ".Resend"; + } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksSendRecordAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksSendRecordAppService.cs new file mode 100644 index 000000000..18e20cee5 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksSendRecordAppService.cs @@ -0,0 +1,15 @@ +using System; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; + +namespace LINGYUN.Abp.WebhooksManagement; + +public interface IWebhooksSendRecordAppService : IApplicationService +{ + Task GetAsync(Guid id); + + Task ResendAsync(Guid id); + + Task> GetListAsync(WebhookSendRecordGetListInput input); +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksSubscriptionAppService.cs similarity index 86% rename from aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionAppService.cs rename to aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksSubscriptionAppService.cs index f250b6418..af7f63163 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionAppService.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksSubscriptionAppService.cs @@ -5,7 +5,7 @@ using Volo.Abp.Application.Services; namespace LINGYUN.Abp.WebhooksManagement; -public interface IWebhookSubscriptionAppService : +public interface IWebhooksSubscriptionAppService : ICrudAppService< WebhookSubscriptionDto, Guid, diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookEventRecordDto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookEventRecordDto.cs new file mode 100644 index 000000000..a282777a6 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookEventRecordDto.cs @@ -0,0 +1,12 @@ +using System; +using Volo.Abp.Application.Dtos; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhookEventRecordDto : EntityDto +{ + public Guid? TenantId { get; set; } + public string WebhookName { get; set; } + public string Data { get; set; } + public DateTime CreationTime { get; set; } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordDto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordDto.cs new file mode 100644 index 000000000..9c0dcd85e --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordDto.cs @@ -0,0 +1,24 @@ +using System; +using System.Net; +using Volo.Abp.Application.Dtos; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhookSendRecordDto : EntityDto +{ + public Guid? TenantId { get; set; } + + public Guid WebhookEventId { get; set; } + + public Guid WebhookSubscriptionId { get; set; } + + public string Response { get; set; } + + public HttpStatusCode? ResponseStatusCode { get; set; } + + public DateTime CreationTime { get; set; } + + public DateTime? LastModificationTime { get; set; } + + public WebhookEventRecordDto WebhookEvent { get; set; } = new WebhookEventRecordDto(); +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordGetListInput.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordGetListInput.cs new file mode 100644 index 000000000..018cec849 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordGetListInput.cs @@ -0,0 +1,20 @@ +using System; +using System.Net; +using Volo.Abp.Application.Dtos; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhookSendRecordGetListInput : PagedAndSortedResultRequestDto +{ + public string Filter { get; set; } + + public Guid? WebhookEventId { get; set; } + + public Guid? SubscriptionId { get; set; } + + public HttpStatusCode? ResponseStatusCode { get; set; } + + public DateTime? BeginCreationTime { get; set; } + + public DateTime? EndCreationTime { get; set; } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksManagementApplicationMapperProfile.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksManagementApplicationMapperProfile.cs index dd3323fec..11ab195a0 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksManagementApplicationMapperProfile.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksManagementApplicationMapperProfile.cs @@ -6,5 +6,7 @@ public class WebhooksManagementApplicationMapperProfile : Profile { public WebhooksManagementApplicationMapperProfile() { + CreateMap(); + CreateMap(); } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksSendRecordAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksSendRecordAppService.cs new file mode 100644 index 000000000..7e29b2e4f --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksSendRecordAppService.cs @@ -0,0 +1,74 @@ +using LINGYUN.Abp.Webhooks; +using LINGYUN.Abp.WebhooksManagement.Authorization; +using LINGYUN.Abp.WebhooksManagement.Extensions; +using Microsoft.AspNetCore.Authorization; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.BackgroundJobs; + +namespace LINGYUN.Abp.WebhooksManagement; + +[Authorize(WebhooksManagementPermissions.WebhooksSendAttempts.Default)] +public class WebhooksSendRecordAppService : WebhooksManagementAppServiceBase, IWebhooksSendRecordAppService +{ + protected IBackgroundJobManager BackgroundJobManager => LazyServiceProvider.LazyGetRequiredService(); + protected IWebhookEventRecordRepository EventRepository => LazyServiceProvider.LazyGetRequiredService(); + protected IWebhookSubscriptionRepository SubscriptionRepository => LazyServiceProvider.LazyGetRequiredService(); + + + protected IWebhookSendRecordRepository RecordRepository { get; } + + public WebhooksSendRecordAppService( + IWebhookSendRecordRepository recordRepository) + { + RecordRepository = recordRepository; + } + + public async virtual Task GetAsync(Guid id) + { + var sendRecord = await RecordRepository.GetAsync(id); + + return ObjectMapper.Map(sendRecord); + } + + public async virtual Task> GetListAsync(WebhookSendRecordGetListInput input) + { + var filter = new WebhookSendRecordFilter + { + SubscriptionId = input.SubscriptionId, + ResponseStatusCode = input.ResponseStatusCode, + BeginCreationTime = input.BeginCreationTime, + EndCreationTime = input.EndCreationTime, + WebhookEventId = input.WebhookEventId, + Filter = input.Filter + }; + var totalCount = await RecordRepository.GetCountAsync(filter); + var sendRecords = await RecordRepository.GetListAsync(filter, + input.Sorting, input.MaxResultCount, input.SkipCount); + + return new PagedResultDto(totalCount, + ObjectMapper.Map, List>(sendRecords)); + } + + [Authorize(WebhooksManagementPermissions.WebhooksSendAttempts.Resend)] + public async virtual Task ResendAsync(Guid id) + { + var sendRecord = await RecordRepository.GetAsync(id); + var sendEvent = await EventRepository.GetAsync(sendRecord.WebhookEventId); + var subscription = await SubscriptionRepository.GetAsync(sendRecord.WebhookSubscriptionId); + + await BackgroundJobManager.EnqueueAsync(new WebhookSenderArgs + { + TenantId = CurrentTenant.Id, + WebhookSubscriptionId = sendRecord.WebhookSubscriptionId, + WebhookEventId = sendRecord.WebhookEventId, + WebhookName = sendEvent.WebhookName, + WebhookUri = subscription.WebhookUri, + Data = sendEvent.Data, + Headers = subscription.GetWebhookHeaders(), + Secret = subscription.Secret, + }); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksSubscriptionAppService.cs similarity index 94% rename from aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionAppService.cs rename to aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksSubscriptionAppService.cs index 6502b4725..17420474e 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionAppService.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksSubscriptionAppService.cs @@ -13,12 +13,12 @@ using Volo.Abp.Application.Dtos; namespace LINGYUN.Abp.WebhooksManagement; [Authorize(WebhooksManagementPermissions.WebhookSubscription.Default)] -public class WebhookSubscriptionAppService : WebhooksManagementAppServiceBase, IWebhookSubscriptionAppService +public class WebhooksSubscriptionAppService : WebhooksManagementAppServiceBase, IWebhooksSubscriptionAppService { protected IWebhookDefinitionManager WebhookDefinitionManager { get; } protected IWebhookSubscriptionRepository SubscriptionRepository { get; } - public WebhookSubscriptionAppService( + public WebhooksSubscriptionAppService( IWebhookDefinitionManager webhookDefinitionManager, IWebhookSubscriptionRepository subscriptionRepository) { diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json index 10f87c775..b3828f603 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json @@ -3,6 +3,13 @@ "texts": { "Features:WebhooksManagement": "Webhooks", "Permission:WebhooksManagement": "Webhooks", + "Permission:Subscriptions": "Subscriptions", + "Permission:SendAttempts": "Attempts", + "Permission:Create": "Create", + "Permission:Update": "Update", + "Permission:Delete": "Delete", + "Permission:Resend": "Resend", + "Permission:Publish": "Publish", "Permission:ManageSettings": "Manage Settings", "DisplayName:CheckConnect": "Check Connect", "Description:CheckConnect": "When a third-party service is connected, it is used to check whether the communication is normal.", diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json index 0e89e364a..d20d0efdd 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json @@ -3,6 +3,13 @@ "texts": { "Features:WebhooksManagement": "Webhooks", "Permission:WebhooksManagement": "Webhooks", + "Permission:Subscriptions": "管理订阅", + "Permission:SendAttempts": "管理发送", + "Permission:Create": "创建", + "Permission:Update": "编辑", + "Permission:Delete": "删除", + "Permission:Resend": "重新发送", + "Permission:Publish": "发布事件", "Permission:ManageSettings": "管理设置", "DisplayName:CheckConnect": "检查连接", "Description:CheckConnect": "第三方服务接入时,用于检查是否通讯正常.", diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookSendRecordRepository.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookSendRecordRepository.cs index f7ba0d433..9f1270348 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookSendRecordRepository.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/EfCoreWebhookSendRecordRepository.cs @@ -43,6 +43,11 @@ public class EfCoreWebhookSendRecordRepository : .ToListAsync(GetCancellationToken(cancellationToken)); } + public async override Task> WithDetailsAsync() + { + return (await base.WithDetailsAsync()).IncludeDetails(); + } + protected virtual IQueryable ApplyFilter( IQueryable queryable, WebhookSendRecordFilter filter) diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksSendRecordController.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksSendRecordController.cs new file mode 100644 index 000000000..f775527c0 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksSendRecordController.cs @@ -0,0 +1,44 @@ +using LINGYUN.Abp.WebhooksManagement.Authorization; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Application.Dtos; + +namespace LINGYUN.Abp.WebhooksManagement; + +[RemoteService(Name = WebhooksManagementRemoteServiceConsts.RemoteServiceName)] +[Area(WebhooksManagementRemoteServiceConsts.ModuleName)] +[Authorize(WebhooksManagementPermissions.WebhooksSendAttempts.Default)] +[Route("api/webhooks/send-attempts")] +public class WebhooksSendRecordController : WebhooksManagementControllerBase, IWebhooksSendRecordAppService +{ + protected IWebhooksSendRecordAppService SendRecordAppService { get; } + + public WebhooksSendRecordController(IWebhooksSendRecordAppService sendRecordAppService) + { + SendRecordAppService = sendRecordAppService; + } + + [HttpGet] + [Route("{id}")] + public Task GetAsync(Guid id) + { + return SendRecordAppService.GetAsync(id); + } + + [HttpGet] + public Task> GetListAsync(WebhookSendRecordGetListInput input) + { + return SendRecordAppService.GetListAsync(input); + } + + [HttpPost] + [Route("{id}/resend")] + [Authorize(WebhooksManagementPermissions.WebhooksSendAttempts.Resend)] + public Task ResendAsync(Guid id) + { + return SendRecordAppService.ResendAsync(id); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionController.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksSubscriptionController.cs similarity index 84% rename from aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionController.cs rename to aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksSubscriptionController.cs index 8a94ce6fb..faa517987 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionController.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksSubscriptionController.cs @@ -12,11 +12,11 @@ namespace LINGYUN.Abp.WebhooksManagement; [Area(WebhooksManagementRemoteServiceConsts.ModuleName)] [Authorize(WebhooksManagementPermissions.WebhookSubscription.Default)] [Route("api/webhooks/subscriptions")] -public class WebhookSubscriptionController : WebhooksManagementControllerBase, IWebhookSubscriptionAppService +public class WebhooksSubscriptionController : WebhooksManagementControllerBase, IWebhooksSubscriptionAppService { - protected IWebhookSubscriptionAppService SubscriptionAppService { get; } + protected IWebhooksSubscriptionAppService SubscriptionAppService { get; } - public WebhookSubscriptionController(IWebhookSubscriptionAppService subscriptionAppService) + public WebhooksSubscriptionController(IWebhooksSubscriptionAppService subscriptionAppService) { SubscriptionAppService = subscriptionAppService; } From 582979b8228690cf5491883e6867b85038264c72 Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Mon, 28 Mar 2022 09:05:21 +0800 Subject: [PATCH 12/17] feat: renames interface --- .../ClientProxies/ClientProxiesWebhookPublisher.cs | 12 ++++++------ .../WebhooksManagement/IWebhookPublishAppService.cs | 9 +++++++++ ...AppService.cs => IWebhookSendRecordAppService.cs} | 2 +- ...pService.cs => IWebhookSubscriptionAppService.cs} | 4 ++-- .../WebhooksManagement/IWebhooksPublishAppService.cs | 9 --------- ...ebhooksAvailableDto.cs => WebhookAvailableDto.cs} | 2 +- ...ebhooksPublishInput.cs => WebhookPublishInput.cs} | 2 +- ...lishAppService.cs => WebhookPublishAppService.cs} | 6 +++--- ...dAppService.cs => WebhookSendRecordAppService.cs} | 4 ++-- ...ppService.cs => WebhookSubscriptionAppService.cs} | 12 ++++++------ ...lishController.cs => WebhookPublishController.cs} | 8 ++++---- ...dController.cs => WebhookSendRecordController.cs} | 6 +++--- ...ontroller.cs => WebhookSubscriptionController.cs} | 8 ++++---- 13 files changed, 42 insertions(+), 42 deletions(-) create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookPublishAppService.cs rename aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/{IWebhooksSendRecordAppService.cs => IWebhookSendRecordAppService.cs} (80%) rename aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/{IWebhooksSubscriptionAppService.cs => IWebhookSubscriptionAppService.cs} (70%) delete mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksPublishAppService.cs rename aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/{WebhooksAvailableDto.cs => WebhookAvailableDto.cs} (80%) rename aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/{WebhooksPublishInput.cs => WebhookPublishInput.cs} (93%) rename aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/{WebhooksPublishAppService.cs => WebhookPublishAppService.cs} (79%) rename aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/{WebhooksSendRecordAppService.cs => WebhookSendRecordAppService.cs} (93%) rename aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/{WebhooksSubscriptionAppService.cs => WebhookSubscriptionAppService.cs} (89%) rename aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/{WebhooksPublishController.cs => WebhookPublishController.cs} (62%) rename aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/{WebhooksSendRecordController.cs => WebhookSendRecordController.cs} (78%) rename aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/{WebhooksSubscriptionController.cs => WebhookSubscriptionController.cs} (80%) diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks.ClientProxies/LINGYUN/Abp/WebHooks/ClientProxies/ClientProxiesWebhookPublisher.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks.ClientProxies/LINGYUN/Abp/WebHooks/ClientProxies/ClientProxiesWebhookPublisher.cs index 85b25db61..9e5ae8b35 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks.ClientProxies/LINGYUN/Abp/WebHooks/ClientProxies/ClientProxiesWebhookPublisher.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks.ClientProxies/LINGYUN/Abp/WebHooks/ClientProxies/ClientProxiesWebhookPublisher.cs @@ -11,17 +11,17 @@ namespace LINGYUN.Abp.Webhooks.ClientProxies; [Dependency(ReplaceServices = true)] public class ClientProxiesWebhookPublisher : IWebhookPublisher, ITransientDependency { - protected IWebhooksPublishAppService PublishAppService { get; } + protected IWebhookPublishAppService PublishAppService { get; } public ClientProxiesWebhookPublisher( - IWebhooksPublishAppService publishAppService) + IWebhookPublishAppService publishAppService) { PublishAppService = publishAppService; } public async virtual Task PublishAsync(string webhookName, object data, bool sendExactSameData = false, WebhookHeader headers = null) { - var input = new WebhooksPublishInput + var input = new WebhookPublishInput { WebhookName = webhookName, Data = JsonConvert.SerializeObject(data), @@ -41,7 +41,7 @@ public class ClientProxiesWebhookPublisher : IWebhookPublisher, ITransientDepend public async virtual Task PublishAsync(string webhookName, object data, Guid? tenantId, bool sendExactSameData = false, WebhookHeader headers = null) { - var input = new WebhooksPublishInput + var input = new WebhookPublishInput { WebhookName = webhookName, Data = JsonConvert.SerializeObject(data), @@ -65,7 +65,7 @@ public class ClientProxiesWebhookPublisher : IWebhookPublisher, ITransientDepend public async virtual Task PublishAsync(Guid?[] tenantIds, string webhookName, object data, bool sendExactSameData = false, WebhookHeader headers = null) { - var input = new WebhooksPublishInput + var input = new WebhookPublishInput { WebhookName = webhookName, Data = JsonConvert.SerializeObject(data), @@ -84,7 +84,7 @@ public class ClientProxiesWebhookPublisher : IWebhookPublisher, ITransientDepend await PublishAsync(input); } - protected virtual async Task PublishAsync(WebhooksPublishInput input) + protected virtual async Task PublishAsync(WebhookPublishInput input) { await PublishAppService.PublishAsync(input); } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookPublishAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookPublishAppService.cs new file mode 100644 index 000000000..1e375d98f --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookPublishAppService.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; +using Volo.Abp.Application.Services; + +namespace LINGYUN.Abp.WebhooksManagement; + +public interface IWebhookPublishAppService : IApplicationService +{ + Task PublishAsync(WebhookPublishInput input); +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksSendRecordAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSendRecordAppService.cs similarity index 80% rename from aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksSendRecordAppService.cs rename to aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSendRecordAppService.cs index 18e20cee5..da24b710b 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksSendRecordAppService.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSendRecordAppService.cs @@ -5,7 +5,7 @@ using Volo.Abp.Application.Services; namespace LINGYUN.Abp.WebhooksManagement; -public interface IWebhooksSendRecordAppService : IApplicationService +public interface IWebhookSendRecordAppService : IApplicationService { Task GetAsync(Guid id); diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksSubscriptionAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionAppService.cs similarity index 70% rename from aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksSubscriptionAppService.cs rename to aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionAppService.cs index af7f63163..1de23c039 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksSubscriptionAppService.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionAppService.cs @@ -5,7 +5,7 @@ using Volo.Abp.Application.Services; namespace LINGYUN.Abp.WebhooksManagement; -public interface IWebhooksSubscriptionAppService : +public interface IWebhookSubscriptionAppService : ICrudAppService< WebhookSubscriptionDto, Guid, @@ -13,5 +13,5 @@ public interface IWebhooksSubscriptionAppService : WebhookSubscriptionCreateInput, WebhookSubscriptionUpdateInput> { - Task> GetAllAvailableWebhooksAsync(); + Task> GetAllAvailableWebhooksAsync(); } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksPublishAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksPublishAppService.cs deleted file mode 100644 index b3236f244..000000000 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhooksPublishAppService.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Threading.Tasks; -using Volo.Abp.Application.Services; - -namespace LINGYUN.Abp.WebhooksManagement; - -public interface IWebhooksPublishAppService : IApplicationService -{ - Task PublishAsync(WebhooksPublishInput input); -} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksAvailableDto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookAvailableDto.cs similarity index 80% rename from aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksAvailableDto.cs rename to aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookAvailableDto.cs index 47b254b64..0e4c5ed6d 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksAvailableDto.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookAvailableDto.cs @@ -1,6 +1,6 @@ namespace LINGYUN.Abp.WebhooksManagement; -public class WebhooksAvailableDto +public class WebhookAvailableDto { public string Name { get; set; } public string DisplayName { get; set; } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksPublishInput.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookPublishInput.cs similarity index 93% rename from aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksPublishInput.cs rename to aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookPublishInput.cs index a7879d87f..e27013228 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhooksPublishInput.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookPublishInput.cs @@ -5,7 +5,7 @@ using Volo.Abp.Validation; namespace LINGYUN.Abp.WebhooksManagement; -public class WebhooksPublishInput +public class WebhookPublishInput { [Required] [DynamicStringLength(typeof(WebhookEventRecordConsts), nameof(WebhookEventRecordConsts.MaxWebhookNameLength))] diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksPublishAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookPublishAppService.cs similarity index 79% rename from aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksPublishAppService.cs rename to aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookPublishAppService.cs index 7e2bee65e..c6d637e77 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksPublishAppService.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookPublishAppService.cs @@ -8,16 +8,16 @@ using System.Threading.Tasks; namespace LINGYUN.Abp.WebhooksManagement; [Authorize(WebhooksManagementPermissions.Publish)] -public class WebhooksPublishAppService : WebhooksManagementAppServiceBase, IWebhooksPublishAppService +public class WebhookPublishAppService : WebhooksManagementAppServiceBase, IWebhookPublishAppService { protected IWebhookPublisher InnerPublisher { get; } - public WebhooksPublishAppService(IWebhookPublisher innerPublisher) + public WebhookPublishAppService(IWebhookPublisher innerPublisher) { InnerPublisher = innerPublisher; } - public async virtual Task PublishAsync(WebhooksPublishInput input) + public async virtual Task PublishAsync(WebhookPublishInput input) { var webhookHeader = new WebhookHeader { diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksSendRecordAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordAppService.cs similarity index 93% rename from aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksSendRecordAppService.cs rename to aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordAppService.cs index 7e29b2e4f..77683b17c 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksSendRecordAppService.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordAppService.cs @@ -11,7 +11,7 @@ using Volo.Abp.BackgroundJobs; namespace LINGYUN.Abp.WebhooksManagement; [Authorize(WebhooksManagementPermissions.WebhooksSendAttempts.Default)] -public class WebhooksSendRecordAppService : WebhooksManagementAppServiceBase, IWebhooksSendRecordAppService +public class WebhookSendRecordAppService : WebhooksManagementAppServiceBase, IWebhookSendRecordAppService { protected IBackgroundJobManager BackgroundJobManager => LazyServiceProvider.LazyGetRequiredService(); protected IWebhookEventRecordRepository EventRepository => LazyServiceProvider.LazyGetRequiredService(); @@ -20,7 +20,7 @@ public class WebhooksSendRecordAppService : WebhooksManagementAppServiceBase, IW protected IWebhookSendRecordRepository RecordRepository { get; } - public WebhooksSendRecordAppService( + public WebhookSendRecordAppService( IWebhookSendRecordRepository recordRepository) { RecordRepository = recordRepository; diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksSubscriptionAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionAppService.cs similarity index 89% rename from aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksSubscriptionAppService.cs rename to aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionAppService.cs index 17420474e..a59b2e84e 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhooksSubscriptionAppService.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionAppService.cs @@ -13,12 +13,12 @@ using Volo.Abp.Application.Dtos; namespace LINGYUN.Abp.WebhooksManagement; [Authorize(WebhooksManagementPermissions.WebhookSubscription.Default)] -public class WebhooksSubscriptionAppService : WebhooksManagementAppServiceBase, IWebhooksSubscriptionAppService +public class WebhookSubscriptionAppService : WebhooksManagementAppServiceBase, IWebhookSubscriptionAppService { protected IWebhookDefinitionManager WebhookDefinitionManager { get; } protected IWebhookSubscriptionRepository SubscriptionRepository { get; } - public WebhooksSubscriptionAppService( + public WebhookSubscriptionAppService( IWebhookDefinitionManager webhookDefinitionManager, IWebhookSubscriptionRepository subscriptionRepository) { @@ -103,16 +103,16 @@ public class WebhooksSubscriptionAppService : WebhooksManagementAppServiceBase, return subscription.ToWebhookSubscriptionDto(); } - public async virtual Task> GetAllAvailableWebhooksAsync() + public async virtual Task> GetAllAvailableWebhooksAsync() { var webhooks = WebhookDefinitionManager.GetAll(); - var definitions = new List(); + var definitions = new List(); foreach (var webhookDefinition in webhooks) { if (await WebhookDefinitionManager.IsAvailableAsync(CurrentTenant.Id, webhookDefinition.Name)) { - definitions.Add(new WebhooksAvailableDto + definitions.Add(new WebhookAvailableDto { Name = webhookDefinition.Name, Description = webhookDefinition.Description?.Localize(StringLocalizerFactory), @@ -121,7 +121,7 @@ public class WebhooksSubscriptionAppService : WebhooksManagementAppServiceBase, } } - return new ListResultDto(definitions.OrderBy(d => d.Name).ToList()); + return new ListResultDto(definitions.OrderBy(d => d.Name).ToList()); } protected async virtual Task CheckSubscribedAsync(WebhookSubscriptionCreateOrUpdateInput input) diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksPublishController.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookPublishController.cs similarity index 62% rename from aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksPublishController.cs rename to aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookPublishController.cs index e9b3275f9..43c72a8eb 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksPublishController.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookPublishController.cs @@ -10,17 +10,17 @@ namespace LINGYUN.Abp.WebhooksManagement; [Area(WebhooksManagementRemoteServiceConsts.ModuleName)] [Authorize(WebhooksManagementPermissions.Publish)] [Route("api/webhooks/publish")] -public class WebhooksPublishController : WebhooksManagementControllerBase, IWebhooksPublishAppService +public class WebhookPublishController : WebhooksManagementControllerBase, IWebhookPublishAppService { - protected IWebhooksPublishAppService PublishAppService { get; } + protected IWebhookPublishAppService PublishAppService { get; } - public WebhooksPublishController(IWebhooksPublishAppService publishAppService) + public WebhookPublishController(IWebhookPublishAppService publishAppService) { PublishAppService = publishAppService; } [HttpPost] - public virtual Task PublishAsync(WebhooksPublishInput input) + public virtual Task PublishAsync(WebhookPublishInput input) { return PublishAppService.PublishAsync(input); } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksSendRecordController.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordController.cs similarity index 78% rename from aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksSendRecordController.cs rename to aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordController.cs index f775527c0..ad05c5e8d 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksSendRecordController.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordController.cs @@ -12,11 +12,11 @@ namespace LINGYUN.Abp.WebhooksManagement; [Area(WebhooksManagementRemoteServiceConsts.ModuleName)] [Authorize(WebhooksManagementPermissions.WebhooksSendAttempts.Default)] [Route("api/webhooks/send-attempts")] -public class WebhooksSendRecordController : WebhooksManagementControllerBase, IWebhooksSendRecordAppService +public class WebhookSendRecordController : WebhooksManagementControllerBase, IWebhookSendRecordAppService { - protected IWebhooksSendRecordAppService SendRecordAppService { get; } + protected IWebhookSendRecordAppService SendRecordAppService { get; } - public WebhooksSendRecordController(IWebhooksSendRecordAppService sendRecordAppService) + public WebhookSendRecordController(IWebhookSendRecordAppService sendRecordAppService) { SendRecordAppService = sendRecordAppService; } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksSubscriptionController.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionController.cs similarity index 80% rename from aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksSubscriptionController.cs rename to aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionController.cs index faa517987..5e42551d2 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhooksSubscriptionController.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionController.cs @@ -12,11 +12,11 @@ namespace LINGYUN.Abp.WebhooksManagement; [Area(WebhooksManagementRemoteServiceConsts.ModuleName)] [Authorize(WebhooksManagementPermissions.WebhookSubscription.Default)] [Route("api/webhooks/subscriptions")] -public class WebhooksSubscriptionController : WebhooksManagementControllerBase, IWebhooksSubscriptionAppService +public class WebhookSubscriptionController : WebhooksManagementControllerBase, IWebhookSubscriptionAppService { - protected IWebhooksSubscriptionAppService SubscriptionAppService { get; } + protected IWebhookSubscriptionAppService SubscriptionAppService { get; } - public WebhooksSubscriptionController(IWebhooksSubscriptionAppService subscriptionAppService) + public WebhookSubscriptionController(IWebhookSubscriptionAppService subscriptionAppService) { SubscriptionAppService = subscriptionAppService; } @@ -59,7 +59,7 @@ public class WebhooksSubscriptionController : WebhooksManagementControllerBase, [HttpGet] [Route("availables")] - public Task> GetAllAvailableWebhooksAsync() + public Task> GetAllAvailableWebhooksAsync() { return SubscriptionAppService.GetAllAvailableWebhooksAsync(); } From a5fd021855e4961eeb0397aa4b1e1513117ab156 Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Mon, 28 Mar 2022 09:12:37 +0800 Subject: [PATCH 13/17] fix: all permissions should be on the host side --- ...bhooksManagementPermissionDefinitionProvider.cs | 14 ++++++++------ ...ebhooksManagementHttpApiHostModule.Configure.cs | 12 ++++++------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs index 7d15875c3..4c9513f02 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Authorization/WebhooksManagementPermissionDefinitionProvider.cs @@ -9,7 +9,10 @@ public class WebhooksManagementPermissionDefinitionProvider : PermissionDefiniti { public override void Define(IPermissionDefinitionContext context) { - var group = context.AddGroup(WebhooksManagementPermissions.GroupName, L("Permission:WebhooksManagement")); + var group = context.AddGroup( + WebhooksManagementPermissions.GroupName, + L("Permission:WebhooksManagement"), + MultiTenancySides.Host); var subscription = group.AddPermission( WebhooksManagementPermissions.WebhookSubscription.Default, @@ -35,13 +38,11 @@ public class WebhooksManagementPermissionDefinitionProvider : PermissionDefiniti var sendAttempts = group.AddPermission( WebhooksManagementPermissions.WebhooksSendAttempts.Default, L("Permission:SendAttempts"), - MultiTenancySides.Host) - .WithProviders(ClientPermissionValueProvider.ProviderName); + MultiTenancySides.Host); sendAttempts.AddChild( WebhooksManagementPermissions.WebhooksSendAttempts.Resend, L("Permission:Resend"), - MultiTenancySides.Host) - .WithProviders(ClientPermissionValueProvider.ProviderName); + MultiTenancySides.Host); group.AddPermission( WebhooksManagementPermissions.Publish, @@ -50,7 +51,8 @@ public class WebhooksManagementPermissionDefinitionProvider : PermissionDefiniti group.AddPermission( WebhooksManagementPermissions.ManageSettings, - L("Permission:ManageSettings")); + L("Permission:ManageSettings"), + MultiTenancySides.Host); } private static LocalizableString L(string name) diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs index 72ff2bbef..ddb24ddb0 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs @@ -81,12 +81,12 @@ public partial class WebhooksManagementHttpApiHostModule // 配置Ef Configure(options => { - //options.UseMySQL(); - options.Configure(cfg => - { - cfg.UseMySQL(); - cfg.DbContextOptions.EnableSensitiveDataLogging(); - }); + options.UseMySQL(); + //options.Configure(cfg => + //{ + // cfg.UseMySQL(); + // cfg.DbContextOptions.EnableSensitiveDataLogging(); + //}); }); } From 33f1b0b31166f1ff3af27be8539ead2cf0276c61 Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Mon, 28 Mar 2022 09:17:16 +0800 Subject: [PATCH 14/17] remove temporarily unnecessary features --- .../Features/WebhooksManagementFeatureDefinitionProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Features/WebhooksManagementFeatureDefinitionProvider.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Features/WebhooksManagementFeatureDefinitionProvider.cs index 22d14bd79..d124abe45 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Features/WebhooksManagementFeatureDefinitionProvider.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/Features/WebhooksManagementFeatureDefinitionProvider.cs @@ -8,7 +8,7 @@ public class WebhooksManagementFeatureDefinitionProvider : FeatureDefinitionProv { public override void Define(IFeatureDefinitionContext context) { - var group = context.AddGroup(WebhooksManagementFeatureNames.GroupName, L("Features:WebhooksManagement")); + //var group = context.AddGroup(WebhooksManagementFeatureNames.GroupName, L("Features:WebhooksManagement")); } private static ILocalizableString L(string name) From 11ca6efa33fda77875b3871aeb6fcb155c00b9d4 Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Mon, 28 Mar 2022 10:33:18 +0800 Subject: [PATCH 15/17] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E9=80=82?= =?UTF-8?q?=E7=94=A8=E4=BA=8Eidentity=E6=A8=A1=E5=9D=97=E7=9A=84webhooks.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 +++++++++ .../LINGYUN.Abp.Webhooks.Identity.csproj | 30 +++++++++ .../Identity/AbpWebhooksIdentityModule.cs | 32 ++++++++++ .../Identity/IdentityRoleNameChangedWto.cs | 12 ++++ .../Identity/IdentityRoleWebHooker.cs | 62 +++++++++++++++++++ .../Abp/Webhooks/Identity/IdentityRoleWto.cs | 10 +++ .../Identity/IdentityUserWebHooker.cs | 55 ++++++++++++++++ .../Abp/Webhooks/Identity/IdentityUserWto.cs | 22 +++++++ .../IdentityWebhookDefinitionProvider.cs | 60 ++++++++++++++++++ .../Webhooks/Identity/IdentityWebhookNames.cs | 22 +++++++ .../Identity/Localization/Resources/en.json | 19 ++++++ .../Localization/Resources/zh-Hans.json | 19 ++++++ .../Identity/OrganizationUnitWebHooker.cs | 49 +++++++++++++++ .../Webhooks/Identity/OrganizationUnitWto.cs | 12 ++++ .../Webhooks/WebhooksNames.cs | 2 +- ...ice.WebhooksManagement.HttpApi.Host.csproj | 1 + .../WebhooksManagementHttpApiHostModule.cs | 2 + 18 files changed, 441 insertions(+), 1 deletion(-) create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/FodyWeavers.xml create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/FodyWeavers.xsd create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN.Abp.Webhooks.Identity.csproj create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/AbpWebhooksIdentityModule.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleNameChangedWto.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleWebHooker.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleWto.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityUserWebHooker.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityUserWto.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityWebhookDefinitionProvider.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityWebhookNames.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/Localization/Resources/en.json create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/Localization/Resources/zh-Hans.json create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/OrganizationUnitWebHooker.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/OrganizationUnitWto.cs diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/FodyWeavers.xml b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/FodyWeavers.xml new file mode 100644 index 000000000..ac6b5b292 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/FodyWeavers.xsd b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN.Abp.Webhooks.Identity.csproj b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN.Abp.Webhooks.Identity.csproj new file mode 100644 index 000000000..32c987515 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN.Abp.Webhooks.Identity.csproj @@ -0,0 +1,30 @@ + + + + + + + netstandard2.0 + + + + + + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/AbpWebhooksIdentityModule.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/AbpWebhooksIdentityModule.cs new file mode 100644 index 000000000..0ca523251 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/AbpWebhooksIdentityModule.cs @@ -0,0 +1,32 @@ +using Volo.Abp.Domain; +using Volo.Abp.EventBus; +using Volo.Abp.Identity; +using Volo.Abp.Identity.Localization; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; +using Volo.Abp.Users; +using Volo.Abp.VirtualFileSystem; + +namespace LINGYUN.Abp.Webhooks.Identity; + +[DependsOn(typeof(AbpDddDomainModule))] +[DependsOn(typeof(AbpEventBusModule))] +[DependsOn(typeof(AbpUsersAbstractionModule))] +[DependsOn(typeof(AbpIdentityDomainSharedModule))] +public class AbpWebhooksIdentityModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + + Configure(options => + { + options.Resources + .Get() + .AddVirtualJson("/LINGYUN/Abp/Webhooks/Identity/Localization/Resources"); + }); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleNameChangedWto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleNameChangedWto.cs new file mode 100644 index 000000000..5f55b78cf --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleNameChangedWto.cs @@ -0,0 +1,12 @@ +using System; + +namespace LINGYUN.Abp.Webhooks.Identity; + +public class IdentityRoleNameChangedWto +{ + public Guid Id { get; set; } + + public string Name { get; set; } + + public string OldName { get; set; } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleWebHooker.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleWebHooker.cs new file mode 100644 index 000000000..ee1fdaee6 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleWebHooker.cs @@ -0,0 +1,62 @@ +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Identity; + +namespace LINGYUN.Abp.Webhooks.Identity; + +public class IdentityRoleWebHooker : + IDistributedEventHandler>, + IDistributedEventHandler>, + IDistributedEventHandler, + ITransientDependency +{ + private readonly IWebhookPublisher _webhookPublisher; + + public IdentityRoleWebHooker( + IWebhookPublisher webhookPublisher) + { + _webhookPublisher = webhookPublisher; + } + + public async virtual Task HandleEventAsync(EntityCreatedEto eventData) + { + await PublishAsync(IdentityWebhookNames.IdentityRole.Create, eventData.Entity); + } + + public async virtual Task HandleEventAsync(EntityUpdatedEto eventData) + { + await PublishAsync(IdentityWebhookNames.IdentityRole.Update, eventData.Entity); + } + + public async virtual Task HandleEventAsync(EntityDeletedEto eventData) + { + await PublishAsync(IdentityWebhookNames.IdentityRole.Delete, eventData.Entity); + } + + public async virtual Task HandleEventAsync(IdentityRoleNameChangedEto eventData) + { + await _webhookPublisher.PublishAsync( + IdentityWebhookNames.IdentityRole.ChangeName, + new IdentityRoleNameChangedWto + { + Id = eventData.Id, + Name = eventData.Name, + OldName = eventData.OldName, + }, + eventData.TenantId); + } + + protected async virtual Task PublishAsync(string webhookName, IdentityRoleEto eto) + { + await _webhookPublisher.PublishAsync( + webhookName, + new IdentityRoleWto + { + Id = eto.Id, + Name = eto.Name + }, + eto.TenantId); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleWto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleWto.cs new file mode 100644 index 000000000..123a9f2dc --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleWto.cs @@ -0,0 +1,10 @@ +using System; + +namespace LINGYUN.Abp.Webhooks.Identity; + +public class IdentityRoleWto +{ + public Guid Id { get; set; } + + public string Name { get; set; } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityUserWebHooker.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityUserWebHooker.cs new file mode 100644 index 000000000..fc48c2cab --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityUserWebHooker.cs @@ -0,0 +1,55 @@ +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Users; + +namespace LINGYUN.Abp.Webhooks.Identity; + +public class IdentityUserWebHooker : + IDistributedEventHandler>, + IDistributedEventHandler>, + IDistributedEventHandler>, + ITransientDependency +{ + private readonly IWebhookPublisher _webhookPublisher; + + public IdentityUserWebHooker( + IWebhookPublisher webhookPublisher) + { + _webhookPublisher = webhookPublisher; + } + + public async virtual Task HandleEventAsync(EntityCreatedEto eventData) + { + await PublishAsync(IdentityWebhookNames.IdentityUser.Create, eventData.Entity); + } + + public async virtual Task HandleEventAsync(EntityUpdatedEto eventData) + { + await PublishAsync(IdentityWebhookNames.IdentityUser.Update, eventData.Entity); + } + + public async virtual Task HandleEventAsync(EntityDeletedEto eventData) + { + await PublishAsync(IdentityWebhookNames.IdentityUser.Delete, eventData.Entity); + } + + protected async virtual Task PublishAsync(string webhookName, UserEto eto) + { + await _webhookPublisher.PublishAsync( + webhookName, + new IdentityUserWto + { + Id = eto.Id, + Name = eto.Name, + Email = eto.Email, + EmailConfirmed = eto.EmailConfirmed, + UserName = eto.UserName, + PhoneNumber = eto.PhoneNumber, + PhoneNumberConfirmed = eto.PhoneNumberConfirmed, + Surname = eto.Surname, + }, + eto.TenantId); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityUserWto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityUserWto.cs new file mode 100644 index 000000000..e5bf48665 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityUserWto.cs @@ -0,0 +1,22 @@ +using System; + +namespace LINGYUN.Abp.Webhooks.Identity; + +public class IdentityUserWto +{ + public Guid Id { get; set; } + + public string UserName { get; set; } + + public string Name { get; set; } + + public string Surname { get; set; } + + public string Email { get; set; } + + public bool EmailConfirmed { get; set; } + + public string PhoneNumber { get; set; } + + public bool PhoneNumberConfirmed { get; set; } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityWebhookDefinitionProvider.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityWebhookDefinitionProvider.cs new file mode 100644 index 000000000..4e5745b06 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityWebhookDefinitionProvider.cs @@ -0,0 +1,60 @@ +using Volo.Abp.Identity.Localization; +using Volo.Abp.Localization; + +namespace LINGYUN.Abp.Webhooks.Identity; + +public class IdentityWebhookDefinitionProvider : WebhookDefinitionProvider +{ + public override void Define(IWebhookDefinitionContext context) + { + context.Add(CreateIdentityRoleWebhooks()); + context.Add(CreateIdentityUserWebhooks()); + } + + protected virtual WebhookDefinition[] CreateIdentityRoleWebhooks() + { + return new[] + { + new WebhookDefinition( + IdentityWebhookNames.IdentityRole.Create, + L("Webhooks:CreateRole"), + L("Webhooks:CreateRoleDesc")), + new WebhookDefinition( + IdentityWebhookNames.IdentityRole.Update, + L("Webhooks:UpdateRole"), + L("Webhooks:UpdateRoleDesc")), + new WebhookDefinition( + IdentityWebhookNames.IdentityRole.Delete, + L("Webhooks:DeleteRole"), + L("Webhooks:DeleteRoleDesc")), + new WebhookDefinition( + IdentityWebhookNames.IdentityRole.ChangeName, + L("Webhooks:ChangeRoleName"), + L("Webhooks:ChangeRoleNameDesc")), + }; + } + + protected virtual WebhookDefinition[] CreateIdentityUserWebhooks() + { + return new[] + { + new WebhookDefinition( + IdentityWebhookNames.IdentityUser.Create, + L("Webhooks:CreateUser"), + L("Webhooks:CreateUserDesc")), + new WebhookDefinition( + IdentityWebhookNames.IdentityUser.Update, + L("Webhooks:UpdateUser"), + L("Webhooks:UpdateUserDesc")), + new WebhookDefinition( + IdentityWebhookNames.IdentityUser.Delete, + L("Webhooks:DeleteUser"), + L("Webhooks:DeleteUserDesc")), + }; + } + + private static ILocalizableString L(string name) + { + return LocalizableString.Create(name); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityWebhookNames.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityWebhookNames.cs new file mode 100644 index 000000000..a190f8692 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityWebhookNames.cs @@ -0,0 +1,22 @@ +namespace LINGYUN.Abp.Webhooks.Identity; + +public static class IdentityWebhookNames +{ + public const string GroupName = "abp.identity"; + public static class IdentityRole + { + public const string Prefix = GroupName + ".roles"; + public const string Create = Prefix + ".create"; + public const string Update = Prefix + ".update"; + public const string Delete = Prefix + ".delete"; + public const string ChangeName = Prefix + ".change_name"; + } + + public static class IdentityUser + { + public const string Prefix = GroupName + ".users"; + public const string Create = Prefix + ".create"; + public const string Update = Prefix + ".update"; + public const string Delete = Prefix + ".delete"; + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/Localization/Resources/en.json b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/Localization/Resources/en.json new file mode 100644 index 000000000..9687bcf0e --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/Localization/Resources/en.json @@ -0,0 +1,19 @@ +{ + "culture": "en", + "texts": { + "Webhooks:CreateRole": "Create Role", + "Webhooks:CreateRoleDesc": "A new role has been created", + "Webhooks:UpdateRole": "Update Role", + "Webhooks:UpdateRoleDesc": "A role has changed", + "Webhooks:DeleteRole": "Delete Role", + "Webhooks:DeleteRoleDesc": "Deleted Role", + "Webhooks:ChangeRoleName": "Change Role Name", + "Webhooks:ChangeRoleNameDesc": "The name of a role was changed", + "Webhooks:CreateUser": "Create User", + "Webhooks:CreateUserDesc": "A new user has been created", + "Webhooks:UpdateUser": "Update User", + "Webhooks:UpdateUserDesc": "A user has been changed", + "Webhooks:DeleteUser": "Delete User", + "Webhooks:DeleteUserDesc": "Deleted User" + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/Localization/Resources/zh-Hans.json b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/Localization/Resources/zh-Hans.json new file mode 100644 index 000000000..853a91b01 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/Localization/Resources/zh-Hans.json @@ -0,0 +1,19 @@ +{ + "culture": "zh-Hans", + "texts": { + "Webhooks:CreateRole": "创建角色", + "Webhooks:CreateRoleDesc": "一个新角色已创建", + "Webhooks:UpdateRole": "编辑角色", + "Webhooks:UpdateRoleDesc": "一个角色属性已变更", + "Webhooks:DeleteRole": "删除角色", + "Webhooks:DeleteRoleDesc": "已删除角色", + "Webhooks:ChangeRoleName": "改变角色名称", + "Webhooks:ChangeRoleNameDesc": "一个角色的名称被更改", + "Webhooks:CreateUser": "创建用户", + "Webhooks:CreateUserDesc": "一个新用户已创建", + "Webhooks:UpdateUser": "编辑用户", + "Webhooks:UpdateUserDesc": "一个用户属性已变更", + "Webhooks:DeleteUser": "删除用户", + "Webhooks:DeleteUserDesc": "已删除用户" + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/OrganizationUnitWebHooker.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/OrganizationUnitWebHooker.cs new file mode 100644 index 000000000..fb7e30913 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/OrganizationUnitWebHooker.cs @@ -0,0 +1,49 @@ +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Identity; + +namespace LINGYUN.Abp.Webhooks.Identity; + +public class OrganizationUnitWebHooker : + IDistributedEventHandler>, + IDistributedEventHandler>, + IDistributedEventHandler>, + ITransientDependency +{ + private readonly IWebhookPublisher _webhookPublisher; + + public OrganizationUnitWebHooker( + IWebhookPublisher webhookPublisher) + { + _webhookPublisher = webhookPublisher; + } + + public async virtual Task HandleEventAsync(EntityCreatedEto eventData) + { + await PublishAsync(IdentityWebhookNames.IdentityRole.Create, eventData.Entity); + } + + public async virtual Task HandleEventAsync(EntityUpdatedEto eventData) + { + await PublishAsync(IdentityWebhookNames.IdentityRole.Update, eventData.Entity); + } + + public async virtual Task HandleEventAsync(EntityDeletedEto eventData) + { + await PublishAsync(IdentityWebhookNames.IdentityRole.Delete, eventData.Entity); + } + + protected async virtual Task PublishAsync(string webhookName, OrganizationUnitEto eto) + { + await _webhookPublisher.PublishAsync( + webhookName, + new OrganizationUnitWto + { + Id = eto.Id, + DisplayName = eto.DisplayName + }, + eto.TenantId); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/OrganizationUnitWto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/OrganizationUnitWto.cs new file mode 100644 index 000000000..fb4929b7a --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/OrganizationUnitWto.cs @@ -0,0 +1,12 @@ +using System; + +namespace LINGYUN.Abp.Webhooks.Identity; + +public class OrganizationUnitWto +{ + public Guid Id { get; set; } + + public string Code { get; set; } + + public string DisplayName { get; set; } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksNames.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksNames.cs index 8b185a686..2332b9681 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksNames.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksNames.cs @@ -2,5 +2,5 @@ public static class WebhooksNames { - public const string CheckConnect = "Abp.Webhooks.CheckConnect"; + public const string CheckConnect = "abp.webhooks.check_connect"; } diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj index 85571cc58..79afc282d 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj @@ -57,6 +57,7 @@ + diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs index cd3d2e9be..c6b452fbe 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs @@ -7,6 +7,7 @@ using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; using LINGYUN.Abp.Saas.EntityFrameworkCore; using LINGYUN.Abp.Serilog.Enrichers.Application; using LINGYUN.Abp.Serilog.Enrichers.UniqueId; +using LINGYUN.Abp.Webhooks.Identity; using LINGYUN.Abp.WebhooksManagement; using LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore; using Microsoft.AspNetCore.Builder; @@ -38,6 +39,7 @@ namespace LY.MicroService.WebhooksManagement; typeof(WebhooksManagementApplicationModule), typeof(WebhooksManagementHttpApiModule), typeof(WebhooksManagementEntityFrameworkCoreModule), + typeof(AbpWebhooksIdentityModule), typeof(AbpEntityFrameworkCoreMySQLModule), typeof(AbpAspNetCoreAuthenticationJwtBearerModule), typeof(AbpEmailingExceptionHandlingModule), From fce3123b63c26e37a1c51963dc69867d3813a9ae Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Mon, 28 Mar 2022 11:32:05 +0800 Subject: [PATCH 16/17] feat: Use group isolation of Webhook definitions --- .../Abp/Webhooks/IWebhookDefinitionContext.cs | 24 ++--- .../Abp/Webhooks/IWebhookDefinitionManager.cs | 6 ++ .../Abp/Webhooks/WebhookDefinitionContext.cs | 35 +++--- .../Abp/Webhooks/WebhookDefinitionManager.cs | 30 ++++++ .../Abp/Webhooks/WebhookGroupDefinition.cs | 101 ++++++++++++++++++ .../FodyWeavers.xml | 2 +- .../Identity/IdentityRoleWebHooker.cs | 5 +- .../Identity/IdentityUserWebHooker.cs | 4 +- .../IdentityWebhookDefinitionProvider.cs | 8 +- .../Webhooks/Identity/IdentityWebhookNames.cs | 2 +- .../Identity/Localization/Resources/en.json | 1 + .../Localization/Resources/zh-Hans.json | 1 + .../Identity/OrganizationUnitWebHooker.cs | 4 +- .../LINGYUN.Abp.Webhooks.Saas/FodyWeavers.xml | 3 + .../LINGYUN.Abp.Webhooks.Saas/FodyWeavers.xsd | 30 ++++++ .../LINGYUN.Abp.Webhooks.Saas.csproj | 30 ++++++ .../Webhooks/Saas/AbpWebhooksSaasModule.cs | 30 ++++++ .../Abp/Webhooks/Saas/EditionWebhooker.cs | 48 +++++++++ .../LINGYUN/Abp/Webhooks/Saas/EditionWto.cs | 11 ++ .../Saas/Localization/Resources/en.json | 18 ++++ .../Saas/Localization/Resources/zh-Hans.json | 18 ++++ .../Saas/SaasWebhookDefinitionProvider.cs | 60 +++++++++++ .../Abp/Webhooks/Saas/SaasWebhookNames.cs | 21 ++++ .../Abp/Webhooks/Saas/TenantWebhooker.cs | 48 +++++++++ .../LINGYUN/Abp/Webhooks/Saas/TenantWto.cs | 12 +++ .../IWebhookSubscriptionAppService.cs | 2 +- .../WebhookAvailableGroupDto.cs | 10 ++ .../WebhookSubscriptionAppService.cs | 33 ++++-- .../Localization/Resources/en.json | 7 +- .../Localization/Resources/zh-Hans.json | 7 +- .../Webhooks/WebhooksDefinitionProvider.cs | 10 +- .../Webhooks/WebhooksNames.cs | 4 +- .../WebhookSubscriptionController.cs | 2 +- ...ice.WebhooksManagement.HttpApi.Host.csproj | 1 + .../WebhooksManagementHttpApiHostModule.cs | 2 + 35 files changed, 565 insertions(+), 65 deletions(-) create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookGroupDefinition.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/FodyWeavers.xml create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/FodyWeavers.xsd create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN.Abp.Webhooks.Saas.csproj create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/AbpWebhooksSaasModule.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/EditionWebhooker.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/EditionWto.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/Localization/Resources/en.json create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/Localization/Resources/zh-Hans.json create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/SaasWebhookDefinitionProvider.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/SaasWebhookNames.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/TenantWebhooker.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/TenantWto.cs create mode 100644 aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookAvailableGroupDto.cs diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookDefinitionContext.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookDefinitionContext.cs index 328c214bd..c170ede3d 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookDefinitionContext.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookDefinitionContext.cs @@ -1,22 +1,16 @@ -namespace LINGYUN.Abp.Webhooks +using JetBrains.Annotations; +using Volo.Abp.Localization; + +namespace LINGYUN.Abp.Webhooks { public interface IWebhookDefinitionContext { - /// - /// Adds the specified webhook definition. Throws exception if it is already added - /// - void Add(params WebhookDefinition[] definitions); + WebhookGroupDefinition AddGroup( + [NotNull] string name, + ILocalizableString displayName = null); - /// - /// Gets a webhook definition by name. - /// Returns null if there is no webhook definition with given name. - /// - WebhookDefinition GetOrNull(string name); + WebhookGroupDefinition GetGroupOrNull(string name); - /// - /// Remove webhook with given name - /// - /// webhook definition name - void Remove(string name); + void RemoveGroup(string name); } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookDefinitionManager.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookDefinitionManager.cs index 057b0b984..a284ab693 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookDefinitionManager.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/IWebhookDefinitionManager.cs @@ -23,6 +23,12 @@ namespace LINGYUN.Abp.Webhooks /// IReadOnlyList GetAll(); + /// + /// Gets all webhook group definitions. + /// + /// + IReadOnlyList GetGroups(); + /// /// Checks if given webhook name is available for given tenant. /// diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionContext.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionContext.cs index 4176fc785..5e8987a8b 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionContext.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionContext.cs @@ -7,48 +7,49 @@ namespace LINGYUN.Abp.Webhooks { public class WebhookDefinitionContext : IWebhookDefinitionContext { - protected Dictionary Webhooks { get; } + protected Dictionary Groups { get; } - public WebhookDefinitionContext(Dictionary webhooks) + public WebhookDefinitionContext(Dictionary webhooks) { - Webhooks = webhooks; + Groups = webhooks; } - public void Add(params WebhookDefinition[] definitions) + public WebhookGroupDefinition AddGroup( + [NotNull] string name, + ILocalizableString displayName = null) { - if (definitions.IsNullOrEmpty()) - { - return; - } + Check.NotNull(name, nameof(name)); - foreach (var definition in definitions) + if (Groups.ContainsKey(name)) { - Webhooks[definition.Name] = definition; + throw new AbpException($"There is already an existing webhook group with name: {name}"); } + + return Groups[name] = new WebhookGroupDefinition(name, displayName); } - public WebhookDefinition GetOrNull([NotNull] string name) + public WebhookGroupDefinition GetGroupOrNull([NotNull] string name) { Check.NotNull(name, nameof(name)); - if (!Webhooks.ContainsKey(name)) + if (!Groups.ContainsKey(name)) { return null; } - return Webhooks[name]; + return Groups[name]; } - public void Remove(string name) + public void RemoveGroup(string name) { Check.NotNull(name, nameof(name)); - if (!Webhooks.ContainsKey(name)) + if (!Groups.ContainsKey(name)) { - throw new AbpException($"Undefined notification webhook: '{name}'."); + throw new AbpException($"Undefined notification webhook group: '{name}'."); } - Webhooks.Remove(name); + Groups.Remove(name); } } } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionManager.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionManager.cs index bf70017be..c0f96f20e 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionManager.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookDefinitionManager.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.DependencyInjection; using Volo.Abp.Features; using Volo.Abp.MultiTenancy; @@ -13,6 +14,9 @@ namespace LINGYUN.Abp.Webhooks { internal class WebhookDefinitionManager : IWebhookDefinitionManager, ISingletonDependency { + protected IDictionary WebhookGroupDefinitions => _lazyWebhookGroupDefinitions.Value; + private readonly Lazy> _lazyWebhookGroupDefinitions; + protected IDictionary WebhookDefinitions => _lazyWebhookDefinitions.Value; private readonly Lazy> _lazyWebhookDefinitions; @@ -26,6 +30,7 @@ namespace LINGYUN.Abp.Webhooks _serviceProvider = serviceProvider; _options = options.Value; + _lazyWebhookGroupDefinitions = new Lazy>(CreateWebhookGroupDefinitions); _lazyWebhookDefinitions = new Lazy>(CreateWebhookDefinitions); } @@ -54,6 +59,11 @@ namespace LINGYUN.Abp.Webhooks return WebhookDefinitions.Values.ToImmutableList(); } + public IReadOnlyList GetGroups() + { + return WebhookGroupDefinitions.Values.ToImmutableList(); + } + public async Task IsAvailableAsync(Guid? tenantId, string name) { if (tenantId == null) // host allowed to subscribe all webhooks @@ -90,6 +100,26 @@ namespace LINGYUN.Abp.Webhooks { var definitions = new Dictionary(); + foreach (var groupDefinition in WebhookGroupDefinitions.Values) + { + foreach (var webhook in groupDefinition.Webhooks) + { + if (definitions.ContainsKey(webhook.Name)) + { + throw new AbpException("Duplicate webhook name: " + webhook.Name); + } + + definitions[webhook.Name] = webhook; + } + } + + return definitions; + } + + protected virtual Dictionary CreateWebhookGroupDefinitions() + { + var definitions = new Dictionary(); + using (var scope = _serviceProvider.CreateScope()) { var providers = _options diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookGroupDefinition.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookGroupDefinition.cs new file mode 100644 index 000000000..ae58049ed --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebHooks/LINGYUN/Abp/Webhooks/WebhookGroupDefinition.cs @@ -0,0 +1,101 @@ +using JetBrains.Annotations; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using Volo.Abp; +using Volo.Abp.Localization; + +namespace LINGYUN.Abp.Webhooks; + +public class WebhookGroupDefinition +{ + [NotNull] + public string Name { get; set; } + public Dictionary Properties { get; } + + private ILocalizableString _displayName; + public ILocalizableString DisplayName + { + get { + return _displayName; + } + set { + _displayName = value; + } + } + + public IReadOnlyList Webhooks => _webhooks.ToImmutableList(); + private readonly List _webhooks; + public object this[string name] { + get => Properties.GetOrDefault(name); + set => Properties[name] = value; + } + + protected internal WebhookGroupDefinition( + string name, + ILocalizableString displayName = null) + { + Name = name; + DisplayName = displayName ?? new FixedLocalizableString(Name); + + Properties = new Dictionary(); + _webhooks = new List(); + } + + public virtual WebhookDefinition AddWebhook( + string name, + ILocalizableString displayName = null, + ILocalizableString description = null) + { + if (Webhooks.Any(hook => hook.Name.Equals(name))) + { + throw new AbpException($"There is already an existing webhook with name: {name} in group {Name}"); + } + + var webhook = new WebhookDefinition( + name, + displayName, + description + ); + + _webhooks.Add(webhook); + + return webhook; + } + + public virtual void AddWebhooks(params WebhookDefinition[] webhooks) + { + foreach (var webhook in webhooks) + { + if (Webhooks.Any(hook => hook.Name.Equals(webhook.Name))) + { + throw new AbpException($"There is already an existing webhook with name: {webhook.Name} in group {Name}"); + } + } + + _webhooks.AddRange(webhooks); + } + + + + [CanBeNull] + public WebhookDefinition GetWebhookOrNull([NotNull] string name) + { + Check.NotNull(name, nameof(name)); + + foreach (var webhook in Webhooks) + { + if (webhook.Name == name) + { + return webhook; + } + } + + return null; + } + + public override string ToString() + { + return $"[{nameof(WebhookGroupDefinition)} {Name}]"; + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/FodyWeavers.xml b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/FodyWeavers.xml index ac6b5b292..c485a4548 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/FodyWeavers.xml +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/FodyWeavers.xml @@ -1,3 +1,3 @@  - + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleWebHooker.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleWebHooker.cs index ee1fdaee6..5d60012c0 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleWebHooker.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleWebHooker.cs @@ -6,15 +6,16 @@ using Volo.Abp.Identity; namespace LINGYUN.Abp.Webhooks.Identity; -public class IdentityRoleWebHooker : +public class IdentityRoleWebhooker : IDistributedEventHandler>, IDistributedEventHandler>, + IDistributedEventHandler>, IDistributedEventHandler, ITransientDependency { private readonly IWebhookPublisher _webhookPublisher; - public IdentityRoleWebHooker( + public IdentityRoleWebhooker( IWebhookPublisher webhookPublisher) { _webhookPublisher = webhookPublisher; diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityUserWebHooker.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityUserWebHooker.cs index fc48c2cab..7dc188cf5 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityUserWebHooker.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityUserWebHooker.cs @@ -6,7 +6,7 @@ using Volo.Abp.Users; namespace LINGYUN.Abp.Webhooks.Identity; -public class IdentityUserWebHooker : +public class IdentityUserWebhooker : IDistributedEventHandler>, IDistributedEventHandler>, IDistributedEventHandler>, @@ -14,7 +14,7 @@ public class IdentityUserWebHooker : { private readonly IWebhookPublisher _webhookPublisher; - public IdentityUserWebHooker( + public IdentityUserWebhooker( IWebhookPublisher webhookPublisher) { _webhookPublisher = webhookPublisher; diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityWebhookDefinitionProvider.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityWebhookDefinitionProvider.cs index 4e5745b06..6c243b942 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityWebhookDefinitionProvider.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityWebhookDefinitionProvider.cs @@ -7,8 +7,12 @@ public class IdentityWebhookDefinitionProvider : WebhookDefinitionProvider { public override void Define(IWebhookDefinitionContext context) { - context.Add(CreateIdentityRoleWebhooks()); - context.Add(CreateIdentityUserWebhooks()); + var identityGroup = context.AddGroup( + IdentityWebhookNames.GroupName, + L("Webhooks:Identity")); + + identityGroup.AddWebhooks(CreateIdentityRoleWebhooks()); + identityGroup.AddWebhooks(CreateIdentityUserWebhooks()); } protected virtual WebhookDefinition[] CreateIdentityRoleWebhooks() diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityWebhookNames.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityWebhookNames.cs index a190f8692..be7fa0232 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityWebhookNames.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityWebhookNames.cs @@ -2,7 +2,7 @@ public static class IdentityWebhookNames { - public const string GroupName = "abp.identity"; + public const string GroupName = "abp.webhooks.identity"; public static class IdentityRole { public const string Prefix = GroupName + ".roles"; diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/Localization/Resources/en.json b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/Localization/Resources/en.json index 9687bcf0e..05df4003d 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/Localization/Resources/en.json +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/Localization/Resources/en.json @@ -1,6 +1,7 @@ { "culture": "en", "texts": { + "Webhooks:Identity": "Identity", "Webhooks:CreateRole": "Create Role", "Webhooks:CreateRoleDesc": "A new role has been created", "Webhooks:UpdateRole": "Update Role", diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/Localization/Resources/zh-Hans.json b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/Localization/Resources/zh-Hans.json index 853a91b01..eb06d0489 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/Localization/Resources/zh-Hans.json +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/Localization/Resources/zh-Hans.json @@ -1,6 +1,7 @@ { "culture": "zh-Hans", "texts": { + "Webhooks:Identity": "身份认证", "Webhooks:CreateRole": "创建角色", "Webhooks:CreateRoleDesc": "一个新角色已创建", "Webhooks:UpdateRole": "编辑角色", diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/OrganizationUnitWebHooker.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/OrganizationUnitWebHooker.cs index fb7e30913..a259bc16b 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/OrganizationUnitWebHooker.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/OrganizationUnitWebHooker.cs @@ -6,7 +6,7 @@ using Volo.Abp.Identity; namespace LINGYUN.Abp.Webhooks.Identity; -public class OrganizationUnitWebHooker : +public class OrganizationUnitWebhooker : IDistributedEventHandler>, IDistributedEventHandler>, IDistributedEventHandler>, @@ -14,7 +14,7 @@ public class OrganizationUnitWebHooker : { private readonly IWebhookPublisher _webhookPublisher; - public OrganizationUnitWebHooker( + public OrganizationUnitWebhooker( IWebhookPublisher webhookPublisher) { _webhookPublisher = webhookPublisher; diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/FodyWeavers.xml b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/FodyWeavers.xml new file mode 100644 index 000000000..c485a4548 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/FodyWeavers.xsd b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN.Abp.Webhooks.Saas.csproj b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN.Abp.Webhooks.Saas.csproj new file mode 100644 index 000000000..66d9fa1b8 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN.Abp.Webhooks.Saas.csproj @@ -0,0 +1,30 @@ + + + + + + + netstandard2.0 + + + + + + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/AbpWebhooksSaasModule.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/AbpWebhooksSaasModule.cs new file mode 100644 index 000000000..93567e45a --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/AbpWebhooksSaasModule.cs @@ -0,0 +1,30 @@ +using LINGYUN.Abp.Saas; +using LINGYUN.Abp.Saas.Localization; +using Volo.Abp.Domain; +using Volo.Abp.EventBus; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; + +namespace LINGYUN.Abp.Webhooks.Saas; + +[DependsOn(typeof(AbpDddDomainModule))] +[DependsOn(typeof(AbpEventBusModule))] +[DependsOn(typeof(AbpSaasDomainSharedModule))] +public class AbpWebhooksSaasModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + + Configure(options => + { + options.Resources + .Get() + .AddVirtualJson("/LINGYUN/Abp/Webhooks/Saas/Localization/Resources"); + }); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/EditionWebhooker.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/EditionWebhooker.cs new file mode 100644 index 000000000..fffdd0328 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/EditionWebhooker.cs @@ -0,0 +1,48 @@ +using LINGYUN.Abp.Saas.Editions; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EventBus.Distributed; + +namespace LINGYUN.Abp.Webhooks.Saas; + +public class EditionWebhooker : + IDistributedEventHandler>, + IDistributedEventHandler>, + IDistributedEventHandler>, + ITransientDependency +{ + private readonly IWebhookPublisher _webhookPublisher; + + public EditionWebhooker( + IWebhookPublisher webhookPublisher) + { + _webhookPublisher = webhookPublisher; + } + + public async virtual Task HandleEventAsync(EntityCreatedEto eventData) + { + await PublishAsync(SaasWebhookNames.Edition.Create, eventData.Entity); + } + + public async virtual Task HandleEventAsync(EntityUpdatedEto eventData) + { + await PublishAsync(SaasWebhookNames.Edition.Update, eventData.Entity); + } + + public async virtual Task HandleEventAsync(EntityDeletedEto eventData) + { + await PublishAsync(SaasWebhookNames.Edition.Delete, eventData.Entity); + } + + protected async virtual Task PublishAsync(string webhookName, EditionEto eto) + { + await _webhookPublisher.PublishAsync( + webhookName, + new EditionWto + { + Id = eto.Id, + DisplayName = eto.DisplayName + }); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/EditionWto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/EditionWto.cs new file mode 100644 index 000000000..8a3a1208b --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/EditionWto.cs @@ -0,0 +1,11 @@ +using System; + +namespace LINGYUN.Abp.Webhooks.Saas; + +[Serializable] +public class EditionWto +{ + public Guid Id { get; set; } + + public string DisplayName { get; set; } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/Localization/Resources/en.json b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/Localization/Resources/en.json new file mode 100644 index 000000000..fdafcd2d1 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/Localization/Resources/en.json @@ -0,0 +1,18 @@ +{ + "culture": "en", + "texts": { + "Webhooks:Saas": "Saas", + "Webhooks:CreateEdition": "Create Edition", + "Webhooks:CreateEditionDesc": "A new Edition has been created", + "Webhooks:UpdateEdition": "Update Edition", + "Webhooks:UpdateEditionDesc": "A Edition has changed", + "Webhooks:DeleteEdition": "Delete Edition", + "Webhooks:DeleteEditionDesc": "Deleted Edition", + "Webhooks:CreateTenant": "Create Tenant", + "Webhooks:CreateTenantDesc": "A new Tenant has been created", + "Webhooks:UpdateTenant": "Update Tenant", + "Webhooks:UpdateTenantDesc": "A Tenant has been changed", + "Webhooks:DeleteTenant": "Delete Tenant", + "Webhooks:DeleteTenantDesc": "Deleted Tenant" + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/Localization/Resources/zh-Hans.json b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/Localization/Resources/zh-Hans.json new file mode 100644 index 000000000..fd5ddbf30 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/Localization/Resources/zh-Hans.json @@ -0,0 +1,18 @@ +{ + "culture": "zh-Hans", + "texts": { + "Webhooks:Saas": "Saas", + "Webhooks:CreateEdition": "创建版本", + "Webhooks:CreateEditionDesc": "一个新版本已创建", + "Webhooks:UpdateEdition": "编辑版本", + "Webhooks:UpdateEditionDesc": "一个版本属性已变更", + "Webhooks:DeleteEdition": "删除版本", + "Webhooks:DeleteEditionDesc": "已删除版本", + "Webhooks:CreateTenant": "创建租户", + "Webhooks:CreateTenantDesc": "一个新租户已创建", + "Webhooks:UpdateTenant": "编辑租户", + "Webhooks:UpdateTenantDesc": "一个租户属性已变更", + "Webhooks:DeleteTenant": "删除租户", + "Webhooks:DeleteTenantDesc": "已删除租户" + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/SaasWebhookDefinitionProvider.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/SaasWebhookDefinitionProvider.cs new file mode 100644 index 000000000..b2624f179 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/SaasWebhookDefinitionProvider.cs @@ -0,0 +1,60 @@ +using LINGYUN.Abp.Saas.Localization; +using Volo.Abp.Localization; + +namespace LINGYUN.Abp.Webhooks.Saas; + +public class SaasWebhookDefinitionProvider : WebhookDefinitionProvider +{ + public override void Define(IWebhookDefinitionContext context) + { + var saasGroup = context.AddGroup( + SaasWebhookNames.GroupName, + L("Webhooks:Saas")); + + saasGroup.AddWebhooks(CreateEditionWebhooks()); + saasGroup.AddWebhooks(CreateTenantWebhooks()); + } + + protected virtual WebhookDefinition[] CreateEditionWebhooks() + { + return new[] + { + new WebhookDefinition( + SaasWebhookNames.Edition.Create, + L("Webhooks:CreateEdition"), + L("Webhooks:CreateEditionDesc")), + new WebhookDefinition( + SaasWebhookNames.Edition.Update, + L("Webhooks:UpdateEdition"), + L("Webhooks:UpdateEditionDesc")), + new WebhookDefinition( + SaasWebhookNames.Edition.Delete, + L("Webhooks:DeleteEdition"), + L("Webhooks:DeleteEditionDesc")), + }; + } + + protected virtual WebhookDefinition[] CreateTenantWebhooks() + { + return new[] + { + new WebhookDefinition( + SaasWebhookNames.Tenant.Create, + L("Webhooks:CreateTenant"), + L("Webhooks:CreateTenantDesc")), + new WebhookDefinition( + SaasWebhookNames.Tenant.Update, + L("Webhooks:UpdateTenant"), + L("Webhooks:UpdateTenantDesc")), + new WebhookDefinition( + SaasWebhookNames.Tenant.Delete, + L("Webhooks:DeleteTenant"), + L("Webhooks:DeleteTenantDesc")), + }; + } + + private static ILocalizableString L(string name) + { + return LocalizableString.Create(name); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/SaasWebhookNames.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/SaasWebhookNames.cs new file mode 100644 index 000000000..399903fc6 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/SaasWebhookNames.cs @@ -0,0 +1,21 @@ +namespace LINGYUN.Abp.Webhooks.Saas; + +public static class SaasWebhookNames +{ + public const string GroupName = "abp.webhooks.saas"; + public static class Edition + { + public const string Prefix = GroupName + ".editions"; + public const string Create = Prefix + ".create"; + public const string Update = Prefix + ".update"; + public const string Delete = Prefix + ".delete"; + } + + public static class Tenant + { + public const string Prefix = GroupName + ".tenants"; + public const string Create = Prefix + ".create"; + public const string Update = Prefix + ".update"; + public const string Delete = Prefix + ".delete"; + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/TenantWebhooker.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/TenantWebhooker.cs new file mode 100644 index 000000000..916fd8f3b --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/TenantWebhooker.cs @@ -0,0 +1,48 @@ +using LINGYUN.Abp.Saas.Tenants; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EventBus.Distributed; + +namespace LINGYUN.Abp.Webhooks.Saas; + +public class TenantWebhooker : + IDistributedEventHandler>, + IDistributedEventHandler>, + IDistributedEventHandler>, + ITransientDependency +{ + private readonly IWebhookPublisher _webhookPublisher; + + public TenantWebhooker( + IWebhookPublisher webhookPublisher) + { + _webhookPublisher = webhookPublisher; + } + + public async virtual Task HandleEventAsync(EntityCreatedEto eventData) + { + await PublishAsync(SaasWebhookNames.Tenant.Create, eventData.Entity); + } + + public async virtual Task HandleEventAsync(EntityUpdatedEto eventData) + { + await PublishAsync(SaasWebhookNames.Tenant.Update, eventData.Entity); + } + + public async virtual Task HandleEventAsync(EntityDeletedEto eventData) + { + await PublishAsync(SaasWebhookNames.Tenant.Delete, eventData.Entity); + } + + protected async virtual Task PublishAsync(string webhookName, TenantEto eto) + { + await _webhookPublisher.PublishAsync( + webhookName, + new TenantWto + { + Id = eto.Id, + Name = eto.Name + }); + } +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/TenantWto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/TenantWto.cs new file mode 100644 index 000000000..ba2d4ef0d --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Saas/LINGYUN/Abp/Webhooks/Saas/TenantWto.cs @@ -0,0 +1,12 @@ +using System; + +namespace LINGYUN.Abp.Webhooks.Saas; + +[Serializable] +public class TenantWto +{ + public Guid Id { get; set; } + + public string Name { get; set; } +} + diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionAppService.cs index 1de23c039..132fcbd73 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionAppService.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/IWebhookSubscriptionAppService.cs @@ -13,5 +13,5 @@ public interface IWebhookSubscriptionAppService : WebhookSubscriptionCreateInput, WebhookSubscriptionUpdateInput> { - Task> GetAllAvailableWebhooksAsync(); + Task> GetAllAvailableWebhooksAsync(); } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookAvailableGroupDto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookAvailableGroupDto.cs new file mode 100644 index 000000000..37a3c8fe1 --- /dev/null +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application.Contracts/LINGYUN/Abp/WebhooksManagement/WebhookAvailableGroupDto.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace LINGYUN.Abp.WebhooksManagement; + +public class WebhookAvailableGroupDto +{ + public string Name { get; set; } + public string DisplayName { get; set; } + public List Webhooks { get; set; } = new List(); +} diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionAppService.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionAppService.cs index a59b2e84e..3b140c91b 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionAppService.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Application/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionAppService.cs @@ -103,25 +103,36 @@ public class WebhookSubscriptionAppService : WebhooksManagementAppServiceBase, I return subscription.ToWebhookSubscriptionDto(); } - public async virtual Task> GetAllAvailableWebhooksAsync() + public async virtual Task> GetAllAvailableWebhooksAsync() { - var webhooks = WebhookDefinitionManager.GetAll(); - var definitions = new List(); + var groups = WebhookDefinitionManager.GetGroups(); + var definitions = new List(); - foreach (var webhookDefinition in webhooks) + foreach (var groupDefinition in groups) { - if (await WebhookDefinitionManager.IsAvailableAsync(CurrentTenant.Id, webhookDefinition.Name)) + var group = new WebhookAvailableGroupDto { - definitions.Add(new WebhookAvailableDto + Name = groupDefinition.Name, + DisplayName = groupDefinition.DisplayName?.Localize(StringLocalizerFactory), + }; + + foreach (var webhookDefinition in groupDefinition.Webhooks.OrderBy(d => d.Name)) + { + if (await WebhookDefinitionManager.IsAvailableAsync(CurrentTenant.Id, webhookDefinition.Name)) { - Name = webhookDefinition.Name, - Description = webhookDefinition.Description?.Localize(StringLocalizerFactory), - DisplayName = webhookDefinition.DisplayName?.Localize(StringLocalizerFactory) - }); + group.Webhooks.Add(new WebhookAvailableDto + { + Name = webhookDefinition.Name, + Description = webhookDefinition.Description?.Localize(StringLocalizerFactory), + DisplayName = webhookDefinition.DisplayName?.Localize(StringLocalizerFactory) + }); + } } + + definitions.Add(group); } - return new ListResultDto(definitions.OrderBy(d => d.Name).ToList()); + return new ListResultDto(definitions.OrderBy(d => d.Name).ToList()); } protected async virtual Task CheckSubscribedAsync(WebhookSubscriptionCreateOrUpdateInput input) diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json index b3828f603..a64f32f2a 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/en.json @@ -11,8 +11,9 @@ "Permission:Resend": "Resend", "Permission:Publish": "Publish", "Permission:ManageSettings": "Manage Settings", - "DisplayName:CheckConnect": "Check Connect", - "Description:CheckConnect": "When a third-party service is connected, it is used to check whether the communication is normal.", - "Webhooks:010001": "Payload address {WebhookUri} has been mounted event {Webhooks}!" + "Webhooks:010001": "Payload address {WebhookUri} has been mounted event {Webhooks}!", + "Webhooks:Tests": "Tests", + "Webhooks:CheckConnect": "Check Connect", + "Webhooks:CheckConnectDesc": "When a third-party service is connected, it is used to check whether the communication is normal." } } \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json index d20d0efdd..efb4975cd 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/Localization/Resources/zh-Hans.json @@ -11,8 +11,9 @@ "Permission:Resend": "重新发送", "Permission:Publish": "发布事件", "Permission:ManageSettings": "管理设置", - "DisplayName:CheckConnect": "检查连接", - "Description:CheckConnect": "第三方服务接入时,用于检查是否通讯正常.", - "Webhooks:010001": "载荷地址 {WebhookUri} 已经挂载事件 {Webhooks}!" + "Webhooks:010001": "载荷地址 {WebhookUri} 已经挂载事件 {Webhooks}!", + "Webhooks:Tests": "测试", + "Webhooks:CheckConnect": "检查连接", + "Webhooks:CheckConnectDesc": "第三方服务接入时,用于检查是否通讯正常." } } \ No newline at end of file diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksDefinitionProvider.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksDefinitionProvider.cs index 9b5e7ce48..0389c1573 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksDefinitionProvider.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksDefinitionProvider.cs @@ -8,11 +8,15 @@ public class WebhooksDefinitionProvider : WebhookDefinitionProvider { public override void Define(IWebhookDefinitionContext context) { - context.Add( + var testsGroup = context.AddGroup( + WebhooksNames.GroupName, + L("Webhooks:Tests")); + + testsGroup.AddWebhooks( new WebhookDefinition( WebhooksNames.CheckConnect, - L("DisplayName:CheckConnect"), - L("Description:CheckConnect"))); + L("Webhooks:CheckConnect"), + L("Webhooks:CheckConnectDesc"))); } private static ILocalizableString L(string name) diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksNames.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksNames.cs index 2332b9681..f650eec4b 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksNames.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/Webhooks/WebhooksNames.cs @@ -2,5 +2,7 @@ public static class WebhooksNames { - public const string CheckConnect = "abp.webhooks.check_connect"; + public const string GroupName = "abp.webhooks.tests"; + + public const string CheckConnect = GroupName + ".check_connect"; } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionController.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionController.cs index 5e42551d2..4cabc602e 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionController.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.HttpApi/LINGYUN/Abp/WebhooksManagement/WebhookSubscriptionController.cs @@ -59,7 +59,7 @@ public class WebhookSubscriptionController : WebhooksManagementControllerBase, I [HttpGet] [Route("availables")] - public Task> GetAllAvailableWebhooksAsync() + public Task> GetAllAvailableWebhooksAsync() { return SubscriptionAppService.GetAllAvailableWebhooksAsync(); } diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj index 79afc282d..78cda36e2 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj @@ -58,6 +58,7 @@ + diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs index c6b452fbe..fe0d5379e 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs @@ -8,6 +8,7 @@ using LINGYUN.Abp.Saas.EntityFrameworkCore; using LINGYUN.Abp.Serilog.Enrichers.Application; using LINGYUN.Abp.Serilog.Enrichers.UniqueId; using LINGYUN.Abp.Webhooks.Identity; +using LINGYUN.Abp.Webhooks.Saas; using LINGYUN.Abp.WebhooksManagement; using LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore; using Microsoft.AspNetCore.Builder; @@ -40,6 +41,7 @@ namespace LY.MicroService.WebhooksManagement; typeof(WebhooksManagementHttpApiModule), typeof(WebhooksManagementEntityFrameworkCoreModule), typeof(AbpWebhooksIdentityModule), + typeof(AbpWebhooksSaasModule), typeof(AbpEntityFrameworkCoreMySQLModule), typeof(AbpAspNetCoreAuthenticationJwtBearerModule), typeof(AbpEmailingExceptionHandlingModule), From 38bf96699522184f73dad9603e4c96c1d1eec4a8 Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Mon, 28 Mar 2022 11:34:11 +0800 Subject: [PATCH 17/17] feat: added serialization attribute --- .../LINGYUN/Abp/Webhooks/Identity/IdentityRoleNameChangedWto.cs | 1 + .../LINGYUN/Abp/Webhooks/Identity/IdentityRoleWto.cs | 1 + .../LINGYUN/Abp/Webhooks/Identity/IdentityUserWto.cs | 1 + .../LINGYUN/Abp/Webhooks/Identity/OrganizationUnitWto.cs | 1 + 4 files changed, 4 insertions(+) diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleNameChangedWto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleNameChangedWto.cs index 5f55b78cf..c91615749 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleNameChangedWto.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleNameChangedWto.cs @@ -2,6 +2,7 @@ namespace LINGYUN.Abp.Webhooks.Identity; +[Serializable] public class IdentityRoleNameChangedWto { public Guid Id { get; set; } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleWto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleWto.cs index 123a9f2dc..1271a5877 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleWto.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityRoleWto.cs @@ -2,6 +2,7 @@ namespace LINGYUN.Abp.Webhooks.Identity; +[Serializable] public class IdentityRoleWto { public Guid Id { get; set; } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityUserWto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityUserWto.cs index e5bf48665..29da00874 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityUserWto.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/IdentityUserWto.cs @@ -2,6 +2,7 @@ namespace LINGYUN.Abp.Webhooks.Identity; +[Serializable] public class IdentityUserWto { public Guid Id { get; set; } diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/OrganizationUnitWto.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/OrganizationUnitWto.cs index fb4929b7a..3dd758890 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/OrganizationUnitWto.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Identity/LINGYUN/Abp/Webhooks/Identity/OrganizationUnitWto.cs @@ -2,6 +2,7 @@ namespace LINGYUN.Abp.Webhooks.Identity; +[Serializable] public class OrganizationUnitWto { public Guid Id { get; set; }