From 83dda99bdad4d8afe49c98893378b8d14f0fa698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Sat, 4 Jun 2022 23:15:41 +0300 Subject: [PATCH 1/5] Introduced IntegrationService --- .../Volo/Abp/Auditing/AbpAuditingOptions.cs | 6 + .../Volo.Abp.Core/Volo/Abp/IRemoteService.cs | 2 +- .../Services/IApplicationService.cs | 5 +- .../Application/AbpDddApplicationModule.cs | 4 +- .../Services/ApplicationService.cs | 133 +----------------- .../Services/ApplicationServiceBase.cs | 133 ++++++++++++++++++ .../Services/IntegrationService.cs | 7 + .../Services/IntegrationServiceAttribute.cs | 9 ++ 8 files changed, 163 insertions(+), 136 deletions(-) create mode 100644 framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationServiceBase.cs create mode 100644 framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IntegrationService.cs create mode 100644 framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IntegrationServiceAttribute.cs diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AbpAuditingOptions.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AbpAuditingOptions.cs index b3c6aeb051..441cd8ef23 100644 --- a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AbpAuditingOptions.cs +++ b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AbpAuditingOptions.cs @@ -37,6 +37,12 @@ public class AbpAuditingOptions /// Default: true. /// public bool AlwaysLogOnException { get; set; } + + /// + /// Disables/enables audit logging for integration services. + /// Default: false. + /// + public bool IsEnabledForIntegrationServices { get; set; } public List>> AlwaysLogSelectors { get; } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/IRemoteService.cs b/framework/src/Volo.Abp.Core/Volo/Abp/IRemoteService.cs index f17a0619dc..613781629c 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/IRemoteService.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/IRemoteService.cs @@ -1,5 +1,5 @@ namespace Volo.Abp; -public interface IRemoteService //TODO: Can we move this to another package? +public interface IRemoteService { } diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/IApplicationService.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/IApplicationService.cs index 34fe187f81..ce59e46832 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/IApplicationService.cs +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/IApplicationService.cs @@ -3,8 +3,7 @@ /// /// This interface must be implemented by all application services to register and identify them by convention. /// -public interface IApplicationService : - IRemoteService +public interface IApplicationService : IRemoteService { -} +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/AbpDddApplicationModule.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/AbpDddApplicationModule.cs index 38a7efdb2e..0608171aeb 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/AbpDddApplicationModule.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/AbpDddApplicationModule.cs @@ -33,10 +33,10 @@ public class AbpDddApplicationModule : AbpModule { Configure(options => { - //TODO: Should we move related items to their own projects? - options.IgnoredInterfaces.AddIfNotContains(typeof(IRemoteService)); + options.IgnoredInterfaces.AddIfNotContains(typeof(IRemoteService)); options.IgnoredInterfaces.AddIfNotContains(typeof(IApplicationService)); options.IgnoredInterfaces.AddIfNotContains(typeof(IUnitOfWorkEnabled)); + //TODO: Should we add others, like IAuditingEnabled...? }); } } diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs index 03b2857ddc..8389cf3fa4 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs @@ -1,133 +1,6 @@ -using JetBrains.Annotations; -using Microsoft.AspNetCore.Authorization; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Localization; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Volo.Abp.Aspects; -using Volo.Abp.Auditing; -using Volo.Abp.Authorization; -using Volo.Abp.Data; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Features; -using Volo.Abp.GlobalFeatures; -using Volo.Abp.Guids; -using Volo.Abp.Linq; -using Volo.Abp.Localization; -using Volo.Abp.MultiTenancy; -using Volo.Abp.ObjectMapping; -using Volo.Abp.Settings; -using Volo.Abp.Timing; -using Volo.Abp.Uow; -using Volo.Abp.Users; -using Volo.Abp.Validation; - namespace Volo.Abp.Application.Services; -public abstract class ApplicationService : - IApplicationService, - IAvoidDuplicateCrossCuttingConcerns, - IValidationEnabled, - IUnitOfWorkEnabled, - IAuditingEnabled, - IGlobalFeatureCheckingEnabled, - ITransientDependency +public abstract class ApplicationService : ApplicationServiceBase { - public IAbpLazyServiceProvider LazyServiceProvider { get; set; } - - [Obsolete("Use LazyServiceProvider instead.")] - public IServiceProvider ServiceProvider { get; set; } - - public static string[] CommonPostfixes { get; set; } = { "AppService", "ApplicationService", "Service" }; - - public List AppliedCrossCuttingConcerns { get; } = new List(); - - protected IUnitOfWorkManager UnitOfWorkManager => LazyServiceProvider.LazyGetRequiredService(); - - protected IAsyncQueryableExecuter AsyncExecuter => LazyServiceProvider.LazyGetRequiredService(); - - protected Type ObjectMapperContext { get; set; } - protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetService(provider => - ObjectMapperContext == null - ? provider.GetRequiredService() - : (IObjectMapper)provider.GetRequiredService(typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext))); - - protected IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService(SimpleGuidGenerator.Instance); - - protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService(); - - protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService(); - - protected IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService(); - - protected ICurrentUser CurrentUser => LazyServiceProvider.LazyGetRequiredService(); - - protected ISettingProvider SettingProvider => LazyServiceProvider.LazyGetRequiredService(); - - protected IClock Clock => LazyServiceProvider.LazyGetRequiredService(); - - protected IAuthorizationService AuthorizationService => LazyServiceProvider.LazyGetRequiredService(); - - protected IFeatureChecker FeatureChecker => LazyServiceProvider.LazyGetRequiredService(); - - protected IStringLocalizerFactory StringLocalizerFactory => LazyServiceProvider.LazyGetRequiredService(); - - protected IStringLocalizer L { - get { - if (_localizer == null) - { - _localizer = CreateLocalizer(); - } - - return _localizer; - } - } - private IStringLocalizer _localizer; - - protected Type LocalizationResource { - get => _localizationResource; - set { - _localizationResource = value; - _localizer = null; - } - } - private Type _localizationResource = typeof(DefaultResource); - - protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current; - - protected ILogger Logger => LazyServiceProvider.LazyGetService(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance); - - /// - /// Checks for given . - /// Throws if given policy has not been granted. - /// - /// The policy name. This method does nothing if given is null or empty. - protected virtual async Task CheckPolicyAsync([CanBeNull] string policyName) - { - if (string.IsNullOrEmpty(policyName)) - { - return; - } - - await AuthorizationService.CheckAsync(policyName); - } - - protected virtual IStringLocalizer CreateLocalizer() - { - if (LocalizationResource != null) - { - return StringLocalizerFactory.Create(LocalizationResource); - } - - var localizer = StringLocalizerFactory.CreateDefaultOrNull(); - if (localizer == null) - { - throw new AbpException($"Set {nameof(LocalizationResource)} or define the default localization resource type (by configuring the {nameof(AbpLocalizationOptions)}.{nameof(AbpLocalizationOptions.DefaultResourceType)}) to be able to use the {nameof(L)} object!"); - } - - return localizer; - } -} + +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationServiceBase.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationServiceBase.cs new file mode 100644 index 0000000000..7ed9ba5d5a --- /dev/null +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationServiceBase.cs @@ -0,0 +1,133 @@ +using JetBrains.Annotations; +using Microsoft.AspNetCore.Authorization; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Aspects; +using Volo.Abp.Auditing; +using Volo.Abp.Authorization; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Features; +using Volo.Abp.GlobalFeatures; +using Volo.Abp.Guids; +using Volo.Abp.Linq; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; +using Volo.Abp.ObjectMapping; +using Volo.Abp.Settings; +using Volo.Abp.Timing; +using Volo.Abp.Uow; +using Volo.Abp.Users; +using Volo.Abp.Validation; + +namespace Volo.Abp.Application.Services; + +public abstract class ApplicationServiceBase : + IApplicationService, + IAvoidDuplicateCrossCuttingConcerns, + IValidationEnabled, + IUnitOfWorkEnabled, + IAuditingEnabled, + IGlobalFeatureCheckingEnabled, + ITransientDependency +{ + public IAbpLazyServiceProvider LazyServiceProvider { get; set; } + + [Obsolete("Use LazyServiceProvider instead.")] + public IServiceProvider ServiceProvider { get; set; } + + public static string[] CommonPostfixes { get; set; } = { "AppService", "ApplicationService", "IntService", "IntegrationService", "Service" }; + + public List AppliedCrossCuttingConcerns { get; } = new(); + + protected IUnitOfWorkManager UnitOfWorkManager => LazyServiceProvider.LazyGetRequiredService(); + + protected IAsyncQueryableExecuter AsyncExecuter => LazyServiceProvider.LazyGetRequiredService(); + + protected Type ObjectMapperContext { get; set; } + protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetService(provider => + ObjectMapperContext == null + ? provider.GetRequiredService() + : (IObjectMapper)provider.GetRequiredService(typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext))); + + protected IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService(SimpleGuidGenerator.Instance); + + protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService(); + + protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService(); + + protected IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService(); + + protected ICurrentUser CurrentUser => LazyServiceProvider.LazyGetRequiredService(); + + protected ISettingProvider SettingProvider => LazyServiceProvider.LazyGetRequiredService(); + + protected IClock Clock => LazyServiceProvider.LazyGetRequiredService(); + + protected IAuthorizationService AuthorizationService => LazyServiceProvider.LazyGetRequiredService(); + + protected IFeatureChecker FeatureChecker => LazyServiceProvider.LazyGetRequiredService(); + + protected IStringLocalizerFactory StringLocalizerFactory => LazyServiceProvider.LazyGetRequiredService(); + + protected IStringLocalizer L { + get { + if (_localizer == null) + { + _localizer = CreateLocalizer(); + } + + return _localizer; + } + } + private IStringLocalizer _localizer; + + protected Type LocalizationResource { + get => _localizationResource; + set { + _localizationResource = value; + _localizer = null; + } + } + private Type _localizationResource = typeof(DefaultResource); + + protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current; + + protected ILogger Logger => LazyServiceProvider.LazyGetService(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance); + + /// + /// Checks for given . + /// Throws if given policy has not been granted. + /// + /// The policy name. This method does nothing if given is null or empty. + protected virtual async Task CheckPolicyAsync([CanBeNull] string policyName) + { + if (string.IsNullOrEmpty(policyName)) + { + return; + } + + await AuthorizationService.CheckAsync(policyName); + } + + protected virtual IStringLocalizer CreateLocalizer() + { + if (LocalizationResource != null) + { + return StringLocalizerFactory.Create(LocalizationResource); + } + + var localizer = StringLocalizerFactory.CreateDefaultOrNull(); + if (localizer == null) + { + throw new AbpException($"Set {nameof(LocalizationResource)} or define the default localization resource type (by configuring the {nameof(AbpLocalizationOptions)}.{nameof(AbpLocalizationOptions.DefaultResourceType)}) to be able to use the {nameof(L)} object!"); + } + + return localizer; + } +} diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IntegrationService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IntegrationService.cs new file mode 100644 index 0000000000..805c3891af --- /dev/null +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IntegrationService.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.Application.Services; + +[IntegrationService] +public abstract class IntegrationService : ApplicationServiceBase +{ + +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IntegrationServiceAttribute.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IntegrationServiceAttribute.cs new file mode 100644 index 0000000000..4ba048a2f2 --- /dev/null +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IntegrationServiceAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace Volo.Abp.Application.Services; + +[AttributeUsage(AttributeTargets.Class)] +public class IntegrationServiceAttribute : Attribute +{ + +} \ No newline at end of file From 4f42ff1ee0e7c57fc8e9b1bf84f5738d1e701038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 8 Sep 2022 13:19:06 +0300 Subject: [PATCH 2/5] Remove ApplicationServiceBase --- .../Application/AbpDddApplicationModule.cs | 6 +- .../Services/ApplicationService.cs | 133 +++++++++++++++++- .../Services/ApplicationServiceBase.cs | 133 ------------------ .../Services/IntegrationService.cs | 7 - 4 files changed, 135 insertions(+), 144 deletions(-) delete mode 100644 framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationServiceBase.cs delete mode 100644 framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IntegrationService.cs diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/AbpDddApplicationModule.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/AbpDddApplicationModule.cs index 0608171aeb..bef608a6ff 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/AbpDddApplicationModule.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/AbpDddApplicationModule.cs @@ -1,5 +1,7 @@ using System.Collections.Generic; using Volo.Abp.Application.Services; +using Volo.Abp.Aspects; +using Volo.Abp.Auditing; using Volo.Abp.Authorization; using Volo.Abp.Domain; using Volo.Abp.Features; @@ -36,7 +38,9 @@ public class AbpDddApplicationModule : AbpModule options.IgnoredInterfaces.AddIfNotContains(typeof(IRemoteService)); options.IgnoredInterfaces.AddIfNotContains(typeof(IApplicationService)); options.IgnoredInterfaces.AddIfNotContains(typeof(IUnitOfWorkEnabled)); - //TODO: Should we add others, like IAuditingEnabled...? + options.IgnoredInterfaces.AddIfNotContains(typeof(IAuditingEnabled)); + options.IgnoredInterfaces.AddIfNotContains(typeof(IValidationEnabled)); + options.IgnoredInterfaces.AddIfNotContains(typeof(IGlobalFeatureCheckingEnabled)); }); } } diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs index 8389cf3fa4..b24e4b2900 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs @@ -1,6 +1,133 @@ +using JetBrains.Annotations; +using Microsoft.AspNetCore.Authorization; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Aspects; +using Volo.Abp.Auditing; +using Volo.Abp.Authorization; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Features; +using Volo.Abp.GlobalFeatures; +using Volo.Abp.Guids; +using Volo.Abp.Linq; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; +using Volo.Abp.ObjectMapping; +using Volo.Abp.Settings; +using Volo.Abp.Timing; +using Volo.Abp.Uow; +using Volo.Abp.Users; +using Volo.Abp.Validation; + namespace Volo.Abp.Application.Services; -public abstract class ApplicationService : ApplicationServiceBase +public abstract class ApplicationService : + IApplicationService, + IAvoidDuplicateCrossCuttingConcerns, + IValidationEnabled, + IUnitOfWorkEnabled, + IAuditingEnabled, + IGlobalFeatureCheckingEnabled, + ITransientDependency { - -} \ No newline at end of file + public IAbpLazyServiceProvider LazyServiceProvider { get; set; } + + [Obsolete("Use LazyServiceProvider instead.")] + public IServiceProvider ServiceProvider { get; set; } + + public static string[] CommonPostfixes { get; set; } = { "AppService", "ApplicationService", "IntService", "IntegrationService", "Service" }; + + public List AppliedCrossCuttingConcerns { get; } = new(); + + protected IUnitOfWorkManager UnitOfWorkManager => LazyServiceProvider.LazyGetRequiredService(); + + protected IAsyncQueryableExecuter AsyncExecuter => LazyServiceProvider.LazyGetRequiredService(); + + protected Type ObjectMapperContext { get; set; } + protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetService(provider => + ObjectMapperContext == null + ? provider.GetRequiredService() + : (IObjectMapper)provider.GetRequiredService(typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext))); + + protected IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService(SimpleGuidGenerator.Instance); + + protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService(); + + protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService(); + + protected IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService(); + + protected ICurrentUser CurrentUser => LazyServiceProvider.LazyGetRequiredService(); + + protected ISettingProvider SettingProvider => LazyServiceProvider.LazyGetRequiredService(); + + protected IClock Clock => LazyServiceProvider.LazyGetRequiredService(); + + protected IAuthorizationService AuthorizationService => LazyServiceProvider.LazyGetRequiredService(); + + protected IFeatureChecker FeatureChecker => LazyServiceProvider.LazyGetRequiredService(); + + protected IStringLocalizerFactory StringLocalizerFactory => LazyServiceProvider.LazyGetRequiredService(); + + protected IStringLocalizer L { + get { + if (_localizer == null) + { + _localizer = CreateLocalizer(); + } + + return _localizer; + } + } + private IStringLocalizer _localizer; + + protected Type LocalizationResource { + get => _localizationResource; + set { + _localizationResource = value; + _localizer = null; + } + } + private Type _localizationResource = typeof(DefaultResource); + + protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current; + + protected ILogger Logger => LazyServiceProvider.LazyGetService(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance); + + /// + /// Checks for given . + /// Throws if given policy has not been granted. + /// + /// The policy name. This method does nothing if given is null or empty. + protected virtual async Task CheckPolicyAsync([CanBeNull] string policyName) + { + if (string.IsNullOrEmpty(policyName)) + { + return; + } + + await AuthorizationService.CheckAsync(policyName); + } + + protected virtual IStringLocalizer CreateLocalizer() + { + if (LocalizationResource != null) + { + return StringLocalizerFactory.Create(LocalizationResource); + } + + var localizer = StringLocalizerFactory.CreateDefaultOrNull(); + if (localizer == null) + { + throw new AbpException($"Set {nameof(LocalizationResource)} or define the default localization resource type (by configuring the {nameof(AbpLocalizationOptions)}.{nameof(AbpLocalizationOptions.DefaultResourceType)}) to be able to use the {nameof(L)} object!"); + } + + return localizer; + } +} diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationServiceBase.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationServiceBase.cs deleted file mode 100644 index 7ed9ba5d5a..0000000000 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationServiceBase.cs +++ /dev/null @@ -1,133 +0,0 @@ -using JetBrains.Annotations; -using Microsoft.AspNetCore.Authorization; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Localization; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Volo.Abp.Aspects; -using Volo.Abp.Auditing; -using Volo.Abp.Authorization; -using Volo.Abp.Data; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Features; -using Volo.Abp.GlobalFeatures; -using Volo.Abp.Guids; -using Volo.Abp.Linq; -using Volo.Abp.Localization; -using Volo.Abp.MultiTenancy; -using Volo.Abp.ObjectMapping; -using Volo.Abp.Settings; -using Volo.Abp.Timing; -using Volo.Abp.Uow; -using Volo.Abp.Users; -using Volo.Abp.Validation; - -namespace Volo.Abp.Application.Services; - -public abstract class ApplicationServiceBase : - IApplicationService, - IAvoidDuplicateCrossCuttingConcerns, - IValidationEnabled, - IUnitOfWorkEnabled, - IAuditingEnabled, - IGlobalFeatureCheckingEnabled, - ITransientDependency -{ - public IAbpLazyServiceProvider LazyServiceProvider { get; set; } - - [Obsolete("Use LazyServiceProvider instead.")] - public IServiceProvider ServiceProvider { get; set; } - - public static string[] CommonPostfixes { get; set; } = { "AppService", "ApplicationService", "IntService", "IntegrationService", "Service" }; - - public List AppliedCrossCuttingConcerns { get; } = new(); - - protected IUnitOfWorkManager UnitOfWorkManager => LazyServiceProvider.LazyGetRequiredService(); - - protected IAsyncQueryableExecuter AsyncExecuter => LazyServiceProvider.LazyGetRequiredService(); - - protected Type ObjectMapperContext { get; set; } - protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetService(provider => - ObjectMapperContext == null - ? provider.GetRequiredService() - : (IObjectMapper)provider.GetRequiredService(typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext))); - - protected IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService(SimpleGuidGenerator.Instance); - - protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService(); - - protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService(); - - protected IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService(); - - protected ICurrentUser CurrentUser => LazyServiceProvider.LazyGetRequiredService(); - - protected ISettingProvider SettingProvider => LazyServiceProvider.LazyGetRequiredService(); - - protected IClock Clock => LazyServiceProvider.LazyGetRequiredService(); - - protected IAuthorizationService AuthorizationService => LazyServiceProvider.LazyGetRequiredService(); - - protected IFeatureChecker FeatureChecker => LazyServiceProvider.LazyGetRequiredService(); - - protected IStringLocalizerFactory StringLocalizerFactory => LazyServiceProvider.LazyGetRequiredService(); - - protected IStringLocalizer L { - get { - if (_localizer == null) - { - _localizer = CreateLocalizer(); - } - - return _localizer; - } - } - private IStringLocalizer _localizer; - - protected Type LocalizationResource { - get => _localizationResource; - set { - _localizationResource = value; - _localizer = null; - } - } - private Type _localizationResource = typeof(DefaultResource); - - protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current; - - protected ILogger Logger => LazyServiceProvider.LazyGetService(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance); - - /// - /// Checks for given . - /// Throws if given policy has not been granted. - /// - /// The policy name. This method does nothing if given is null or empty. - protected virtual async Task CheckPolicyAsync([CanBeNull] string policyName) - { - if (string.IsNullOrEmpty(policyName)) - { - return; - } - - await AuthorizationService.CheckAsync(policyName); - } - - protected virtual IStringLocalizer CreateLocalizer() - { - if (LocalizationResource != null) - { - return StringLocalizerFactory.Create(LocalizationResource); - } - - var localizer = StringLocalizerFactory.CreateDefaultOrNull(); - if (localizer == null) - { - throw new AbpException($"Set {nameof(LocalizationResource)} or define the default localization resource type (by configuring the {nameof(AbpLocalizationOptions)}.{nameof(AbpLocalizationOptions.DefaultResourceType)}) to be able to use the {nameof(L)} object!"); - } - - return localizer; - } -} diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IntegrationService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IntegrationService.cs deleted file mode 100644 index 805c3891af..0000000000 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IntegrationService.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Volo.Abp.Application.Services; - -[IntegrationService] -public abstract class IntegrationService : ApplicationServiceBase -{ - -} \ No newline at end of file From 02516fa20db19a9d85b45e8ea81db1b465ee26f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 8 Sep 2022 14:07:20 +0300 Subject: [PATCH 3/5] Integration service prefix should be `integration-service` by default. --- .../ConventionalControllerSetting.cs | 16 +++++++++ .../Conventions/ConventionalRouteBuilder.cs | 36 +++++++++++++++---- .../Mvc/PeopleIntegrationService_Tests.cs | 15 ++++++++ .../Application/IPeopleIntegrationService.cs | 9 +++++ .../Application/PeopleIntegrationService.cs | 13 +++++++ 5 files changed, 82 insertions(+), 7 deletions(-) create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PeopleIntegrationService_Tests.cs create mode 100644 framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/IPeopleIntegrationService.cs create mode 100644 framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleIntegrationService.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalControllerSetting.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalControllerSetting.cs index d1b0eef6ab..bb2f7f1d6f 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalControllerSetting.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalControllerSetting.cs @@ -33,6 +33,22 @@ public class ConventionalControllerSetting } } private string _rootPath; + + /// + /// Default value: null. + /// If not set, it uses + /// "api" for application services, + /// "integration-api" for integration services. + /// + [CanBeNull] + public string ApiRoutePrefix { + get => _apiRoutePrefix; + set { + Check.NotNull(value, nameof(value)); + _apiRoutePrefix = value; + } + } + private string _apiRoutePrefix; [NotNull] public string RemoteServiceName { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalRouteBuilder.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalRouteBuilder.cs index 3891827c0f..aa809e0ef3 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalRouteBuilder.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalRouteBuilder.cs @@ -4,6 +4,7 @@ using System.Reflection; using JetBrains.Annotations; using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.Extensions.Options; +using Volo.Abp.Application.Services; using Volo.Abp.DependencyInjection; using Volo.Abp.Http; using Volo.Abp.Reflection; @@ -26,9 +27,11 @@ public class ConventionalRouteBuilder : IConventionalRouteBuilder, ITransientDep string httpMethod, [CanBeNull] ConventionalControllerSetting configuration) { - var controllerNameInUrl = NormalizeUrlControllerName(rootPath, controllerName, action, httpMethod, configuration); + var apiRoutePrefix = GetApiRoutePrefix(action, configuration); + var controllerNameInUrl = + NormalizeUrlControllerName(rootPath, controllerName, action, httpMethod, configuration); - var url = $"api/{rootPath}/{NormalizeControllerNameCase(controllerNameInUrl, configuration)}"; + var url = $"{apiRoutePrefix}/{rootPath}/{NormalizeControllerNameCase(controllerNameInUrl, configuration)}"; //Add {id} path if needed var idParameterModel = action.Parameters.FirstOrDefault(p => p.ParameterName == "id"); @@ -69,6 +72,21 @@ public class ConventionalRouteBuilder : IConventionalRouteBuilder, ITransientDep return url; } + protected virtual string GetApiRoutePrefix(ActionModel actionModel, ConventionalControllerSetting configuration) + { + if (!configuration.ApiRoutePrefix.IsNullOrWhiteSpace()) + { + return configuration.ApiRoutePrefix; + } + + if (actionModel.Controller.ControllerType.IsDefined(typeof(IntegrationServiceAttribute), true)) + { + return "integration-api"; + } + + return "api"; + } + protected virtual string NormalizeUrlActionName(string rootPath, string controllerName, ActionModel action, string httpMethod, [CanBeNull] ConventionalControllerSetting configuration) { @@ -108,7 +126,8 @@ public class ConventionalRouteBuilder : IConventionalRouteBuilder, ITransientDep ); } - protected virtual string NormalizeControllerNameCase(string controllerName, [CanBeNull] ConventionalControllerSetting configuration) + protected virtual string NormalizeControllerNameCase(string controllerName, + [CanBeNull] ConventionalControllerSetting configuration) { if (configuration?.UseV3UrlStyle ?? Options.UseV3UrlStyle) { @@ -120,7 +139,8 @@ public class ConventionalRouteBuilder : IConventionalRouteBuilder, ITransientDep } } - protected virtual string NormalizeActionNameCase(string actionName, [CanBeNull] ConventionalControllerSetting configuration) + protected virtual string NormalizeActionNameCase(string actionName, + [CanBeNull] ConventionalControllerSetting configuration) { if (configuration?.UseV3UrlStyle ?? Options.UseV3UrlStyle) { @@ -132,13 +152,15 @@ public class ConventionalRouteBuilder : IConventionalRouteBuilder, ITransientDep } } - protected virtual string NormalizeIdPropertyNameCase(PropertyInfo property, [CanBeNull] ConventionalControllerSetting configuration) + protected virtual string NormalizeIdPropertyNameCase(PropertyInfo property, + [CanBeNull] ConventionalControllerSetting configuration) { return property.Name; } - protected virtual string NormalizeSecondaryIdNameCase(ParameterModel secondaryId, [CanBeNull] ConventionalControllerSetting configuration) + protected virtual string NormalizeSecondaryIdNameCase(ParameterModel secondaryId, + [CanBeNull] ConventionalControllerSetting configuration) { return secondaryId.ParameterName; } -} +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PeopleIntegrationService_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PeopleIntegrationService_Tests.cs new file mode 100644 index 0000000000..850eb12862 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PeopleIntegrationService_Tests.cs @@ -0,0 +1,15 @@ +using System.Threading.Tasks; +using Shouldly; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc; + +public class PeopleIntegrationService_Tests : AspNetCoreMvcTestBase +{ + [Fact] + public async Task GetValueAsync() + { + var result = await GetResponseAsStringAsync("/integration-api/app/people/value"); + result.ShouldBe("42"); + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/IPeopleIntegrationService.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/IPeopleIntegrationService.cs new file mode 100644 index 0000000000..7e4c76daaa --- /dev/null +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/IPeopleIntegrationService.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; +using Volo.Abp.Application.Services; + +namespace Volo.Abp.TestApp.Application; + +public interface IPeopleIntegrationService : IApplicationService +{ + Task GetValueAsync(); +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleIntegrationService.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleIntegrationService.cs new file mode 100644 index 0000000000..4501fdb16f --- /dev/null +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleIntegrationService.cs @@ -0,0 +1,13 @@ +using System.Threading.Tasks; +using Volo.Abp.Application.Services; + +namespace Volo.Abp.TestApp.Application; + +[IntegrationService] +public class PeopleIntegrationService : ApplicationService, IPeopleIntegrationService +{ + public async Task GetValueAsync() + { + return "42"; + } +} \ No newline at end of file From c8ec7d69059b58ec13fabd7e6c0b94eef54e390c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 8 Sep 2022 16:06:06 +0300 Subject: [PATCH 4/5] Implement AbpAuditingOptions.IsEnabledForIntegrationServices --- .../ActionDescriptorExtensions.cs | 10 ++++ .../Mvc/Auditing/AbpAuditActionFilter.cs | 20 ++++++- .../Mvc/Auditing/AbpAuditPageFilter.cs | 2 +- .../Conventions/ConventionalRouteBuilder.cs | 5 +- .../Abp/AspNetCore/AbpAspNetCoreConsts.cs | 7 +++ .../Auditing/AbpAspNetCoreAuditingOptions.cs | 2 +- .../Auditing/AbpAuditingMiddleware.cs | 19 +++++- .../Volo/Abp/Auditing/AuditingHelper.cs | 4 +- .../Volo/Abp/Auditing/AuditingInterceptor.cs | 4 +- .../Auditing/AuditingInterceptorRegistrar.cs | 9 ++- .../Volo/Abp/Auditing/IAuditingHelper.cs | 2 +- .../Volo/Abp}/IntegrationServiceAttribute.cs | 2 +- .../AuditIntegrationServiceTestController.cs | 14 +++++ ...tIntegrationServiceTestController_Tests.cs | 58 +++++++++++++++++++ .../Mvc/Auditing/AuditTestController_Tests.cs | 3 +- .../Volo/Abp/Auditing/Auditing_Tests.cs | 24 ++++++++ 16 files changed, 167 insertions(+), 18 deletions(-) create mode 100644 framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreConsts.cs rename framework/src/{Volo.Abp.Ddd.Application/Volo/Abp/Application/Services => Volo.Abp.Core/Volo/Abp}/IntegrationServiceAttribute.cs (74%) create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditIntegrationServiceTestController.cs create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditIntegrationServiceTestController_Tests.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/AspNetCore/Mvc/Abstractions/ActionDescriptorExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/AspNetCore/Mvc/Abstractions/ActionDescriptorExtensions.cs index 4bc4673860..24c9b071bd 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/AspNetCore/Mvc/Abstractions/ActionDescriptorExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/AspNetCore/Mvc/Abstractions/ActionDescriptorExtensions.cs @@ -43,4 +43,14 @@ public static class ActionDescriptorExtensions { return actionDescriptor is PageActionDescriptor; } + + public static PageActionDescriptor AsPageAction(this ActionDescriptor actionDescriptor) + { + if (!actionDescriptor.IsPageAction()) + { + throw new AbpException($"{nameof(actionDescriptor)} should be type of {typeof(PageActionDescriptor).AssemblyQualifiedName}"); + } + + return actionDescriptor as PageActionDescriptor; + } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs index 47ed4c4614..dfffeea5b4 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs @@ -70,7 +70,9 @@ public class AbpAuditActionFilter : IAsyncActionFilter, ITransientDependency } var auditingHelper = context.GetRequiredService(); - if (!auditingHelper.ShouldSaveAudit(context.ActionDescriptor.GetMethodInfo(), true)) + if (!auditingHelper.ShouldSaveAudit( + context.ActionDescriptor.GetMethodInfo(), + defaultValue: GetDefaultAuditBehavior(options, context.ActionDescriptor))) { return false; } @@ -85,4 +87,20 @@ public class AbpAuditActionFilter : IAsyncActionFilter, ITransientDependency return true; } + + private static bool GetDefaultAuditBehavior( + AbpAuditingOptions abpAuditingOptions, + ActionDescriptor actionDescriptor) + { + if (!abpAuditingOptions.IsEnabledForIntegrationServices && + actionDescriptor + .AsControllerActionDescriptor() + .ControllerTypeInfo + .IsDefined(typeof(IntegrationServiceAttribute), true)) + { + return false; + } + + return true; + } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs index 2abfd477db..1f347decf7 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs @@ -75,7 +75,7 @@ public class AbpAuditPageFilter : IAsyncPageFilter, ITransientDependency } var auditingHelper = context.GetRequiredService(); - if (!auditingHelper.ShouldSaveAudit(context.HandlerMethod.MethodInfo, true)) + if (!auditingHelper.ShouldSaveAudit(context.HandlerMethod.MethodInfo, defaultValue: true)) { return false; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalRouteBuilder.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalRouteBuilder.cs index aa809e0ef3..05e85fd340 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalRouteBuilder.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalRouteBuilder.cs @@ -4,7 +4,6 @@ using System.Reflection; using JetBrains.Annotations; using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.Extensions.Options; -using Volo.Abp.Application.Services; using Volo.Abp.DependencyInjection; using Volo.Abp.Http; using Volo.Abp.Reflection; @@ -81,10 +80,10 @@ public class ConventionalRouteBuilder : IConventionalRouteBuilder, ITransientDep if (actionModel.Controller.ControllerType.IsDefined(typeof(IntegrationServiceAttribute), true)) { - return "integration-api"; + return AbpAspNetCoreConsts.DefaultIntegrationServiceApiPrefix; } - return "api"; + return AbpAspNetCoreConsts.DefaultApiPrefix; } protected virtual string NormalizeUrlActionName(string rootPath, string controllerName, ActionModel action, diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreConsts.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreConsts.cs new file mode 100644 index 0000000000..dff987b6b3 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreConsts.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.AspNetCore; + +public static class AbpAspNetCoreConsts +{ + public const string DefaultApiPrefix = "api"; + public const string DefaultIntegrationServiceApiPrefix = "integration-api"; +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAspNetCoreAuditingOptions.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAspNetCoreAuditingOptions.cs index 7977205096..693945e903 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAspNetCoreAuditingOptions.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAspNetCoreAuditingOptions.cs @@ -10,5 +10,5 @@ public class AbpAspNetCoreAuditingOptions /// will be disabled for URLs /// starting with an ignored URL. /// - public List IgnoredUrls { get; } = new List(); + public List IgnoredUrls { get; } = new(); } diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs index 9cae64501a..83deaef26a 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs @@ -94,8 +94,23 @@ public class AbpAuditingMiddleware : IMiddleware, ITransientDependency private bool IsIgnoredUrl(HttpContext context) { - return context.Request.Path.Value != null && - AspNetCoreAuditingOptions.IgnoredUrls.Any(x => context.Request.Path.Value.StartsWith(x)); + if (context.Request.Path.Value == null) + { + return false; + } + + if (!AuditingOptions.IsEnabledForIntegrationServices && + context.Request.Path.Value.StartsWith($"/{AbpAspNetCoreConsts.DefaultIntegrationServiceApiPrefix}/")) + { + return true; + } + + if (AspNetCoreAuditingOptions.IgnoredUrls.Any(x => context.Request.Path.Value.StartsWith(x))) + { + return true; + } + + return false; } private async Task ShouldWriteAuditLogAsync(AuditLogInfo auditLogInfo, HttpContext httpContext, bool hasError) diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingHelper.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingHelper.cs index 1f3c6b433c..7468f10986 100644 --- a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingHelper.cs +++ b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingHelper.cs @@ -52,7 +52,7 @@ public class AuditingHelper : IAuditingHelper, ITransientDependency CorrelationIdProvider = correlationIdProvider; } - public virtual bool ShouldSaveAudit(MethodInfo methodInfo, bool defaultValue = false) + public virtual bool ShouldSaveAudit(MethodInfo methodInfo, bool defaultValue = false, bool ignoreIntegrationServiceAttribute = false) { if (methodInfo == null) { @@ -77,7 +77,7 @@ public class AuditingHelper : IAuditingHelper, ITransientDependency var classType = methodInfo.DeclaringType; if (classType != null) { - var shouldAudit = AuditingInterceptorRegistrar.ShouldAuditTypeByDefaultOrNull(classType); + var shouldAudit = AuditingInterceptorRegistrar.ShouldAuditTypeByDefaultOrNull(classType, ignoreIntegrationServiceAttribute); if (shouldAudit != null) { return shouldAudit.Value; diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs index 63c38ef3c3..78de793b6c 100644 --- a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs +++ b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs @@ -62,7 +62,9 @@ public class AuditingInterceptor : AbpInterceptor, ITransientDependency return false; } - if (!auditingHelper.ShouldSaveAudit(invocation.Method)) + if (!auditingHelper.ShouldSaveAudit( + invocation.Method, + ignoreIntegrationServiceAttribute: options.IsEnabledForIntegrationServices)) { return false; } diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptorRegistrar.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptorRegistrar.cs index 45af44ef91..db5d44cec5 100644 --- a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptorRegistrar.cs +++ b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptorRegistrar.cs @@ -22,7 +22,7 @@ public static class AuditingInterceptorRegistrar return false; } - if (ShouldAuditTypeByDefaultOrNull(type) == true) + if (ShouldAuditTypeByDefaultOrNull(type, ignoreIntegrationServiceAttribute: true) == true) { return true; } @@ -36,7 +36,7 @@ public static class AuditingInterceptorRegistrar } //TODO: Move to a better place - public static bool? ShouldAuditTypeByDefaultOrNull(Type type) + public static bool? ShouldAuditTypeByDefaultOrNull(Type type, bool ignoreIntegrationServiceAttribute) { //TODO: In an inheritance chain, it would be better to check the attributes on the top class first. @@ -52,7 +52,10 @@ public static class AuditingInterceptorRegistrar if (typeof(IAuditingEnabled).IsAssignableFrom(type)) { - return true; + if (ignoreIntegrationServiceAttribute || !type.IsDefined(typeof(IntegrationServiceAttribute), true)) + { + return true; + } } return null; diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/IAuditingHelper.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/IAuditingHelper.cs index 915d2fcfc1..5a2878d1b0 100644 --- a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/IAuditingHelper.cs +++ b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/IAuditingHelper.cs @@ -7,7 +7,7 @@ namespace Volo.Abp.Auditing; //TODO: Move ShouldSaveAudit & IsEntityHistoryEnabled and rename to IAuditingFactory public interface IAuditingHelper { - bool ShouldSaveAudit(MethodInfo methodInfo, bool defaultValue = false); + bool ShouldSaveAudit(MethodInfo methodInfo, bool defaultValue = false, bool ignoreIntegrationServiceAttribute = false); bool IsEntityHistoryEnabled(Type entityType, bool defaultValue = false); diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IntegrationServiceAttribute.cs b/framework/src/Volo.Abp.Core/Volo/Abp/IntegrationServiceAttribute.cs similarity index 74% rename from framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IntegrationServiceAttribute.cs rename to framework/src/Volo.Abp.Core/Volo/Abp/IntegrationServiceAttribute.cs index 4ba048a2f2..016a7a49c7 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IntegrationServiceAttribute.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/IntegrationServiceAttribute.cs @@ -1,6 +1,6 @@ using System; -namespace Volo.Abp.Application.Services; +namespace Volo.Abp; [AttributeUsage(AttributeTargets.Class)] public class IntegrationServiceAttribute : Attribute diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditIntegrationServiceTestController.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditIntegrationServiceTestController.cs new file mode 100644 index 0000000000..6e14e04d32 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditIntegrationServiceTestController.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Volo.Abp.AspNetCore.Mvc.Auditing; + +[Route("integration-api/audit-test")] +[IntegrationService] +public class AuditIntegrationServiceTestController : AbpController +{ + [HttpGet] + public IActionResult Get() + { + return Ok(); + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditIntegrationServiceTestController_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditIntegrationServiceTestController_Tests.cs new file mode 100644 index 0000000000..129035f406 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditIntegrationServiceTestController_Tests.cs @@ -0,0 +1,58 @@ +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Options; +using NSubstitute; +using Shouldly; +using Volo.Abp.Auditing; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.Auditing; + +public class AuditIntegrationServiceTestController_Tests : AspNetCoreMvcTestBase +{ + private readonly AbpAuditingOptions _options; + private IAuditingStore _auditingStore; + + public AuditIntegrationServiceTestController_Tests() + { + _options = ServiceProvider.GetRequiredService>().Value; + _auditingStore = ServiceProvider.GetRequiredService(); + } + + protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services) + { + _auditingStore = Substitute.For(); + services.Replace(ServiceDescriptor.Singleton(_auditingStore)); + base.ConfigureServices(context, services); + } + + [Fact] + public async Task Should_Write_Audit_Log_For_Controllers_With_IntegrationService_Attribute_If_IsEnabledForIntegrationServices() + { + _options.IsEnabledForGetRequests = true; + _options.IsEnabledForIntegrationServices = true; + await GetResponseAsync("/integration-api/audit-test/"); + await _auditingStore + .Received() + .SaveAsync( + Arg.Is( + x => x.Actions.Any( + a => + a.MethodName == nameof(AuditIntegrationServiceTestController.Get) && + a.ServiceName == typeof(AuditIntegrationServiceTestController).FullName + ) + ) + ); + } + + [Fact] + public async Task Should_Not_Write_Audit_Log_For_Controllers_With_IntegrationService_Attribute() + { + _options.IsEnabledForGetRequests = true; + await GetResponseAsync("/integration-api/audit-test/"); + await _auditingStore.DidNotReceive().SaveAsync(Arg.Any()); + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestController_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestController_Tests.cs index d36b5a5723..886df9a0ac 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestController_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestController_Tests.cs @@ -1,5 +1,4 @@ -using System; -using System.Linq; +using System.Linq; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; diff --git a/framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/Auditing_Tests.cs b/framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/Auditing_Tests.cs index e40fdd8b59..49d92d2776 100644 --- a/framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/Auditing_Tests.cs +++ b/framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/Auditing_Tests.cs @@ -55,6 +55,16 @@ public class Auditing_Tests : AbpAuditingTestBase await _auditingStore.Received().SaveAsync(Arg.Any()); } + + [Fact] + public async Task Should_Not_Write_AuditLog_For_Classes_With_IntegrationService_Attribute() + { + var myAuditedObject1 = GetRequiredService(); + + await myAuditedObject1.DoItAsync(new InputObject { Value1 = "forty-two", Value2 = 42 }); + + await _auditingStore.DidNotReceive().SaveAsync(Arg.Any()); + } public interface IMyAuditedObject : ITransientDependency, IAuditingEnabled { @@ -72,6 +82,20 @@ public class Auditing_Tests : AbpAuditingTestBase }); } } + + /* Integration services should not be audited by default */ + [IntegrationService] + public class MyNotAuditedIntegrationService1 : IMyAuditedObject + { + public virtual Task DoItAsync(InputObject inputObject) + { + return Task.FromResult(new ResultObject + { + Value1 = inputObject.Value1 + "-result", + Value2 = inputObject.Value2 + 1 + }); + } + } public class ResultObject { From c56473eeb7b02efdca7fd48f7fdabd3cbb9ee1d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 9 Sep 2022 08:31:01 +0300 Subject: [PATCH 5/5] Remove ConventionalControllerSetting.ApiRoutePrefix. --- .../Conventions/ConventionalControllerSetting.cs | 16 ---------------- .../Mvc/Conventions/ConventionalRouteBuilder.cs | 5 ----- 2 files changed, 21 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalControllerSetting.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalControllerSetting.cs index bb2f7f1d6f..d1b0eef6ab 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalControllerSetting.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalControllerSetting.cs @@ -33,22 +33,6 @@ public class ConventionalControllerSetting } } private string _rootPath; - - /// - /// Default value: null. - /// If not set, it uses - /// "api" for application services, - /// "integration-api" for integration services. - /// - [CanBeNull] - public string ApiRoutePrefix { - get => _apiRoutePrefix; - set { - Check.NotNull(value, nameof(value)); - _apiRoutePrefix = value; - } - } - private string _apiRoutePrefix; [NotNull] public string RemoteServiceName { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalRouteBuilder.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalRouteBuilder.cs index 05e85fd340..0906d46006 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalRouteBuilder.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalRouteBuilder.cs @@ -73,11 +73,6 @@ public class ConventionalRouteBuilder : IConventionalRouteBuilder, ITransientDep protected virtual string GetApiRoutePrefix(ActionModel actionModel, ConventionalControllerSetting configuration) { - if (!configuration.ApiRoutePrefix.IsNullOrWhiteSpace()) - { - return configuration.ApiRoutePrefix; - } - if (actionModel.Controller.ControllerType.IsDefined(typeof(IntegrationServiceAttribute), true)) { return AbpAspNetCoreConsts.DefaultIntegrationServiceApiPrefix;